LCOV - code coverage report
Current view: top level - common - scores.c (source / functions) Hit Total Coverage
Test: Pacemaker code coverage Lines: 37 37 100.0 %
Date: 2024-05-07 11:09:47 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2004-2024 the Pacemaker project contributors
       3             :  *
       4             :  * The version control history for this file may have further details.
       5             :  *
       6             :  * This source code is licensed under the GNU Lesser General Public License
       7             :  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
       8             :  */
       9             : 
      10             : #include <crm_internal.h>
      11             : 
      12             : #ifndef _GNU_SOURCE
      13             : #  define _GNU_SOURCE
      14             : #endif
      15             : 
      16             : #include <stdio.h>      // snprintf(), NULL
      17             : #include <string.h>     // strcpy(), strdup()
      18             : #include <sys/types.h>  // size_t
      19             : 
      20             : int pcmk__score_red = 0;
      21             : int pcmk__score_green = 0;
      22             : int pcmk__score_yellow = 0;
      23             : 
      24             : /*!
      25             :  * \brief Get the integer value of a score string
      26             :  *
      27             :  * Given a string representation of a score, return the integer equivalent.
      28             :  * This accepts infinity strings as well as red, yellow, and green, and
      29             :  * bounds the result to +/-INFINITY.
      30             :  *
      31             :  * \param[in] score  Score as string
      32             :  *
      33             :  * \return Integer value corresponding to \p score
      34             :  */
      35             : int
      36         319 : char2score(const char *score)
      37             : {
      38         319 :     if (score == NULL) {
      39         231 :         return 0;
      40             : 
      41          88 :     } else if (pcmk_str_is_minus_infinity(score)) {
      42           7 :         return -PCMK_SCORE_INFINITY;
      43             : 
      44          81 :     } else if (pcmk_str_is_infinity(score)) {
      45           2 :         return PCMK_SCORE_INFINITY;
      46             : 
      47          79 :     } else if (pcmk__str_eq(score, PCMK_VALUE_RED, pcmk__str_casei)) {
      48           2 :         return pcmk__score_red;
      49             : 
      50          77 :     } else if (pcmk__str_eq(score, PCMK_VALUE_YELLOW, pcmk__str_casei)) {
      51           2 :         return pcmk__score_yellow;
      52             : 
      53          75 :     } else if (pcmk__str_eq(score, PCMK_VALUE_GREEN, pcmk__str_casei)) {
      54           2 :         return pcmk__score_green;
      55             : 
      56             :     } else {
      57             :         long long score_ll;
      58             : 
      59          73 :         pcmk__scan_ll(score, &score_ll, 0LL);
      60          73 :         if (score_ll > PCMK_SCORE_INFINITY) {
      61           2 :             return PCMK_SCORE_INFINITY;
      62             : 
      63          71 :         } else if (score_ll < -PCMK_SCORE_INFINITY) {
      64           1 :             return -PCMK_SCORE_INFINITY;
      65             : 
      66             :         } else {
      67          70 :             return (int) score_ll;
      68             :         }
      69             :     }
      70             : }
      71             : 
      72             : /*!
      73             :  * \brief Return a displayable static string for a score value
      74             :  *
      75             :  * Given a score value, return a pointer to a static string representation of
      76             :  * the score suitable for log messages, output, etc.
      77             :  *
      78             :  * \param[in] score  Score to display
      79             :  *
      80             :  * \return Pointer to static memory containing string representation of \p score
      81             :  * \note Subsequent calls to this function will overwrite the returned value, so
      82             :  *       it should be used only in a local context such as a printf()-style
      83             :  *       statement.
      84             :  */
      85             : const char *
      86           5 : pcmk_readable_score(int score)
      87             : {
      88             :     // The longest possible result is "-INFINITY"
      89             :     static char score_s[sizeof(PCMK_VALUE_MINUS_INFINITY)];
      90             : 
      91           5 :     if (score >= PCMK_SCORE_INFINITY) {
      92           1 :         strcpy(score_s, PCMK_VALUE_INFINITY);
      93             : 
      94           4 :     } else if (score <= -PCMK_SCORE_INFINITY) {
      95           1 :         strcpy(score_s, PCMK_VALUE_MINUS_INFINITY);
      96             : 
      97             :     } else {
      98             :         // Range is limited to +/-1000000, so no chance of overflow
      99           3 :         snprintf(score_s, sizeof(score_s), "%d", score);
     100             :     }
     101             : 
     102           5 :     return score_s;
     103             : }
     104             : 
     105             : /*!
     106             :  * \internal
     107             :  * \brief Add two scores, bounding to +/-INFINITY
     108             :  *
     109             :  * \param[in] score1  First score to add
     110             :  * \param[in] score2  Second score to add
     111             :  *
     112             :  * \note This function does not have context about what the scores mean, so it
     113             :  *       does not log any messages.
     114             :  */
     115             : int
     116         588 : pcmk__add_scores(int score1, int score2)
     117             : {
     118             :     /* As long as PCMK_SCORE_INFINITY is less than half of the maximum integer,
     119             :      * we can ignore the possibility of integer overflow.
     120             :      */
     121         588 :     int result = score1 + score2;
     122             : 
     123             :     // First handle the cases where one or both is infinite
     124         588 :     if ((score1 <= -PCMK_SCORE_INFINITY) || (score2 <= -PCMK_SCORE_INFINITY)) {
     125          79 :         return -PCMK_SCORE_INFINITY;
     126             :     }
     127         509 :     if ((score1 >= PCMK_SCORE_INFINITY) || (score2 >= PCMK_SCORE_INFINITY)) {
     128          10 :         return PCMK_SCORE_INFINITY;
     129             :     }
     130             : 
     131             :     // Bound result to infinity.
     132         499 :     if (result >= PCMK_SCORE_INFINITY) {
     133           1 :         return PCMK_SCORE_INFINITY;
     134             :     }
     135         498 :     if (result <= -PCMK_SCORE_INFINITY) {
     136           1 :         return -PCMK_SCORE_INFINITY;
     137             :     }
     138             : 
     139         497 :     return result;
     140             : }
     141             : 
     142             : // Deprecated functions kept only for backward API compatibility
     143             : // LCOV_EXCL_START
     144             : 
     145             : #include <crm/common/scores_compat.h>
     146             : 
     147             : char *
     148             : score2char(int score)
     149             : {
     150             :     return pcmk__str_copy(pcmk_readable_score(score));
     151             : }
     152             : 
     153             : char *
     154             : score2char_stack(int score, char *buf, size_t len)
     155             : {
     156             :     CRM_CHECK((buf != NULL) && (len >= sizeof(PCMK_VALUE_MINUS_INFINITY)),
     157             :               return NULL);
     158             :     strcpy(buf, pcmk_readable_score(score));
     159             :     return buf;
     160             : }
     161             : 
     162             : // LCOV_EXCL_STOP
     163             : // End deprecated API

Generated by: LCOV version 1.14