pacemaker  2.1.5-b7adf64e51
Scalable High-Availability cluster resource manager
scores.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2022 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 
23 
35 int
36 char2score(const char *score)
37 {
38  if (score == NULL) {
39  return 0;
40 
41  } else if (pcmk_str_is_minus_infinity(score)) {
42  return -CRM_SCORE_INFINITY;
43 
44  } else if (pcmk_str_is_infinity(score)) {
45  return CRM_SCORE_INFINITY;
46 
47  } else if (pcmk__str_eq(score, PCMK__VALUE_RED, pcmk__str_casei)) {
48  return pcmk__score_red;
49 
50  } else if (pcmk__str_eq(score, PCMK__VALUE_YELLOW, pcmk__str_casei)) {
51  return pcmk__score_yellow;
52 
53  } else if (pcmk__str_eq(score, PCMK__VALUE_GREEN, pcmk__str_casei)) {
54  return pcmk__score_green;
55 
56  } else {
57  long long score_ll;
58 
59  pcmk__scan_ll(score, &score_ll, 0LL);
60  if (score_ll > CRM_SCORE_INFINITY) {
61  return CRM_SCORE_INFINITY;
62 
63  } else if (score_ll < -CRM_SCORE_INFINITY) {
64  return -CRM_SCORE_INFINITY;
65 
66  } else {
67  return (int) score_ll;
68  }
69  }
70 }
71 
85 const char *
87 {
88  // The longest possible result is "-INFINITY"
89  static char score_s[sizeof(CRM_MINUS_INFINITY_S)];
90 
91  if (score >= CRM_SCORE_INFINITY) {
92  strcpy(score_s, CRM_INFINITY_S);
93 
94  } else if (score <= -CRM_SCORE_INFINITY) {
95  strcpy(score_s, CRM_MINUS_INFINITY_S);
96 
97  } else {
98  // Range is limited to +/-1000000, so no chance of overflow
99  snprintf(score_s, sizeof(score_s), "%d", score);
100  }
101 
102  return score_s;
103 }
104 
112 int
113 pcmk__add_scores(int score1, int score2)
114 {
115  int result = score1 + score2;
116 
117  // First handle the cases where one or both is infinite
118 
119  if (score1 <= -CRM_SCORE_INFINITY) {
120 
121  if (score2 <= -CRM_SCORE_INFINITY) {
122  crm_trace("-INFINITY + -INFINITY = -INFINITY");
123  } else if (score2 >= CRM_SCORE_INFINITY) {
124  crm_trace("-INFINITY + +INFINITY = -INFINITY");
125  } else {
126  crm_trace("-INFINITY + %d = -INFINITY", score2);
127  }
128 
129  return -CRM_SCORE_INFINITY;
130 
131  } else if (score2 <= -CRM_SCORE_INFINITY) {
132 
133  if (score1 >= CRM_SCORE_INFINITY) {
134  crm_trace("+INFINITY + -INFINITY = -INFINITY");
135  } else {
136  crm_trace("%d + -INFINITY = -INFINITY", score1);
137  }
138 
139  return -CRM_SCORE_INFINITY;
140 
141  } else if (score1 >= CRM_SCORE_INFINITY) {
142 
143  if (score2 >= CRM_SCORE_INFINITY) {
144  crm_trace("+INFINITY + +INFINITY = +INFINITY");
145  } else {
146  crm_trace("+INFINITY + %d = +INFINITY", score2);
147  }
148 
149  return CRM_SCORE_INFINITY;
150 
151  } else if (score2 >= CRM_SCORE_INFINITY) {
152  crm_trace("%d + +INFINITY = +INFINITY", score1);
153  return CRM_SCORE_INFINITY;
154  }
155 
156  /* As long as CRM_SCORE_INFINITY is less than half of the maximum integer,
157  * we can ignore the possibility of integer overflow
158  */
159 
160  // Bound result to infinity
161 
162  if (result >= CRM_SCORE_INFINITY) {
163  crm_trace("%d + %d = +INFINITY", score1, score2);
164  return CRM_SCORE_INFINITY;
165 
166  } else if (result <= -CRM_SCORE_INFINITY) {
167  crm_trace("%d + %d = -INFINITY", score1, score2);
168  return -CRM_SCORE_INFINITY;
169  }
170 
171  crm_trace("%d + %d = %d", score1, score2, result);
172  return result;
173 }
174 
175 // Deprecated functions kept only for backward API compatibility
176 // LCOV_EXCL_START
177 
178 #include <crm/common/util_compat.h>
179 
180 char *
181 score2char(int score)
182 {
183  char *result = strdup(pcmk_readable_score(score));
184 
185  CRM_ASSERT(result != NULL);
186  return result;
187 }
188 
189 char *
190 score2char_stack(int score, char *buf, size_t len)
191 {
192  CRM_CHECK((buf != NULL) && (len >= sizeof(CRM_MINUS_INFINITY_S)),
193  return NULL);
194  strcpy(buf, pcmk_readable_score(score));
195  return buf;
196 }
197 
198 // LCOV_EXCL_STOP
199 // End deprecated API
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:227
#define PCMK__VALUE_GREEN
int pcmk__add_scores(int score1, int score2)
Definition: scores.c:113
int pcmk__score_yellow
Definition: scores.c:22
int char2score(const char *score)
Get the integer value of a score string.
Definition: scores.c:36
#define CRM_SCORE_INFINITY
Definition: crm.h:85
#define PCMK__VALUE_RED
int pcmk__scan_ll(const char *text, long long *result, long long default_value)
Definition: strings.c:97
int pcmk__score_red
Definition: scores.c:20
#define crm_trace(fmt, args...)
Definition: logging.h:365
#define CRM_MINUS_INFINITY_S
Definition: crm.h:88
int pcmk__score_green
Definition: scores.c:21
const char * pcmk_readable_score(int score)
Return a displayable static string for a score value.
Definition: scores.c:86
char * score2char(int score)
Definition: scores.c:181
bool pcmk_str_is_infinity(const char *s)
Definition: utils.c:543
pcmk__action_result_t result
Definition: pcmk_fence.c:35
#define CRM_ASSERT(expr)
Definition: results.h:42
bool pcmk_str_is_minus_infinity(const char *s)
Definition: utils.c:548
#define CRM_INFINITY_S
Definition: crm.h:86
Deprecated Pacemaker utilities.
#define PCMK__VALUE_YELLOW
char * score2char_stack(int score, char *buf, size_t len)
Definition: scores.c:190