  2729 |     */
  2730 |
  2731 |     snprintf(pc->custom_ppd_size, sizeof(pc->custom_ppd_size), "Custom.%dx%d",
  2732 |              (int)PWG_TO_POINTS(jobsize.width), (int)PWG_TO_POINTS(jobsize.length));
  2733 |
  2734 |     if (margins_set && exact)
  2735 |     {
  2736 |       dleft   = pc->custom_size.left - jobsize.left;
  2737 |       dright  = pc->custom_size.right - jobsize.right;
  2738 |       dtop    = pc->custom_size.top - jobsize.top;
  2739 |       dbottom = pc->custom_size.bottom - jobsize.bottom;
  2740 |
  2741 |       if (dleft > -35 && dleft < 35 && dright > -35 && dright < 35 &&
  2742 |           dtop > -35 && dtop < 35 && dbottom > -35 && dbottom < 35)
  2743 | 	*exact = 1;
  2744 |     }
  2745 |     else if (exact)
  2746 |       *exact = 1;
  2747 |
  2748 |     DEBUG_printf("1_ppdCacheGetPageSize: Returning \"%s\" (custom)", pc->custom_ppd_size);
  2749 |
  2750 |     return (pc->custom_ppd_size);
  2751 |   }
  2752 |
  2753 |  /*
  2754 |   * No custom page size support or the size is out of range - return NULL.
  2755 |   */
  2756 |
  2757 |   DEBUG_puts("1_ppdCacheGetPageSize: Returning NULL");
  2758 |
  2759 |   return (NULL);
  2760 | }
  2761 |
  2762 |
  2763 | /*
  2764 |  * '_ppdCacheGetSize()' - Get the PWG size associated with a PPD PageSize.
  2765 |  */
  2766 |
  2767 | pwg_size_t *				/* O - PWG size or NULL */
  2768 | _ppdCacheGetSize(
  2769 |     _ppd_cache_t *pc,			/* I - PPD cache and mapping data */
  2770 |     const char   *page_size,		/* I - PPD PageSize */
  2771 |     ppd_size_t   *ppd_size)		/* I - PPD page size information */
  2772 | {
  2773 |   int		i;			/* Looping var */
  2774 |   pwg_media_t	*media;			/* Media */
  2775 |   pwg_size_t	*size;			/* Current size */
  2776 |
  2777 |
  2778 |  /*
  2779 |   * Range check input...
  2780 |   */
  2781 |
  2782 |   if (!pc || !page_size)
  2783 |     return (NULL);
  2784 |
  2785 |   if (!_cups_strcasecmp(page_size, "Custom") || !_cups_strncasecmp(page_size, "Custom.", 7))
  2786 |   {
  2787 |    /*
  2788 |     * Custom size; size name can be one of the following:
  2789 |     *
  2790 |     *    Custom.WIDTHxLENGTHin    - Size in inches
  2791 |     *    Custom.WIDTHxLENGTHft    - Size in feet
  2792 |     *    Custom.WIDTHxLENGTHcm    - Size in centimeters
  2793 |     *    Custom.WIDTHxLENGTHmm    - Size in millimeters
  2794 |     *    Custom.WIDTHxLENGTHm     - Size in meters
  2795 |     *    Custom.WIDTHxLENGTH[pt]  - Size in points
  2796 |     */
  2797 |
  2798 |     double		w, l;		/* Width and length of page */
  2799 |     char		*ptr;		/* Pointer into PageSize */
  2800 |     struct lconv	*loc;		/* Locale data */
  2801 |
  2802 |     if (page_size[6])
  2803 |     {
  2804 |       loc = localeconv();
  2805 |       w   = (float)_cupsStrScand(page_size + 7, &ptr, loc);
  2806 |       if (!ptr || *ptr != 'x')
  2807 | 	return (NULL);
  2808 |
  2809 |       l = (float)_cupsStrScand(ptr + 1, &ptr, loc);
  2810 |       if (!ptr)
  2811 | 	return (NULL);
  2812 |
  2813 |       if (!_cups_strcasecmp(ptr, "in"))
  2814 |       {
  2815 | 	w *= 2540.0;
  2816 | 	l *= 2540.0;
  2817 |       }
  2818 |       else if (!_cups_strcasecmp(ptr, "ft"))
  2819 |       {
  2820 | 	w *= 12.0 * 2540.0;
  2821 | 	l *= 12.0 * 2540.0;
  2822 |       }
  2823 |       else if (!_cups_strcasecmp(ptr, "mm"))
  2824 |       {
  2825 | 	w *= 100.0;
  2826 | 	l *= 100.0;
  2827 |       }
  2828 |       else if (!_cups_strcasecmp(ptr, "cm"))
> 2829 |       {
  2830 | 	w *= 1000.0;
  2831 | 	l *= 1000.0;
  2832 |       }
  2833 |       else if (!_cups_strcasecmp(ptr, "m"))
  2834 |       {
  2835 | 	w *= 100000.0;
  2836 | 	l *= 100000.0;
  2837 |       }
  2838 |       else
  2839 |       {
  2840 | 	w *= 2540.0 / 72.0;
  2841 | 	l *= 2540.0 / 72.0;
  2842 |       }
  2843 |     }
  2844 |     else if (ppd_size)
  2845 |     {
  2846 |       w = ppd_size->width * 2540.0 / 72.0;
  2847 |       l = ppd_size->length * 2540.0 / 72.0;
  2848 |     }
  2849 |     else
  2850 |     {
  2851 |       // No custom size information...
  2852 |       return (NULL);
  2853 |     }
  2854 |
  2855 |     pwgFormatSizeName(pc->custom_pwg_size, sizeof(pc->custom_pwg_size), "custom", /*name*/NULL, (int)w, (int)l, /*units*/NULL);
  2856 |
  2857 |     pc->custom_size.map.ppd = (char *)page_size;
  2858 |     pc->custom_size.map.pwg = pc->custom_pwg_size;
  2859 |     pc->custom_size.width   = (int)w;
  2860 |     pc->custom_size.length  = (int)l;
  2861 |
  2862 |     return (&(pc->custom_size));
  2863 |   }
  2864 |
  2865 |  /*
  2866 |   * Not a custom size - look it up...
  2867 |   */
  2868 |
  2869 |   for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++)
  2870 |   {
  2871 |     if (!_cups_strcasecmp(page_size, size->map.ppd) ||
  2872 |         !_cups_strcasecmp(page_size, size->map.pwg))
  2873 |       return (size);
  2874 |   }
  2875 |
  2876 |  /*
  2877 |   * Look up standard sizes...
  2878 |   */
  2879 |
  2880 |   if ((media = pwgMediaForPPD(page_size)) == NULL)
  2881 |   {
  2882 |     if ((media = pwgMediaForLegacy(page_size)) == NULL)
  2883 |       media = pwgMediaForPWG(page_size);
  2884 |   }
  2885 |
  2886 |   if (media)
  2887 |   {
  2888 |     pc->custom_size.map.ppd = (char *)page_size;
  2889 |     pc->custom_size.map.pwg = (char *)media->pwg;
  2890 |     pc->custom_size.width   = media->width;
  2891 |     pc->custom_size.length  = media->length;
  2892 |
  2893 |     return (&(pc->custom_size));
  2894 |   }
  2895 |
  2896 |   return (NULL);
  2897 | }
  2898 |
  2899 |
  2900 | /*
  2901 |  * '_ppdCacheGetSource()' - Get the PWG media-source associated with a PPD
  2902 |  *                          InputSlot.
  2903 |  */
  2904 |
  2905 | const char *				/* O - PWG media-source keyword */
  2906 | _ppdCacheGetSource(
  2907 |     _ppd_cache_t *pc,			/* I - PPD cache and mapping data */
  2908 |     const char   *input_slot)		/* I - PPD InputSlot */
  2909 | {
  2910 |   int		i;			/* Looping var */
  2911 |   pwg_map_t	*source;		/* Current source */
  2912 |
  2913 |
  2914 |  /*
  2915 |   * Range check input...
  2916 |   */
  2917 |
  2918 |   if (!pc || !input_slot)
  2919 |     return (NULL);
  2920 |
  2921 |   for (i = pc->num_sources, source = pc->sources; i > 0; i --, source ++)
  2922 |     if (!_cups_strcasecmp(input_slot, source->ppd) || !_cups_strcasecmp(input_slot, source->pwg))
  2923 |       return (source->pwg);
  2924 |
  2925 |   return (NULL);
  2926 | }
  2927 |
  2928 |
  2929 | /*

Reach line at /src/cups/cups/ppd-cache.c:2829 (observed count 3).


  1340 | 	  cupsCopyString(option->text, name, sizeof(option->text));
  1341 |       }
  1342 |
  1343 |       option->section = PPD_ORDER_ANY;
  1344 |
  1345 |       free(string);
  1346 |       string = NULL;
  1347 |
  1348 |      /*
  1349 |       * Add a custom option choice if we have already seen a CustomFoo
  1350 |       * attribute...
  1351 |       */
  1352 |
  1353 |       if (!_cups_strcasecmp(name, "PageRegion"))
  1354 |         cupsCopyString(custom_name, "CustomPageSize", sizeof(custom_name));
  1355 |       else
  1356 |         snprintf(custom_name, sizeof(custom_name), "Custom%s", name);
  1357 |
  1358 |       if ((custom_attr = ppdFindAttr(ppd, custom_name, "True")) != NULL)
  1359 |       {
  1360 |         if ((choice = ppdFindChoice(option, "Custom")) == NULL)
  1361 | 	  if ((choice = ppd_add_choice(option, "Custom")) == NULL)
  1362 | 	  {
  1363 | 	    DEBUG_puts("1_ppdOpen: Unable to add Custom choice!");
  1364 |
  1365 | 	    pg->ppd_status = PPD_ALLOC_ERROR;
  1366 |
  1367 | 	    goto error;
  1368 | 	  }
  1369 |
  1370 | 	cupsCopyString(choice->text,
  1371 | 	        custom_attr->text[0] ? custom_attr->text : _("Custom"),
  1372 | 		sizeof(choice->text));
  1373 |         choice->code = strdup(custom_attr->value);
  1374 |       }
  1375 |     }
  1376 |     else if (!strcmp(keyword, "JCLOpenUI"))
  1377 |     {
  1378 |      /*
  1379 |       * Don't allow nesting of options...
  1380 |       */
  1381 |
  1382 |       if (option && pg->ppd_conform == PPD_CONFORM_STRICT)
  1383 |       {
  1384 |         pg->ppd_status = PPD_NESTED_OPEN_UI;
  1385 |
  1386 | 	goto error;
  1387 |       }
  1388 |
  1389 |      /*
  1390 |       * Find the JCL group, and add if needed...
  1391 |       */
  1392 |
  1393 |       group = ppd_get_group(ppd, "JCL", _("JCL"), pg, encoding);
  1394 |
  1395 |       if (group == NULL)
  1396 | 	goto error;
  1397 |
  1398 |      /*
  1399 |       * Add an option record to the current JCLs...
  1400 |       */
  1401 |
  1402 |       if (name[0] == '*')
  1403 |         _cups_strcpy(name, name + 1);
  1404 |
  1405 |       option = ppd_get_option(group, name);
  1406 |
  1407 |       if (option == NULL)
  1408 |       {
  1409 |         pg->ppd_status = PPD_ALLOC_ERROR;
  1410 |
  1411 | 	goto error;
  1412 |       }
  1413 |
  1414 |      /*
  1415 |       * Now fill in the initial information for the option...
  1416 |       */
  1417 |
  1418 |       if (string && !strcmp(string, "PickMany"))
  1419 |         option->ui = PPD_UI_PICKMANY;
  1420 |       else if (string && !strcmp(string, "Boolean"))
  1421 |         option->ui = PPD_UI_BOOLEAN;
  1422 |       else if (string && !strcmp(string, "PickOne"))
  1423 |         option->ui = PPD_UI_PICKONE;
  1424 |       else
  1425 |       {
  1426 |         pg->ppd_status = PPD_BAD_OPEN_UI;
  1427 |
  1428 | 	goto error;
  1429 |       }
  1430 |
  1431 |       for (j = 0; j < ppd->num_attrs; j ++)
  1432 | 	if (!strncmp(ppd->attrs[j]->name, "Default", 7) &&
  1433 | 	    !strcmp(ppd->attrs[j]->name + 7, name) &&
  1434 | 	    ppd->attrs[j]->value)
  1435 | 	{
  1436 | 	  DEBUG_printf("2_ppdOpen: Setting Default%s to %s via attribute...", option->keyword, ppd->attrs[j]->value);
  1437 | 	  cupsCopyString(option->defchoice, ppd->attrs[j]->value,
  1438 | 	          sizeof(option->defchoice));
  1439 | 	  break;
> 1440 | 	}
  1441 |
  1442 |       if (text[0])
  1443 |         cupsCharsetToUTF8((cups_utf8_t *)option->text, text,
  1444 | 	                   sizeof(option->text), encoding);
  1445 |       else
  1446 |         cupsCopyString(option->text, name, sizeof(option->text));
  1447 |
  1448 |       option->section = PPD_ORDER_JCL;
  1449 |       group = NULL;
  1450 |
  1451 |       free(string);
  1452 |       string = NULL;
  1453 |
  1454 |      /*
  1455 |       * Add a custom option choice if we have already seen a CustomFoo
  1456 |       * attribute...
  1457 |       */
  1458 |
  1459 |       snprintf(custom_name, sizeof(custom_name), "Custom%s", name);
  1460 |
  1461 |       if ((custom_attr = ppdFindAttr(ppd, custom_name, "True")) != NULL)
  1462 |       {
  1463 | 	if ((choice = ppd_add_choice(option, "Custom")) == NULL)
  1464 | 	{
  1465 | 	  DEBUG_puts("1_ppdOpen: Unable to add Custom choice!");
  1466 |
  1467 | 	  pg->ppd_status = PPD_ALLOC_ERROR;
  1468 |
  1469 | 	  goto error;
  1470 | 	}
  1471 |
  1472 | 	cupsCopyString(choice->text,
  1473 | 	        custom_attr->text[0] ? custom_attr->text : _("Custom"),
  1474 | 		sizeof(choice->text));
  1475 |         choice->code = strdup(custom_attr->value);
  1476 |       }
  1477 |     }
  1478 |     else if (!strcmp(keyword, "CloseUI"))
  1479 |     {
  1480 |       if ((!option || option->section == PPD_ORDER_JCL) && pg->ppd_conform == PPD_CONFORM_STRICT)
  1481 |       {
  1482 |         pg->ppd_status = PPD_BAD_CLOSE_UI;
  1483 |
  1484 | 	goto error;
  1485 |       }
  1486 |
  1487 |       if (option && (!_cups_strcasecmp(option->defchoice, "custom") || !_cups_strncasecmp(option->defchoice, "custom.", 7)))
  1488 |       {
  1489 |        /*
  1490 | 	* "*DefaultOption: Custom..." may set the default to a custom value
  1491 | 	* or (for a very small number of incompatible PPD files) select a
  1492 | 	* standard choice for the option, which CUPS renames to "_Custom..."
  1493 | 	* to avoid compatibility issues.  See which this is...
  1494 | 	*/
  1495 |
  1496 |         char tchoice[PPD_MAX_NAME];	/* Temporary choice name */
  1497 |
  1498 | 	snprintf(tchoice, sizeof(tchoice), "_%s", option->defchoice);
  1499 |
  1500 | 	if (ppdFindChoice(option, tchoice))
  1501 | 	{
  1502 | 	  cupsCopyString(option->defchoice, tchoice, sizeof(option->defchoice));
  1503 |
  1504 | 	  DEBUG_printf("2_ppdOpen: Reset Default%s to %s...", option->keyword, tchoice);
  1505 | 	}
  1506 |       }
  1507 |
  1508 |       option = NULL;
  1509 |
  1510 |       free(string);
  1511 |       string = NULL;
  1512 |     }
  1513 |     else if (!strcmp(keyword, "JCLCloseUI"))
  1514 |     {
  1515 |       if ((!option || option->section != PPD_ORDER_JCL) && pg->ppd_conform == PPD_CONFORM_STRICT)
  1516 |       {
  1517 |         pg->ppd_status = PPD_BAD_CLOSE_UI;
  1518 |
  1519 | 	goto error;
  1520 |       }
  1521 |
  1522 |       if (option && (!_cups_strcasecmp(option->defchoice, "custom") || !_cups_strncasecmp(option->defchoice, "custom.", 7)))
  1523 |       {
  1524 |        /*
  1525 | 	* "*DefaultOption: Custom..." may set the default to a custom value
  1526 | 	* or (for a very small number of incompatible PPD files) select a
  1527 | 	* standard choice for the option, which CUPS renames to "_Custom..."
  1528 | 	* to avoid compatibility issues.  See which this is...
  1529 | 	*/
  1530 |
  1531 |         char tchoice[PPD_MAX_NAME];	/* Temporary choice name */
  1532 |
  1533 | 	snprintf(tchoice, sizeof(tchoice), "_%s", option->defchoice);
  1534 |
  1535 | 	if (ppdFindChoice(option, tchoice))
  1536 | 	{
  1537 | 	  cupsCopyString(option->defchoice, tchoice, sizeof(option->defchoice));
  1538 |
  1539 | 	  DEBUG_printf("2_ppdOpen: Reset Default%s to %s...", option->keyword, tchoice);
  1540 | 	}

Reach line at /src/cups/cups/ppd.c:1440 (observed count 29600).


  2725 |       jobsize.length <= pc->custom_max_length)
  2726 |   {
  2727 |    /*
  2728 |     * In range, format as Custom.WWWWxLLLL (points).
  2729 |     */
  2730 |
  2731 |     snprintf(pc->custom_ppd_size, sizeof(pc->custom_ppd_size), "Custom.%dx%d",
  2732 |              (int)PWG_TO_POINTS(jobsize.width), (int)PWG_TO_POINTS(jobsize.length));
  2733 |
  2734 |     if (margins_set && exact)
  2735 |     {
  2736 |       dleft   = pc->custom_size.left - jobsize.left;
  2737 |       dright  = pc->custom_size.right - jobsize.right;
  2738 |       dtop    = pc->custom_size.top - jobsize.top;
  2739 |       dbottom = pc->custom_size.bottom - jobsize.bottom;
  2740 |
  2741 |       if (dleft > -35 && dleft < 35 && dright > -35 && dright < 35 &&
  2742 |           dtop > -35 && dtop < 35 && dbottom > -35 && dbottom < 35)
  2743 | 	*exact = 1;
  2744 |     }
  2745 |     else if (exact)
  2746 |       *exact = 1;
  2747 |
  2748 |     DEBUG_printf("1_ppdCacheGetPageSize: Returning \"%s\" (custom)", pc->custom_ppd_size);
  2749 |
  2750 |     return (pc->custom_ppd_size);
  2751 |   }
  2752 |
  2753 |  /*
  2754 |   * No custom page size support or the size is out of range - return NULL.
  2755 |   */
  2756 |
  2757 |   DEBUG_puts("1_ppdCacheGetPageSize: Returning NULL");
  2758 |
  2759 |   return (NULL);
  2760 | }
  2761 |
  2762 |
  2763 | /*
  2764 |  * '_ppdCacheGetSize()' - Get the PWG size associated with a PPD PageSize.
  2765 |  */
  2766 |
  2767 | pwg_size_t *				/* O - PWG size or NULL */
  2768 | _ppdCacheGetSize(
  2769 |     _ppd_cache_t *pc,			/* I - PPD cache and mapping data */
  2770 |     const char   *page_size,		/* I - PPD PageSize */
  2771 |     ppd_size_t   *ppd_size)		/* I - PPD page size information */
  2772 | {
  2773 |   int		i;			/* Looping var */
  2774 |   pwg_media_t	*media;			/* Media */
  2775 |   pwg_size_t	*size;			/* Current size */
  2776 |
  2777 |
  2778 |  /*
  2779 |   * Range check input...
  2780 |   */
  2781 |
  2782 |   if (!pc || !page_size)
  2783 |     return (NULL);
  2784 |
  2785 |   if (!_cups_strcasecmp(page_size, "Custom") || !_cups_strncasecmp(page_size, "Custom.", 7))
  2786 |   {
  2787 |    /*
  2788 |     * Custom size; size name can be one of the following:
  2789 |     *
  2790 |     *    Custom.WIDTHxLENGTHin    - Size in inches
  2791 |     *    Custom.WIDTHxLENGTHft    - Size in feet
  2792 |     *    Custom.WIDTHxLENGTHcm    - Size in centimeters
  2793 |     *    Custom.WIDTHxLENGTHmm    - Size in millimeters
  2794 |     *    Custom.WIDTHxLENGTHm     - Size in meters
  2795 |     *    Custom.WIDTHxLENGTH[pt]  - Size in points
  2796 |     */
  2797 |
  2798 |     double		w, l;		/* Width and length of page */
  2799 |     char		*ptr;		/* Pointer into PageSize */
  2800 |     struct lconv	*loc;		/* Locale data */
  2801 |
  2802 |     if (page_size[6])
  2803 |     {
  2804 |       loc = localeconv();
  2805 |       w   = (float)_cupsStrScand(page_size + 7, &ptr, loc);
  2806 |       if (!ptr || *ptr != 'x')
  2807 | 	return (NULL);
  2808 |
  2809 |       l = (float)_cupsStrScand(ptr + 1, &ptr, loc);
  2810 |       if (!ptr)
  2811 | 	return (NULL);
  2812 |
  2813 |       if (!_cups_strcasecmp(ptr, "in"))
  2814 |       {
  2815 | 	w *= 2540.0;
  2816 | 	l *= 2540.0;
  2817 |       }
  2818 |       else if (!_cups_strcasecmp(ptr, "ft"))
  2819 |       {
  2820 | 	w *= 12.0 * 2540.0;
  2821 | 	l *= 12.0 * 2540.0;
  2822 |       }
  2823 |       else if (!_cups_strcasecmp(ptr, "mm"))
  2824 |       {
> 2825 | 	w *= 100.0;
  2826 | 	l *= 100.0;
  2827 |       }
  2828 |       else if (!_cups_strcasecmp(ptr, "cm"))
  2829 |       {
  2830 | 	w *= 1000.0;
  2831 | 	l *= 1000.0;
  2832 |       }
  2833 |       else if (!_cups_strcasecmp(ptr, "m"))
  2834 |       {
  2835 | 	w *= 100000.0;
  2836 | 	l *= 100000.0;
  2837 |       }
  2838 |       else
  2839 |       {
  2840 | 	w *= 2540.0 / 72.0;
  2841 | 	l *= 2540.0 / 72.0;
  2842 |       }
  2843 |     }
  2844 |     else if (ppd_size)
  2845 |     {
  2846 |       w = ppd_size->width * 2540.0 / 72.0;
  2847 |       l = ppd_size->length * 2540.0 / 72.0;
  2848 |     }
  2849 |     else
  2850 |     {
  2851 |       // No custom size information...
  2852 |       return (NULL);
  2853 |     }
  2854 |
  2855 |     pwgFormatSizeName(pc->custom_pwg_size, sizeof(pc->custom_pwg_size), "custom", /*name*/NULL, (int)w, (int)l, /*units*/NULL);
  2856 |
  2857 |     pc->custom_size.map.ppd = (char *)page_size;
  2858 |     pc->custom_size.map.pwg = pc->custom_pwg_size;
  2859 |     pc->custom_size.width   = (int)w;
  2860 |     pc->custom_size.length  = (int)l;
  2861 |
  2862 |     return (&(pc->custom_size));
  2863 |   }
  2864 |
  2865 |  /*
  2866 |   * Not a custom size - look it up...
  2867 |   */
  2868 |
  2869 |   for (i = pc->num_sizes, size = pc->sizes; i > 0; i --, size ++)
  2870 |   {
  2871 |     if (!_cups_strcasecmp(page_size, size->map.ppd) ||
  2872 |         !_cups_strcasecmp(page_size, size->map.pwg))
  2873 |       return (size);
  2874 |   }
  2875 |
  2876 |  /*
  2877 |   * Look up standard sizes...
  2878 |   */
  2879 |
  2880 |   if ((media = pwgMediaForPPD(page_size)) == NULL)
  2881 |   {
  2882 |     if ((media = pwgMediaForLegacy(page_size)) == NULL)
  2883 |       media = pwgMediaForPWG(page_size);
  2884 |   }
  2885 |
  2886 |   if (media)
  2887 |   {
  2888 |     pc->custom_size.map.ppd = (char *)page_size;
  2889 |     pc->custom_size.map.pwg = (char *)media->pwg;
  2890 |     pc->custom_size.width   = media->width;
  2891 |     pc->custom_size.length  = media->length;
  2892 |
  2893 |     return (&(pc->custom_size));
  2894 |   }
  2895 |
  2896 |   return (NULL);
  2897 | }
  2898 |
  2899 |
  2900 | /*
  2901 |  * '_ppdCacheGetSource()' - Get the PWG media-source associated with a PPD
  2902 |  *                          InputSlot.
  2903 |  */
  2904 |
  2905 | const char *				/* O - PWG media-source keyword */
  2906 | _ppdCacheGetSource(
  2907 |     _ppd_cache_t *pc,			/* I - PPD cache and mapping data */
  2908 |     const char   *input_slot)		/* I - PPD InputSlot */
  2909 | {
  2910 |   int		i;			/* Looping var */
  2911 |   pwg_map_t	*source;		/* Current source */
  2912 |
  2913 |
  2914 |  /*
  2915 |   * Range check input...
  2916 |   */
  2917 |
  2918 |   if (!pc || !input_slot)
  2919 |     return (NULL);
  2920 |
  2921 |   for (i = pc->num_sources, source = pc->sources; i > 0; i --, source ++)
  2922 |     if (!_cups_strcasecmp(input_slot, source->ppd) || !_cups_strcasecmp(input_slot, source->pwg))
  2923 |       return (source->pwg);
  2924 |
  2925 |   return (NULL);

Reach line at /src/cups/cups/ppd-cache.c:2825 (observed count 3).


  601 |
  602 |   return (*(fp->ptr)++ & 255);
  603 | }
  604 |
  605 |
  606 | //
  607 | // 'cupsFileGetConf()' - Get a line from a configuration file.
  608 | //
  609 | // @since CUPS 1.2@
  610 | //
  611 |
  612 | char *					// O  - Line read or @code NULL@ on end of file or error
  613 | cupsFileGetConf(cups_file_t *fp,	// I  - CUPS file
  614 |                 char        *buf,	// O  - String buffer
  615 | 		size_t      buflen,	// I  - Size of string buffer
  616 |                 char        **value,	// O  - Pointer to value
  617 | 		int         *linenum)	// IO - Current line number
  618 | {
  619 |   char	*ptr;				// Pointer into line
  620 |
  621 |
  622 |   // Range check input...
  623 |   DEBUG_printf("2cupsFileGetConf(fp=%p, buf=%p, buflen=" CUPS_LLFMT ", value=%p, linenum=%p)", (void *)fp, (void *)buf, CUPS_LLCAST buflen, (void *)value, (void *)linenum);
  624 |
  625 |   if (!fp || (fp->mode != 'r' && fp->mode != 's') || !buf || buflen < 2 || !value)
  626 |   {
  627 |     if (value)
  628 |       *value = NULL;
  629 |
  630 |     return (NULL);
  631 |   }
  632 |
  633 |   // Read the next non-comment line...
  634 |   *value = NULL;
  635 |
  636 |   while (cupsFileGets(fp, buf, buflen))
  637 |   {
  638 |     (*linenum) ++;
  639 |
  640 |     // Handle escaped characters and strip any comments...
  641 |     for (ptr = buf; *ptr; ptr ++)
  642 |     {
  643 |       if (*ptr == '#')
  644 |       {
  645 |         // Strip comment text...
  646 |         *ptr = '\0';
  647 |         break;
  648 |       }
  649 |       else if (*ptr == '\\' && (ptr[1] == '\\' || ptr[1] == '#' || ptr[1] == 'n' || ptr[1] == 'r'))
  650 |       {
  651 | 	// \\, \#, \n, or \r, remove backslash and update the escaped char as needed...
  652 | 	_cups_strcpy(ptr, ptr + 1);
  653 |
  654 | 	if (*ptr == 'n')
  655 | 	  *ptr = '\n';
  656 | 	else if (*ptr == 'r')
  657 | 	  *ptr = '\r';
  658 |       }
  659 |     }
  660 |
  661 |     // Strip leading whitespace...
  662 |     for (ptr = buf; *ptr; ptr ++)
  663 |     {
  664 |       if (!_cups_isspace(*ptr))
  665 |         break;
  666 |     }
  667 |
  668 |     if (ptr > buf)
  669 |       _cups_strcpy(buf, ptr);
  670 |
  671 |     // See if there is anything left...
  672 |     if (buf[0])
  673 |     {
  674 |       // Yes, grab any value and return...
  675 |       for (ptr = buf; *ptr; ptr ++)
  676 |       {
  677 |         if (_cups_isspace(*ptr))
  678 | 	  break;
  679 |       }
  680 |
  681 |       if (*ptr)
  682 |       {
  683 |         // Have a value, skip any other spaces...
  684 |         while (_cups_isspace(*ptr))
  685 | 	  *ptr++ = '\0';
  686 |
  687 |         if (*ptr)
  688 | 	  *value = ptr;
  689 |
  690 |         // Strip trailing whitespace and > for lines that begin with <...
  691 |         ptr += strlen(ptr) - 1;
  692 |
  693 |         if (buf[0] == '<' && *ptr == '>')
  694 |         {
  695 | 	  *ptr-- = '\0';
  696 | 	}
  697 | 	else if (buf[0] == '<' && *ptr != '>')
  698 |         {
  699 | 	  // Syntax error...
  700 | 	  *value = NULL;
> 701 | 	  return (buf);
  702 | 	}
  703 |
  704 |         while (ptr > *value && _cups_isspace(*ptr))
  705 | 	  *ptr-- = '\0';
  706 |       }
  707 |
  708 |       // Return the line...
  709 |       return (buf);
  710 |     }
  711 |   }
  712 |
  713 |   return (NULL);
  714 | }
  715 |
  716 |
  717 | //
  718 | // 'cupsFileGetLine()' - Get a CR and/or LF-terminated line that may
  719 | //                       contain binary data.
  720 | //
  721 | // This function differs from @link cupsFileGets@ in that the trailing CR
  722 | // and LF are preserved, as is any binary data on the line. The buffer is
  723 | // nul-terminated, however you should use the returned length to determine
  724 | // the number of bytes on the line.
  725 | //
  726 | // @since CUPS 1.2@
  727 | //
  728 |
  729 | size_t					// O - Number of bytes on line or 0 on end of file
  730 | cupsFileGetLine(cups_file_t *fp,	// I - File to read from
  731 |                 char        *buf,	// I - Buffer
  732 |                 size_t      buflen)	// I - Size of buffer
  733 | {
  734 |   int		ch;			// Character from file
  735 |   char		*ptr,			// Current position in line buffer
  736 | 		*end;			// End of line buffer
  737 |
  738 |
  739 |   // Range check input...
  740 |   DEBUG_printf("2cupsFileGetLine(fp=%p, buf=%p, buflen=" CUPS_LLFMT ")", (void *)fp, (void *)buf, CUPS_LLCAST buflen);
  741 |
  742 |   if (!fp || (fp->mode != 'r' && fp->mode != 's') || !buf || buflen < 3)
  743 |     return (0);
  744 |
  745 |   // Now loop until we have a valid line...
  746 |   for (ptr = buf, end = buf + buflen - 2; ptr < end ;)
  747 |   {
  748 |     if (fp->ptr >= fp->end)
  749 |       if (cups_fill(fp) <= 0)
  750 |         break;
  751 |
  752 |     *ptr++ = ch = *(fp->ptr)++;
  753 |     fp->pos ++;
  754 |
  755 |     if (ch == '\r')
  756 |     {
  757 |       // Check for CR LF...
  758 |       if (fp->ptr >= fp->end)
  759 | 	if (cups_fill(fp) <= 0)
  760 |           break;
  761 |
  762 |       if (*(fp->ptr) == '\n')
  763 |       {
  764 |         *ptr++ = *(fp->ptr)++;
  765 | 	fp->pos ++;
  766 |       }
  767 |
  768 |       break;
  769 |     }
  770 |     else if (ch == '\n')
  771 |     {
  772 |       // Line feed ends a line...
  773 |       break;
  774 |     }
  775 |   }
  776 |
  777 |   *ptr = '\0';
  778 |
  779 |   DEBUG_printf("4cupsFileGetLine: pos=" CUPS_LLFMT, CUPS_LLCAST fp->pos);
  780 |
  781 |   return ((size_t)(ptr - buf));
  782 | }
  783 |
  784 |
  785 | //
  786 | // 'cupsFileGets()' - Get a CR and/or LF-terminated line.
  787 | //
  788 | // @since CUPS 1.2@
  789 | //
  790 |
  791 | char *					// O - Line read or @code NULL@ on end of file or error
  792 | cupsFileGets(cups_file_t *fp,		// I - CUPS file
  793 |              char        *buf,		// O - String buffer
  794 | 	     size_t      buflen)	// I - Size of string buffer
  795 | {
  796 |   int		ch;			// Character from file
  797 |   char		*ptr,			// Current position in line buffer
  798 | 		*end;			// End of line buffer
  799 |
  800 |
  801 |   // Range check input...

Reach line at /src/cups/cups/file.c:701 (observed count 6).


   840 | 	  case PPD_CUSTOM_UNKNOWN :
   841 | 	      break;
   842 |
   843 | 	  case PPD_CUSTOM_CURVE :
   844 | 	  case PPD_CUSTOM_INVCURVE :
   845 | 	  case PPD_CUSTOM_REAL :
   846 | 	      cparam->current.custom_real = (float)_cupsStrScand(choice + 7,
   847 | 	                                                         NULL, loc);
   848 | 	      break;
   849 |
   850 | 	  case PPD_CUSTOM_POINTS :
   851 | 	      cparam->current.custom_points = (float)_cupsStrScand(choice + 7,
   852 | 	                                                           &units,
   853 | 	                                                           loc);
   854 |
   855 |               if (units)
   856 | 	      {
   857 |         	if (!_cups_strcasecmp(units, "cm"))
   858 | 	          cparam->current.custom_points *= 72.0f / 2.54f;
   859 |         	else if (!_cups_strcasecmp(units, "mm"))
   860 | 	          cparam->current.custom_points *= 72.0f / 25.4f;
   861 |         	else if (!_cups_strcasecmp(units, "m"))
   862 | 	          cparam->current.custom_points *= 72.0f / 0.0254f;
   863 |         	else if (!_cups_strcasecmp(units, "in"))
   864 | 	          cparam->current.custom_points *= 72.0f;
   865 |         	else if (!_cups_strcasecmp(units, "ft"))
   866 | 	          cparam->current.custom_points *= 12.0f * 72.0f;
   867 |               }
   868 | 	      break;
   869 |
   870 | 	  case PPD_CUSTOM_INT :
   871 | 	      cparam->current.custom_int = atoi(choice + 7);
   872 | 	      break;
   873 |
   874 | 	  case PPD_CUSTOM_PASSCODE :
   875 | 	  case PPD_CUSTOM_PASSWORD :
   876 | 	  case PPD_CUSTOM_STRING :
   877 | 	      if (cparam->current.custom_string)
   878 | 	        free(cparam->current.custom_string);
   879 |
   880 | 	      cparam->current.custom_string = strdup(choice + 7);
   881 | 	      break;
   882 | 	}
   883 |       }
   884 |     }
   885 |
   886 |    /*
   887 |     * Make sure that we keep the option marked below...
   888 |     */
   889 |
   890 |     choice = "Custom";
   891 |   }
   892 |   else if (choice[0] == '{')
   893 |   {
   894 |    /*
   895 |     * Handle multi-value custom options...
   896 |     */
   897 |
   898 |     ppd_coption_t	*coption;	/* Custom option */
   899 |     ppd_cparam_t	*cparam;	/* Custom parameter */
   900 |     char		*units;		/* Custom points units */
   901 |     int			num_vals;	/* Number of values */
   902 |     cups_option_t	*vals,		/* Values */
   903 | 			*val;		/* Value */
   904 |
   905 |
   906 |     if ((c = ppdFindChoice(o, "Custom")) == NULL)
   907 |       return;
   908 |
   909 |     if ((coption = ppdFindCustomOption(ppd, option)) != NULL)
   910 |     {
   911 |       num_vals = cupsParseOptions(choice, 0, &vals);
   912 |
   913 |       for (i = 0, val = vals; i < num_vals; i ++, val ++)
   914 |       {
   915 |         if ((cparam = ppdFindCustomParam(coption, val->name)) == NULL)
   916 | 	  continue;
   917 |
   918 | 	switch (cparam->type)
   919 | 	{
   920 | 	  case PPD_CUSTOM_UNKNOWN :
   921 | 	      break;
   922 |
   923 | 	  case PPD_CUSTOM_CURVE :
   924 | 	  case PPD_CUSTOM_INVCURVE :
   925 | 	  case PPD_CUSTOM_REAL :
   926 | 	      cparam->current.custom_real = (float)_cupsStrScand(val->value,
   927 | 	                                                         NULL, loc);
   928 | 	      break;
   929 |
   930 | 	  case PPD_CUSTOM_POINTS :
   931 | 	      cparam->current.custom_points = (float)_cupsStrScand(val->value,
   932 | 	                                                           &units,
   933 | 	                                                           loc);
   934 |
   935 | 	      if (units)
   936 | 	      {
   937 |         	if (!_cups_strcasecmp(units, "cm"))
   938 | 		  cparam->current.custom_points *= 72.0f / 2.54f;
   939 |         	else if (!_cups_strcasecmp(units, "mm"))
>  940 | 		  cparam->current.custom_points *= 72.0f / 25.4f;
   941 |         	else if (!_cups_strcasecmp(units, "m"))
   942 | 		  cparam->current.custom_points *= 72.0f / 0.0254f;
   943 |         	else if (!_cups_strcasecmp(units, "in"))
   944 | 		  cparam->current.custom_points *= 72.0f;
   945 |         	else if (!_cups_strcasecmp(units, "ft"))
   946 | 		  cparam->current.custom_points *= 12.0f * 72.0f;
   947 | 	      }
   948 | 	      break;
   949 |
   950 | 	  case PPD_CUSTOM_INT :
   951 | 	      cparam->current.custom_int = atoi(val->value);
   952 | 	      break;
   953 |
   954 | 	  case PPD_CUSTOM_PASSCODE :
   955 | 	  case PPD_CUSTOM_PASSWORD :
   956 | 	  case PPD_CUSTOM_STRING :
   957 | 	      if (cparam->current.custom_string)
   958 | 		free(cparam->current.custom_string);
   959 |
   960 | 	      cparam->current.custom_string = strdup(val->value);
   961 | 	      break;
   962 | 	}
   963 |       }
   964 |
   965 |       cupsFreeOptions(num_vals, vals);
   966 |     }
   967 |   }
   968 |   else
   969 |   {
   970 |     for (i = o->num_choices, c = o->choices; i > 0; i --, c ++)
   971 |       if (!_cups_strcasecmp(c->choice, choice))
   972 |         break;
   973 |
   974 |     if (!i)
   975 |       return;
   976 |   }
   977 |
   978 |  /*
   979 |   * Option found; mark it and then handle unmarking any other options.
   980 |   */
   981 |
   982 |   if (o->ui != PPD_UI_PICKMANY)
   983 |   {
   984 |    /*
   985 |     * Unmark all other choices...
   986 |     */
   987 |
   988 |     if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, c)) != NULL)
   989 |     {
   990 |       oldc->marked = 0;
   991 |       cupsArrayRemove(ppd->marked, oldc);
   992 |     }
   993 |
   994 |     if (!_cups_strcasecmp(option, "PageSize") || !_cups_strcasecmp(option, "PageRegion"))
   995 |     {
   996 |      /*
   997 |       * Mark current page size...
   998 |       */
   999 |
  1000 |       for (j = 0; j < ppd->num_sizes; j ++)
  1001 | 	ppd->sizes[j].marked = !_cups_strcasecmp(ppd->sizes[j].name,
  1002 | 		                           choice);
  1003 |
  1004 |      /*
  1005 |       * Unmark the current PageSize or PageRegion setting, as
  1006 |       * appropriate...
  1007 |       */
  1008 |
  1009 |       cupsArraySave(ppd->options);
  1010 |
  1011 |       if (!_cups_strcasecmp(option, "PageSize"))
  1012 |       {
  1013 | 	if ((o = ppdFindOption(ppd, "PageRegion")) != NULL)
  1014 |         {
  1015 |           key.option = o;
  1016 |           if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
  1017 |           {
  1018 |             oldc->marked = 0;
  1019 |             cupsArrayRemove(ppd->marked, oldc);
  1020 |           }
  1021 |         }
  1022 |       }
  1023 |       else
  1024 |       {
  1025 | 	if ((o = ppdFindOption(ppd, "PageSize")) != NULL)
  1026 |         {
  1027 |           key.option = o;
  1028 |           if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
  1029 |           {
  1030 |             oldc->marked = 0;
  1031 |             cupsArrayRemove(ppd->marked, oldc);
  1032 |           }
  1033 |         }
  1034 |       }
  1035 |
  1036 |       cupsArrayRestore(ppd->options);
  1037 |     }
  1038 |     else if (!_cups_strcasecmp(option, "InputSlot"))
  1039 |     {
  1040 |      /*

Reach line at /src/cups/cups/ppd-mark.c:940 (observed count 489).


  158 |         ddsrt_fibheap_node_t *n = mark;
  159 |         do {
  160 |             n->parent = NULL;
  161 |             n->mark = 0;
  162 |             n = n->next;
  163 |         } while (n != mark);
  164 |
  165 |         ddsrt_fibheap_merge_nonempty_list (&fh->roots, min->children);
  166 |     }
  167 |
  168 |     /* iteratively merge roots of equal degree, completely messing up
  169 |        fh->roots, ... */
  170 |     {
  171 |         assert(fh->roots); /* silence GCC's static analyzer */
  172 |         ddsrt_fibheap_node_t *const mark = fh->roots;
  173 |         ddsrt_fibheap_node_t *n = mark;
  174 |         do {
  175 |             ddsrt_fibheap_node_t * const n1 = n->next;
  176 |
  177 |             /* if n is first root with this high a degree, there's certainly
  178 |                not going to be another root to merge with yet
  179 |
  180 |                GCC 12 static analyzer warns that roots[n->degree] may be
  181 |                uninitialized, but that is clearly wrong, it is just lazily
  182 |                initialized a few lines down.  Always initializing all of
  183 |                roots[] would take care of that, but high-degree nodes are
  184 |                rather rare and extract_min is called very often. */
  185 | #if __GNUC__ >= 12
  186 |             DDSRT_WARNING_GNUC_OFF(analyzer-use-of-uninitialized-value)
  187 | #endif
  188 |             while (n->degree < min_degree_noninit && roots[n->degree]) {
  189 |                 unsigned const degree = n->degree;
  190 |                 ddsrt_fibheap_node_t *u, *v;
  191 |
  192 |                 if (cmp (fhdef, roots[degree], n) < 0) {
  193 |                     u = roots[degree]; v = n;
  194 |                 } else {
  195 |                     u = n; v = roots[degree];
  196 |                 }
  197 |                 roots[degree] = NULL;
  198 |                 ddsrt_fibheap_add_as_child (u, v);
  199 |                 n = u;
  200 |             }
  201 | #if __GNUC__ >= 12
  202 |             DDSRT_WARNING_GNUC_ON(analyzer-use-of-uninitialized-value)
  203 | #endif
  204 |
  205 |             /* n may have changed, hence need to retest whether or not
  206 |                enough of roots has been initialised -- note that
  207 |                initialising roots[n->degree] is unnecessary, but easier */
  208 |             assert (n->degree <= MAX_DEGREE);
  209 |             while (min_degree_noninit <= n->degree) {
  210 |                 roots[min_degree_noninit++] = NULL;
  211 |             }
  212 |             roots[n->degree] = n;
  213 |             n = n1;
  214 |         } while (n != mark);
  215 |     }
  216 |
  217 |     /* ... but we don't mind because we have roots[], we can scan linear
  218 |        memory at an astonishing rate, and we need to compare the root
  219 |        keys anyway to find the minimum */
  220 |     {
  221 |         ddsrt_fibheap_node_t *mark, *cursor, *newmin;
  222 |         uint32_t i;
  223 |         for (i = 0; roots[i] == NULL; i++) {
  224 |             assert (i+1 < min_degree_noninit);
  225 |         }
  226 |         newmin = roots[i];
  227 |         assert (newmin != NULL);
  228 |         mark = cursor = roots[i];
  229 |         for (++i; i < min_degree_noninit; i++) {
  230 |             if (roots[i]) {
  231 |                 ddsrt_fibheap_node_t * const r = roots[i];
  232 |                 if (cmp (fhdef, r, newmin) < 0)
  233 |                     newmin = r;
  234 |                 r->prev = cursor;
  235 |                 cursor->next = r;
  236 |                 cursor = r;
  237 |             }
  238 |         }
  239 |         mark->prev = cursor;
  240 |         cursor->next = mark;
  241 |
  242 |         fh->roots = newmin;
  243 |     }
  244 |
  245 |     return (void *) ((char *) min - fhdef->offset);
  246 | }
  247 |
  248 | static void ddsrt_fibheap_cutnode (ddsrt_fibheap_t *fh, ddsrt_fibheap_node_t *node)
  249 | {
  250 |     /* by marking the node, we ensure it gets cut */
  251 |     node->mark = 1;
  252 |
  253 |     /* traverse towards the root, cutting marked nodes on the way */
  254 |     while (node->parent && node->mark) {
  255 |         ddsrt_fibheap_node_t *parent = node->parent;
  256 |
  257 |         assert (parent->degree > 0);
> 258 |         ddsrt_fibheap_delete_one_from_list (&parent->children, node);
  259 |         parent->degree--;
  260 |
  261 |         node->mark = 0;
  262 |         node->parent = NULL;
  263 |         node->next = node->prev = node;
  264 |
  265 |         /* we assume heap properties haven't been violated, and therefore
  266 |            none of the nodes we cut can become the new minimum */
  267 |         ddsrt_fibheap_merge_nonempty_list (&fh->roots, node);
  268 |
  269 |         node = parent;
  270 |     }
  271 |
  272 |     /* if we stopped because we hit an unmarked interior node, we must
  273 |        mark it */
  274 |     if (node->parent) {
  275 |         node->mark = 1;
  276 |     }
  277 | }
  278 |
  279 | void ddsrt_fibheap_decrease_key (const ddsrt_fibheap_def_t *fhdef, ddsrt_fibheap_t *fh, const void *vnode)
  280 | {
  281 |     /* fibheap node is opaque => nothing in node changes as far as
  282 |        caller is concerned => declare as const argument, then drop the
  283 |        const qualifier */
  284 |     ddsrt_fibheap_node_t *node = (ddsrt_fibheap_node_t *) ((char *) vnode + fhdef->offset);
  285 |
  286 |     if (node->parent && cmp (fhdef, node->parent, node) <= 0) {
  287 |         /* heap property not violated, do nothing */
  288 |     } else {
  289 |         if (node->parent) {
  290 |             /* heap property violated by decreasing the key, but we cut it
  291 |                pretending nothing has happened yet, then fix up the minimum if
  292 |                this node is the new minimum */
  293 |             ddsrt_fibheap_cutnode (fh, node);
  294 |         }
  295 |         if (cmp (fhdef, node, fh->roots) < 0) {
  296 |             fh->roots = node;
  297 |         }
  298 |     }
  299 | }
  300 |
  301 | void ddsrt_fibheap_delete (const ddsrt_fibheap_def_t *fhdef, ddsrt_fibheap_t *fh, const void *vnode)
  302 | {
  303 |     /* fibheap node is opaque => nothing in node changes as far as
  304 |        caller is concerned => declare as const argument, then drop the
  305 |        const qualifier */
  306 |     ddsrt_fibheap_node_t *node = (ddsrt_fibheap_node_t *) ((char *) vnode + fhdef->offset);
  307 |
  308 |     /* essentially decreasekey(node);extractmin while pretending the
  309 |        node key is -infinity.  That means we can't directly call
  310 |        decreasekey, because it considers the actual value of the key. */
  311 |     if (node->parent != NULL) {
  312 |         ddsrt_fibheap_cutnode (fh, node);
  313 |     }
  314 |     fh->roots = node;
  315 |     (void) ddsrt_fibheap_extract_min (fhdef, fh);
  316 | }

Reach line at /src/cyclonedds/src/ddsrt/src/fibheap.c:258 (observed count 865).


   34 | #include "ddsi__endpoint.h"
   35 | #include "ddsi__proxy_endpoint.h"
   36 | #include "ddsi__proxy_participant.h"
   37 |
   38 | /* This is absolute bottom for signed integers, where -x = x and yet x
   39 |    != 0 -- and note that it had better be 2's complement machine! */
   40 | #define TSCHED_NOT_ON_HEAP INT64_MIN
   41 |
   42 | const ddsrt_fibheap_def_t lease_fhdef = DDSRT_FIBHEAPDEF_INITIALIZER (offsetof (struct ddsi_lease, heapnode), ddsi_compare_lease_tsched);
   43 |
   44 | static void force_lease_check (struct ddsi_gcreq_queue *gcreq_queue)
   45 | {
   46 |   ddsi_gcreq_enqueue (ddsi_gcreq_new (gcreq_queue, ddsi_gcreq_free));
   47 | }
   48 |
   49 | int ddsi_compare_lease_tsched (const void *va, const void *vb)
   50 | {
   51 |   const struct ddsi_lease *a = va;
   52 |   const struct ddsi_lease *b = vb;
   53 |   return (a->tsched.v == b->tsched.v) ? 0 : (a->tsched.v < b->tsched.v) ? -1 : 1;
   54 | }
   55 |
   56 | int ddsi_compare_lease_tdur (const void *va, const void *vb)
   57 | {
   58 |   const struct ddsi_lease *a = va;
   59 |   const struct ddsi_lease *b = vb;
   60 |   return (a->tdur == b->tdur) ? 0 : (a->tdur < b->tdur) ? -1 : 1;
   61 | }
   62 |
   63 | void ddsi_lease_management_init (struct ddsi_domaingv *gv)
   64 | {
   65 |   ddsrt_mutex_init (&gv->leaseheap_lock);
   66 |   ddsrt_fibheap_init (&lease_fhdef, &gv->leaseheap);
   67 | }
   68 |
   69 | void ddsi_lease_management_term (struct ddsi_domaingv *gv)
   70 | {
   71 |   assert (ddsrt_fibheap_min (&lease_fhdef, &gv->leaseheap) == NULL);
   72 |   ddsrt_mutex_destroy (&gv->leaseheap_lock);
   73 | }
   74 |
   75 | struct ddsi_lease *ddsi_lease_new (ddsrt_etime_t texpire, dds_duration_t tdur, struct ddsi_entity_common *e)
   76 | {
   77 |   struct ddsi_lease *l;
   78 |   if ((l = ddsrt_malloc (sizeof (*l))) == NULL)
   79 |     return NULL;
   80 |   EETRACE (e, "ddsi_lease_new(tdur %"PRId64" guid "PGUIDFMT") @ %p\n", tdur, PGUID (e->guid), (void *) l);
   81 |   l->tdur = tdur;
   82 |   ddsrt_atomic_st64 (&l->tend, (uint64_t) texpire.v);
   83 |   l->tsched.v = TSCHED_NOT_ON_HEAP;
   84 |   l->entity = e;
   85 |   return l;
   86 | }
   87 |
   88 | /**
   89 |  * Returns a clone of the provided lease. Note that this function does not use
   90 |  * locking and should therefore only be called from a context where lease 'l'
   91 |  * cannot be changed by another thread during the function call.
   92 |  */
   93 | struct ddsi_lease *ddsi_lease_clone (const struct ddsi_lease *l)
   94 | {
   95 |   ddsrt_etime_t texp;
   96 |   dds_duration_t tdur;
   97 |   texp.v = (int64_t) ddsrt_atomic_ld64 (&l->tend);
   98 |   tdur = l->tdur;
   99 |   return ddsi_lease_new (texp, tdur, l->entity);
  100 | }
  101 |
  102 | void ddsi_lease_register (struct ddsi_lease *l) /* FIXME: make lease admin struct */
  103 | {
  104 |   struct ddsi_domaingv * const gv = l->entity->gv;
  105 |   GVTRACE ("ddsi_lease_register(l %p guid "PGUIDFMT")\n", (void *) l, PGUID (l->entity->guid));
  106 |   ddsrt_mutex_lock (&gv->leaseheap_lock);
  107 |   assert (l->tsched.v == TSCHED_NOT_ON_HEAP);
  108 |   int64_t tend = (int64_t) ddsrt_atomic_ld64 (&l->tend);
  109 |   if (tend != DDS_NEVER)
  110 |   {
  111 |     l->tsched.v = tend;
  112 |     ddsrt_fibheap_insert (&lease_fhdef, &gv->leaseheap, l);
  113 |   }
  114 |   ddsrt_mutex_unlock (&gv->leaseheap_lock);
  115 |
  116 |   /* ddsi_check_and_handle_lease_expiration runs on GC thread and the only way to be sure that it wakes up in time is by forcing re-evaluation (strictly speaking only needed if this is the first lease to expire, but this operation is quite rare anyway) */
  117 |   force_lease_check (gv->gcreq_queue);
  118 | }
  119 |
  120 | void ddsi_lease_unregister (struct ddsi_lease *l)
  121 | {
  122 |   struct ddsi_domaingv * const gv = l->entity->gv;
  123 |   GVTRACE ("ddsi_lease_unregister(l %p guid "PGUIDFMT")\n", (void *) l, PGUID (l->entity->guid));
  124 |   ddsrt_mutex_lock (&gv->leaseheap_lock);
  125 |   if (l->tsched.v != TSCHED_NOT_ON_HEAP)
  126 |   {
  127 |     ddsrt_fibheap_delete (&lease_fhdef, &gv->leaseheap, l);
  128 |     l->tsched.v = TSCHED_NOT_ON_HEAP;
  129 |   }
  130 |   ddsrt_mutex_unlock (&gv->leaseheap_lock);
  131 |
  132 |   /* see ddsi_lease_register() */
  133 |   force_lease_check (gv->gcreq_queue);
> 134 | }
  135 |
  136 | void ddsi_lease_free (struct ddsi_lease *l)
  137 | {
  138 |   struct ddsi_domaingv * const gv = l->entity->gv;
  139 |   GVTRACE ("ddsi_lease_free(l %p guid "PGUIDFMT")\n", (void *) l, PGUID (l->entity->guid));
  140 |   ddsrt_free (l);
  141 | }
  142 |
  143 | static void trace_lease_renew (const struct ddsi_lease *l, const char *tag, ddsrt_etime_t tend_new)
  144 | {
  145 |   struct ddsi_domaingv const * gv = l->entity->gv;
  146 |   if (gv->logconfig.c.mask & DDS_LC_TRACE)
  147 |   {
  148 |     int32_t tsec, tusec;
  149 |     GVTRACE (" L(%s", tag);
  150 |     if (l->entity->guid.entityid.u == DDSI_ENTITYID_PARTICIPANT)
  151 |       GVTRACE (":%"PRIx32, l->entity->guid.entityid.u);
  152 |     else
  153 |       GVTRACE (""PGUIDFMT"", PGUID (l->entity->guid));
  154 |     ddsrt_etime_to_sec_usec (&tsec, &tusec, tend_new);
  155 |     GVTRACE (" %"PRId32".%06"PRId32")", tsec, tusec);
  156 |   }
  157 | }
  158 |
  159 | void ddsi_lease_renew (struct ddsi_lease *l, ddsrt_etime_t tnowE)
  160 | {
  161 |   ddsrt_etime_t tend_new = ddsrt_etime_add_duration (tnowE, l->tdur);
  162 |
  163 |   /* do not touch tend if moving forward or if already expired */
  164 |   int64_t tend;
  165 |   do {
  166 |     tend = (int64_t) ddsrt_atomic_ld64 (&l->tend);
  167 |     if (tend_new.v <= tend || tnowE.v >= tend)
  168 |       return;
  169 |   } while (!ddsrt_atomic_cas64 (&l->tend, (uint64_t) tend, (uint64_t) tend_new.v));
  170 |
  171 |   /* Only at this point we can assume that gv can be recovered from the entity in the
  172 |    * lease (i.e. the entity still exists). In cases where dereferencing l->entity->gv
  173 |    * is not safe (e.g. the deletion of entities), the early out in the loop above
  174 |    * will be the case because tend is set to DDS_NEVER. */
  175 |   trace_lease_renew (l, "", tend_new);
  176 | }
  177 |
  178 | void ddsi_lease_set_expiry (struct ddsi_lease *l, ddsrt_etime_t when)
  179 | {
  180 |   struct ddsi_domaingv * const gv = l->entity->gv;
  181 |   bool trigger = false;
  182 |   assert (when.v >= 0);
  183 |   ddsrt_mutex_lock (&gv->leaseheap_lock);
  184 |   /* only possible concurrent action is to move tend into the future (renew_lease),
  185 |     all other operations occur with leaseheap_lock held */
  186 |   ddsrt_atomic_st64 (&l->tend, (uint64_t) when.v);
  187 |   if (when.v < l->tsched.v)
  188 |   {
  189 |     /* moved forward and currently scheduled (by virtue of
  190 |        TSCHED_NOT_ON_HEAP == INT64_MIN) */
  191 |     l->tsched = when;
  192 |     ddsrt_fibheap_decrease_key (&lease_fhdef, &gv->leaseheap, l);
  193 |     trace_lease_renew (l, "earlier ", when);
  194 |     trigger = true;
  195 |   }
  196 |   else if (l->tsched.v == TSCHED_NOT_ON_HEAP && when.v < DDS_NEVER)
  197 |   {
  198 |     /* not currently scheduled, with a finite new expiry time */
  199 |     l->tsched = when;
  200 |     ddsrt_fibheap_insert (&lease_fhdef, &gv->leaseheap, l);
  201 |     trace_lease_renew (l, "insert ", when);
  202 |     trigger = true;
  203 |   }
  204 |   ddsrt_mutex_unlock (&gv->leaseheap_lock);
  205 |
  206 |   /* see ddsi_lease_register() */
  207 |   if (trigger)
  208 |     force_lease_check (gv->gcreq_queue);
  209 | }
  210 |
  211 | int64_t ddsi_check_and_handle_lease_expiration (struct ddsi_domaingv *gv, ddsrt_etime_t tnowE)
  212 | {
  213 |   struct ddsi_lease *l;
  214 |   int64_t delay;
  215 |   ddsrt_mutex_lock (&gv->leaseheap_lock);
  216 |   while ((l = ddsrt_fibheap_min (&lease_fhdef, &gv->leaseheap)) != NULL && l->tsched.v <= tnowE.v)
  217 |   {
  218 |     ddsi_guid_t g = l->entity->guid;
  219 |     enum ddsi_entity_kind k = l->entity->kind;
  220 |
  221 |     assert (l->tsched.v != TSCHED_NOT_ON_HEAP);
  222 |     ddsrt_fibheap_extract_min (&lease_fhdef, &gv->leaseheap);
  223 |     /* only possible concurrent action is to move tend into the future (renew_lease),
  224 |        all other operations occur with leaseheap_lock held */
  225 |     int64_t tend = (int64_t) ddsrt_atomic_ld64 (&l->tend);
  226 |     if (tnowE.v < tend)
  227 |     {
  228 |       if (tend == DDS_NEVER) {
  229 |         /* don't reinsert if it won't expire */
  230 |         l->tsched.v = TSCHED_NOT_ON_HEAP;
  231 |       } else {
  232 |         l->tsched.v = tend;
  233 |         ddsrt_fibheap_insert (&lease_fhdef, &gv->leaseheap, l);
  234 |       }

Reach line at /src/cyclonedds/src/core/ddsi/src/ddsi_lease.c:134 (observed count 867).


  548 | ddsrt_nonnull ((1, 2, 3))
  549 | static void dds_os_put_bytes_aligned_base (restrict_ostream_base_t *os, const struct dds_cdrstream_allocator *allocator, const void *data, uint32_t num, uint32_t elem_sz, align_t cdr_align, void **dst)
  550 | {
  551 |   const uint32_t sz = num * elem_sz;
  552 |   dds_cdr_alignto_clear_and_resize_base (os, allocator, cdr_align, sz);
  553 |   if (dst)
  554 |     *dst = os->m_buffer + os->m_index;
  555 |   memcpy (os->m_buffer + os->m_index, data, sz);
  556 |   os->m_index += sz;
  557 | }
  558 |
  559 | static inline bool is_primitive_type (enum dds_stream_typecode type)
  560 | {
  561 |   return type <= DDS_OP_VAL_8BY || type == DDS_OP_VAL_BLN || type == DDS_OP_VAL_WCHAR;
  562 | }
  563 |
  564 | static inline bool is_primitive_or_enum_type (enum dds_stream_typecode type)
  565 | {
  566 |   return is_primitive_type (type) || type == DDS_OP_VAL_ENU;
  567 | }
  568 |
  569 | static inline bool is_dheader_needed (enum dds_stream_typecode type, uint32_t xcdrv)
  570 | {
  571 |   return !is_primitive_type (type) && xcdrv == DDSI_RTPS_CDR_ENC_VERSION_2;
  572 | }
  573 |
  574 | static uint32_t get_primitive_size (enum dds_stream_typecode type)
  575 | {
  576 |   DDSRT_STATIC_ASSERT (DDS_OP_VAL_1BY == 1 && DDS_OP_VAL_2BY == 2 && DDS_OP_VAL_4BY == 3 && DDS_OP_VAL_8BY == 4);
  577 |   assert (is_primitive_type (type));
  578 |   if (type <= DDS_OP_VAL_8BY)
  579 |     return (uint32_t)1 << ((uint32_t) type - 1);
  580 |   else if (type == DDS_OP_VAL_BLN)
  581 |     return 1;
  582 |   else if (type == DDS_OP_VAL_WCHAR)
  583 |     return 2;
  584 |   else
  585 |     abort ();
  586 | }
  587 |
  588 | ddsrt_nonnull_all
  589 | static uint32_t get_collection_elem_size (uint32_t insn, const uint32_t *ops)
  590 | {
  591 |   switch (DDS_OP_SUBTYPE (insn))
  592 |   {
  593 |     case DDS_OP_VAL_BLN: case DDS_OP_VAL_1BY: case DDS_OP_VAL_2BY: case DDS_OP_VAL_4BY: case DDS_OP_VAL_8BY:
  594 |       return get_primitive_size (DDS_OP_SUBTYPE (insn));
  595 |     case DDS_OP_VAL_ENU:
  596 |       return sizeof (uint32_t);
  597 |     case DDS_OP_VAL_BMK:
  598 |       return DDS_OP_TYPE_SZ (insn);
  599 |     case DDS_OP_VAL_STR:
  600 |       return sizeof (char *);
  601 |     case DDS_OP_VAL_WSTR:
  602 |       return sizeof (wchar_t *);
  603 |     case DDS_OP_VAL_WCHAR:
  604 |       return sizeof (wchar_t);
  605 |     case DDS_OP_VAL_BST: case DDS_OP_VAL_BWSTR:
  606 |     case DDS_OP_VAL_SEQ: case DDS_OP_VAL_BSQ: case DDS_OP_VAL_ARR: case DDS_OP_VAL_UNI: case DDS_OP_VAL_STU:
  607 |       if (DDS_OP_TYPE (insn) == DDS_OP_VAL_ARR)
  608 |         return ops[4];
  609 |       break;
  610 |     case DDS_OP_VAL_EXT:
  611 |       break;
  612 |   }
  613 |   abort ();
  614 |   return 0u;
  615 | }
  616 |
  617 | ddsrt_nonnull_all
  618 | static uint32_t get_adr_type_size (uint32_t insn, const uint32_t *ops)
  619 | {
  620 |   uint32_t sz = 0;
  621 |   switch (DDS_OP_TYPE (insn))
  622 |   {
  623 |     case DDS_OP_VAL_BLN: case DDS_OP_VAL_1BY: case DDS_OP_VAL_2BY: case DDS_OP_VAL_4BY: case DDS_OP_VAL_8BY:
  624 |       sz = get_primitive_size (DDS_OP_TYPE (insn));
  625 |       break;
  626 |     case DDS_OP_VAL_ENU:
  627 |       sz = sizeof (uint32_t);
  628 |       break;
  629 |     case DDS_OP_VAL_BMK:
  630 |       sz = DDS_OP_TYPE_SZ (insn);
  631 |       break;
  632 |     case DDS_OP_VAL_STR:
  633 |       sz = sizeof (char *);
  634 |       break;
  635 |     case DDS_OP_VAL_WSTR:
  636 |       sz = sizeof (wchar_t *);
  637 |       break;
  638 |     case DDS_OP_VAL_WCHAR:
  639 |       sz = sizeof (wchar_t);
  640 |       break;
  641 |     case DDS_OP_VAL_BST: case DDS_OP_VAL_BWSTR:
  642 |       sz = ops[2];
  643 |       break;
  644 |     case DDS_OP_VAL_ARR:
  645 |     {
  646 |       uint32_t num = ops[2];
  647 |       uint32_t elem_sz = get_collection_elem_size (ops[0], ops);
> 648 |       sz = num * elem_sz;
  649 |       break;
  650 |     }
  651 |     case DDS_OP_VAL_SEQ:
  652 |     case DDS_OP_VAL_BSQ:
  653 |       /* external sequence member is a pointer to a dds_sequence_t, so element size and
  654 |          sequence length are not relevant for the allocation size for the member */
  655 |       sz = sizeof (struct dds_sequence);
  656 |       break;
  657 |     case DDS_OP_VAL_EXT:
  658 |       sz = ops[3];
  659 |       break;
  660 |     case DDS_OP_VAL_UNI:
  661 |     case DDS_OP_VAL_STU:
  662 |       /* for UNI and STU members are externally defined, so are using EXT type */
  663 |       abort ();
  664 |       break;
  665 |   }
  666 |   return sz;
  667 | }
  668 |
  669 | ddsrt_nonnull_all
  670 | static uint32_t get_jeq4_type_size (const enum dds_stream_typecode valtype, const uint32_t *jeq_op)
  671 | {
  672 |   uint32_t sz = 0;
  673 |   switch (valtype)
  674 |   {
  675 |     case DDS_OP_VAL_BLN: case DDS_OP_VAL_1BY: case DDS_OP_VAL_2BY: case DDS_OP_VAL_4BY: case DDS_OP_VAL_8BY:
  676 |       sz = get_primitive_size (valtype);
  677 |       break;
  678 |     case DDS_OP_VAL_ENU:
  679 |       sz = sizeof (uint32_t);
  680 |       break;
  681 |     case DDS_OP_VAL_STR:
  682 |       sz = sizeof (char *);
  683 |       break;
  684 |     case DDS_OP_VAL_WSTR:
  685 |       sz = sizeof (wchar_t *);
  686 |       break;
  687 |     case DDS_OP_VAL_WCHAR:
  688 |       sz = sizeof (wchar_t);
  689 |       break;
  690 |     case DDS_OP_VAL_BMK:
  691 |     case DDS_OP_VAL_BST: case DDS_OP_VAL_BWSTR:
  692 |     case DDS_OP_VAL_ARR: {
  693 |       const uint32_t *jsr_ops = jeq_op + DDS_OP_ADR_JSR (jeq_op[0]);
  694 |       sz = get_adr_type_size (jsr_ops[0], jsr_ops);
  695 |       break;
  696 |     }
  697 |     case DDS_OP_VAL_SEQ: case DDS_OP_VAL_BSQ: case DDS_OP_VAL_STU: case DDS_OP_VAL_UNI:
  698 |       sz = jeq_op[3];
  699 |       break;
  700 |     case DDS_OP_VAL_EXT:
  701 |       abort ();
  702 |       break;
  703 |   }
  704 |   return sz;
  705 | }
  706 |
  707 | static bool type_has_subtype_or_members (enum dds_stream_typecode type)
  708 | {
  709 |   return type == DDS_OP_VAL_SEQ || type == DDS_OP_VAL_BSQ || type == DDS_OP_VAL_ARR || type == DDS_OP_VAL_UNI || type == DDS_OP_VAL_STU;
  710 | }
  711 |
  712 | static bool seq_is_bounded (enum dds_stream_typecode type)
  713 | {
  714 |   assert (type == DDS_OP_VAL_SEQ || type == DDS_OP_VAL_BSQ);
  715 |   return type == DDS_OP_VAL_BSQ;
  716 | }
  717 |
  718 | static inline bool bitmask_value_valid (uint32_t val_h, uint32_t val_l, uint32_t bits_h, uint32_t bits_l)
  719 | {
  720 |   return (val_h & ~bits_h) == 0 && (val_l & ~bits_l) == 0;
  721 | }
  722 |
  723 | static inline bool op_type_external (const uint32_t insn)
  724 | {
  725 |   uint32_t typeflags = DDS_OP_TYPE_FLAGS (insn);
  726 |   return (typeflags & DDS_OP_FLAG_EXT);
  727 | }
  728 |
  729 | static inline bool op_type_optional (const uint32_t insn)
  730 | {
  731 |   uint32_t flags = DDS_OP_FLAGS (insn);
  732 |   return (flags & DDS_OP_FLAG_OPT);
  733 | }
  734 |
  735 | static inline bool op_type_base (const uint32_t insn)
  736 | {
  737 |   uint32_t opflags = DDS_OP_FLAGS (insn);
  738 |   return (opflags & DDS_OP_FLAG_BASE);
  739 | }
  740 |
  741 | ddsrt_nonnull_all
  742 | static inline bool check_optimize_impl (uint32_t xcdr_version, const uint32_t *ops, uint32_t size, uint32_t num, uint32_t *off, uint32_t member_offs)
  743 | {
  744 |   align_t cdr_align = dds_cdr_get_align (xcdr_version, size);
  745 |   if (*off % ALIGN(cdr_align))
  746 |     *off += ALIGN(cdr_align) - (*off % ALIGN(cdr_align));
  747 |   if (member_offs + ops[1] != *off)
  748 |     return false;

Reach line at /src/cyclonedds/src/core/cdr/src/dds_cdrstream.c:648 (observed count 178).


  278 |     } else if (delta > 0) {
  279 |       data.extra = (uint32_t) DDSI_LIVELINESS_CHANGED_NOT_ALIVE_TO_ALIVE;
  280 |       (rd->status_cb) (rd->status_cb_entity, &data);
  281 |     } else {
  282 |       /* Twitch: the resulting (proxy)writer state is unchanged, but there has been
  283 |         a transition to another state and back to the current state. So we'll call
  284 |         the callback twice in this case. */
  285 |       static const enum ddsi_liveliness_changed_data_extra x[] = {
  286 |         DDSI_LIVELINESS_CHANGED_NOT_ALIVE_TO_ALIVE,
  287 |         DDSI_LIVELINESS_CHANGED_ALIVE_TO_NOT_ALIVE
  288 |       };
  289 |       data.extra = (uint32_t) x[alive_state->alive];
  290 |       (rd->status_cb) (rd->status_cb_entity, &data);
  291 |       data.extra = (uint32_t) x[!alive_state->alive];
  292 |       (rd->status_cb) (rd->status_cb_entity, &data);
  293 |     }
  294 |   }
  295 | }
  296 |
  297 | void ddsi_reader_update_notify_wr_alive_state (struct ddsi_reader *rd, const struct ddsi_writer *wr, const struct ddsi_alive_state *alive_state)
  298 | {
  299 |   struct ddsi_rd_wr_match *m;
  300 |   bool notify = false;
  301 |   int delta = 0; /* -1: alive -> not_alive; 0: unchanged; 1: not_alive -> alive */
  302 |   ddsrt_mutex_lock (&rd->e.lock);
  303 |   if ((m = ddsrt_avl_lookup (&ddsi_rd_local_writers_treedef, &rd->local_writers, &wr->e.guid)) != NULL)
  304 |   {
  305 |     if ((int32_t) (alive_state->vclock - m->wr_alive_vclock) > 0)
  306 |     {
  307 |       delta = (int) alive_state->alive - (int) m->wr_alive;
  308 |       notify = true;
  309 |       m->wr_alive = alive_state->alive;
  310 |       m->wr_alive_vclock = alive_state->vclock;
  311 |     }
  312 |   }
  313 |   ddsrt_mutex_unlock (&rd->e.lock);
  314 |
  315 |   if (delta < 0 && rd->rhc)
  316 |   {
  317 |     struct ddsi_writer_info wrinfo;
  318 |     ddsi_make_writer_info (&wrinfo, &wr->e, wr->xqos, DDSI_STATUSINFO_UNREGISTER);
  319 |     ddsi_rhc_unregister_wr (rd->rhc, &wrinfo);
  320 |   }
  321 |
  322 |   reader_update_notify_alive_state_invoke_cb (rd, wr->e.iid, notify, delta, alive_state);
  323 | }
  324 |
  325 | static void ddsi_reader_update_notify_wr_alive_state_guid (const struct ddsi_guid *rd_guid, const struct ddsi_writer *wr, const struct ddsi_alive_state *alive_state)
  326 | {
  327 |   struct ddsi_reader *rd;
  328 |   if ((rd = ddsi_entidx_lookup_reader_guid (wr->e.gv->entity_index, rd_guid)) != NULL)
  329 |     ddsi_reader_update_notify_wr_alive_state (rd, wr, alive_state);
  330 | }
  331 |
  332 | void ddsi_reader_update_notify_pwr_alive_state (struct ddsi_reader *rd, const struct ddsi_proxy_writer *pwr, const struct ddsi_alive_state *alive_state)
  333 | {
  334 |   struct ddsi_rd_pwr_match *m;
  335 |   bool notify = false;
  336 |   int delta = 0; /* -1: alive -> not_alive; 0: unchanged; 1: not_alive -> alive */
  337 |   ddsrt_mutex_lock (&rd->e.lock);
  338 |   if ((m = ddsrt_avl_lookup (&ddsi_rd_writers_treedef, &rd->writers, &pwr->e.guid)) != NULL)
  339 |   {
  340 |     if ((int32_t) (alive_state->vclock - m->pwr_alive_vclock) > 0)
  341 |     {
  342 |       delta = (int) alive_state->alive - (int) m->pwr_alive;
  343 |       notify = true;
  344 |       m->pwr_alive = alive_state->alive;
  345 |       m->pwr_alive_vclock = alive_state->vclock;
  346 |     }
  347 |   }
  348 |   ddsrt_mutex_unlock (&rd->e.lock);
  349 |
  350 |   if (delta < 0 && rd->rhc)
  351 |   {
  352 |     struct ddsi_writer_info wrinfo;
  353 |     ddsi_make_writer_info (&wrinfo, &pwr->e, pwr->c.xqos, DDSI_STATUSINFO_UNREGISTER);
  354 |     ddsi_rhc_unregister_wr (rd->rhc, &wrinfo);
  355 |   }
  356 |
  357 |   reader_update_notify_alive_state_invoke_cb (rd, pwr->e.iid, notify, delta, alive_state);
  358 | }
  359 |
  360 | void ddsi_reader_update_notify_pwr_alive_state_guid (const struct ddsi_guid *rd_guid, const struct ddsi_proxy_writer *pwr, const struct ddsi_alive_state *alive_state)
  361 | {
  362 |   struct ddsi_reader *rd;
  363 |   if ((rd = ddsi_entidx_lookup_reader_guid (pwr->e.gv->entity_index, rd_guid)) != NULL)
  364 |     ddsi_reader_update_notify_pwr_alive_state (rd, pwr, alive_state);
  365 | }
  366 |
  367 | void ddsi_update_reader_init_acknack_count (const ddsrt_log_cfg_t *logcfg, const struct ddsi_entity_index *entidx, const struct ddsi_guid *rd_guid, ddsi_count_t count)
  368 | {
  369 |   struct ddsi_reader *rd;
  370 |
  371 |   /* Update the initial acknack sequence number for the reader.  See
  372 |      also ddsi_reader_add_connection(). */
  373 |   DDS_CLOG (DDS_LC_DISCOVERY, logcfg, "ddsi_update_reader_init_acknack_count ("PGUIDFMT", %"PRIu32"): ", PGUID (*rd_guid), count);
  374 |   if ((rd = ddsi_entidx_lookup_reader_guid (entidx, rd_guid)) != NULL)
  375 |   {
  376 |     ddsrt_mutex_lock (&rd->e.lock);
  377 |     DDS_CLOG (DDS_LC_DISCOVERY, logcfg, "%"PRIu32" -> ", rd->init_acknack_count);
> 378 |     if (count > rd->init_acknack_count)
  379 |       rd->init_acknack_count = count;
  380 |     DDS_CLOG (DDS_LC_DISCOVERY, logcfg, "%"PRIu32"\n", count);
  381 |     ddsrt_mutex_unlock (&rd->e.lock);
  382 |   }
  383 |   else
  384 |   {
  385 |     DDS_CLOG (DDS_LC_DISCOVERY, logcfg, "reader no longer exists\n");
  386 |   }
  387 | }
  388 |
  389 | void ddsi_deliver_historical_data (const struct ddsi_writer *wr, const struct ddsi_reader *rd)
  390 | {
  391 |   struct ddsi_domaingv * const gv = wr->e.gv;
  392 |   struct ddsi_tkmap * const tkmap = gv->m_tkmap;
  393 |   struct ddsi_whc_sample_iter it;
  394 |   struct ddsi_whc_borrowed_sample sample;
  395 |   /* FIXME: should limit ourselves to what it is available because of durability history, not writer history */
  396 |   ddsi_whc_sample_iter_init (wr->whc, &it);
  397 |   while (ddsi_whc_sample_iter_borrow_next (&it, &sample))
  398 |   {
  399 |     struct ddsi_serdata *payload;
  400 |     if ((payload = ddsi_serdata_ref_as_type (rd->type, sample.serdata)) == NULL)
  401 |     {
  402 |       GVWARNING ("local: deserialization of %s/%s as %s/%s failed in topic type conversion\n",
  403 |                  wr->xqos->topic_name, wr->type->type_name, rd->xqos->topic_name, rd->type->type_name);
  404 |     }
  405 |     else
  406 |     {
  407 |       struct ddsi_writer_info wrinfo;
  408 |       struct ddsi_tkmap_instance *tk = ddsi_tkmap_lookup_instance_ref (tkmap, payload);
  409 |       ddsi_make_writer_info (&wrinfo, &wr->e, wr->xqos, payload->statusinfo);
  410 |       (void) ddsi_rhc_store (rd->rhc, &wrinfo, payload, tk);
  411 |       ddsi_tkmap_instance_unref (tkmap, tk);
  412 |       ddsi_serdata_unref (payload);
  413 |     }
  414 |   }
  415 | }
  416 |
  417 | static void new_reader_writer_common (const struct ddsrt_log_cfg *logcfg, const struct ddsi_guid *guid, const char *topic_name, const char *type_name, const struct dds_qos *xqos)
  418 | {
  419 |   const char *partition = "(default)";
  420 |   const char *partition_suffix = "";
  421 |   assert (topic_name != NULL);
  422 |   assert (type_name != NULL);
  423 |   if (ddsi_is_builtin_entityid (guid->entityid, DDSI_VENDORID_ECLIPSE))
  424 |   {
  425 |     /* continue printing it as not being in a partition, the actual
  426 |        value doesn't matter because it is never matched based on QoS
  427 |        settings */
  428 |     partition = "(null)";
  429 |   }
  430 |   else if ((xqos->present & DDSI_QP_PARTITION) && xqos->partition.n > 0 && strcmp (xqos->partition.strs[0], "") != 0)
  431 |   {
  432 |     partition = xqos->partition.strs[0];
  433 |     if (xqos->partition.n > 1)
  434 |       partition_suffix = "+";
  435 |   }
  436 |   DDS_CLOG (DDS_LC_DISCOVERY, logcfg, "new_%s(guid "PGUIDFMT", %s%s.%s/%s)\n",
  437 |             ddsi_is_writer_entityid (guid->entityid) ? "writer" : "reader",
  438 |             PGUID (*guid),
  439 |             partition, partition_suffix,
  440 |             topic_name,
  441 |             type_name);
  442 | }
  443 |
  444 | static bool is_onlylocal_endpoint (struct ddsi_participant *pp, const char *topic_name, const struct ddsi_sertype *type, const struct dds_qos *xqos)
  445 | {
  446 |   if (ddsi_builtintopic_is_builtintopic (pp->e.gv->builtin_topic_interface, type))
  447 |     return true;
  448 | #ifdef DDS_HAS_NETWORK_PARTITIONS
  449 |   if (ddsi_is_ignored_nwpart (pp->e.gv, xqos, topic_name))
  450 |     return true;
  451 | #endif
  452 |   return false;
  453 | }
  454 |
  455 | static void endpoint_common_init (struct ddsi_entity_common *e, struct ddsi_endpoint_common *c, struct ddsi_domaingv *gv, enum ddsi_entity_kind kind, const struct ddsi_guid *guid, const struct ddsi_guid *group_guid, struct ddsi_participant *pp, bool onlylocal, const struct ddsi_sertype *sertype, struct ddsi_psmx_locators_set *psmx_locators)
  456 | {
  457 | #ifndef DDS_HAS_TYPELIB
  458 |   DDSRT_UNUSED_ARG (sertype);
  459 | #endif
  460 |   ddsi_entity_common_init (e, gv, guid, kind, ddsrt_time_wallclock (), DDSI_VENDORID_ECLIPSE, pp->e.onlylocal || onlylocal);
  461 |   c->pp = ddsi_ref_participant (pp, &e->guid);
  462 |   if (group_guid)
  463 |     c->group_guid = *group_guid;
  464 |   else
  465 |     memset (&c->group_guid, 0, sizeof (c->group_guid));
  466 |
  467 |   if (psmx_locators)
  468 |   {
  469 |     c->psmx_locators.length = psmx_locators->length;
  470 |     if (psmx_locators->length > 0)
  471 |       c->psmx_locators.locators = ddsrt_memdup (psmx_locators->locators, psmx_locators->length * sizeof (*psmx_locators->locators));
  472 |   }
  473 |   else
  474 |   {
  475 |     c->psmx_locators.length = 0;
  476 |   }
  477 |
  478 | #ifdef DDS_HAS_TYPELIB

Reach line at /src/cyclonedds/src/core/ddsi/src/ddsi_endpoint.c:378 (observed count 867).


  1095 |         return ret;
  1096 |       break;
  1097 |     case DDS_XTypes_TK_MAP:
  1098 |       if ((ret = xt_valid_type_flags (gv, t->_u.map.c.flags, t->_d))
  1099 |           || (ret = xt_valid_member_flags (gv, t->_u.map.c.element_flags, MEMBER_FLAG_COLLECTION_ELEMENT, in_key))
  1100 |           || (ret = xt_validate_impl (gv, &t->_u.map.key_type->xt, false, in_key))
  1101 |           || (ret = xt_validate_impl (gv, &t->_u.map.c.element_type->xt, false, in_key)))
  1102 |         return ret;
  1103 |       break;
  1104 |     case DDS_XTypes_TK_BOOLEAN: case DDS_XTypes_TK_BYTE:
  1105 |     case DDS_XTypes_TK_INT8: case DDS_XTypes_TK_INT16: case DDS_XTypes_TK_INT32: case DDS_XTypes_TK_INT64:
  1106 |     case DDS_XTypes_TK_UINT8: case DDS_XTypes_TK_UINT16: case DDS_XTypes_TK_UINT32: case DDS_XTypes_TK_UINT64:
  1107 |     case DDS_XTypes_TK_FLOAT32: case DDS_XTypes_TK_FLOAT64: case DDS_XTypes_TK_FLOAT128:
  1108 |     case DDS_XTypes_TK_CHAR8: case DDS_XTypes_TK_CHAR16: case DDS_XTypes_TK_STRING8: case DDS_XTypes_TK_STRING16:
  1109 |       // no validations
  1110 |       break;
  1111 |     default:
  1112 |       return DDS_RETCODE_UNSUPPORTED;
  1113 |   }
  1114 |   return DDS_RETCODE_OK;
  1115 | }
  1116 |
  1117 | dds_return_t ddsi_xt_validate (struct ddsi_domaingv *gv, const struct xt_type *t)
  1118 | {
  1119 |   return xt_validate_impl (gv, t, true, false);
  1120 | }
  1121 |
  1122 | static dds_return_t add_minimal_typeobj (struct ddsi_domaingv *gv, struct xt_type *xt, const struct DDS_XTypes_TypeObject *to)
  1123 | {
  1124 |   const struct DDS_XTypes_MinimalTypeObject *mto = &to->_u.minimal;
  1125 |   dds_return_t ret = DDS_RETCODE_OK;
  1126 |   if (!xt->_d)
  1127 |     xt->_d = mto->_d;
  1128 |   else if (xt->_d != mto->_d)
  1129 |   {
  1130 |     GVTRACE ("typeobject has invalid type kind\n");
  1131 |     ret = DDS_RETCODE_BAD_PARAMETER;
  1132 |     goto err_tk;
  1133 |   }
  1134 |   switch (mto->_d)
  1135 |   {
  1136 |     case DDS_XTypes_TK_ALIAS:
  1137 |       xt->_u.alias.flags = mto->_u.alias_type.alias_flags;
  1138 |       if ((ret = ddsi_type_register_dep (gv, &xt->id, &xt->_u.alias.related_type, &mto->_u.alias_type.body.common.related_type)) != DDS_RETCODE_OK)
  1139 |         goto err_to;
  1140 |       xt->_u.alias.related_flags = mto->_u.alias_type.body.common.related_flags;
  1141 |       break;
  1142 |     case DDS_XTypes_TK_ANNOTATION:
  1143 |       ret = DDS_RETCODE_UNSUPPORTED; /* FIXME: not implemented */
  1144 |       goto err_to;
  1145 |     case DDS_XTypes_TK_STRUCTURE:
  1146 |       xt->_u.structure.flags = mto->_u.struct_type.struct_flags;
  1147 |       if (mto->_u.struct_type.header.base_type._d)
  1148 |       {
  1149 |         if ((ret = ddsi_type_register_dep (gv, &xt->id, &xt->_u.structure.base_type, &mto->_u.struct_type.header.base_type)) != DDS_RETCODE_OK)
  1150 |           goto err_to;
  1151 |       }
  1152 |       else
  1153 |         xt->_u.structure.base_type = NULL;
  1154 |       xt->_u.structure.members.length = mto->_u.struct_type.member_seq._length;
  1155 |       xt->_u.structure.members.seq = ddsrt_calloc (xt->_u.structure.members.length, sizeof (*xt->_u.structure.members.seq));
  1156 |       for (uint32_t n = 0; n < xt->_u.structure.members.length; n++)
  1157 |       {
  1158 |         xt->_u.structure.members.seq[n].id = mto->_u.struct_type.member_seq._buffer[n].common.member_id;
  1159 |         xt->_u.structure.members.seq[n].flags = mto->_u.struct_type.member_seq._buffer[n].common.member_flags;
  1160 |         if ((ret = ddsi_type_register_dep (gv, &xt->id, &xt->_u.structure.members.seq[n].type, &mto->_u.struct_type.member_seq._buffer[n].common.member_type_id)) != DDS_RETCODE_OK)
  1161 |         {
  1162 |           for (uint32_t m = 0; m < n; m++)
  1163 |             ddsi_type_unref_locked (gv, xt->_u.structure.members.seq[m].type);
  1164 |           if (xt->_u.structure.base_type)
  1165 |             ddsi_type_unref_locked (gv, xt->_u.structure.base_type);
  1166 |           ddsrt_free (xt->_u.structure.members.seq);
  1167 |           goto err_to;
  1168 |         }
  1169 |         memcpy (xt->_u.structure.members.seq[n].detail.name_hash, mto->_u.struct_type.member_seq._buffer[n].detail.name_hash,
  1170 |           sizeof (xt->_u.structure.members.seq[n].detail.name_hash));
  1171 |       }
  1172 |       break;
  1173 |     case DDS_XTypes_TK_UNION:
  1174 |       xt->_u.union_type.flags = mto->_u.union_type.union_flags;
  1175 |       if ((ret = ddsi_type_register_dep (gv, &xt->id, &xt->_u.union_type.disc_type, &mto->_u.union_type.discriminator.common.type_id)) != DDS_RETCODE_OK)
  1176 |         goto err_to;
  1177 |       xt->_u.union_type.disc_flags = mto->_u.union_type.discriminator.common.member_flags;
  1178 |       xt->_u.union_type.members.length = mto->_u.union_type.member_seq._length;
  1179 |       xt->_u.union_type.members.seq = ddsrt_calloc (xt->_u.union_type.members.length, sizeof (*xt->_u.union_type.members.seq));
  1180 |       for (uint32_t n = 0; n < xt->_u.union_type.members.length; n++)
  1181 |       {
  1182 |         xt->_u.union_type.members.seq[n].id = mto->_u.union_type.member_seq._buffer[n].common.member_id;
  1183 |         xt->_u.union_type.members.seq[n].flags = mto->_u.union_type.member_seq._buffer[n].common.member_flags;
  1184 |         if ((ret = ddsi_type_register_dep (gv, &xt->id, &xt->_u.union_type.members.seq[n].type, &mto->_u.union_type.member_seq._buffer[n].common.type_id)) != DDS_RETCODE_OK)
  1185 |         {
  1186 |           for (uint32_t m = 0; m < n; m++)
  1187 |           {
  1188 |             ddsi_type_unref_locked (gv, xt->_u.union_type.members.seq[m].type);
  1189 |             ddsrt_free (xt->_u.union_type.members.seq[m].label_seq._buffer);
  1190 |           }
  1191 |           ddsi_type_unref_locked (gv, xt->_u.union_type.disc_type);
  1192 |           ddsrt_free (xt->_u.union_type.members.seq);
  1193 |           goto err_to;
  1194 |         }
> 1195 |         xt->_u.union_type.members.seq[n].label_seq._length = mto->_u.union_type.member_seq._buffer[n].common.label_seq._length;
  1196 |         if (xt->_u.union_type.members.seq[n].label_seq._length > 0) {
  1197 |           xt->_u.union_type.members.seq[n].label_seq._buffer =
  1198 |             ddsrt_memdup (mto->_u.union_type.member_seq._buffer[n].common.label_seq._buffer,
  1199 |                           mto->_u.union_type.member_seq._buffer[n].common.label_seq._length * sizeof (*mto->_u.union_type.member_seq._buffer[n].common.label_seq._buffer));
  1200 |           xt->_u.union_type.members.seq[n].label_seq._release = true;
  1201 |         } else {
  1202 |           xt->_u.union_type.members.seq[n].label_seq._buffer = NULL;
  1203 |           xt->_u.union_type.members.seq[n].label_seq._release = false;
  1204 |         }
  1205 |         memcpy (xt->_u.union_type.members.seq[n].detail.name_hash, mto->_u.union_type.member_seq._buffer[n].detail.name_hash,
  1206 |           sizeof (xt->_u.union_type.members.seq[n].detail.name_hash));
  1207 |       }
  1208 |       break;
  1209 |     case DDS_XTypes_TK_BITSET:
  1210 |       xt->_u.bitset.flags = mto->_u.bitset_type.bitset_flags;
  1211 |       xt->_u.bitset.fields.length = mto->_u.bitset_type.field_seq._length;
  1212 |       xt->_u.bitset.fields.seq = ddsrt_calloc (xt->_u.bitset.fields.length, sizeof (*xt->_u.bitset.fields.seq));
  1213 |       for (uint32_t n = 0; n < xt->_u.bitset.fields.length; n++)
  1214 |       {
  1215 |         xt->_u.bitset.fields.seq[n].position = mto->_u.bitset_type.field_seq._buffer[n].common.position;
  1216 |         xt->_u.bitset.fields.seq[n].flags = mto->_u.bitset_type.field_seq._buffer[n].common.flags;
  1217 |         xt->_u.bitset.fields.seq[n].bitcount = mto->_u.bitset_type.field_seq._buffer[n].common.bitcount;
  1218 |         xt->_u.bitset.fields.seq[n].holder_type = mto->_u.bitset_type.field_seq._buffer[n].common.holder_type;
  1219 |         xt->_u.bitset.fields.seq[n].flags = mto->_u.bitset_type.field_seq._buffer[n].common.flags;
  1220 |         memcpy (xt->_u.bitset.fields.seq[n].detail.name_hash, mto->_u.bitset_type.field_seq._buffer[n].name_hash,
  1221 |           sizeof (xt->_u.bitset.fields.seq[n].detail.name_hash));
  1222 |       }
  1223 |       break;
  1224 |     case DDS_XTypes_TK_SEQUENCE:
  1225 |       xt->_u.seq.c.flags = mto->_u.sequence_type.collection_flag;
  1226 |       if ((ret = ddsi_type_register_dep (gv, &xt->id, &xt->_u.seq.c.element_type, &mto->_u.sequence_type.element.common.type)) != DDS_RETCODE_OK)
  1227 |         goto err_to;
  1228 |       xt->_u.seq.c.element_flags = mto->_u.sequence_type.element.common.element_flags;
  1229 |       xt->_u.seq.bound = mto->_u.sequence_type.header.common.bound;
  1230 |       break;
  1231 |     case DDS_XTypes_TK_ARRAY:
  1232 |       xt->_u.array.c.flags = mto->_u.array_type.collection_flag;
  1233 |       if ((ret = ddsi_type_register_dep (gv, &xt->id, &xt->_u.array.c.element_type, &mto->_u.array_type.element.common.type)) != DDS_RETCODE_OK)
  1234 |         goto err_to;
  1235 |       xt->_u.array.c.element_flags = mto->_u.array_type.element.common.element_flags;
  1236 |       xt_lbounds_dup (&xt->_u.array.bounds, &mto->_u.array_type.header.common.bound_seq);
  1237 |       break;
  1238 |     case DDS_XTypes_TK_MAP:
  1239 |       xt->_u.map.c.flags = mto->_u.map_type.collection_flag;
  1240 |       if ((ret = ddsi_type_register_dep (gv, &xt->id, &xt->_u.map.c.element_type, &mto->_u.map_type.element.common.type)) != DDS_RETCODE_OK)
  1241 |         goto err_to;
  1242 |       xt->_u.map.c.element_flags = mto->_u.map_type.element.common.element_flags;
  1243 |       if ((ret = ddsi_type_register_dep (gv, &xt->id, &xt->_u.map.key_type, &mto->_u.map_type.key.common.type)) != DDS_RETCODE_OK)
  1244 |       {
  1245 |         ddsi_type_unref_locked (gv, xt->_u.map.c.element_type);
  1246 |         goto err_to;
  1247 |       }
  1248 |       xt->_u.map.bound = mto->_u.map_type.header.common.bound;
  1249 |       break;
  1250 |     case DDS_XTypes_TK_ENUM:
  1251 |       xt->_u.enum_type.flags = mto->_u.enumerated_type.enum_flags;
  1252 |       xt->_u.enum_type.bit_bound = mto->_u.enumerated_type.header.common.bit_bound;
  1253 |       xt->_u.enum_type.literals.length = mto->_u.enumerated_type.literal_seq._length;
  1254 |       xt->_u.enum_type.literals.seq = ddsrt_calloc (xt->_u.enum_type.literals.length, sizeof (*xt->_u.enum_type.literals.seq));
  1255 |       for (uint32_t n = 0; n < xt->_u.enum_type.literals.length; n++)
  1256 |       {
  1257 |         xt->_u.enum_type.literals.seq[n].value = mto->_u.enumerated_type.literal_seq._buffer[n].common.value;
  1258 |         xt->_u.enum_type.literals.seq[n].flags = mto->_u.enumerated_type.literal_seq._buffer[n].common.flags;
  1259 |         memcpy (xt->_u.enum_type.literals.seq[n].detail.name_hash, mto->_u.enumerated_type.literal_seq._buffer[n].detail.name_hash,
  1260 |           sizeof (xt->_u.enum_type.literals.seq[n].detail.name_hash));
  1261 |       }
  1262 |       break;
  1263 |     case DDS_XTypes_TK_BITMASK:
  1264 |       xt->_u.bitmask.flags = mto->_u.bitmask_type.bitmask_flags;
  1265 |       xt->_u.bitmask.bit_bound = mto->_u.bitmask_type.header.common.bit_bound;
  1266 |       xt->_u.bitmask.bitflags.length = mto->_u.bitmask_type.flag_seq._length;
  1267 |       xt->_u.bitmask.bitflags.seq = ddsrt_calloc (xt->_u.bitmask.bitflags.length, sizeof (*xt->_u.bitmask.bitflags.seq));
  1268 |       for (uint32_t n = 0; n < xt->_u.bitmask.bitflags.length; n++)
  1269 |       {
  1270 |         xt->_u.bitmask.bitflags.seq[n].position = mto->_u.bitmask_type.flag_seq._buffer[n].common.position;
  1271 |         xt->_u.bitmask.bitflags.seq[n].flags = mto->_u.bitmask_type.flag_seq._buffer[n].common.flags;
  1272 |         memcpy (xt->_u.bitmask.bitflags.seq[n].detail.name_hash, mto->_u.bitmask_type.flag_seq._buffer[n].detail.name_hash,
  1273 |           sizeof (xt->_u.bitmask.bitflags.seq[n].detail.name_hash));
  1274 |       }
  1275 |       break;
  1276 |     default:
  1277 |       ret = DDS_RETCODE_UNSUPPORTED; /* not supported */
  1278 |       goto err_tk;
  1279 |   }
  1280 |   return ret;
  1281 |
  1282 | err_tk:
  1283 | err_to:
  1284 |   xt->_d = DDS_XTypes_TK_NONE;
  1285 |   return ret;
  1286 | }
  1287 |
  1288 | static dds_return_t add_complete_typeobj (struct ddsi_domaingv *gv, struct xt_type *xt, const struct DDS_XTypes_TypeObject *to)
  1289 | {
  1290 |   const struct DDS_XTypes_CompleteTypeObject *cto = &to->_u.complete;
  1291 |   dds_return_t ret = DDS_RETCODE_OK;
  1292 |   if (!xt->_d)
  1293 |     xt->_d = cto->_d;
  1294 |   else if (xt->_d != cto->_d)
  1295 |   {

Reach line at /src/cyclonedds/src/core/ddsi/src/ddsi_typewrap.c:1195 (observed count 90).


  7117 |                 if (H5T__detect_vlen_ref(dt->shared->u.compnd.memb[u].type))
  7118 |                     HGOTO_DONE(true);
  7119 |             break;
  7120 |
  7121 |         case H5T_ARRAY:
  7122 |         case H5T_VLEN:
  7123 |         case H5T_ENUM:
  7124 |             HGOTO_DONE(H5T__detect_vlen_ref(dt->shared->parent));
  7125 |             break;
  7126 |
  7127 |         case H5T_NO_CLASS:
  7128 |         case H5T_INTEGER:
  7129 |         case H5T_FLOAT:
  7130 |         case H5T_TIME:
  7131 |         case H5T_STRING:
  7132 |         case H5T_BITFIELD:
  7133 |         case H5T_OPAQUE:
  7134 |         case H5T_REFERENCE:
  7135 |         case H5T_COMPLEX:
  7136 |         case H5T_NCLASSES:
  7137 |         default:
  7138 |             break;
  7139 |     } /* end if */
  7140 |
  7141 | done:
  7142 |     FUNC_LEAVE_NOAPI(ret_value)
  7143 | } /* end H5T__detect_vlen_ref() */
  7144 |
  7145 | /*-------------------------------------------------------------------------
  7146 |  * Function:    H5T_is_vl_storage
  7147 |  *
  7148 |  * Purpose:     Check if a datatype will be stored in a variable-length form.
  7149 |  *
  7150 |  * Notes:       Currently, only variable-length string & sequences and region
  7151 |  *              references are stored in a variable-length form.
  7152 |  *
  7153 |  * Return:
  7154 |  *  One of two values on success:
  7155 |  *      true - If the datatype will be stored in a variable-length form
  7156 |  *      false - If the datatype will NOT be stored in a variable-length form
  7157 |  *  <0 is returned on failure
  7158 |  *
  7159 |  *-------------------------------------------------------------------------
  7160 |  */
  7161 | htri_t
  7162 | H5T_is_vl_storage(const H5T_t *dt)
  7163 | {
  7164 |     htri_t ret_value = false;
  7165 |
  7166 |     FUNC_ENTER_NOAPI(FAIL)
  7167 |
  7168 |     /* Sanity check */
  7169 |     assert(dt);
  7170 |
  7171 |     /* VL and region reference datatypes are stored in variable-length form */
  7172 |     if (H5T_detect_class(dt, H5T_VLEN, false))
  7173 |         ret_value = true;
  7174 |     else if (H5T_detect_class(dt, H5T_REFERENCE, false))
  7175 |         ret_value = H5T__detect_vlen_ref(dt);
  7176 |     else
  7177 |         ret_value = false;
  7178 |
  7179 | done:
  7180 |     FUNC_LEAVE_NOAPI(ret_value)
  7181 | } /* end H5T_is_vl_storage() */
  7182 |
  7183 | /*-------------------------------------------------------------------------
  7184 |  * Function:    H5T__upgrade_version_cb
  7185 |  *
  7186 |  * Purpose:     H5T__visit callback to Upgrade the version of a datatype
  7187 |  *              (if there's any benefit to doing so)
  7188 |  *
  7189 |  * Note:        The behavior below is tightly coupled with the "better"
  7190 |  *              encodings for datatype messages in the datatype message
  7191 |  *              encoding routine.
  7192 |  *
  7193 |  * Return:      Non-negative on success/Negative on failure
  7194 |  *
  7195 |  *-------------------------------------------------------------------------
  7196 |  */
  7197 | static herr_t
  7198 | H5T__upgrade_version_cb(H5T_t *dt, void *op_value)
  7199 | {
  7200 |     FUNC_ENTER_PACKAGE_NOERR
  7201 |
  7202 |     /* Sanity check */
  7203 |     assert(dt);
  7204 |     assert(op_value);
  7205 |
  7206 |     /* Special behavior for each type of datatype */
  7207 |     switch (dt->shared->type) {
  7208 |         case H5T_COMPOUND:
  7209 |         case H5T_ARRAY:
  7210 |         case H5T_ENUM:
  7211 |             /* These types benefit from "upgrading" their version */
  7212 |             if (*(unsigned *)op_value > dt->shared->version)
  7213 |                 dt->shared->version = *(unsigned *)op_value;
  7214 |             break;
  7215 |
  7216 |         case H5T_VLEN:
> 7217 |             if (dt->shared->parent->shared->version > dt->shared->version)
  7218 |                 dt->shared->version = dt->shared->parent->shared->version;
  7219 |             break;
  7220 |
  7221 |         case H5T_COMPLEX:
  7222 |             if (dt->shared->parent->shared->version > dt->shared->version)
  7223 |                 dt->shared->version = dt->shared->parent->shared->version;
  7224 |             break;
  7225 |
  7226 |         case H5T_NO_CLASS:
  7227 |         case H5T_INTEGER:
  7228 |         case H5T_FLOAT:
  7229 |         case H5T_TIME:
  7230 |         case H5T_STRING:
  7231 |         case H5T_BITFIELD:
  7232 |         case H5T_OPAQUE:
  7233 |         case H5T_REFERENCE:
  7234 |         case H5T_NCLASSES:
  7235 |         default:
  7236 |             break;
  7237 |     } /* end switch */
  7238 |
  7239 |     FUNC_LEAVE_NOAPI(SUCCEED)
  7240 | } /* end H5T__upgrade_version_cb() */
  7241 |
  7242 | /*-------------------------------------------------------------------------
  7243 |  * Function:    H5T__upgrade_version
  7244 |  *
  7245 |  * Purpose:     Upgrade the version of a datatype (if there's any benefit to
  7246 |  *              doing so) and recursively apply to compound members and/or
  7247 |  *              parent datatypes.
  7248 |  *
  7249 |  * Return:      Non-negative on success/Negative on failure
  7250 |  *
  7251 |  *-------------------------------------------------------------------------
  7252 |  */
  7253 | herr_t
  7254 | H5T__upgrade_version(H5T_t *dt, unsigned new_version)
  7255 | {
  7256 |     herr_t ret_value = SUCCEED; /* Return value */
  7257 |
  7258 |     FUNC_ENTER_PACKAGE
  7259 |
  7260 |     /* Sanity check */
  7261 |     assert(dt);
  7262 |
  7263 |     /* Iterate over entire datatype, upgrading the version of components, if it's useful */
  7264 |     if (H5T__visit(dt, (H5T_VISIT_SIMPLE | H5T_VISIT_COMPOSITE_LAST), H5T__upgrade_version_cb, &new_version) <
  7265 |         0)
  7266 |         HGOTO_ERROR(H5E_DATATYPE, H5E_BADITER, FAIL, "iteration to upgrade datatype encoding version failed");
  7267 |
  7268 | done:
  7269 |     FUNC_LEAVE_NOAPI(ret_value)
  7270 | } /* end H5T__upgrade_version() */
  7271 |
  7272 | /*-------------------------------------------------------------------------
  7273 |  * Function:    H5T_set_version
  7274 |  *
  7275 |  * Purpose:     Set the encoding for a datatype to the version indicated by
  7276 |  *              the file's low bound if that is higher than the datatype's
  7277 |  *              version.
  7278 |  *
  7279 |  * Return:      Non-negative on success/Negative on failure
  7280 |  *
  7281 |  *-------------------------------------------------------------------------
  7282 |  */
  7283 | herr_t
  7284 | H5T_set_version(H5F_t *f, H5T_t *dt)
  7285 | {
  7286 |     unsigned vers;                /* The version */
  7287 |     herr_t   ret_value = SUCCEED; /* Return value */
  7288 |
  7289 |     FUNC_ENTER_NOAPI(FAIL)
  7290 |
  7291 |     /* Sanity check */
  7292 |     assert(f);
  7293 |     assert(dt);
  7294 |
  7295 |     vers = H5O_dtype_ver_bounds[H5F_LOW_BOUND(f)];
  7296 |     if (vers > dt->shared->version) {
  7297 |         /* Upgrade the format version for the datatype */
  7298 |         if (H5T__upgrade_version(dt, vers) < 0)
  7299 |             HGOTO_ERROR(H5E_DATATYPE, H5E_CANTSET, FAIL, "can't upgrade datatype encoding");
  7300 |     }
  7301 |
  7302 |     /* Version bounds check */
  7303 |     if (dt->shared->version > H5O_dtype_ver_bounds[H5F_HIGH_BOUND(f)])
  7304 |         HGOTO_ERROR(H5E_DATATYPE, H5E_BADRANGE, FAIL, "Datatype version out of bounds");
  7305 |
  7306 | done:
  7307 |     FUNC_LEAVE_NOAPI(ret_value)
  7308 | } /* end H5T_set_version() */
  7309 |
  7310 | /*-------------------------------------------------------------------------
  7311 |  * Function:    H5T_patch_file
  7312 |  *
  7313 |  * Purpose:     Patch the top-level file pointers contained in dt to point
  7314 |  *              to f, if dt is a committed type.  This is possible because
  7315 |  *              the top-level file pointer can be closed out from under
  7316 |  *              dt while dt is contained in the shared file's cache.
  7317 |  *

Reach line at /src/hdf5/src/H5T.c:7217 (observed count 321).


  2163 |     /* Get the value */
  2164 |     *dt_conv_cb = (*head)->ctx.dt_conv_cb;
  2165 |
  2166 | done:
  2167 |     FUNC_LEAVE_NOAPI(ret_value)
  2168 | } /* end H5CX_get_dt_conv_cb() */
  2169 |
  2170 | /*-------------------------------------------------------------------------
  2171 |  * Function:    H5CX_get_selection_io_mode
  2172 |  *
  2173 |  * Purpose:     Retrieves the selection I/O mode for the current API call context.
  2174 |  *
  2175 |  * Return:      Non-negative on success / Negative on failure
  2176 |  *
  2177 |  *-------------------------------------------------------------------------
  2178 |  */
  2179 | herr_t
  2180 | H5CX_get_selection_io_mode(H5D_selection_io_mode_t *selection_io_mode)
  2181 | {
  2182 |     H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
  2183 |     herr_t        ret_value = SUCCEED; /* Return value */
  2184 |
  2185 |     FUNC_ENTER_NOAPI(FAIL)
  2186 |
  2187 |     /* Sanity check */
  2188 |     assert(selection_io_mode);
  2189 |     head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
  2190 |     assert(head && *head);
  2191 |     assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
  2192 |
  2193 |     H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_SELECTION_IO_MODE_NAME,
  2194 |                              selection_io_mode)
  2195 |
  2196 |     /* Get the value */
  2197 |     *selection_io_mode = (*head)->ctx.selection_io_mode;
  2198 |
  2199 | done:
  2200 |     FUNC_LEAVE_NOAPI(ret_value)
  2201 | } /* end H5CX_get_selection_io_mode() */
  2202 |
  2203 | /*-------------------------------------------------------------------------
  2204 |  * Function:    H5CX_get_no_selection_io_cause
  2205 |  *
  2206 |  * Purpose:     Retrieves the cause for not performing selection I/O
  2207 |  *              for the current API call context.
  2208 |  *
  2209 |  * Return:      Non-negative on success / Negative on failure
  2210 |  *
  2211 |  *-------------------------------------------------------------------------
  2212 |  */
  2213 | herr_t
  2214 | H5CX_get_no_selection_io_cause(uint32_t *no_selection_io_cause)
  2215 | {
  2216 |     H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
  2217 |     herr_t        ret_value = SUCCEED; /* Return value */
  2218 |
  2219 |     FUNC_ENTER_NOAPI(FAIL)
  2220 |
  2221 |     /* Sanity check */
  2222 |     assert(no_selection_io_cause);
  2223 |     head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
  2224 |     assert(head && *head);
  2225 |     assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
  2226 |
  2227 |     H5CX_RETRIEVE_PROP_VALID_SET(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_NO_SELECTION_IO_CAUSE_NAME,
  2228 |                                  no_selection_io_cause)
  2229 |
  2230 |     /* Get the value */
  2231 |     *no_selection_io_cause = (*head)->ctx.no_selection_io_cause;
  2232 |
  2233 | done:
  2234 |     FUNC_LEAVE_NOAPI(ret_value)
  2235 | } /* end H5CX_get_no_selection_io_cause() */
  2236 |
  2237 | /*-------------------------------------------------------------------------
  2238 |  * Function:    H5CX_get_actual_selection_io_mode
  2239 |  *
  2240 |  * Purpose:     Retrieves the actual I/O mode (scalar, vector, and/or selection) for the current API call
  2241 |  *context.
  2242 |  *
  2243 |  * Return:      Non-negative on success / Negative on failure
  2244 |  *
  2245 |  *-------------------------------------------------------------------------
  2246 |  */
  2247 | herr_t
  2248 | H5CX_get_actual_selection_io_mode(uint32_t *actual_selection_io_mode)
  2249 | {
  2250 |     H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
  2251 |     herr_t        ret_value = SUCCEED; /* Return value */
  2252 |
  2253 |     FUNC_ENTER_NOAPI(FAIL)
  2254 |
  2255 |     /* Sanity check */
  2256 |     assert(actual_selection_io_mode);
  2257 |     head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
  2258 |     assert(head && *head);
  2259 |     assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
  2260 |
  2261 |     /* This property is a special case - we want to wipe out any previous setting.  Copy the default setting
  2262 |      * if it has not been set yet. */
> 2263 |     if ((*head)->ctx.dxpl_id != H5P_DATASET_XFER_DEFAULT && !(*head)->ctx.actual_selection_io_mode_set &&
  2264 |         !(*head)->ctx.actual_selection_io_mode_valid) {
  2265 |         (*head)->ctx.actual_selection_io_mode     = H5CX_def_dxpl_cache.actual_selection_io_mode;
  2266 |         (*head)->ctx.actual_selection_io_mode_set = true;
  2267 |     }
  2268 |     H5CX_RETRIEVE_PROP_VALID_SET(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_ACTUAL_SELECTION_IO_MODE_NAME,
  2269 |                                  actual_selection_io_mode)
  2270 |
  2271 |     /* Get the value */
  2272 |     *actual_selection_io_mode = (*head)->ctx.actual_selection_io_mode;
  2273 |
  2274 | done:
  2275 |     FUNC_LEAVE_NOAPI(ret_value)
  2276 | } /* end H5CX_get_actual_selection_io_mode() */
  2277 |
  2278 | /*-------------------------------------------------------------------------
  2279 |  * Function:    H5CX_get_modify_write_buf
  2280 |  *
  2281 |  * Purpose:     Retrieves the modify write buffer property for the current API call context.
  2282 |  *
  2283 |  * Return:      Non-negative on success / Negative on failure
  2284 |  *
  2285 |  *-------------------------------------------------------------------------
  2286 |  */
  2287 | herr_t
  2288 | H5CX_get_modify_write_buf(bool *modify_write_buf)
  2289 | {
  2290 |     H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
  2291 |     herr_t        ret_value = SUCCEED; /* Return value */
  2292 |
  2293 |     FUNC_ENTER_NOAPI(FAIL)
  2294 |
  2295 |     /* Sanity check */
  2296 |     assert(modify_write_buf);
  2297 |     head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
  2298 |     assert(head && *head);
  2299 |     assert(H5P_DEFAULT != (*head)->ctx.dxpl_id);
  2300 |
  2301 |     H5CX_RETRIEVE_PROP_VALID(dxpl, H5P_DATASET_XFER_DEFAULT, H5D_XFER_MODIFY_WRITE_BUF_NAME, modify_write_buf)
  2302 |
  2303 |     /* Get the value */
  2304 |     *modify_write_buf = (*head)->ctx.modify_write_buf;
  2305 |
  2306 | done:
  2307 |     FUNC_LEAVE_NOAPI(ret_value)
  2308 | } /* end H5CX_get_selection_io_mode() */
  2309 |
  2310 | /*-------------------------------------------------------------------------
  2311 |  * Function:    H5CX_get_encoding
  2312 |  *
  2313 |  * Purpose:     Retrieves the character encoding for the current API call context.
  2314 |  *
  2315 |  * Return:      Non-negative on success / Negative on failure
  2316 |  *
  2317 |  *-------------------------------------------------------------------------
  2318 |  */
  2319 | herr_t
  2320 | H5CX_get_encoding(H5T_cset_t *encoding)
  2321 | {
  2322 |     H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
  2323 |     herr_t        ret_value = SUCCEED; /* Return value */
  2324 |
  2325 |     FUNC_ENTER_NOAPI(FAIL)
  2326 |
  2327 |     /* Sanity check */
  2328 |     assert(encoding);
  2329 |     head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
  2330 |     assert(head && *head);
  2331 |     assert(H5P_DEFAULT != (*head)->ctx.lcpl_id);
  2332 |
  2333 |     H5CX_RETRIEVE_PROP_VALID(lcpl, H5P_LINK_CREATE_DEFAULT, H5P_STRCRT_CHAR_ENCODING_NAME, encoding)
  2334 |
  2335 |     /* Get the value */
  2336 |     *encoding = (*head)->ctx.encoding;
  2337 |
  2338 | done:
  2339 |     FUNC_LEAVE_NOAPI(ret_value)
  2340 | } /* end H5CX_get_encoding() */
  2341 |
  2342 | /*-------------------------------------------------------------------------
  2343 |  * Function:    H5CX_get_intermediate_group
  2344 |  *
  2345 |  * Purpose:     Retrieves the create intermediate group flag for the current API call context.
  2346 |  *
  2347 |  * Return:      Non-negative on success / Negative on failure
  2348 |  *
  2349 |  *-------------------------------------------------------------------------
  2350 |  */
  2351 | herr_t
  2352 | H5CX_get_intermediate_group(unsigned *crt_intermed_group)
  2353 | {
  2354 |     H5CX_node_t **head      = NULL;    /* Pointer to head of API context list */
  2355 |     herr_t        ret_value = SUCCEED; /* Return value */
  2356 |
  2357 |     FUNC_ENTER_NOAPI(FAIL)
  2358 |
  2359 |     /* Sanity check */
  2360 |     assert(crt_intermed_group);
  2361 |     head = H5CX_get_my_context(); /* Get the pointer to the head of the API context, for this thread */
  2362 |     assert(head && *head);
  2363 |     assert(H5P_DEFAULT != (*head)->ctx.lcpl_id);

Reach line at /src/hdf5/src/H5CX.c:2263 (observed count 10).