Freeciv21
Develop your civilization from humble roots to a global empire
capability.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 #include "capability.h"
15 
16 #include "log.h"
17 
18 #include <QChar>
19 
20 #include <cstring>
21 
22 #define GET_TOKEN(start, end) \
23  { \
24  /* skip leading whitespace */ \
25  while (QChar::isSpace(*start)) { \
26  start++; \
27  } \
28  /* skip to end of token */ \
29  for (end = start; *end != '\0' && !QChar::isSpace(*end) && *end != ','; \
30  end++) { \
31  /* nothing */ \
32  } \
33  }
34 
40 static bool fc_has_capability(const char *cap, const char *capstr,
41  const size_t cap_len)
42 {
43  const char *next;
44 
45  fc_assert_ret_val(capstr != nullptr, false);
46 
47  for (;;) {
48  GET_TOKEN(capstr, next);
49 
50  if (*capstr == '+') {
51  capstr++;
52  }
53 
54  fc_assert(next >= capstr);
55 
56  if ((static_cast<size_t>(next - capstr) == cap_len)
57  && strncmp(cap, capstr, cap_len) == 0) {
58  return true;
59  }
60  if (*next == '\0') {
61  return false;
62  }
63 
64  capstr = next + 1;
65  }
66 }
67 
71 bool has_capability(const char *cap, const char *capstr)
72 {
73  return fc_has_capability(cap, capstr, qstrlen(cap));
74 }
75 
80 bool has_capabilities(const char *us, const char *them)
81 {
82  const char *next;
83 
84  for (;;) {
85  GET_TOKEN(us, next);
86 
87  if (*us == '+' && !fc_has_capability(us + 1, them, next - (us + 1))) {
88  return false;
89  }
90  if (*next == '\0') {
91  return true;
92  }
93 
94  us = next + 1;
95  }
96 }
static bool fc_has_capability(const char *cap, const char *capstr, const size_t cap_len)
This routine returns true if the capability in cap appears in the capability list in capstr.
Definition: capability.cpp:40
bool has_capability(const char *cap, const char *capstr)
Wrapper for fc_has_capability() for nullptr terminated strings.
Definition: capability.cpp:71
#define GET_TOKEN(start, end)
Definition: capability.cpp:22
bool has_capabilities(const char *us, const char *them)
This routine returns true if all the mandatory capabilities in us appear in them.
Definition: capability.cpp:80
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_val(condition, val)
Definition: log.h:114