AUnit  1.2
Unit testing framework for Arduino platforms inspired by ArduinoUnit and Google Test.
Compare.cpp
1 /*
2 MIT License
3 
4 Copyright (c) 2018 Brian T. Park
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23 */
24 
25 /*
26 Design Notes:
27 ============
28 
29 Template Specialization:
30 -----------------------
31 One way to implement the compareEqual() for these types is to use template
32 specialization. The problem with Template specialization is that templates
33 use strict type matching, and does not perform the normal implicit type
34 conversion, including const-casting. Therefore, all of the various c-style
35 string types, for example:
36 
37  - char*
38  - const char*
39  - char[1]
40  - char[N]
41  - const char[1]
42  - const char[N]
43 
44 are considered to be different types under the C++ templating system. This
45 causes a combinatorial explosion of template specialization which produces
46 code that is difficult to understand, test and maintain.
47 An example can be seen in the Compare.h file of the ArduinoUnit project:
48 https://github.com/mmurdoch/arduinounit/blob/master/src/ArduinoUnitUtility/Compare.h
49 
50 Function Overloading:
51 ---------------------
52 In this project, I used function overloading instead of template
53 specialization. Function overloading handles c-style strings (i.e. character
54 arrays) naturally, in the way most users expect. For example, (char*) is
55 automarically cast to (const char*), and (char[N]) is autonmatically
56 cast to (const char*).
57 
58 For the primitive value types (e.g. (char), (int), (unsigned char), etc.) I
59 attempted to use a generic templatized version, using sonmething like:
60 
61  template<typename T>
62  compareEqual(const T& a, const T& b) { ... }
63 
64 However, this template introduced this method:
65 
66  compareEqual(char* const& a, char* const& b);
67 
68 that seemed to take precedence over the explicitly defined overload:
69 
70  compareEqual(const char* a, const char*b);
71 
72 When the compareEqual() method is called with a (char*) or a (char[N]),
73 like this:
74 
75  char a[3] = {...};
76  char b[4] = {...};
77  compareEqual(a, b);
78 
79 this calls compareEqual(char* const&, const* const&), which is the wrong
80 version for a c-style string. The only way I could get this to work was to
81 avoid templates completely and manually define all the function overloads
82 even for primitive integer types.
83 
84 Implicit Conversions:
85 ---------------------
86 For basic primitive types, I depend on some casts to avoid having to define
87 some functions. I assume that signed and unsigned integers smaller or equal
88 to (int) will be converted to an (int) to match compareEqual(int, int).
89 
90 I provided an explicit compareEqual(char, char) overload because in C++, a
91 (char) type is distinct from (signed char) and (unsigned char).
92 
93 Technically, there should be a (long long) version and an (unsigned long
94 long) version of compareEqual(). However, it turns out that the Arduino
95 Print::print() method does not have an overload for these types, so it would
96 not do us much good to provide an assertEqual() or compareEqual() for the
97 (long long) and (unsigned long long) types.
98 
99 Custom Assert and Compare Functions:
100 ------------------------------------
101 Another advantage of using function overloading instead of template
102 specialization is that the user is able to add additional function overloads
103 into the 'aunit' namespace. This should allow the user to define the various
104 comporeXxx() and assertXxx() functions for a custom class. I have not
105 tested this though.
106 
107 Comparing Flash Strings:
108 ------------------------
109 Flash memory must be read using 4-byte alignment on the ESP8266. AVR doesn't
110 care. Teensy-ARM fakes the flash memory API but really just uses the normal
111 static RAM. The following code for comparing two (__FlashStringHelper*)
112 against each other will work for all 3 environments.
113 
114 Inlining:
115 --------
116 Even though most of these functions are one-liners, there is no advantage to
117 inlining them because they are almost always used through a function pointer.
118 */
119 
120 #include <stdint.h>
121 #include <string.h>
122 #include <math.h> // fabs()
123 #include <WString.h>
124 #include "Flash.h"
125 #include "Compare.h"
126 
127 namespace aunit {
128 namespace internal {
129 
130 //---------------------------------------------------------------------------
131 // compareString()
132 //---------------------------------------------------------------------------
133 
134 int compareString(const char* a, const char* b) {
135  if (a == b) { return 0; }
136  if (a == nullptr) { return -1; }
137  if (b == nullptr) { return 1; }
138  return strcmp(a, b);
139 }
140 
141 int compareString(const char* a, const String& b) {
142  if (a == nullptr) { return -1; }
143  return strcmp(a, b.c_str());
144 }
145 
146 int compareString(const char* a, const __FlashStringHelper* b) {
147  if (a == (const char*) b) { return 0; }
148  if (a == nullptr) { return -1; }
149  if (b == nullptr) { return 1; }
150  return strcmp_P(a, (const char*) b);
151 }
152 
153 int compareString(const String& a, const char* b) {
154  return -compareString(b, a);
155 }
156 
157 int compareString(const String& a, const String& b) {
158  return strcmp(a.c_str(), b.c_str());
159 }
160 
161 int compareString(const String& a, const __FlashStringHelper* b) {
162  if (b == nullptr) { return 1; }
163  return strcmp_P(a.c_str(), (const char*) b);
164 }
165 
166 int compareString(const __FlashStringHelper* a, const char* b) {
167  return -compareString(b, a);
168 }
169 
170 int compareString(const __FlashStringHelper* a, const String& b) {
171  return -compareString(b, a);
172 }
173 
174 // On ESP8266, pgm_read_byte() already takes care of 4-byte alignment, and
175 // memcpy_P(s, p, 4) makes 4 calls to pgm_read_byte() anyway, so don't bother
176 // optimizing for 4-byte alignment here.
177 int compareString(const __FlashStringHelper* a, const __FlashStringHelper* b) {
178  if (a == b) { return 0; }
179  if (a == nullptr) { return -1; }
180  if (b == nullptr) { return 1; }
181  const char* aa = reinterpret_cast<const char*>(a);
182  const char* bb = reinterpret_cast<const char*>(b);
183 
184  while (true) {
185  uint8_t ca = pgm_read_byte(aa);
186  uint8_t cb = pgm_read_byte(bb);
187  if (ca != cb) return (int) ca - (int) cb;
188  if (ca == '\0') return 0;
189  aa++;
190  bb++;
191  }
192 }
193 
194 //---------------------------------------------------------------------------
195 // compareStringCase()
196 //---------------------------------------------------------------------------
197 
198 int compareStringCase(const char* a, const char* b) {
199  if (a == b) { return 0; }
200  if (a == nullptr) { return -1; }
201  if (b == nullptr) { return 1; }
202  return strcasecmp(a, b);
203 }
204 
205 int compareStringCase(const char* a, const String& b) {
206  if (a == nullptr) { return -1; }
207  return strcasecmp(a, b.c_str());
208 }
209 
210 int compareStringCase(const char* a, const __FlashStringHelper* b) {
211  if (a == (const char*) b) { return 0; }
212  if (a == nullptr) { return -1; }
213  if (b == nullptr) { return 1; }
214  return strcasecmp_P(a, (const char*) b);
215 }
216 
217 int compareStringCase(const String& a, const char* b) {
218  return -compareStringCase(b, a);
219 }
220 
221 int compareStringCase(const String& a, const String& b) {
222  return strcasecmp(a.c_str(), b.c_str());
223 }
224 
225 int compareStringCase(const String& a, const __FlashStringHelper* b) {
226  if (b == nullptr) { return 1; }
227  return strcasecmp_P(a.c_str(), (const char*) b);
228 }
229 
230 int compareStringCase(const __FlashStringHelper* a, const char* b) {
231  return -compareStringCase(b, a);
232 }
233 
234 int compareStringCase(const __FlashStringHelper* a, const String& b) {
235  return -compareStringCase(b, a);
236 }
237 
238 // On ESP8266, pgm_read_byte() already takes care of 4-byte alignment, and
239 // memcpy_P(s, p, 4) makes 4 calls to pgm_read_byte() anyway, so don't bother
240 // optimizing for 4-byte alignment here.
241 int compareStringCase(const __FlashStringHelper* a,
242  const __FlashStringHelper* b) {
243  if (a == b) { return 0; }
244  if (a == nullptr) { return -1; }
245  if (b == nullptr) { return 1; }
246  const char* aa = reinterpret_cast<const char*>(a);
247  const char* bb = reinterpret_cast<const char*>(b);
248 
249  while (true) {
250  uint8_t ca = pgm_read_byte(aa);
251  uint8_t cb = pgm_read_byte(bb);
252  uint8_t la = tolower(ca);
253  uint8_t lb = tolower(cb);
254  if (la != lb) return (int) la - (int) lb;
255  if (ca == '\0') return 0;
256  aa++;
257  bb++;
258  }
259 }
260 
261 //---------------------------------------------------------------------------
262 // compareStringN
263 //---------------------------------------------------------------------------
264 
265 // We need compareStringN() to support only (const char*) and (const
266 // __FlashStringHelper*). And it turns out that compareStringN(a, b, N) ==
267 // -compareString(b, a, N).
268 
269 int compareStringN(const char* a, const char* b, size_t n) {
270  if (a == b) { return 0; }
271  if (a == nullptr) { return -1; }
272  if (b == nullptr) { return 1; }
273  return strncmp(a, b, n);
274 }
275 
276 int compareStringN(const char* a, const __FlashStringHelper* b, size_t n) {
277  if (a == (const char*) b) { return 0; }
278  if (a == nullptr) { return -1; }
279  if (b == nullptr) { return 1; }
280  return strncmp_P(a, (const char*) b, n);
281 }
282 
283 int compareStringN(const __FlashStringHelper* a, const char* b, size_t n) {
284  return -compareStringN(b, a, n);
285 }
286 
287 // On ESP8266, pgm_read_byte() already takes care of 4-byte alignment, and
288 // memcpy_P(s, p, 4) makes 4 calls to pgm_read_byte() anyway, so don't bother
289 // optimizing for 4-byte alignment here.
290 int compareStringN(const __FlashStringHelper* a, const __FlashStringHelper* b,
291  size_t n) {
292  if (a == b) { return 0; }
293  if (a == nullptr) { return -1; }
294  if (b == nullptr) { return 1; }
295  const char* aa = reinterpret_cast<const char*>(a);
296  const char* bb = reinterpret_cast<const char*>(b);
297 
298  while (n > 0) {
299  uint8_t ca = pgm_read_byte(aa);
300  uint8_t cb = pgm_read_byte(bb);
301  if (ca != cb) return (int) ca - (int) cb;
302  if (ca == '\0') return 0;
303  aa++;
304  bb++;
305  n--;
306  }
307  return 0;
308 }
309 
310 //---------------------------------------------------------------------------
311 // compareEqual()
312 //---------------------------------------------------------------------------
313 
314 bool compareEqual(bool a, bool b) {
315  return (a == b);
316 }
317 
318 bool compareEqual(char a, char b) {
319  return (a == b);
320 }
321 
322 bool compareEqual(int a, int b) {
323  return (a == b);
324 }
325 
326 bool compareEqual(unsigned int a, unsigned int b) {
327  return (a == b);
328 }
329 
330 bool compareEqual(long a, long b) {
331  return (a == b);
332 }
333 
334 bool compareEqual(unsigned long a, unsigned long b) {
335  return (a == b);
336 }
337 
338 bool compareEqual(double a, double b) {
339  return (a == b);
340 }
341 
342 bool compareEqual(const char* a, const char* b) {
343  return compareString(a, b) == 0;
344 }
345 
346 bool compareEqual(const char* a, const String& b) {
347  return compareString(a, b) == 0;
348 }
349 
350 bool compareEqual(const char* a, const __FlashStringHelper* b) {
351  return compareString(a, b) == 0;
352 }
353 
354 bool compareEqual(const __FlashStringHelper* a, const char* b) {
355  return compareString(a, b) == 0;
356 }
357 
358 bool compareEqual(const __FlashStringHelper* a, const __FlashStringHelper* b) {
359  return compareString(a, b) == 0;
360 }
361 
362 bool compareEqual(const __FlashStringHelper* a, const String& b) {
363  return compareString(a, b) == 0;
364 }
365 
366 bool compareEqual(const String& a, const char* b) {
367  return compareString(a, b) == 0;
368 }
369 
370 bool compareEqual(const String& a, const String& b) {
371  return compareString(a, b) == 0;
372 }
373 
374 bool compareEqual(const String& a, const __FlashStringHelper* b) {
375  return compareString(a, b) == 0;
376 }
377 
378 //---------------------------------------------------------------------------
379 // compareLess()
380 //---------------------------------------------------------------------------
381 
382 bool compareLess(bool a, bool b) {
383  return (a < b);
384 }
385 
386 bool compareLess(char a, char b) {
387  return (a < b);
388 }
389 
390 bool compareLess(int a, int b) {
391  return (a < b);
392 }
393 
394 bool compareLess(unsigned int a, unsigned int b) {
395  return (a < b);
396 }
397 
398 bool compareLess(long a, long b) {
399  return (a < b);
400 }
401 
402 bool compareLess(unsigned long a, unsigned long b) {
403  return (a < b);
404 }
405 
406 bool compareLess(double a, double b) {
407  return (a < b);
408 }
409 
410 bool compareLess(const char* a, const char* b) {
411  return compareString(a, b) < 0;
412 }
413 
414 bool compareLess(const char* a, const String& b) {
415  return compareString(a, b) < 0;
416 }
417 
418 bool compareLess(const char* a, const __FlashStringHelper* b) {
419  return compareString(a, b) < 0;
420 }
421 
422 bool compareLess(const __FlashStringHelper* a, const char* b) {
423  return compareString(a, b) < 0;
424 }
425 
426 bool compareLess(
427  const __FlashStringHelper* a, const __FlashStringHelper* b) {
428  return compareString(a, b) < 0;
429 }
430 
431 bool compareLess(const __FlashStringHelper* a, const String& b) {
432  return compareString(a, b) < 0;
433 }
434 
435 bool compareLess(const String& a, const char* b) {
436  return compareString(a, b) < 0;
437 }
438 
439 bool compareLess(const String& a, const String& b) {
440  return compareString(a, b) < 0;
441 }
442 
443 bool compareLess(const String& a, const __FlashStringHelper* b) {
444  return compareString(a, b) < 0;
445 }
446 
447 //---------------------------------------------------------------------------
448 // compareMore()
449 //---------------------------------------------------------------------------
450 
451 bool compareMore(bool a, bool b) {
452  return (a > b);
453 }
454 
455 bool compareMore(char a, char b) {
456  return (a > b);
457 }
458 
459 bool compareMore(int a, int b) {
460  return (a > b);
461 }
462 
463 bool compareMore(unsigned int a, unsigned int b) {
464  return (a > b);
465 }
466 
467 bool compareMore(long a, long b) {
468  return (a > b);
469 }
470 
471 bool compareMore(unsigned long a, unsigned long b) {
472  return (a > b);
473 }
474 
475 bool compareMore(double a, double b) {
476  return (a > b);
477 }
478 
479 bool compareMore(const char* a, const char* b) {
480  return compareString(a, b) > 0;
481 }
482 
483 bool compareMore(const char* a, const String& b) {
484  return compareString(a, b) > 0;
485 }
486 
487 bool compareMore(const char* a, const __FlashStringHelper* b) {
488  return compareString(a, b) > 0;
489 }
490 
491 bool compareMore(const __FlashStringHelper* a, const char* b) {
492  return compareString(a, b) > 0;
493 }
494 
495 bool compareMore(const __FlashStringHelper* a, const __FlashStringHelper* b) {
496  return compareString(a, b) > 0;
497 }
498 
499 bool compareMore(const __FlashStringHelper* a, const String& b) {
500  return compareString(a, b) > 0;
501 }
502 
503 bool compareMore(const String& a, const char* b) {
504  return compareString(a, b) > 0;
505 }
506 
507 bool compareMore(const String& a, const String& b) {
508  return compareString(a, b) > 0;
509 }
510 
511 bool compareMore(const String& a, const __FlashStringHelper* b) {
512  return compareString(a, b) > 0;
513 }
514 
515 //---------------------------------------------------------------------------
516 // compareLessOrEqual
517 //---------------------------------------------------------------------------
518 
519 bool compareLessOrEqual(bool a, bool b) {
520  return (a <= b);
521 }
522 
523 bool compareLessOrEqual(char a, char b) {
524  return (a <= b);
525 }
526 
527 bool compareLessOrEqual(int a, int b) {
528  return (a <= b);
529 }
530 
531 bool compareLessOrEqual(unsigned int a, unsigned int b) {
532  return (a <= b);
533 }
534 
535 bool compareLessOrEqual(long a, long b) {
536  return (a <= b);
537 }
538 
539 bool compareLessOrEqual(unsigned long a, unsigned long b) {
540  return (a <= b);
541 }
542 
543 bool compareLessOrEqual(double a, double b) {
544  return (a <= b);
545 }
546 
547 bool compareLessOrEqual(const char* a, const char* b) {
548  return compareString(a, b) <= 0;
549 }
550 
551 bool compareLessOrEqual(const char* a, const String& b) {
552  return compareString(a, b) <= 0;
553 }
554 
555 bool compareLessOrEqual(const char* a, const __FlashStringHelper* b) {
556  return compareString(a, b) <= 0;
557 }
558 
559 bool compareLessOrEqual(const __FlashStringHelper* a, const char* b) {
560  return compareString(a, b) <= 0;
561 }
562 
563 bool compareLessOrEqual(
564  const __FlashStringHelper* a, const __FlashStringHelper* b) {
565  return compareString(a, b) <= 0;
566 }
567 
568 bool compareLessOrEqual(const __FlashStringHelper* a, const String& b) {
569  return compareString(a, b) <= 0;
570 }
571 
572 bool compareLessOrEqual(const String& a, const char* b) {
573  return compareString(a, b) <= 0;
574 }
575 
576 bool compareLessOrEqual(const String& a, const String& b) {
577  return compareString(a, b) <= 0;
578 }
579 
580 bool compareLessOrEqual(const String& a, const __FlashStringHelper* b) {
581  return compareString(a, b) <= 0;
582 }
583 
584 //---------------------------------------------------------------------------
585 // compareMoreOrEqual
586 //---------------------------------------------------------------------------
587 
588 bool compareMoreOrEqual(bool a, bool b) {
589  return (a >= b);
590 }
591 
592 bool compareMoreOrEqual(char a, char b) {
593  return (a >= b);
594 }
595 
596 bool compareMoreOrEqual(int a, int b) {
597  return (a >= b);
598 }
599 
600 bool compareMoreOrEqual(unsigned int a, unsigned int b) {
601  return (a >= b);
602 }
603 
604 bool compareMoreOrEqual(long a, long b) {
605  return (a >= b);
606 }
607 
608 bool compareMoreOrEqual(unsigned long a, unsigned long b) {
609  return (a >= b);
610 }
611 
612 bool compareMoreOrEqual(double a, double b) {
613  return (a >= b);
614 }
615 
616 bool compareMoreOrEqual(const char* a, const char* b) {
617  return compareString(a, b) >= 0;
618 }
619 
620 bool compareMoreOrEqual(const char* a, const String& b) {
621  return compareString(a, b) >= 0;
622 }
623 
624 bool compareMoreOrEqual(const char* a, const __FlashStringHelper* b) {
625  return compareString(a, b) >= 0;
626 }
627 
628 bool compareMoreOrEqual(const __FlashStringHelper* a, const char* b) {
629  return compareString(a, b) >= 0;
630 }
631 
632 bool compareMoreOrEqual(
633  const __FlashStringHelper* a, const __FlashStringHelper* b) {
634  return compareString(a, b) >= 0;
635 }
636 
637 bool compareMoreOrEqual(const __FlashStringHelper* a, const String& b) {
638  return compareString(a, b) >= 0;
639 }
640 
641 bool compareMoreOrEqual(const String& a, const char* b) {
642  return compareString(a, b) >= 0;
643 }
644 
645 bool compareMoreOrEqual(const String& a, const String& b) {
646  return compareString(a, b) >= 0;
647 }
648 
649 bool compareMoreOrEqual(const String& a, const __FlashStringHelper* b) {
650  return compareString(a, b) >= 0;
651 }
652 
653 //---------------------------------------------------------------------------
654 // compareNotEqual
655 //---------------------------------------------------------------------------
656 
657 bool compareNotEqual(bool a, bool b) {
658  return (a != b);
659 }
660 
661 bool compareNotEqual(char a, char b) {
662  return (a != b);
663 }
664 
665 bool compareNotEqual(int a, int b) {
666  return (a != b);
667 }
668 
669 bool compareNotEqual(unsigned int a, unsigned int b) {
670  return (a != b);
671 }
672 
673 bool compareNotEqual(long a, long b) {
674  return (a != b);
675 }
676 
677 bool compareNotEqual(unsigned long a, unsigned long b) {
678  return (a != b);
679 }
680 
681 bool compareNotEqual(double a, double b) {
682  return (a != b);
683 }
684 
685 bool compareNotEqual(const char* a, const char* b) {
686  return compareString(a, b) != 0;
687 }
688 
689 bool compareNotEqual(const char* a, const String& b) {
690  return compareString(a, b) != 0;
691 }
692 
693 bool compareNotEqual(const char* a, const __FlashStringHelper* b) {
694  return compareString(a, b) != 0;
695 }
696 
697 bool compareNotEqual(const __FlashStringHelper* a, const char* b) {
698  return compareString(a, b) != 0;
699 }
700 
701 bool compareNotEqual(
702  const __FlashStringHelper* a, const __FlashStringHelper* b) {
703  return compareString(a, b) != 0;
704 }
705 
706 bool compareNotEqual(const __FlashStringHelper* a, const String& b) {
707  return compareString(a, b) != 0;
708 }
709 
710 bool compareNotEqual(const String& a, const char* b) {
711  return compareString(a, b) != 0;
712 }
713 
714 bool compareNotEqual(const String& a, const String& b) {
715  return compareString(a, b) != 0;
716 }
717 
718 bool compareNotEqual(const String& a, const __FlashStringHelper* b) {
719  return compareString(a, b) != 0;
720 }
721 
722 //---------------------------------------------------------------------------
723 // compareStringCaseEqual()
724 //---------------------------------------------------------------------------
725 
726 bool compareStringCaseEqual(const char* a, const char* b) {
727  return compareStringCase(a, b) == 0;
728 }
729 
730 bool compareStringCaseEqual(const char* a, const String& b) {
731  return compareStringCase(a, b) == 0;
732 }
733 
734 bool compareStringCaseEqual(const char* a, const __FlashStringHelper* b) {
735  return compareStringCase(a, b) == 0;
736 }
737 
738 bool compareStringCaseEqual(const __FlashStringHelper* a, const char* b) {
739  return compareStringCase(a, b) == 0;
740 }
741 
742 bool compareStringCaseEqual(const __FlashStringHelper* a,
743  const __FlashStringHelper* b) {
744  return compareStringCase(a, b) == 0;
745 }
746 
747 bool compareStringCaseEqual(const __FlashStringHelper* a, const String& b) {
748  return compareStringCase(a, b) == 0;
749 }
750 
751 bool compareStringCaseEqual(const String& a, const char* b) {
752  return compareStringCase(a, b) == 0;
753 }
754 
755 bool compareStringCaseEqual(const String& a, const String& b) {
756  return compareStringCase(a, b) == 0;
757 }
758 
759 bool compareStringCaseEqual(const String& a, const __FlashStringHelper* b) {
760  return compareStringCase(a, b) == 0;
761 }
762 
763 //---------------------------------------------------------------------------
764 // compareStringCaseNotEqual()
765 //---------------------------------------------------------------------------
766 
767 bool compareStringCaseNotEqual(const char* a, const char* b) {
768  return compareStringCase(a, b) != 0;
769 }
770 
771 bool compareStringCaseNotEqual(const char* a, const String& b) {
772  return compareStringCase(a, b) != 0;
773 }
774 
775 bool compareStringCaseNotEqual(const char* a, const __FlashStringHelper* b) {
776  return compareStringCase(a, b) != 0;
777 }
778 
779 bool compareStringCaseNotEqual(const __FlashStringHelper* a, const char* b) {
780  return compareStringCase(a, b) != 0;
781 }
782 
783 bool compareStringCaseNotEqual(const __FlashStringHelper* a,
784  const __FlashStringHelper* b) {
785  return compareStringCase(a, b) != 0;
786 }
787 
788 bool compareStringCaseNotEqual(const __FlashStringHelper* a, const String& b) {
789  return compareStringCase(a, b) != 0;
790 }
791 
792 bool compareStringCaseNotEqual(const String& a, const char* b) {
793  return compareStringCase(a, b) != 0;
794 }
795 
796 bool compareStringCaseNotEqual(const String& a, const String& b) {
797  return compareStringCase(a, b) != 0;
798 }
799 
800 bool compareStringCaseNotEqual(const String& a, const __FlashStringHelper* b) {
801  return compareStringCase(a, b) != 0;
802 }
803 
804 //---------------------------------------------------------------------------
805 // compareNear()
806 //---------------------------------------------------------------------------
807 
808 bool compareNear(int a, int b, int error) {
809  return abs(a - b) <= error;
810 }
811 
812 bool compareNear(unsigned int a, unsigned int b, unsigned int error) {
813  return abs(a - b) <= error;
814 }
815 
816 bool compareNear(long a, long b, long error) {
817  return abs(a - b) <= error;
818 }
819 
820 bool compareNear(unsigned long a, unsigned long b, unsigned long error) {
821  return abs(a - b) <= error;
822 }
823 
824 bool compareNear(double a, double b, double error) {
825  return fabs(a - b) <= error;
826 }
827 
828 bool compareNotNear(int a, int b, int error) {
829  return !compareNear(a, b, error);
830 }
831 
832 bool compareNotNear(unsigned int a, unsigned int b, unsigned int error) {
833  return !compareNear(a, b, error);
834 }
835 
836 bool compareNotNear(long a, long b, long error) {
837  return !compareNear(a, b, error);
838 }
839 
840 bool compareNotNear(unsigned long a, unsigned long b, unsigned long error) {
841  return !compareNear(a, b, error);
842 }
843 
844 bool compareNotNear(double a, double b, double error) {
845  return !compareNear(a, b, error);
846 }
847 
848 }
849 }
This file provides overloaded compareXxx(a, b) functions which are used by the various assertXxx(a...
Various macros to smooth over the differences among the various platforms with regards to their suppo...