This is Unofficial EPICS BASE Doxygen Site
lnkDebug.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2018 UChicago Argonne LLC, as Operator of Argonne
3 * National Laboratory.
4 * EPICS BASE is distributed subject to a Software License Agreement found
5 * in file LICENSE that is included with this distribution.
6 \*************************************************************************/
7 /* lnkDebug.c */
8 
9 /* Usage
10  * {debug:{...:...}}
11  */
12 
13 #include <string.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 
17 #include "alarm.h"
18 #include "dbDefs.h"
19 #include "dbAccessDefs.h"
20 #include "dbLink.h"
21 #include "dbJLink.h"
22 #include "dbStaticLib.h"
23 #include "errlog.h"
24 #include "epicsTime.h"
25 
26 #include "epicsExport.h"
27 
28 /* This is for debugging the debug link-type */
31 
32 #define IFDEBUG(n) if (lnkDebug_debug >= (n))
33 
34 typedef struct debug_link {
35  jlink jlink; /* embedded object */
36  short dbfType;
37  unsigned trace:1;
38  const jlif *child_jlif;
39  const lset *child_lset;
42  struct link child_link;
43 } debug_link;
44 
45 
46 /********************* Delegating jlif Routines *********************/
47 
48 static void delegate_free(jlink *pjlink)
49 {
50  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
51  const jlif *pif = dlink->child_jlif;
52  struct link *plink = &dlink->child_link;
53 
54  if (dlink->trace)
55  printf("Link trace: Calling %s::free_jlink(%p)\n",
56  pif->name, pjlink);
57 
58  pif->free_jlink(pjlink);
59  plink->type = 0;
60  plink->value.json.jlink = NULL;
61 
62  if (dlink->trace)
63  printf("Link trace: %s::free_jlink(%p) returned\n",
64  pif->name, pjlink);
65 }
66 
67 static jlif_result delegate_null(jlink *pjlink)
68 {
69  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
70  const jlif *pif = dlink->child_jlif;
71  jlif_result res;
72 
73  if (dlink->trace)
74  printf("Link trace: Calling %s::parse_null(%p)\n",
75  pif->name, pjlink);
76 
77  res = pif->parse_null(pjlink);
78 
79  if (dlink->trace)
80  printf("Link trace: %s::parse_null(%p) returned %s\n",
81  pif->name, pjlink, jlif_result_name[res]);
82 
83  return res;
84 }
85 
86 static jlif_result delegate_boolean(jlink *pjlink, int val)
87 {
88  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
89  const jlif *pif = dlink->child_jlif;
90  jlif_result res;
91 
92  if (dlink->trace)
93  printf("Link trace: Calling %s::parse_boolean(%p, %d)\n",
94  pif->name, pjlink, val);
95 
96  res = pif->parse_boolean(pjlink, val);
97 
98  if (dlink->trace)
99  printf("Link trace: %s::parse_boolean(%p) returned %s\n",
100  pif->name, pjlink, jlif_result_name[res]);
101 
102  return res;
103 }
104 
105 static jlif_result delegate_integer(jlink *pjlink, long long num)
106 {
107  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
108  const jlif *pif = dlink->child_jlif;
109  jlif_result res;
110 
111  if (dlink->trace)
112  printf("Link trace: Calling %s::parse_integer(%p, %lld)\n",
113  pif->name, pjlink, num);
114 
115  res = pif->parse_integer(pjlink, num);
116 
117  if (dlink->trace)
118  printf("Link trace: %s::parse_integer(%p) returned %s\n",
119  pif->name, pjlink, jlif_result_name[res]);
120 
121  return res;
122 }
123 
124 static jlif_result delegate_double(jlink *pjlink, double num)
125 {
126  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
127  const jlif *pif = dlink->child_jlif;
128  jlif_result res;
129 
130  if (dlink->trace)
131  printf("Link trace: Calling %s::parse_double(%p, %g)\n",
132  pif->name, pjlink, num);
133 
134  res = pif->parse_double(pjlink, num);
135 
136  if (dlink->trace)
137  printf("Link trace: %s::parse_double(%p) returned %s\n",
138  pif->name, pjlink, jlif_result_name[res]);
139 
140  return res;
141 }
142 
143 static jlif_result delegate_string(jlink *pjlink, const char *val, size_t len)
144 {
145  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
146  const jlif *pif = dlink->child_jlif;
147  jlif_result res;
148 
149  if (dlink->trace)
150  printf("Link trace: Calling %s::parse_string(%p, \"%.*s\")\n",
151  pif->name, pjlink, (int) len, val);
152 
153  res = pif->parse_string(pjlink, val, len);
154 
155  if (dlink->trace)
156  printf("Link trace: %s::parse_string(%p) returned %s\n",
157  pif->name, pjlink, jlif_result_name[res]);
158 
159  return res;
160 }
161 
162 static jlif_key_result delegate_start_map(jlink *pjlink)
163 {
164  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
165  const jlif *pif = dlink->child_jlif;
166  jlif_key_result res;
167 
168  if (dlink->trace)
169  printf("Link trace: Calling %s::parse_start_map(%p)\n",
170  pif->name, pjlink);
171 
172  res = pif->parse_start_map(pjlink);
173 
174  if (dlink->trace)
175  printf("Link trace: %s::parse_start_map(%p) returned %s\n",
176  pif->name, pjlink, jlif_key_result_name[res]);
177 
178  return res;
179 }
180 
181 static jlif_result delegate_map_key(jlink *pjlink, const char *key, size_t len)
182 {
183  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
184  const jlif *pif = dlink->child_jlif;
185  jlif_result res;
186 
187  if (dlink->trace)
188  printf("Link trace: Calling %s::parse_map_key(%p, \"%.*s\")\n",
189  pif->name, pjlink, (int) len, key);
190 
191  res = pif->parse_map_key(pjlink, key, len);
192 
193  if (dlink->trace)
194  printf("Link trace: %s::parse_map_key(%p) returned %s\n",
195  pif->name, pjlink, jlif_result_name[res]);
196 
197  return res;
198 }
199 
200 static jlif_result delegate_end_map(jlink *pjlink)
201 {
202  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
203  const jlif *pif = dlink->child_jlif;
204  jlif_result res;
205 
206  if (dlink->trace)
207  printf("Link trace: Calling %s::parse_end_map(%p)\n",
208  pif->name, pjlink);
209 
210  res = pif->parse_end_map(pjlink);
211 
212  if (dlink->trace)
213  printf("Link trace: %s::parse_end_map(%p) returned %s\n",
214  pif->name, pjlink, jlif_result_name[res]);
215 
216  return res;
217 }
218 
219 static jlif_result delegate_start_array(jlink *pjlink)
220 {
221  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
222  const jlif *pif = dlink->child_jlif;
223  jlif_result res;
224 
225  if (dlink->trace)
226  printf("Link trace: Calling %s::parse_(%p)\n",
227  pif->name, pjlink);
228 
229  res = pif->parse_start_array(pjlink);
230 
231  if (dlink->trace)
232  printf("Link trace: %s::parse_start_array(%p) returned %s\n",
233  pif->name, pjlink, jlif_result_name[res]);
234 
235  return res;
236 }
237 
238 static jlif_result delegate_end_array(jlink *pjlink)
239 {
240  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
241  const jlif *pif = dlink->child_jlif;
242  jlif_result res;
243 
244  if (dlink->trace)
245  printf("Link trace: Calling %s::parse_end_array(%p)\n",
246  pif->name, pjlink);
247 
248  res = pif->parse_end_array(pjlink);
249 
250  if (dlink->trace)
251  printf("Link trace: %s::parse_end_array(%p) returned %s\n",
252  pif->name, pjlink, jlif_result_name[res]);
253 
254  return res;
255 }
256 
257 static void delegate_start_child(jlink *pjlink, jlink *child)
258 {
259  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
260  const jlif *pif = dlink->child_jlif;
261 
262  if (dlink->trace)
263  printf("Link trace: Calling %s::start_child(%p, %p)\n",
264  pif->name, pjlink, child);
265 
266  pif->start_child(pjlink, child);
267 
268  if (dlink->trace)
269  printf("Link trace: %s::start_child(%p) returned\n",
270  pif->name, pjlink);
271 }
272 
273 static void delegate_end_child(jlink *pjlink, jlink *child)
274 {
275  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
276  const jlif *pif = dlink->child_jlif;
277 
278  if (dlink->trace)
279  printf("Link trace: Calling %s::end_child(%p, %p)\n",
280  pif->name, pjlink, child);
281 
282  pif->end_child(pjlink, child);
283 
284  if (dlink->trace)
285  printf("Link trace: %s::end_child(%p) returned\n",
286  pif->name, pjlink);
287 }
288 
289 static struct lset* delegate_get_lset(const jlink *pjlink)
290 {
291  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
292 
293  if (dlink->trace)
294  printf("Link trace: NOT calling %s::get_lset(%p)\n",
295  dlink->child_jlif->name, pjlink);
296 
297  return &dlink->lset;
298 }
299 
300 static void delegate_report(const jlink *pjlink, int level, int indent)
301 {
302  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
303  const jlif *pif = dlink->child_jlif;
304 
305  if (dlink->trace)
306  printf("Link trace: Calling %s::report(%p, %d, %d)\n",
307  pif->name, pjlink, level, indent);
308 
309  pif->report(pjlink, level, indent);
310 
311  if (dlink->trace)
312  printf("Link trace: %s::report(%p) returned\n",
313  pif->name, pjlink);
314 }
315 
316 static long delegate_map_children(jlink *pjlink, jlink_map_fn rtn, void *ctx)
317 {
318  debug_link *dlink = CONTAINER(pjlink->parent, struct debug_link, jlink);
319  const jlif *pif = dlink->child_jlif;
320  long res;
321 
322  if (dlink->trace)
323  printf("Link trace: Calling %s::map_children(%p, %p, %p)\n",
324  pif->name, pjlink, rtn, ctx);
325 
326  res = pif->map_children(pjlink, rtn, ctx);
327 
328  if (dlink->trace)
329  printf("Link trace: %s::map_children(%p) returned %ld\n",
330  pif->name, pjlink, res);
331 
332  return res;
333 }
334 
335 
336 /********************* Delegating lset Routines *********************/
337 
338 static void delegate_openLink(struct link *plink)
339 {
340  debug_link *dlink = CONTAINER(plink->value.json.jlink,
341  struct debug_link, jlink);
342  struct link *clink = &dlink->child_link;
343  const lset *clset = dlink->child_lset;
344 
345  if (dlink->trace)
346  printf("Link trace: Calling %s::openLink(%p = jlink %p)\n",
347  dlink->child_jlif->name, clink, clink->value.json.jlink);
348 
349  clink->precord = plink->precord;
350  clset->openLink(clink);
351 
352  if (dlink->trace)
353  printf("Link trace: %s::openLink(%p) returned\n",
354  dlink->child_jlif->name, clink);
355 }
356 
357 static void delegate_removeLink(struct dbLocker *locker, struct link *plink)
358 {
359  debug_link *dlink = CONTAINER(plink->value.json.jlink,
360  struct debug_link, jlink);
361  struct link *clink = &dlink->child_link;
362  const lset *clset = dlink->child_lset;
363 
364  if (dlink->trace)
365  printf("Link trace: Calling %s::removeLink(%p, %p)\n",
366  dlink->child_jlif->name, locker, clink);
367 
368  clset->removeLink(locker, clink);
369 
370  if (dlink->trace)
371  printf("Link trace: %s::removeLink(%p) returned\n",
372  dlink->child_jlif->name, clink);
373 }
374 
375 static long delegate_loadScalar(struct link *plink, short dbrType, void *pbuffer)
376 {
377  debug_link *dlink = CONTAINER(plink->value.json.jlink,
378  struct debug_link, jlink);
379  struct link *clink = &dlink->child_link;
380  const lset *clset = dlink->child_lset;
381  long res;
382 
383  if (dlink->trace)
384  printf("Link trace: Calling %s::loadScalar(%p, %s, %p)\n",
385  dlink->child_jlif->name, clink,
386  dbGetFieldTypeString(dbrType), pbuffer);
387 
388  res = clset->loadScalar(clink, dbrType, pbuffer);
389 
390  if (dlink->trace)
391  printf("Link trace: %s::loadScalar(%p) returned %ld (0x%lx)\n",
392  dlink->child_jlif->name, clink, res, res);
393 
394  return res;
395 }
396 
397 static long delegate_loadLS(struct link *plink, char *pbuffer, epicsUInt32 size,
398  epicsUInt32 *plen)
399 {
400  debug_link *dlink = CONTAINER(plink->value.json.jlink,
401  struct debug_link, jlink);
402  struct link *clink = &dlink->child_link;
403  const lset *clset = dlink->child_lset;
404  long res;
405 
406  if (dlink->trace)
407  printf("Link trace: Calling %s::loadLS(%p, %p, %u)\n",
408  dlink->child_jlif->name, clink, pbuffer, size);
409 
410  res = clset->loadLS(clink, pbuffer, size, plen);
411 
412  if (dlink->trace) {
413  printf("Link trace: %s::loadLS(%p) returned %ld (0x%lx)\n",
414  dlink->child_jlif->name, clink, res, res);
415  if (res == 0)
416  printf(" Loaded: %u byte(s) \"%s\"\n", *plen, pbuffer);
417  }
418 
419  return res;
420 }
421 
422 static long delegate_loadArray(struct link *plink, short dbrType, void *pbuffer,
423  long *pnRequest)
424 {
425  debug_link *dlink = CONTAINER(plink->value.json.jlink,
426  struct debug_link, jlink);
427  struct link *clink = &dlink->child_link;
428  const lset *clset = dlink->child_lset;
429  long res;
430 
431  if (dlink->trace)
432  printf("Link trace: Calling %s::loadArray(%p, %s, %p, %ld)\n",
433  dlink->child_jlif->name, clink,
434  dbGetFieldTypeString(dbrType), pbuffer, pnRequest ? *pnRequest : 0l);
435 
436  res = clset->loadArray(clink, dbrType, pbuffer, pnRequest);
437 
438  if (dlink->trace) {
439  printf("Link trace: %s::loadArray(%p) returned %ld (0x%lx)\n",
440  dlink->child_jlif->name, clink, res, res);
441  if (res == 0)
442  printf(" Loaded: %ld element(s)\n", pnRequest ? *pnRequest : 1l);
443  }
444 
445  return res;
446 }
447 
448 static int delegate_isConnected(const struct link *plink)
449 {
450  debug_link *dlink = CONTAINER(plink->value.json.jlink,
451  struct debug_link, jlink);
452  struct link *clink = &dlink->child_link;
453  const lset *clset = dlink->child_lset;
454  int res;
455 
456  if (dlink->trace)
457  printf("Link trace: Calling %s::isConnected(%p)\n",
458  dlink->child_jlif->name, clink);
459 
460  res = clset->isConnected(clink);
461 
462  if (dlink->trace)
463  printf("Link trace: %s::isConnected(%p) returned %d (%s)\n",
464  dlink->child_jlif->name, clink, res,
465  res == 0 ? "No" : res == 1 ? "Yes" : "Bad value");
466 
467  return res;
468 }
469 
470 static int delegate_getDBFtype(const struct link *plink)
471 {
472  debug_link *dlink = CONTAINER(plink->value.json.jlink,
473  struct debug_link, jlink);
474  struct link *clink = &dlink->child_link;
475  const lset *clset = dlink->child_lset;
476  int res;
477 
478  if (dlink->trace)
479  printf("Link trace: Calling %s::getDBFtype(%p)\n",
480  dlink->child_jlif->name, clink);
481 
482  res = clset->getDBFtype(clink);
483 
484  if (dlink->trace)
485  printf("Link trace: %s::getDBFtype(%p) returned %d (%s)\n",
486  dlink->child_jlif->name, clink, res,
487  res == -1 ? "Link disconnected" : dbGetFieldTypeString(res));
488 
489  return res;
490 }
491 
492 static long delegate_getElements(const struct link *plink, long *pnElements)
493 {
494  debug_link *dlink = CONTAINER(plink->value.json.jlink,
495  struct debug_link, jlink);
496  struct link *clink = &dlink->child_link;
497  const lset *clset = dlink->child_lset;
498  long res;
499 
500  if (dlink->trace)
501  printf("Link trace: Calling %s::getElements(%p)\n",
502  dlink->child_jlif->name, clink);
503 
504  res = clset->getElements(clink, pnElements);
505 
506  if (dlink->trace) {
507  printf("Link trace: %s::getElements(%p) returned %ld (0x%lx)\n",
508  dlink->child_jlif->name, clink, res, res);
509  if (res == 0)
510  printf(" Result: %ld element(s)\n", *pnElements);
511  }
512 
513  return res;
514 }
515 
516 static long delegate_getValue(struct link *plink, short dbrType, void *pbuffer,
517  long *pnRequest)
518 {
519  debug_link *dlink = CONTAINER(plink->value.json.jlink,
520  struct debug_link, jlink);
521  struct link *clink = &dlink->child_link;
522  const lset *clset = dlink->child_lset;
523  long res;
524 
525  if (dlink->trace)
526  printf("Link trace: Calling %s::getValue(%p, %s, %p, %ld)\n",
527  dlink->child_jlif->name, clink,
528  dbGetFieldTypeString(dbrType), pbuffer, pnRequest ? *pnRequest : 0l);
529 
530  res = clset->getValue(clink, dbrType, pbuffer, pnRequest);
531 
532  if (dlink->trace) {
533  printf("Link trace: %s::getValue(%p) returned %ld (0x%lx)\n",
534  dlink->child_jlif->name, clink, res, res);
535  if (res == 0)
536  printf(" Got: %ld element(s)\n", pnRequest ? *pnRequest : 1l);
537  }
538 
539  return res;
540 }
541 
542 static long delegate_getControlLimits(const struct link *plink,
543  double *lo, double *hi)
544 {
545  debug_link *dlink = CONTAINER(plink->value.json.jlink,
546  struct debug_link, jlink);
547  struct link *clink = &dlink->child_link;
548  const lset *clset = dlink->child_lset;
549  long res;
550 
551  if (dlink->trace)
552  printf("Link trace: Calling %s::getControlLimits(%p)\n",
553  dlink->child_jlif->name, clink);
554 
555  res = clset->getControlLimits(clink, lo, hi);
556 
557  if (dlink->trace) {
558  printf("Link trace: %s::getControlLimits(%p) returned %ld (0x%lx)\n",
559  dlink->child_jlif->name, clink, res, res);
560  if (res == 0)
561  printf(" Got: Lo = %g, Hi = %g\n", *lo, *hi);
562  }
563 
564  return res;
565 }
566 
567 static long delegate_getGraphicLimits(const struct link *plink,
568  double *lo, double *hi)
569 {
570  debug_link *dlink = CONTAINER(plink->value.json.jlink,
571  struct debug_link, jlink);
572  struct link *clink = &dlink->child_link;
573  const lset *clset = dlink->child_lset;
574  long res;
575 
576  if (dlink->trace)
577  printf("Link trace: Calling %s::getGraphicLimits(%p)\n",
578  dlink->child_jlif->name, clink);
579 
580  res = clset->getGraphicLimits(clink, lo, hi);
581 
582  if (dlink->trace) {
583  printf("Link trace: %s::getGraphicLimits(%p) returned %ld (0x%lx)\n",
584  dlink->child_jlif->name, clink, res, res);
585  if (res == 0)
586  printf(" Got: Lo = %g, Hi = %g\n", *lo, *hi);
587  }
588 
589  return res;
590 }
591 
592 static long delegate_getAlarmLimits(const struct link *plink,
593  double *lolo, double *lo, double *hi, double *hihi)
594 {
595  debug_link *dlink = CONTAINER(plink->value.json.jlink,
596  struct debug_link, jlink);
597  struct link *clink = &dlink->child_link;
598  const lset *clset = dlink->child_lset;
599  long res;
600 
601  if (dlink->trace)
602  printf("Link trace: Calling %s::getAlarmLimits(%p)\n",
603  dlink->child_jlif->name, clink);
604 
605  res = clset->getAlarmLimits(clink, lolo, lo, hi, hihi);
606 
607  if (dlink->trace) {
608  printf("Link trace: %s::getAlarmLimits(%p) returned %ld (0x%lx)\n",
609  dlink->child_jlif->name, clink, res, res);
610  if (res == 0)
611  printf(" Got: Lolo = %g, Lo = %g, Hi = %g, Hihi = %g\n",
612  *lolo, *lo, *hi, *hihi);
613  }
614 
615  return res;
616 }
617 
618 static long delegate_getPrecision(const struct link *plink, short *precision)
619 {
620  debug_link *dlink = CONTAINER(plink->value.json.jlink,
621  struct debug_link, jlink);
622  struct link *clink = &dlink->child_link;
623  const lset *clset = dlink->child_lset;
624  long res;
625 
626  if (dlink->trace)
627  printf("Link trace: Calling %s::getPrecision(%p)\n",
628  dlink->child_jlif->name, clink);
629 
630  res = clset->getPrecision(clink, precision);
631 
632  if (dlink->trace) {
633  printf("Link trace: %s::getPrecision(%p) returned %ld (0x%lx)\n",
634  dlink->child_jlif->name, clink, res, res);
635  if (res == 0)
636  printf(" Got: prec = %d\n", *precision);
637  }
638 
639  return res;
640 }
641 
642 static long delegate_getUnits(const struct link *plink, char *units, int unitsSize)
643 {
644  debug_link *dlink = CONTAINER(plink->value.json.jlink,
645  struct debug_link, jlink);
646  struct link *clink = &dlink->child_link;
647  const lset *clset = dlink->child_lset;
648  long res;
649 
650  if (dlink->trace)
651  printf("Link trace: Calling %s::getUnits(%p)\n",
652  dlink->child_jlif->name, clink);
653 
654  res = clset->getUnits(clink, units, unitsSize);
655 
656  if (dlink->trace) {
657  printf("Link trace: %s::getUnits(%p) returned %ld (0x%lx)\n",
658  dlink->child_jlif->name, clink, res, res);
659  if (res == 0)
660  printf(" Got: Units = '%s'\n", units);
661  }
662 
663  return res;
664 }
665 
666 static long delegate_getAlarm(const struct link *plink, epicsEnum16 *stat,
667  epicsEnum16 *sevr)
668 {
669  debug_link *dlink = CONTAINER(plink->value.json.jlink,
670  struct debug_link, jlink);
671  struct link *clink = &dlink->child_link;
672  const lset *clset = dlink->child_lset;
673  long res;
674 
675  if (dlink->trace)
676  printf("Link trace: Calling %s::getAlarm(%p)\n",
677  dlink->child_jlif->name, clink);
678 
679  res = clset->getAlarm(clink, stat, sevr);
680 
681  if (dlink->trace) {
682  printf("Link trace: %s::getAlarm(%p) returned %ld (0x%lx)\n",
683  dlink->child_jlif->name, clink, res, res);
684  if (res == 0)
685  printf(" Got:%s%s%s%s\n",
686  stat ? " Status = " : "",
687  stat && (*stat < ALARM_NSTATUS) ?
688  epicsAlarmConditionStrings[*stat] : "Bad-status",
689  sevr ? " Severity = " : "",
690  sevr && (*sevr < ALARM_NSEV) ?
691  epicsAlarmSeverityStrings[*sevr] : "Bad-severity"
692  );
693  }
694 
695  return res;
696 }
697 
698 static long delegate_getTimeStamp(const struct link *plink, epicsTimeStamp *pstamp)
699 {
700  debug_link *dlink = CONTAINER(plink->value.json.jlink,
701  struct debug_link, jlink);
702  struct link *clink = &dlink->child_link;
703  const lset *clset = dlink->child_lset;
704  long res;
705 
706  if (dlink->trace)
707  printf("Link trace: Calling %s::getTimeStamp(%p)\n",
708  dlink->child_jlif->name, clink);
709 
710  res = clset->getTimeStamp(clink, pstamp);
711 
712  if (dlink->trace) {
713  printf("Link trace: %s::getTimeStamp(%p) returned %ld (0x%lx)\n",
714  dlink->child_jlif->name, clink, res, res);
715  if (res == 0) {
716  char timeStr[32];
717 
718  epicsTimeToStrftime(timeStr, sizeof(timeStr),
719  "%Y-%m-%d %H:%M:%S.%09f", pstamp);
720  printf(" Got: Timestamp = '%s'\n", timeStr);
721  }
722  }
723 
724  return res;
725 }
726 
727 static long delegate_putValue(struct link *plink, short dbrType,
728  const void *pbuffer, long nRequest)
729 {
730  debug_link *dlink = CONTAINER(plink->value.json.jlink,
731  struct debug_link, jlink);
732  struct link *clink = &dlink->child_link;
733  const lset *clset = dlink->child_lset;
734  long res;
735 
736  if (dlink->trace)
737  printf("Link trace: Calling %s::putValue(%p, %s, %p, %ld)\n",
738  dlink->child_jlif->name, clink,
739  dbGetFieldTypeString(dbrType), pbuffer, nRequest);
740 
741  res = clset->putValue(clink, dbrType, pbuffer, nRequest);
742 
743  if (dlink->trace)
744  printf("Link trace: %s::putValue(%p) returned %ld (0x%lx)\n",
745  dlink->child_jlif->name, clink, res, res);
746 
747  return res;
748 }
749 
750 static long delegate_putAsync(struct link *plink, short dbrType,
751  const void *pbuffer, long nRequest)
752 {
753  debug_link *dlink = CONTAINER(plink->value.json.jlink,
754  struct debug_link, jlink);
755  struct link *clink = &dlink->child_link;
756  const lset *clset = dlink->child_lset;
757  long res;
758 
759  if (dlink->trace)
760  printf("Link trace: Calling %s::putAsync(%p, %s, %p, %ld)\n",
761  dlink->child_jlif->name, clink,
762  dbGetFieldTypeString(dbrType), pbuffer, nRequest);
763 
764  res = clset->putAsync(clink, dbrType, pbuffer, nRequest);
765 
766  if (dlink->trace)
767  printf("Link trace: %s::putAsync(%p) returned %ld (0x%lx)\n",
768  dlink->child_jlif->name, clink, res, res);
769 
770  return res;
771 }
772 
773 static void delegate_scanForward(struct link *plink)
774 {
775  debug_link *dlink = CONTAINER(plink->value.json.jlink,
776  struct debug_link, jlink);
777  struct link *clink = &dlink->child_link;
778  const lset *clset = dlink->child_lset;
779 
780  if (dlink->trace)
781  printf("Link trace: Calling %s::scanForward(%p)\n",
782  dlink->child_jlif->name, clink);
783 
784  clset->scanForward(clink);
785 
786  if (dlink->trace)
787  printf("Link trace: %s::scanForward(%p) returned\n",
788  dlink->child_jlif->name, clink);
789 }
790 
791 static long delegate_doLocked(struct link *plink, dbLinkUserCallback rtn, void *priv)
792 {
793  debug_link *dlink = CONTAINER(plink->value.json.jlink,
794  struct debug_link, jlink);
795  struct link *clink = &dlink->child_link;
796  const lset *clset = dlink->child_lset;
797  long res;
798 
799  if (dlink->trace)
800  printf("Link trace: Calling %s::doLocked(%p, %p, %p)\n",
801  dlink->child_jlif->name, clink, rtn, priv);
802 
803  res = clset->doLocked(clink, rtn, priv);
804 
805  if (dlink->trace)
806  printf("Link trace: %s::doLocked(%p) returned %ld (0x%lx)\n",
807  dlink->child_jlif->name, clink, res, res);
808 
809  return res;
810 }
811 
812 
813 /************************ Debug jlif Routines ***********************/
814 
815 static jlink* lnkDebug_alloc(short dbfType)
816 {
817  debug_link *dlink;
818 
819  IFDEBUG(10)
820  printf("lnkDebug_alloc(%s)\n", dbGetFieldTypeString(dbfType));
821 
822  dlink = calloc(1, sizeof(struct debug_link));
823  if (!dlink) {
824  errlogPrintf("lnkDebug: calloc() failed.\n");
825  return NULL;
826  }
827 
828  dlink->dbfType = dbfType;
829 
830  IFDEBUG(10)
831  printf("lnkDebug_alloc -> debug@%p\n", dlink);
832 
833  return &dlink->jlink;
834 }
835 
836 static jlink* lnkTrace_alloc(short dbfType)
837 {
838  debug_link *dlink;
839 
840  IFDEBUG(10)
841  printf("lnkTrace_alloc(%s)\n", dbGetFieldTypeString(dbfType));
842 
843  dlink = calloc(1, sizeof(struct debug_link));
844  if (!dlink) {
845  errlogPrintf("lnkTrace: calloc() failed.\n");
846  return NULL;
847  }
848 
849  dlink->dbfType = dbfType;
850  dlink->trace = 1;
851 
852  IFDEBUG(10)
853  printf("lnkTrace_alloc -> debug@%p\n", dlink);
854 
855  return &dlink->jlink;
856 }
857 
858 static void lnkDebug_free(jlink *pjlink)
859 {
860  debug_link *dlink = CONTAINER(pjlink, struct debug_link, jlink);
861 
862  IFDEBUG(10)
863  printf("lnkDebug_free(debug@%p)\n", dlink);
864 
865  dbJLinkFree(dlink->child_link.value.json.jlink);
866 
867  free(dlink);
868 }
869 
870 static jlif_key_result lnkDebug_start_map(jlink *pjlink)
871 {
872  debug_link *dlink = CONTAINER(pjlink, struct debug_link, jlink);
873 
874  IFDEBUG(10)
875  printf("lnkDebug_start_map(debug@%p)\n", dlink);
876 
877  switch (dlink->dbfType) {
878  case DBF_INLINK:
879  return jlif_key_child_inlink;
880  case DBF_OUTLINK:
881  return jlif_key_child_outlink;
882  case DBF_FWDLINK:
883  return jlif_key_child_outlink;
884  }
885  return jlif_key_stop;
886 }
887 
888 static jlif_result lnkDebug_end_map(jlink *pjlink)
889 {
890  debug_link *dlink = CONTAINER(pjlink, struct debug_link, jlink);
891 
892  IFDEBUG(10)
893  printf("lnkDebug_end_map(debug@%p)\n", dlink);
894 
895  return jlif_continue;
896 }
897 
898 static void lnkDebug_start_child(jlink *parent, jlink *child)
899 {
900  debug_link *dlink = CONTAINER(parent, struct debug_link, jlink);
901  const jlif *pif = child->pif;
902  const jlif delegate_jlif = {
903  pif->name,
904  pif->alloc_jlink, /* Never used */
905  delegate_free,
906  pif->parse_null ? delegate_null : NULL,
907  pif->parse_boolean ? delegate_boolean : NULL,
908  pif->parse_integer ? delegate_integer : NULL,
909  pif->parse_double ? delegate_double : NULL,
910  pif->parse_string ? delegate_string : NULL,
911  pif->parse_start_map ? delegate_start_map : NULL,
912  pif->parse_map_key ? delegate_map_key : NULL,
913  pif->parse_end_map ? delegate_end_map : NULL,
914  pif->parse_start_array ? delegate_start_array : NULL,
915  pif->parse_end_array ? delegate_end_array : NULL,
916  pif->end_child ? delegate_end_child : NULL,
917  delegate_get_lset,
918  pif->report ? delegate_report : NULL,
919  pif->map_children ? delegate_map_children : NULL,
920  pif->start_child ? delegate_start_child : NULL
921  };
922 
923  IFDEBUG(10)
924  printf("lnkDebug_start_child(debug@%p, %s@%p)\n", dlink,
925  child->pif->name, child);
926 
927  dlink->child_jlif = pif;
928  memcpy(&dlink->jlif, &delegate_jlif, sizeof(jlif));
929 
930  child->debug = 1;
931  child->pif = &dlink->jlif; /* Replace Child's interface table */
932 
933  IFDEBUG(15)
934  printf("lnkDebug_start_child: pif %p => %p\n", pif, child->pif);
935 
936  if (dlink->trace)
937  printf("Link trace: %s::alloc_jlink(%s) returned %p\n",
938  pif->name, dbGetFieldTypeString(dlink->dbfType), child);
939 }
940 
941 static void lnkDebug_end_child(jlink *parent, jlink *child)
942 {
943  debug_link *dlink = CONTAINER(parent, struct debug_link, jlink);
944  struct link *plink = &dlink->child_link;
945  const lset *plset = dlink->child_jlif->get_lset(child);
946  lset delegate_lset = {
947  plset->isConstant,
948  plset->isVolatile,
949  plset->openLink ? delegate_openLink : NULL,
950  plset->removeLink ? delegate_removeLink : NULL,
951  plset->loadScalar ? delegate_loadScalar : NULL,
952  plset->loadLS ? delegate_loadLS : NULL,
953  plset->loadArray ? delegate_loadArray : NULL,
954  plset->isConnected ? delegate_isConnected : NULL,
955  plset->getDBFtype ? delegate_getDBFtype : NULL,
956  plset->getElements ? delegate_getElements : NULL,
957  plset->getValue ? delegate_getValue : NULL,
958  plset->getControlLimits ? delegate_getControlLimits : NULL,
959  plset->getGraphicLimits ? delegate_getGraphicLimits : NULL,
960  plset->getAlarmLimits ? delegate_getAlarmLimits : NULL,
961  plset->getPrecision ? delegate_getPrecision : NULL,
962  plset->getUnits ? delegate_getUnits : NULL,
963  plset->getAlarm ? delegate_getAlarm : NULL,
964  plset->getTimeStamp ? delegate_getTimeStamp : NULL,
965  plset->putValue ? delegate_putValue : NULL,
966  plset->putAsync ? delegate_putAsync : NULL,
967  plset->scanForward ? delegate_scanForward : NULL,
968  plset->doLocked ? delegate_doLocked : NULL
969  };
970 
971  IFDEBUG(10)
972  printf("lnkDebug_end_child(debug@%p, %s@%p)\n", dlink,
973  child->pif->name, child);
974 
975  plink->type = JSON_LINK;
976  plink->value.json.string = NULL;
977  plink->value.json.jlink = child;
978 
979  dlink->child_lset = plset;
980  memcpy(&dlink->lset, &delegate_lset, sizeof(lset));
981 
982  IFDEBUG(15)
983  printf("lnkDebug_end_child: lset %p => %p\n", plset, &dlink->lset);
984 }
985 
986 static struct lset* lnkDebug_get_lset(const jlink *pjlink)
987 {
988  debug_link *dlink = CONTAINER(pjlink, struct debug_link, jlink);
989 
990  IFDEBUG(10)
991  printf("lnkDebug_get_lset(debug@%p)\n", pjlink);
992 
993  return &dlink->lset;
994 }
995 
996 static void lnkDebug_report(const jlink *pjlink, int level, int indent)
997 {
998  debug_link *dlink = CONTAINER(pjlink, struct debug_link, jlink);
999 
1000  IFDEBUG(10)
1001  printf("lnkDebug_report(debug@%p)\n", dlink);
1002 
1003  if (dlink->trace)
1004  printf("%*s'trace':\n", indent, "");
1005  else
1006  printf("%*s'debug':\n", indent, "");
1007 
1008  if (dlink->child_link.type == JSON_LINK) {
1009  dbJLinkReport(dlink->child_link.value.json.jlink, level, indent + 2);
1010  }
1011 }
1012 
1013 long lnkDebug_map_children(jlink *pjlink, jlink_map_fn rtn, void *ctx)
1014 {
1015  debug_link *dlink = CONTAINER(pjlink, struct debug_link, jlink);
1016 
1017  IFDEBUG(10)
1018  printf("lnkDebug_map_children(debug@%p)\n", dlink);
1019 
1020  if (dlink->child_link.type == JSON_LINK) {
1021  return dbJLinkMapChildren(&dlink->child_link, rtn, ctx);
1022  }
1023  return 0;
1024 }
1025 
1026 
1027 /************************* Interface Tables *************************/
1028 
1029 static jlif lnkDebugIf = {
1030  "debug", lnkDebug_alloc, lnkDebug_free,
1031  NULL, NULL, NULL, NULL, NULL,
1032  lnkDebug_start_map, NULL, lnkDebug_end_map,
1033  NULL, NULL, lnkDebug_end_child, lnkDebug_get_lset,
1034  lnkDebug_report, lnkDebug_map_children, lnkDebug_start_child
1035 };
1036 epicsExportAddress(jlif, lnkDebugIf);
1037 
1038 static jlif lnkTraceIf = {
1039  "trace", lnkTrace_alloc, lnkDebug_free,
1040  NULL, NULL, NULL, NULL, NULL,
1041  lnkDebug_start_map, NULL, lnkDebug_end_map,
1042  NULL, NULL, lnkDebug_end_child, lnkDebug_get_lset,
1043  lnkDebug_report, lnkDebug_map_children, lnkDebug_start_child
1044 };
1045 epicsExportAddress(jlif, lnkTraceIf);
Definition: link.h:174
struct debug_link debug_link
#define CONTAINER(ptr, structure, member)
Find parent object from a member pointer.
Definition: dbDefs.h:66
#define printf
Definition: epicsStdio.h:41
pvd::StructureConstPtr type
#define NULL
Definition: catime.c:38
unsigned int epicsUInt32
Definition: epicsTypes.h:43
dbfType
Definition: dbFldTypes.h:24
Miscellaneous macro definitions.
int lnkDebug_debug
Definition: lnkDebug.c:29
LIBCOM_API const char * epicsAlarmSeverityStrings[ALARM_NSEV]
How to convert an alarm severity into a string.
Definition: alarmString.c:16
#define IFDEBUG(n)
Definition: lnkDebug.c:32
LIBCOM_API size_t epicsStdCall epicsTimeToStrftime(char *pBuff, size_t bufLength, const char *pFormat, const epicsTimeStamp *pTS)
Convert epicsTimeStamp to string. See epicsTime::strftime()
Definition: epicsTime.cpp:1120
#define static
Definition: reader.c:44
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
char * pbuffer
Definition: errlog.c:85
epicsUInt16 epicsEnum16
Definition: epicsTypes.h:47
EPICS time stamp, for use from C code.
Definition: epicsTime.h:33
long lnkDebug_map_children(jlink *pjlink, jlink_map_fn rtn, void *ctx)
Definition: lnkDebug.c:1013
if(yy_init)
Definition: scan.c:972
const char * dbGetFieldTypeString(int dbfType)
Definition: dbStaticLib.c:2988
epicsExportAddress(int, lnkDebug_debug)
EPICS time-stamps (epicsTimeStamp), epicsTime C++ class and C functions for handling wall-clock times...
struct json_link json
Definition: link.h:177
LIBCOM_API const char * epicsAlarmConditionStrings[ALARM_NSTATUS]
How to convert an alarm condition/status into a string.
Definition: alarmString.c:26
Exporting IOC objects.