frontlib: Improved and unified parameter checking, moved the cmdlineClient out
of the frontlib code.
--- a/project_files/frontlib/base64/base64.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/base64/base64.c Thu Jul 05 00:33:24 2012 +0200
@@ -1,423 +1,572 @@
-/* base64.c -- Encode binary data using printable characters.
- Copyright (C) 1999, 2000, 2001, 2004, 2005, 2006 Free Software
- Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-/* Written by Simon Josefsson. Partially adapted from GNU MailUtils
- * (mailbox/filter_trans.c, as of 2004-11-28). Improved by review
- * from Paul Eggert, Bruno Haible, and Stepan Kasal.
- *
- * See also RFC 3548 <http://www.ietf.org/rfc/rfc3548.txt>.
- *
- * Be careful with error checking. Here is how you would typically
- * use these functions:
- *
- * bool ok = base64_decode_alloc (in, inlen, &out, &outlen);
- * if (!ok)
- * FAIL: input was not valid base64
- * if (out == NULL)
- * FAIL: memory allocation error
- * OK: data in OUT/OUTLEN
- *
- * size_t outlen = base64_encode_alloc (in, inlen, &out);
- * if (out == NULL && outlen == 0 && inlen != 0)
- * FAIL: input too long
- * if (out == NULL)
- * FAIL: memory allocation error
- * OK: data in OUT/OUTLEN.
- *
- */
-
-/* Get prototype. */
-#include "base64.h"
-
-/* Get malloc. */
-#include <stdlib.h>
-
-/* Get UCHAR_MAX. */
-#include <limits.h>
-
-/* C89 compliant way to cast 'char' to 'unsigned char'. */
-static inline unsigned char
-to_uchar (char ch)
-{
- return ch;
-}
-
-/* Base64 encode IN array of size INLEN into OUT array of size OUTLEN.
- If OUTLEN is less than BASE64_LENGTH(INLEN), write as many bytes as
- possible. If OUTLEN is larger than BASE64_LENGTH(INLEN), also zero
- terminate the output buffer. */
-void
-base64_encode (const char *restrict in, size_t inlen,
- char *restrict out, size_t outlen)
-{
- static const char b64str[64] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
- while (inlen && outlen)
- {
- *out++ = b64str[(to_uchar (in[0]) >> 2) & 0x3f];
- if (!--outlen)
- break;
- *out++ = b64str[((to_uchar (in[0]) << 4)
- + (--inlen ? to_uchar (in[1]) >> 4 : 0))
- & 0x3f];
- if (!--outlen)
- break;
- *out++ =
- (inlen
- ? b64str[((to_uchar (in[1]) << 2)
- + (--inlen ? to_uchar (in[2]) >> 6 : 0))
- & 0x3f]
- : '=');
- if (!--outlen)
- break;
- *out++ = inlen ? b64str[to_uchar (in[2]) & 0x3f] : '=';
- if (!--outlen)
- break;
- if (inlen)
- inlen--;
- if (inlen)
- in += 3;
- }
-
- if (outlen)
- *out = '\0';
-}
-
-/* Allocate a buffer and store zero terminated base64 encoded data
- from array IN of size INLEN, returning BASE64_LENGTH(INLEN), i.e.,
- the length of the encoded data, excluding the terminating zero. On
- return, the OUT variable will hold a pointer to newly allocated
- memory that must be deallocated by the caller. If output string
- length would overflow, 0 is returned and OUT is set to NULL. If
- memory allocation failed, OUT is set to NULL, and the return value
- indicates length of the requested memory block, i.e.,
- BASE64_LENGTH(inlen) + 1. */
-size_t
-base64_encode_alloc (const char *in, size_t inlen, char **out)
-{
- size_t outlen = 1 + BASE64_LENGTH (inlen);
-
- /* Check for overflow in outlen computation.
- *
- * If there is no overflow, outlen >= inlen.
- *
- * If the operation (inlen + 2) overflows then it yields at most +1, so
- * outlen is 0.
- *
- * If the multiplication overflows, we lose at least half of the
- * correct value, so the result is < ((inlen + 2) / 3) * 2, which is
- * less than (inlen + 2) * 0.66667, which is less than inlen as soon as
- * (inlen > 4).
- */
- if (inlen > outlen)
- {
- *out = NULL;
- return 0;
- }
-
- *out = malloc (outlen);
- if (!*out)
- return outlen;
-
- base64_encode (in, inlen, *out, outlen);
-
- return outlen - 1;
-}
-
-/* With this approach this file works independent of the charset used
- (think EBCDIC). However, it does assume that the characters in the
- Base64 alphabet (A-Za-z0-9+/) are encoded in 0..255. POSIX
- 1003.1-2001 require that char and unsigned char are 8-bit
- quantities, though, taking care of that problem. But this may be a
- potential problem on non-POSIX C99 platforms.
-
- IBM C V6 for AIX mishandles "#define B64(x) ...'x'...", so use "_"
- as the formal parameter rather than "x". */
-#define B64(_) \
- ((_) == 'A' ? 0 \
- : (_) == 'B' ? 1 \
- : (_) == 'C' ? 2 \
- : (_) == 'D' ? 3 \
- : (_) == 'E' ? 4 \
- : (_) == 'F' ? 5 \
- : (_) == 'G' ? 6 \
- : (_) == 'H' ? 7 \
- : (_) == 'I' ? 8 \
- : (_) == 'J' ? 9 \
- : (_) == 'K' ? 10 \
- : (_) == 'L' ? 11 \
- : (_) == 'M' ? 12 \
- : (_) == 'N' ? 13 \
- : (_) == 'O' ? 14 \
- : (_) == 'P' ? 15 \
- : (_) == 'Q' ? 16 \
- : (_) == 'R' ? 17 \
- : (_) == 'S' ? 18 \
- : (_) == 'T' ? 19 \
- : (_) == 'U' ? 20 \
- : (_) == 'V' ? 21 \
- : (_) == 'W' ? 22 \
- : (_) == 'X' ? 23 \
- : (_) == 'Y' ? 24 \
- : (_) == 'Z' ? 25 \
- : (_) == 'a' ? 26 \
- : (_) == 'b' ? 27 \
- : (_) == 'c' ? 28 \
- : (_) == 'd' ? 29 \
- : (_) == 'e' ? 30 \
- : (_) == 'f' ? 31 \
- : (_) == 'g' ? 32 \
- : (_) == 'h' ? 33 \
- : (_) == 'i' ? 34 \
- : (_) == 'j' ? 35 \
- : (_) == 'k' ? 36 \
- : (_) == 'l' ? 37 \
- : (_) == 'm' ? 38 \
- : (_) == 'n' ? 39 \
- : (_) == 'o' ? 40 \
- : (_) == 'p' ? 41 \
- : (_) == 'q' ? 42 \
- : (_) == 'r' ? 43 \
- : (_) == 's' ? 44 \
- : (_) == 't' ? 45 \
- : (_) == 'u' ? 46 \
- : (_) == 'v' ? 47 \
- : (_) == 'w' ? 48 \
- : (_) == 'x' ? 49 \
- : (_) == 'y' ? 50 \
- : (_) == 'z' ? 51 \
- : (_) == '0' ? 52 \
- : (_) == '1' ? 53 \
- : (_) == '2' ? 54 \
- : (_) == '3' ? 55 \
- : (_) == '4' ? 56 \
- : (_) == '5' ? 57 \
- : (_) == '6' ? 58 \
- : (_) == '7' ? 59 \
- : (_) == '8' ? 60 \
- : (_) == '9' ? 61 \
- : (_) == '+' ? 62 \
- : (_) == '/' ? 63 \
- : -1)
-
-static const signed char b64[0x100] = {
- B64 (0), B64 (1), B64 (2), B64 (3),
- B64 (4), B64 (5), B64 (6), B64 (7),
- B64 (8), B64 (9), B64 (10), B64 (11),
- B64 (12), B64 (13), B64 (14), B64 (15),
- B64 (16), B64 (17), B64 (18), B64 (19),
- B64 (20), B64 (21), B64 (22), B64 (23),
- B64 (24), B64 (25), B64 (26), B64 (27),
- B64 (28), B64 (29), B64 (30), B64 (31),
- B64 (32), B64 (33), B64 (34), B64 (35),
- B64 (36), B64 (37), B64 (38), B64 (39),
- B64 (40), B64 (41), B64 (42), B64 (43),
- B64 (44), B64 (45), B64 (46), B64 (47),
- B64 (48), B64 (49), B64 (50), B64 (51),
- B64 (52), B64 (53), B64 (54), B64 (55),
- B64 (56), B64 (57), B64 (58), B64 (59),
- B64 (60), B64 (61), B64 (62), B64 (63),
- B64 (64), B64 (65), B64 (66), B64 (67),
- B64 (68), B64 (69), B64 (70), B64 (71),
- B64 (72), B64 (73), B64 (74), B64 (75),
- B64 (76), B64 (77), B64 (78), B64 (79),
- B64 (80), B64 (81), B64 (82), B64 (83),
- B64 (84), B64 (85), B64 (86), B64 (87),
- B64 (88), B64 (89), B64 (90), B64 (91),
- B64 (92), B64 (93), B64 (94), B64 (95),
- B64 (96), B64 (97), B64 (98), B64 (99),
- B64 (100), B64 (101), B64 (102), B64 (103),
- B64 (104), B64 (105), B64 (106), B64 (107),
- B64 (108), B64 (109), B64 (110), B64 (111),
- B64 (112), B64 (113), B64 (114), B64 (115),
- B64 (116), B64 (117), B64 (118), B64 (119),
- B64 (120), B64 (121), B64 (122), B64 (123),
- B64 (124), B64 (125), B64 (126), B64 (127),
- B64 (128), B64 (129), B64 (130), B64 (131),
- B64 (132), B64 (133), B64 (134), B64 (135),
- B64 (136), B64 (137), B64 (138), B64 (139),
- B64 (140), B64 (141), B64 (142), B64 (143),
- B64 (144), B64 (145), B64 (146), B64 (147),
- B64 (148), B64 (149), B64 (150), B64 (151),
- B64 (152), B64 (153), B64 (154), B64 (155),
- B64 (156), B64 (157), B64 (158), B64 (159),
- B64 (160), B64 (161), B64 (162), B64 (163),
- B64 (164), B64 (165), B64 (166), B64 (167),
- B64 (168), B64 (169), B64 (170), B64 (171),
- B64 (172), B64 (173), B64 (174), B64 (175),
- B64 (176), B64 (177), B64 (178), B64 (179),
- B64 (180), B64 (181), B64 (182), B64 (183),
- B64 (184), B64 (185), B64 (186), B64 (187),
- B64 (188), B64 (189), B64 (190), B64 (191),
- B64 (192), B64 (193), B64 (194), B64 (195),
- B64 (196), B64 (197), B64 (198), B64 (199),
- B64 (200), B64 (201), B64 (202), B64 (203),
- B64 (204), B64 (205), B64 (206), B64 (207),
- B64 (208), B64 (209), B64 (210), B64 (211),
- B64 (212), B64 (213), B64 (214), B64 (215),
- B64 (216), B64 (217), B64 (218), B64 (219),
- B64 (220), B64 (221), B64 (222), B64 (223),
- B64 (224), B64 (225), B64 (226), B64 (227),
- B64 (228), B64 (229), B64 (230), B64 (231),
- B64 (232), B64 (233), B64 (234), B64 (235),
- B64 (236), B64 (237), B64 (238), B64 (239),
- B64 (240), B64 (241), B64 (242), B64 (243),
- B64 (244), B64 (245), B64 (246), B64 (247),
- B64 (248), B64 (249), B64 (250), B64 (251),
- B64 (252), B64 (253), B64 (254), B64 (255)
-};
-
-#if UCHAR_MAX == 255
-# define uchar_in_range(c) true
-#else
-# define uchar_in_range(c) ((c) <= 255)
-#endif
-
-/* Return true if CH is a character from the Base64 alphabet, and
- false otherwise. Note that '=' is padding and not considered to be
- part of the alphabet. */
-bool
-isbase64 (char ch)
-{
- return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)];
-}
-
-/* Decode base64 encoded input array IN of length INLEN to output
- array OUT that can hold *OUTLEN bytes. Return true if decoding was
- successful, i.e. if the input was valid base64 data, false
- otherwise. If *OUTLEN is too small, as many bytes as possible will
- be written to OUT. On return, *OUTLEN holds the length of decoded
- bytes in OUT. Note that as soon as any non-alphabet characters are
- encountered, decoding is stopped and false is returned. This means
- that, when applicable, you must remove any line terminators that is
- part of the data stream before calling this function. */
-bool
-base64_decode (const char *restrict in, size_t inlen,
- char *restrict out, size_t *outlen)
-{
- size_t outleft = *outlen;
-
- while (inlen >= 2)
- {
- if (!isbase64 (in[0]) || !isbase64 (in[1]))
- break;
-
- if (outleft)
- {
- *out++ = ((b64[to_uchar (in[0])] << 2)
- | (b64[to_uchar (in[1])] >> 4));
- outleft--;
- }
-
- if (inlen == 2)
- break;
-
- if (in[2] == '=')
- {
- if (inlen != 4)
- break;
-
- if (in[3] != '=')
- break;
-
- }
- else
- {
- if (!isbase64 (in[2]))
- break;
-
- if (outleft)
- {
- *out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0)
- | (b64[to_uchar (in[2])] >> 2));
- outleft--;
- }
-
- if (inlen == 3)
- break;
-
- if (in[3] == '=')
- {
- if (inlen != 4)
- break;
- }
- else
- {
- if (!isbase64 (in[3]))
- break;
-
- if (outleft)
- {
- *out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0)
- | b64[to_uchar (in[3])]);
- outleft--;
- }
- }
- }
-
- in += 4;
- inlen -= 4;
- }
-
- *outlen -= outleft;
-
- if (inlen != 0)
- return false;
-
- return true;
-}
-
-/* Allocate an output buffer in *OUT, and decode the base64 encoded
- data stored in IN of size INLEN to the *OUT buffer. On return, the
- size of the decoded data is stored in *OUTLEN. OUTLEN may be NULL,
- if the caller is not interested in the decoded length. *OUT may be
- NULL to indicate an out of memory error, in which case *OUTLEN
- contains the size of the memory block needed. The function returns
- true on successful decoding and memory allocation errors. (Use the
- *OUT and *OUTLEN parameters to differentiate between successful
- decoding and memory error.) The function returns false if the
- input was invalid, in which case *OUT is NULL and *OUTLEN is
- undefined. */
-bool
-base64_decode_alloc (const char *in, size_t inlen, char **out,
- size_t *outlen)
-{
- /* This may allocate a few bytes too much, depending on input,
- but it's not worth the extra CPU time to compute the exact amount.
- The exact amount is 3 * inlen / 4, minus 1 if the input ends
- with "=" and minus another 1 if the input ends with "==".
- Dividing before multiplying avoids the possibility of overflow. */
- size_t needlen = 3 * (inlen / 4) + 2;
-
- *out = malloc (needlen);
- if (!*out)
- return true;
-
- if (!base64_decode (in, inlen, *out, &needlen))
- {
- free (*out);
- *out = NULL;
- return false;
- }
-
- if (outlen)
- *outlen = needlen;
-
- return true;
-}
+/* base64.c -- Encode binary data using printable characters.
+ Copyright (C) 1999-2001, 2004-2006, 2009-2012 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>. */
+
+/* Written by Simon Josefsson. Partially adapted from GNU MailUtils
+ * (mailbox/filter_trans.c, as of 2004-11-28). Improved by review
+ * from Paul Eggert, Bruno Haible, and Stepan Kasal.
+ *
+ * See also RFC 4648 <http://www.ietf.org/rfc/rfc4648.txt>.
+ *
+ * Be careful with error checking. Here is how you would typically
+ * use these functions:
+ *
+ * bool ok = base64_decode_alloc (in, inlen, &out, &outlen);
+ * if (!ok)
+ * FAIL: input was not valid base64
+ * if (out == NULL)
+ * FAIL: memory allocation error
+ * OK: data in OUT/OUTLEN
+ *
+ * size_t outlen = base64_encode_alloc (in, inlen, &out);
+ * if (out == NULL && outlen == 0 && inlen != 0)
+ * FAIL: input too long
+ * if (out == NULL)
+ * FAIL: memory allocation error
+ * OK: data in OUT/OUTLEN.
+ *
+ */
+
+/* Get prototype. */
+#include "base64.h"
+
+/* Get malloc. */
+#include <stdlib.h>
+
+/* Get UCHAR_MAX. */
+#include <limits.h>
+
+#include <string.h>
+
+/* C89 compliant way to cast 'char' to 'unsigned char'. */
+static inline unsigned char
+to_uchar (char ch)
+{
+ return ch;
+}
+
+/* Base64 encode IN array of size INLEN into OUT array of size OUTLEN.
+ If OUTLEN is less than BASE64_LENGTH(INLEN), write as many bytes as
+ possible. If OUTLEN is larger than BASE64_LENGTH(INLEN), also zero
+ terminate the output buffer. */
+void
+base64_encode (const char *restrict in, size_t inlen,
+ char *restrict out, size_t outlen)
+{
+ static const char b64str[64] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ while (inlen && outlen)
+ {
+ *out++ = b64str[(to_uchar (in[0]) >> 2) & 0x3f];
+ if (!--outlen)
+ break;
+ *out++ = b64str[((to_uchar (in[0]) << 4)
+ + (--inlen ? to_uchar (in[1]) >> 4 : 0))
+ & 0x3f];
+ if (!--outlen)
+ break;
+ *out++ =
+ (inlen
+ ? b64str[((to_uchar (in[1]) << 2)
+ + (--inlen ? to_uchar (in[2]) >> 6 : 0))
+ & 0x3f]
+ : '=');
+ if (!--outlen)
+ break;
+ *out++ = inlen ? b64str[to_uchar (in[2]) & 0x3f] : '=';
+ if (!--outlen)
+ break;
+ if (inlen)
+ inlen--;
+ if (inlen)
+ in += 3;
+ }
+
+ if (outlen)
+ *out = '\0';
+}
+
+/* Allocate a buffer and store zero terminated base64 encoded data
+ from array IN of size INLEN, returning BASE64_LENGTH(INLEN), i.e.,
+ the length of the encoded data, excluding the terminating zero. On
+ return, the OUT variable will hold a pointer to newly allocated
+ memory that must be deallocated by the caller. If output string
+ length would overflow, 0 is returned and OUT is set to NULL. If
+ memory allocation failed, OUT is set to NULL, and the return value
+ indicates length of the requested memory block, i.e.,
+ BASE64_LENGTH(inlen) + 1. */
+size_t
+base64_encode_alloc (const char *in, size_t inlen, char **out)
+{
+ size_t outlen = 1 + BASE64_LENGTH (inlen);
+
+ /* Check for overflow in outlen computation.
+ *
+ * If there is no overflow, outlen >= inlen.
+ *
+ * If the operation (inlen + 2) overflows then it yields at most +1, so
+ * outlen is 0.
+ *
+ * If the multiplication overflows, we lose at least half of the
+ * correct value, so the result is < ((inlen + 2) / 3) * 2, which is
+ * less than (inlen + 2) * 0.66667, which is less than inlen as soon as
+ * (inlen > 4).
+ */
+ if (inlen > outlen)
+ {
+ *out = NULL;
+ return 0;
+ }
+
+ *out = malloc (outlen);
+ if (!*out)
+ return outlen;
+
+ base64_encode (in, inlen, *out, outlen);
+
+ return outlen - 1;
+}
+
+/* With this approach this file works independent of the charset used
+ (think EBCDIC). However, it does assume that the characters in the
+ Base64 alphabet (A-Za-z0-9+/) are encoded in 0..255. POSIX
+ 1003.1-2001 require that char and unsigned char are 8-bit
+ quantities, though, taking care of that problem. But this may be a
+ potential problem on non-POSIX C99 platforms.
+
+ IBM C V6 for AIX mishandles "#define B64(x) ...'x'...", so use "_"
+ as the formal parameter rather than "x". */
+#define B64(_) \
+ ((_) == 'A' ? 0 \
+ : (_) == 'B' ? 1 \
+ : (_) == 'C' ? 2 \
+ : (_) == 'D' ? 3 \
+ : (_) == 'E' ? 4 \
+ : (_) == 'F' ? 5 \
+ : (_) == 'G' ? 6 \
+ : (_) == 'H' ? 7 \
+ : (_) == 'I' ? 8 \
+ : (_) == 'J' ? 9 \
+ : (_) == 'K' ? 10 \
+ : (_) == 'L' ? 11 \
+ : (_) == 'M' ? 12 \
+ : (_) == 'N' ? 13 \
+ : (_) == 'O' ? 14 \
+ : (_) == 'P' ? 15 \
+ : (_) == 'Q' ? 16 \
+ : (_) == 'R' ? 17 \
+ : (_) == 'S' ? 18 \
+ : (_) == 'T' ? 19 \
+ : (_) == 'U' ? 20 \
+ : (_) == 'V' ? 21 \
+ : (_) == 'W' ? 22 \
+ : (_) == 'X' ? 23 \
+ : (_) == 'Y' ? 24 \
+ : (_) == 'Z' ? 25 \
+ : (_) == 'a' ? 26 \
+ : (_) == 'b' ? 27 \
+ : (_) == 'c' ? 28 \
+ : (_) == 'd' ? 29 \
+ : (_) == 'e' ? 30 \
+ : (_) == 'f' ? 31 \
+ : (_) == 'g' ? 32 \
+ : (_) == 'h' ? 33 \
+ : (_) == 'i' ? 34 \
+ : (_) == 'j' ? 35 \
+ : (_) == 'k' ? 36 \
+ : (_) == 'l' ? 37 \
+ : (_) == 'm' ? 38 \
+ : (_) == 'n' ? 39 \
+ : (_) == 'o' ? 40 \
+ : (_) == 'p' ? 41 \
+ : (_) == 'q' ? 42 \
+ : (_) == 'r' ? 43 \
+ : (_) == 's' ? 44 \
+ : (_) == 't' ? 45 \
+ : (_) == 'u' ? 46 \
+ : (_) == 'v' ? 47 \
+ : (_) == 'w' ? 48 \
+ : (_) == 'x' ? 49 \
+ : (_) == 'y' ? 50 \
+ : (_) == 'z' ? 51 \
+ : (_) == '0' ? 52 \
+ : (_) == '1' ? 53 \
+ : (_) == '2' ? 54 \
+ : (_) == '3' ? 55 \
+ : (_) == '4' ? 56 \
+ : (_) == '5' ? 57 \
+ : (_) == '6' ? 58 \
+ : (_) == '7' ? 59 \
+ : (_) == '8' ? 60 \
+ : (_) == '9' ? 61 \
+ : (_) == '+' ? 62 \
+ : (_) == '/' ? 63 \
+ : -1)
+
+static const signed char b64[0x100] = {
+ B64 (0), B64 (1), B64 (2), B64 (3),
+ B64 (4), B64 (5), B64 (6), B64 (7),
+ B64 (8), B64 (9), B64 (10), B64 (11),
+ B64 (12), B64 (13), B64 (14), B64 (15),
+ B64 (16), B64 (17), B64 (18), B64 (19),
+ B64 (20), B64 (21), B64 (22), B64 (23),
+ B64 (24), B64 (25), B64 (26), B64 (27),
+ B64 (28), B64 (29), B64 (30), B64 (31),
+ B64 (32), B64 (33), B64 (34), B64 (35),
+ B64 (36), B64 (37), B64 (38), B64 (39),
+ B64 (40), B64 (41), B64 (42), B64 (43),
+ B64 (44), B64 (45), B64 (46), B64 (47),
+ B64 (48), B64 (49), B64 (50), B64 (51),
+ B64 (52), B64 (53), B64 (54), B64 (55),
+ B64 (56), B64 (57), B64 (58), B64 (59),
+ B64 (60), B64 (61), B64 (62), B64 (63),
+ B64 (64), B64 (65), B64 (66), B64 (67),
+ B64 (68), B64 (69), B64 (70), B64 (71),
+ B64 (72), B64 (73), B64 (74), B64 (75),
+ B64 (76), B64 (77), B64 (78), B64 (79),
+ B64 (80), B64 (81), B64 (82), B64 (83),
+ B64 (84), B64 (85), B64 (86), B64 (87),
+ B64 (88), B64 (89), B64 (90), B64 (91),
+ B64 (92), B64 (93), B64 (94), B64 (95),
+ B64 (96), B64 (97), B64 (98), B64 (99),
+ B64 (100), B64 (101), B64 (102), B64 (103),
+ B64 (104), B64 (105), B64 (106), B64 (107),
+ B64 (108), B64 (109), B64 (110), B64 (111),
+ B64 (112), B64 (113), B64 (114), B64 (115),
+ B64 (116), B64 (117), B64 (118), B64 (119),
+ B64 (120), B64 (121), B64 (122), B64 (123),
+ B64 (124), B64 (125), B64 (126), B64 (127),
+ B64 (128), B64 (129), B64 (130), B64 (131),
+ B64 (132), B64 (133), B64 (134), B64 (135),
+ B64 (136), B64 (137), B64 (138), B64 (139),
+ B64 (140), B64 (141), B64 (142), B64 (143),
+ B64 (144), B64 (145), B64 (146), B64 (147),
+ B64 (148), B64 (149), B64 (150), B64 (151),
+ B64 (152), B64 (153), B64 (154), B64 (155),
+ B64 (156), B64 (157), B64 (158), B64 (159),
+ B64 (160), B64 (161), B64 (162), B64 (163),
+ B64 (164), B64 (165), B64 (166), B64 (167),
+ B64 (168), B64 (169), B64 (170), B64 (171),
+ B64 (172), B64 (173), B64 (174), B64 (175),
+ B64 (176), B64 (177), B64 (178), B64 (179),
+ B64 (180), B64 (181), B64 (182), B64 (183),
+ B64 (184), B64 (185), B64 (186), B64 (187),
+ B64 (188), B64 (189), B64 (190), B64 (191),
+ B64 (192), B64 (193), B64 (194), B64 (195),
+ B64 (196), B64 (197), B64 (198), B64 (199),
+ B64 (200), B64 (201), B64 (202), B64 (203),
+ B64 (204), B64 (205), B64 (206), B64 (207),
+ B64 (208), B64 (209), B64 (210), B64 (211),
+ B64 (212), B64 (213), B64 (214), B64 (215),
+ B64 (216), B64 (217), B64 (218), B64 (219),
+ B64 (220), B64 (221), B64 (222), B64 (223),
+ B64 (224), B64 (225), B64 (226), B64 (227),
+ B64 (228), B64 (229), B64 (230), B64 (231),
+ B64 (232), B64 (233), B64 (234), B64 (235),
+ B64 (236), B64 (237), B64 (238), B64 (239),
+ B64 (240), B64 (241), B64 (242), B64 (243),
+ B64 (244), B64 (245), B64 (246), B64 (247),
+ B64 (248), B64 (249), B64 (250), B64 (251),
+ B64 (252), B64 (253), B64 (254), B64 (255)
+};
+
+#if UCHAR_MAX == 255
+# define uchar_in_range(c) true
+#else
+# define uchar_in_range(c) ((c) <= 255)
+#endif
+
+/* Return true if CH is a character from the Base64 alphabet, and
+ false otherwise. Note that '=' is padding and not considered to be
+ part of the alphabet. */
+bool
+isbase64 (char ch)
+{
+ return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)];
+}
+
+/* Initialize decode-context buffer, CTX. */
+void
+base64_decode_ctx_init (struct base64_decode_context *ctx)
+{
+ ctx->i = 0;
+}
+
+/* If CTX->i is 0 or 4, there are four or more bytes in [*IN..IN_END), and
+ none of those four is a newline, then return *IN. Otherwise, copy up to
+ 4 - CTX->i non-newline bytes from that range into CTX->buf, starting at
+ index CTX->i and setting CTX->i to reflect the number of bytes copied,
+ and return CTX->buf. In either case, advance *IN to point to the byte
+ after the last one processed, and set *N_NON_NEWLINE to the number of
+ verified non-newline bytes accessible through the returned pointer. */
+static inline char *
+get_4 (struct base64_decode_context *ctx,
+ char const *restrict *in, char const *restrict in_end,
+ size_t *n_non_newline)
+{
+ if (ctx->i == 4)
+ ctx->i = 0;
+
+ if (ctx->i == 0)
+ {
+ char const *t = *in;
+ if (4 <= in_end - *in && memchr (t, '\n', 4) == NULL)
+ {
+ /* This is the common case: no newline. */
+ *in += 4;
+ *n_non_newline = 4;
+ return (char *) t;
+ }
+ }
+
+ {
+ /* Copy non-newline bytes into BUF. */
+ char const *p = *in;
+ while (p < in_end)
+ {
+ char c = *p++;
+ if (c != '\n')
+ {
+ ctx->buf[ctx->i++] = c;
+ if (ctx->i == 4)
+ break;
+ }
+ }
+
+ *in = p;
+ *n_non_newline = ctx->i;
+ return ctx->buf;
+ }
+}
+
+#define return_false \
+ do \
+ { \
+ *outp = out; \
+ return false; \
+ } \
+ while (false)
+
+/* Decode up to four bytes of base64-encoded data, IN, of length INLEN
+ into the output buffer, *OUT, of size *OUTLEN bytes. Return true if
+ decoding is successful, false otherwise. If *OUTLEN is too small,
+ as many bytes as possible are written to *OUT. On return, advance
+ *OUT to point to the byte after the last one written, and decrement
+ *OUTLEN to reflect the number of bytes remaining in *OUT. */
+static inline bool
+decode_4 (char const *restrict in, size_t inlen,
+ char *restrict *outp, size_t *outleft)
+{
+ char *out = *outp;
+ if (inlen < 2)
+ return false;
+
+ if (!isbase64 (in[0]) || !isbase64 (in[1]))
+ return false;
+
+ if (*outleft)
+ {
+ *out++ = ((b64[to_uchar (in[0])] << 2)
+ | (b64[to_uchar (in[1])] >> 4));
+ --*outleft;
+ }
+
+ if (inlen == 2)
+ return_false;
+
+ if (in[2] == '=')
+ {
+ if (inlen != 4)
+ return_false;
+
+ if (in[3] != '=')
+ return_false;
+ }
+ else
+ {
+ if (!isbase64 (in[2]))
+ return_false;
+
+ if (*outleft)
+ {
+ *out++ = (((b64[to_uchar (in[1])] << 4) & 0xf0)
+ | (b64[to_uchar (in[2])] >> 2));
+ --*outleft;
+ }
+
+ if (inlen == 3)
+ return_false;
+
+ if (in[3] == '=')
+ {
+ if (inlen != 4)
+ return_false;
+ }
+ else
+ {
+ if (!isbase64 (in[3]))
+ return_false;
+
+ if (*outleft)
+ {
+ *out++ = (((b64[to_uchar (in[2])] << 6) & 0xc0)
+ | b64[to_uchar (in[3])]);
+ --*outleft;
+ }
+ }
+ }
+
+ *outp = out;
+ return true;
+}
+
+/* Decode base64-encoded input array IN of length INLEN to output array
+ OUT that can hold *OUTLEN bytes. The input data may be interspersed
+ with newlines. Return true if decoding was successful, i.e. if the
+ input was valid base64 data, false otherwise. If *OUTLEN is too
+ small, as many bytes as possible will be written to OUT. On return,
+ *OUTLEN holds the length of decoded bytes in OUT. Note that as soon
+ as any non-alphabet, non-newline character is encountered, decoding
+ is stopped and false is returned. If INLEN is zero, then process
+ only whatever data is stored in CTX.
+
+ Initially, CTX must have been initialized via base64_decode_ctx_init.
+ Subsequent calls to this function must reuse whatever state is recorded
+ in that buffer. It is necessary for when a quadruple of base64 input
+ bytes spans two input buffers.
+
+ If CTX is NULL then newlines are treated as garbage and the input
+ buffer is processed as a unit. */
+
+bool
+base64_decode_ctx (struct base64_decode_context *ctx,
+ const char *restrict in, size_t inlen,
+ char *restrict out, size_t *outlen)
+{
+ size_t outleft = *outlen;
+ bool ignore_newlines = ctx != NULL;
+ bool flush_ctx = false;
+ unsigned int ctx_i = 0;
+
+ if (ignore_newlines)
+ {
+ ctx_i = ctx->i;
+ flush_ctx = inlen == 0;
+ }
+
+
+ while (true)
+ {
+ size_t outleft_save = outleft;
+ if (ctx_i == 0 && !flush_ctx)
+ {
+ while (true)
+ {
+ /* Save a copy of outleft, in case we need to re-parse this
+ block of four bytes. */
+ outleft_save = outleft;
+ if (!decode_4 (in, inlen, &out, &outleft))
+ break;
+
+ in += 4;
+ inlen -= 4;
+ }
+ }
+
+ if (inlen == 0 && !flush_ctx)
+ break;
+
+ /* Handle the common case of 72-byte wrapped lines.
+ This also handles any other multiple-of-4-byte wrapping. */
+ if (inlen && *in == '\n' && ignore_newlines)
+ {
+ ++in;
+ --inlen;
+ continue;
+ }
+
+ /* Restore OUT and OUTLEFT. */
+ out -= outleft_save - outleft;
+ outleft = outleft_save;
+
+ {
+ char const *in_end = in + inlen;
+ char const *non_nl;
+
+ if (ignore_newlines)
+ non_nl = get_4 (ctx, &in, in_end, &inlen);
+ else
+ non_nl = in; /* Might have nl in this case. */
+
+ /* If the input is empty or consists solely of newlines (0 non-newlines),
+ then we're done. Likewise if there are fewer than 4 bytes when not
+ flushing context and not treating newlines as garbage. */
+ if (inlen == 0 || (inlen < 4 && !flush_ctx && ignore_newlines))
+ {
+ inlen = 0;
+ break;
+ }
+ if (!decode_4 (non_nl, inlen, &out, &outleft))
+ break;
+
+ inlen = in_end - in;
+ }
+ }
+
+ *outlen -= outleft;
+
+ return inlen == 0;
+}
+
+/* Allocate an output buffer in *OUT, and decode the base64 encoded
+ data stored in IN of size INLEN to the *OUT buffer. On return, the
+ size of the decoded data is stored in *OUTLEN. OUTLEN may be NULL,
+ if the caller is not interested in the decoded length. *OUT may be
+ NULL to indicate an out of memory error, in which case *OUTLEN
+ contains the size of the memory block needed. The function returns
+ true on successful decoding and memory allocation errors. (Use the
+ *OUT and *OUTLEN parameters to differentiate between successful
+ decoding and memory error.) The function returns false if the
+ input was invalid, in which case *OUT is NULL and *OUTLEN is
+ undefined. */
+bool
+base64_decode_alloc_ctx (struct base64_decode_context *ctx,
+ const char *in, size_t inlen, char **out,
+ size_t *outlen)
+{
+ /* This may allocate a few bytes too many, depending on input,
+ but it's not worth the extra CPU time to compute the exact size.
+ The exact size is 3 * (inlen + (ctx ? ctx->i : 0)) / 4, minus 1 if the
+ input ends with "=" and minus another 1 if the input ends with "==".
+ Dividing before multiplying avoids the possibility of overflow. */
+ size_t needlen = 3 * (inlen / 4) + 3;
+
+ *out = malloc (needlen);
+ if (!*out)
+ return true;
+
+ if (!base64_decode_ctx (ctx, in, inlen, *out, &needlen))
+ {
+ free (*out);
+ *out = NULL;
+ return false;
+ }
+
+ if (outlen)
+ *outlen = needlen;
+
+ return true;
+}
--- a/project_files/frontlib/base64/base64.h Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/base64/base64.h Thu Jul 05 00:33:24 2012 +0200
@@ -1,45 +1,60 @@
-/* base64.h -- Encode binary data using printable characters.
- Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
- Written by Simon Josefsson.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
-
-#ifndef BASE64_H
-# define BASE64_H
-
-/* Get size_t. */
-# include <stddef.h>
-
-/* Get bool. */
-# include <stdbool.h>
-
-/* This uses that the expression (n+(k-1))/k means the smallest
- integer >= n/k, i.e., the ceiling of n/k. */
-# define BASE64_LENGTH(inlen) ((((inlen) + 2) / 3) * 4)
-
-extern bool isbase64 (char ch);
-
-extern void base64_encode (const char *restrict in, size_t inlen,
- char *restrict out, size_t outlen);
-
-extern size_t base64_encode_alloc (const char *in, size_t inlen, char **out);
-
-extern bool base64_decode (const char *restrict in, size_t inlen,
- char *restrict out, size_t *outlen);
-
-extern bool base64_decode_alloc (const char *in, size_t inlen,
- char **out, size_t *outlen);
-
-#endif /* BASE64_H */
+/* base64.h -- Encode binary data using printable characters.
+ Copyright (C) 2004-2006, 2009-2012 Free Software Foundation, Inc.
+ Written by Simon Josefsson.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef BASE64_H
+# define BASE64_H
+
+/* Get size_t. */
+# include <stddef.h>
+
+/* Get bool. */
+# include <stdbool.h>
+
+/* This uses that the expression (n+(k-1))/k means the smallest
+ integer >= n/k, i.e., the ceiling of n/k. */
+# define BASE64_LENGTH(inlen) ((((inlen) + 2) / 3) * 4)
+
+struct base64_decode_context
+{
+ unsigned int i;
+ char buf[4];
+};
+
+extern bool isbase64 (char ch);
+
+extern void base64_encode (const char *restrict in, size_t inlen,
+ char *restrict out, size_t outlen);
+
+extern size_t base64_encode_alloc (const char *in, size_t inlen, char **out);
+
+extern void base64_decode_ctx_init (struct base64_decode_context *ctx);
+
+extern bool base64_decode_ctx (struct base64_decode_context *ctx,
+ const char *restrict in, size_t inlen,
+ char *restrict out, size_t *outlen);
+
+extern bool base64_decode_alloc_ctx (struct base64_decode_context *ctx,
+ const char *in, size_t inlen,
+ char **out, size_t *outlen);
+
+#define base64_decode(in, inlen, out, outlen) \
+ base64_decode_ctx (NULL, in, inlen, out, outlen)
+
+#define base64_decode_alloc(in, inlen, out, outlen) \
+ base64_decode_alloc_ctx (NULL, in, inlen, out, outlen)
+
+#endif /* BASE64_H */
--- a/project_files/frontlib/cmdlineClient.c Wed Jun 27 22:52:19 2012 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,482 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "frontlib.h"
-#include "util/logging.h"
-#include "util/buffer.h"
-#include "util/util.h"
-#include "util/list.h"
-#include "model/map.h"
-#include "model/weapon.h"
-#include "model/schemelist.h"
-#include "ipc/mapconn.h"
-#include "ipc/gameconn.h"
-#include "net/netconn.h"
-#include "base64/base64.h"
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <assert.h>
-#include <string.h>
-#include <conio.h>
-#include <windows.h>
-
-#define ENGINE_DIR ".\\"
-#define CONFIG_DIR "..\\share\\hedgewars"
-#define DATA_DIR CONFIG_DIR"\\Data"
-
-static flib_netconn *netconn;
-static flib_gameconn *gameconn;
-static flib_mapconn *mapconn;
-static char nickname[128];
-static flib_cfg_meta *metacfg;
-static bool netConnected = false;
-
-// Callback function that will be called when the map is rendered
-static void handleMapGenerated(void *context, const uint8_t *bitmap, int numHedgehogs) {
- printf("Drawing map for %i brave little hogs...", numHedgehogs);
-
- // Draw the map as ASCII art
- for(int y=0; y<MAPIMAGE_HEIGHT; y+=8) {
- for(int x=0; x<MAPIMAGE_WIDTH; x+=6) {
- int pixelnum = x + y*MAPIMAGE_WIDTH;
- bool pixel = bitmap[pixelnum>>3] & (1<<(7-(pixelnum&7)));
- printf(pixel ? "#" : " ");
- }
- printf("\n");
- }
-
- flib_mapconn_destroy(mapconn);
- mapconn = NULL;
-}
-
-static void onGameDisconnect(void *context, int reason) {
- flib_log_i("Connection closed. Reason: %i", reason);
- flib_gameconn_destroy(gameconn);
- gameconn = NULL;
- if(netconn) {
- flib_netconn_send_roundfinished(netconn, reason==GAME_END_FINISHED);
- }
-}
-
-// Callback function that will be called on error
-static void handleMapFailure(void *context, const char *errormessage) {
- flib_log_e("Map rendering failed: %s", errormessage);
- flib_mapconn_destroy(mapconn);
- mapconn = NULL;
-}
-
-static void startEngineMap(int port) {
- char cmdbuffer[255];
- char argbuffer[255];
- snprintf(cmdbuffer, 255, "%shwengine.exe", ENGINE_DIR);
- snprintf(argbuffer, 255, "%s %i landpreview", CONFIG_DIR, port);
- ShellExecute(NULL, NULL, cmdbuffer, argbuffer, NULL, SW_HIDE);
-}
-
-static void startEngineGame(int port) {
- char cmdbuffer[255];
- char argbuffer[255];
- char base64PlayerName[255];
- base64_encode(nickname, strlen(nickname), base64PlayerName, sizeof(base64PlayerName));
- snprintf(cmdbuffer, 255, "%shwengine.exe", ENGINE_DIR);
- snprintf(argbuffer, 255, "%s 1024 768 32 %i 0 0 0 10 10 %s 0 0 %s 0 0 en.txt", CONFIG_DIR, port, DATA_DIR, base64PlayerName);
- ShellExecute(NULL, NULL, cmdbuffer, argbuffer, NULL, SW_HIDE);
-}
-
-void handleNetDisconnect(void *context, int reason, const char *message) {
- printf("Disconnected: %s", message);
- flib_netconn_destroy(netconn);
- netconn = NULL;
-}
-
-void printRoomList() {
- const flib_roomlist *roomlist = flib_netconn_get_roomlist(netconn);
- if(roomlist) {
- if(roomlist->roomCount>0) {
- for(int i=0; i<roomlist->roomCount; i++) {
- if(i>0) {
- printf(", ");
- }
- flib_room *room = roomlist->rooms[i];
- printf("%s", room->name);
- }
- } else {
- puts("Unfortunately, there are no rooms at the moment.");
- }
- } else {
- puts("Sorry, due to an error the room list is not available.");
- }
- puts("\n");
-}
-
-void printTeamList() {
- flib_gamesetup *setup = flib_netconn_create_gamesetup(netconn);
- if(setup) {
- puts("The following teams are in this room:");
- for(int i=0; i<setup->teamlist->teamCount; i++) {
- if(i>0) {
- printf(", ");
- }
- printf("%s", setup->teamlist->teams[i]->name);
- }
- puts("\n");
- } else {
- puts("Sorry, due to an error the team list is not available.");
- }
- flib_gamesetup_destroy(setup);
-}
-
-void handleNetConnected(void *context) {
- printf("You enter the lobby of a strange house inhabited by hedgehogs. Looking around, you see hallways branching off to these rooms:\n");
- printRoomList();
- printf("\n\nNow, you can chat by just entering text, or join a room with /join <roomname>.");
- printf(" You can also /quit or let me /describe <roomname>. Once in a room, you can /add <teamname> and set yourself /ready. You can also /list the available rooms (in the lobby) or the teams (in a room).\n");
- netConnected = true;
-}
-
-void handleChat(void *context, const char *nick, const char *msg) {
- if(gameconn) {
- flib_gameconn_send_chatmsg(gameconn, nick, msg);
- }
- printf("%s: %s\n", nick, msg);
-}
-
-void handleEnterRoom(void *context, bool isChief) {
- puts("You have entered the room.");
-}
-
-void handleRoomJoin(void *context, const char *nick) {
- if(strcmp(nick, nickname)) {
- printf("%s is here.\n", nick);
- }
-}
-
-void handleRoomLeave(void *context, const char *nick, const char *partmsg) {
- if(strcmp(nick, nickname)) {
- printf("%s leaves.\n", nick);
- }
-}
-
-void handleReady(void *context, const char *nick, bool ready) {
- if(strcmp(nick, nickname)) {
- if(ready) {
- printf("%s is ready to go.\n", nick);
- } else {
- printf("%s is not ready.\n", nick);
- }
- } else {
- if(ready) {
- printf("You are ready to go.\n");
- } else {
- printf("You are not ready.\n");
- }
- }
-}
-
-void handleEmFromNet(void *context, const uint8_t *em, size_t size) {
- if(gameconn) {
- flib_gameconn_send_enginemsg(gameconn, (const uint8_t*)em, size);
- }
-}
-
-void handleEmFromEngine(void *context, const uint8_t *em, size_t size) {
- if(netconn) {
- flib_netconn_send_engineMessage(netconn, em, size);
- }
-}
-
-void handleChatFromGame(void *context, const char *message, bool teamchat) {
- if(netconn) {
- if(teamchat) {
- flib_netconn_send_teamchat(netconn, message);
- } else {
- flib_netconn_send_chat(netconn, message);
- }
- }
-}
-
-void handleRunGame(void *context) {
- flib_gamesetup *gamesetup = flib_netconn_create_gamesetup(netconn);
- if(gameconn) {
- flib_log_e("Request to start game, but a game is already running.");
- } else if(gamesetup) {
- gameconn = flib_gameconn_create(nickname, gamesetup, true);
- flib_gameconn_onEngineMessage(gameconn, handleEmFromEngine, NULL);
- flib_gameconn_onDisconnect(gameconn, onGameDisconnect, NULL);
- flib_gameconn_onChat(gameconn, handleChatFromGame, NULL);
- startEngineGame(flib_gameconn_getport(gameconn));
- }
- flib_gamesetup_destroy(gamesetup);
-}
-
-void handleNickTaken(void *context, const char *nick) {
- printf("The nickname %s is already in use, please choose a different one:\n", nick);
- flib_gets(nickname, sizeof(nickname));
- flib_netconn_send_nick(netconn, nickname);
-}
-
-void handlePwRequest(void *context, const char *nick) {
- printf("A password is required to log in as %s, please enter (warning: shown in cleartext):\n", nick);
- char password[256];
- flib_gets(password, sizeof(password));
- flib_netconn_send_password(netconn, password);
-}
-
-void handleMessage(void *context, int type, const char *msg) {
- if(gameconn) {
- flib_gameconn_send_textmsg(gameconn, 1, msg);
- }
- printf("*** %s\n", msg);
-}
-
-void handleTeamAccepted(void *context, const char *teamname) {
- printf("The team %s has been accepted.\n", teamname);
-}
-
-void handleMapChanged(void *context, const flib_map *map, int changetype) {
- if(map->mapgen != MAPGEN_NAMED && changetype != NETCONN_MAPCHANGE_THEME) {
- if(mapconn) {
- flib_mapconn_destroy(mapconn);
- mapconn = NULL;
- }
- mapconn = flib_mapconn_create(map);
- if(mapconn) {
- flib_mapconn_onSuccess(mapconn, handleMapGenerated, NULL);
- flib_mapconn_onFailure(mapconn, handleMapFailure, NULL);
- startEngineMap(flib_mapconn_getport(mapconn));
- }
- } else if(map->mapgen == MAPGEN_NAMED) {
- printf("The map %s has been selected.\n", map->name);
- }
-}
-
-void handleLeaveRoom(void *context, int reason, const char *msg) {
- if(reason == NETCONN_ROOMLEAVE_ABANDONED) {
- printf("The chief has abandoned the room.");
- } else if(reason == NETCONN_ROOMLEAVE_KICKED) {
- printf("You have been kicked from the room.");
- }
- if(msg) {
- printf(" (%s)", msg);
- }
- puts(" You are back in the lobby.");
-}
-
-void handleSchemeChanged(void *context, flib_cfg *scheme) {
- printf("Game scheme: %s.\n", scheme->name);
-}
-
-void handleWeaponsetChanged(void *context, flib_weaponset *weaponset) {
- printf("Weaponset: %s.\n", weaponset->name);
-}
-
-void handleHogcountChanged(void *context, const char *team, int count) {
- printf("Team %s will send %i hogs into the fight.\n", team, count);
-}
-
-void handleRoomAdd(void *context, const flib_room *room) {
- printf("%s created a new room called %s.\n", room->owner, room->name);
-}
-
-void handleRoomDelete(void *context, const char *roomName) {
- printf("The room %s has collapsed.\n", roomName);
-}
-
-void handleScriptChanged(void *context, const char *script) {
- printf("Game Type: %s\n", script);
-}
-
-void handleTeamAdd(void *context, flib_team *team) {
- printf("%s puts the team %s to the planning board.\n", team->ownerName, team->name);
-}
-
-void handleTeamDelete(void *context, const char *teamName) {
- printf("The team %s decided not to fight this battle after all.\n", teamName);
-}
-
-void handleTeamColorChanged(void *context, const char *name, int colorIndex) {
- static const char* colorNames[] = {"red", "blue", "teal", "purple", "pink", "green", "orange", "brown", "yellow"};
- const char *colorName = "strange";
- if(colorIndex>=0 && colorIndex < 9) {
- colorName = colorNames[colorIndex];
- }
- printf("The team %s will wear %s uniforms today.\n", name, colorName);
-}
-
-void tick() {
- if(gameconn) {
- flib_gameconn_tick(gameconn);
- }
- if(netconn) {
- flib_netconn_tick(netconn);
- }
- if(mapconn) {
- flib_mapconn_tick(mapconn);
- }
-}
-
-static HANDLE hStdin;
-
-static int init() {
- hStdin = GetStdHandle(STD_INPUT_HANDLE);
- if(hStdin == INVALID_HANDLE_VALUE) {
- flib_log_e("Unable to get stdin handle");
- return 1;
- }
- if(!flib_init(0)) {
- flib_log_setLevel(FLIB_LOGLEVEL_WARNING);
- freopen( "CON", "w", stdout );
- freopen( "CON", "w", stderr );
- metacfg = flib_cfg_meta_from_ini("metasettings.ini");
- if(!metacfg) {
- flib_quit();
- return -1;
- } else {
- return 0;
- }
- }
- return -1;
-}
-
-int main(int argc, char *argv[]) {
- if(init()) {
- return -1;
- }
-
- puts("Please enter a nickname:");
- flib_gets(nickname, sizeof(nickname));
-
- netconn = flib_netconn_create(nickname, metacfg, DATA_DIR"\\", "140.247.62.101", 46631);
- if(!netconn) {
- flib_quit();
- return -1;
- }
-
- flib_netconn_onConnected(netconn, handleNetConnected, NULL);
- flib_netconn_onDisconnected(netconn, handleNetDisconnect, NULL);
- flib_netconn_onChat(netconn, handleChat, NULL);
- flib_netconn_onEnterRoom(netconn, handleEnterRoom, NULL);
- flib_netconn_onRunGame(netconn, handleRunGame, NULL);
- flib_netconn_onEngineMessage(netconn, handleEmFromNet, NULL);
- flib_netconn_onRoomJoin(netconn, handleRoomJoin, NULL);
- flib_netconn_onRoomLeave(netconn, handleRoomLeave, NULL);
- flib_netconn_onReadyState(netconn, handleReady, NULL);
- flib_netconn_onNickTaken(netconn, handleNickTaken, NULL);
- flib_netconn_onPasswordRequest(netconn, handlePwRequest, NULL);
- flib_netconn_onMessage(netconn, handleMessage, NULL);
- flib_netconn_onTeamAccepted(netconn, handleTeamAccepted, NULL);
- flib_netconn_onMapChanged(netconn, handleMapChanged, NULL);
- flib_netconn_onLeaveRoom(netconn, handleLeaveRoom, NULL);
- flib_netconn_onCfgScheme(netconn, handleSchemeChanged, NULL);
- flib_netconn_onWeaponsetChanged(netconn, handleWeaponsetChanged, NULL);
- flib_netconn_onHogCountChanged(netconn, handleHogcountChanged, NULL);
- flib_netconn_onRoomAdd(netconn, handleRoomAdd, NULL);
- flib_netconn_onRoomDelete(netconn, handleRoomDelete, NULL);
- flib_netconn_onScriptChanged(netconn, handleScriptChanged, NULL);
- flib_netconn_onTeamAdd(netconn, handleTeamAdd, NULL);
- flib_netconn_onTeamDelete(netconn, handleTeamDelete, NULL);
- flib_netconn_onTeamColorChanged(netconn, handleTeamColorChanged, NULL);
-
- INPUT_RECORD inputRecord;
- DWORD eventCount = 0;
-
- while(netconn || gameconn) {
- tick();
- if(netconn && netConnected) {
- while(PeekConsoleInput(hStdin, &inputRecord, 1, &eventCount) && eventCount>0) {
- if(inputRecord.EventType != KEY_EVENT) {
- ReadConsoleInput(hStdin, &inputRecord, 1, &eventCount);
- } else {
- printf("%s: ", nickname);
- char input[256];
- if(!flib_gets(input, sizeof(input))) {
- if(!memcmp("/quit", input, strlen("/quit"))) {
- flib_netconn_send_quit(netconn, "Player quit.");
- } else if(!memcmp("/describe ", input, strlen("/describe "))) {
- const char *roomname = input+strlen("/describe ");
- const flib_roomlist *roomlist = flib_netconn_get_roomlist(netconn);
- flib_room *room = flib_roomlist_find(roomlist, roomname);
- if(!room) {
- puts("Unknown room.");
- } else {
- char *text = flib_asprintf(
- "%s is a room created by %s, where %i players (%i teams) are %s on %s%s, using the %s scheme and %s weaponset.",
- room->name,
- room->owner,
- room->playerCount,
- room->teamCount,
- room->inProgress ? "fighting" : "preparing to fight",
- room->map[0]=='+' ? "" : "the map ",
- !strcmp("+rnd+", room->map) ? "a random map" :
- !strcmp("+maze+", room->map) ? "a random maze" :
- !strcmp("+drawn+", room->map) ? "a hand-drawn map" :
- room->map,
- room->scheme,
- room->weapons);
- if(text) {
- puts(text);
- }
- free(text);
- }
- } else if(!memcmp("/join ", input, strlen("/join "))) {
- const char *roomname = input+strlen("/join ");
- flib_netconn_send_joinRoom(netconn, roomname);
- } else if(!memcmp("/ready", input, strlen("/ready"))) {
- flib_netconn_send_toggleReady(netconn);
- } else if(!memcmp("/loglevel ", input, strlen("/loglevel "))) {
- int loglevel = atoi(input+strlen("/loglevel "));
- flib_log_setLevel(loglevel);
- } else if(!memcmp("/list", input, strlen("/list"))) {
- if(flib_netconn_is_in_room_context(netconn)) {
- printTeamList();
- } else {
- puts("From this big and expansive lobby, hallways branch off to these rooms:");
- printRoomList();
- }
- } else if(!memcmp("/addteam ", input, strlen("/addteam "))) {
- const char *teamname = input+strlen("/addteam ");
- if(!flib_contains_dir_separator(teamname)) {
- char *teamfilename = flib_asprintf("%s.hwt", teamname);
- if(teamfilename) {
- flib_team *team = flib_team_from_ini(teamfilename);
- if(team) {
- flib_netconn_send_addTeam(netconn, team);
- } else {
- printf("Teamfile %s not found.\n", teamfilename);
- }
- flib_team_release(team);
- }
- free(teamfilename);
- }
- } else if(strlen(input)>0) {
- flib_netconn_send_chat(netconn, input);
- }
- }
- }
- }
- }
- fflush(stdout);
- Sleep(10);
- }
-
-
- flib_cfg_meta_release(metacfg);
- return 0;
-}
--- a/project_files/frontlib/frontlib.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/frontlib.c Thu Jul 05 00:33:24 2012 +0200
@@ -19,27 +19,12 @@
#include "frontlib.h"
#include "util/logging.h"
-#include <SDL.h>
#include <SDL_net.h>
-static int flib_initflags;
-
int flib_init(int flags) {
- flib_initflags = flags;
-
flib_log_d("Initializing frontlib");
- if(!(flib_initflags | FRONTLIB_SDL_ALREADY_INITIALIZED)) {
- if(SDL_Init(0)==-1) {
- flib_log_e("Error in SDL_Init: %s", SDL_GetError());
- return -1;
- }
- }
-
if(SDLNet_Init()==-1) {
flib_log_e("Error in SDLNet_Init: %s", SDLNet_GetError());
- if(!(flib_initflags | FRONTLIB_SDL_ALREADY_INITIALIZED)) {
- SDL_Quit();
- }
return -1;
}
@@ -49,7 +34,4 @@
void flib_quit() {
flib_log_d("Shutting down frontlib");
SDLNet_Quit();
- if(!(flib_initflags | FRONTLIB_SDL_ALREADY_INITIALIZED)) {
- SDL_Quit();
- }
}
--- a/project_files/frontlib/frontlib.h Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/frontlib.h Thu Jul 05 00:33:24 2012 +0200
@@ -26,6 +26,10 @@
#ifndef FRONTLIB_H_
#define FRONTLIB_H_
+#include "ipc/gameconn.h"
+#include "ipc/mapconn.h"
+#include "net/netconn.h"
+
#define FRONTLIB_SDL_ALREADY_INITIALIZED 1
/**
--- a/project_files/frontlib/ipc/gameconn.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/ipc/gameconn.c Thu Jul 05 00:33:24 2012 +0200
@@ -84,29 +84,30 @@
static flib_gameconn *flib_gameconn_create_partial(bool record, const char *playerName, bool netGame) {
flib_gameconn *result = NULL;
- if(!log_badparams_if(!playerName)) {
- flib_gameconn *tempConn = flib_calloc(1, sizeof(flib_gameconn));
- if(tempConn) {
- tempConn->ipcBase = flib_ipcbase_create();
- tempConn->configBuffer = flib_vector_create();
- tempConn->playerName = flib_strdupnull(playerName);
- if(tempConn->ipcBase && tempConn->configBuffer && tempConn->playerName) {
- if(record) {
- tempConn->demoBuffer = flib_vector_create();
- }
- tempConn->state = AWAIT_CONNECTION;
- tempConn->netgame = netGame;
- clearCallbacks(tempConn);
- result = tempConn;
- tempConn = NULL;
+ flib_gameconn *tempConn = flib_calloc(1, sizeof(flib_gameconn));
+ if(tempConn) {
+ tempConn->ipcBase = flib_ipcbase_create();
+ tempConn->configBuffer = flib_vector_create();
+ tempConn->playerName = flib_strdupnull(playerName);
+ if(tempConn->ipcBase && tempConn->configBuffer && tempConn->playerName) {
+ if(record) {
+ tempConn->demoBuffer = flib_vector_create();
}
+ tempConn->state = AWAIT_CONNECTION;
+ tempConn->netgame = netGame;
+ clearCallbacks(tempConn);
+ result = tempConn;
+ tempConn = NULL;
}
- flib_gameconn_destroy(tempConn);
}
+ flib_gameconn_destroy(tempConn);
return result;
}
flib_gameconn *flib_gameconn_create(const char *playerName, const flib_gamesetup *setup, bool netgame) {
+ if(log_badargs_if2(playerName==NULL, setup==NULL)) {
+ return NULL;
+ }
flib_gameconn *result = NULL;
flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, netgame);
if(tempConn) {
@@ -121,7 +122,10 @@
return result;
}
-flib_gameconn *flib_gameconn_create_playdemo(const uint8_t *demo, int size) {
+flib_gameconn *flib_gameconn_create_playdemo(const uint8_t *demo, size_t size) {
+ if(log_badargs_if(demo==NULL && size>0)) {
+ return NULL;
+ }
flib_gameconn *result = NULL;
flib_gameconn *tempConn = flib_gameconn_create_partial(false, "Player", false);
if(tempConn) {
@@ -134,7 +138,10 @@
return result;
}
-flib_gameconn *flib_gameconn_create_loadgame(const char *playerName, const uint8_t *save, int size) {
+flib_gameconn *flib_gameconn_create_loadgame(const char *playerName, const uint8_t *save, size_t size) {
+ if(log_badargs_if(save==NULL && size>0)) {
+ return NULL;
+ }
flib_gameconn *result = NULL;
flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, false);
if(tempConn) {
@@ -148,6 +155,9 @@
}
flib_gameconn *flib_gameconn_create_campaign(const char *playerName, const char *seed, const char *script) {
+ if(log_badargs_if3(playerName==NULL, seed==NULL, script==NULL)) {
+ return NULL;
+ }
flib_gameconn *result = NULL;
flib_gameconn *tempConn = flib_gameconn_create_partial(true, playerName, false);
if(tempConn) {
@@ -184,10 +194,10 @@
}
int flib_gameconn_getport(flib_gameconn *conn) {
- if(!log_badparams_if(!conn)) {
- return flib_ipcbase_port(conn->ipcBase);
+ if(log_badargs_if(conn==NULL)) {
+ return 0;
}
- return 0;
+ return flib_ipcbase_port(conn->ipcBase);
}
static void demo_append(flib_gameconn *conn, const void *data, size_t len) {
@@ -207,11 +217,11 @@
bool meMessage = msglen >= 4 && !memcmp(message, "/me ", 4);
const char *template = meMessage ? "s\x02* %s %s " : "s\x01%s: %s ";
int size = snprintf((char*)buffer+1, 256, template, playerName, meMessage ? message+4 : message);
- if(size>0) {
+ if(log_e_if(size<=0, "printf error")) {
+ return -1;
+ } else {
buffer[0] = size>255 ? 255 : size;
return 0;
- } else {
- return -1;
}
}
@@ -235,100 +245,78 @@
}
int flib_gameconn_send_enginemsg(flib_gameconn *conn, const uint8_t *data, size_t len) {
- int result = -1;
- if(!log_badparams_if(!conn || (!data && len>0))
- && !flib_ipcbase_send_raw(conn->ipcBase, data, len)) {
+ if(log_badargs_if2(conn==NULL, data==NULL && len>0)) {
+ return -1;
+ }
+ int result = flib_ipcbase_send_raw(conn->ipcBase, data, len);
+ if(!result) {
demo_append(conn, data, len);
- result = 0;
}
return result;
}
int flib_gameconn_send_textmsg(flib_gameconn *conn, int msgtype, const char *msg) {
+ if(log_badargs_if2(conn==NULL, msg==NULL)) {
+ return -1;
+ }
int result = -1;
- if(!conn || !msg) {
- flib_log_e("null parameter in flib_gameconn_send_textmsg");
- } else {
- uint8_t converted[257];
- int size = snprintf((char*)converted+1, 256, "s%c%s", (char)msgtype, msg);
- if(size>0) {
- converted[0] = size>255 ? 255 : size;
- if(!flib_ipcbase_send_raw(conn->ipcBase, converted, converted[0]+1)) {
- demo_append(conn, converted, converted[0]+1);
- result = 0;
- }
+ uint8_t converted[257];
+ int size = snprintf((char*)converted+1, 256, "s%c%s", (char)msgtype, msg);
+ if(size>0) {
+ converted[0] = size>255 ? 255 : size;
+ if(!flib_ipcbase_send_raw(conn->ipcBase, converted, converted[0]+1)) {
+ demo_append(conn, converted, converted[0]+1);
+ result = 0;
}
}
return result;
}
int flib_gameconn_send_chatmsg(flib_gameconn *conn, const char *playername, const char *msg) {
- int result = -1;
- uint8_t converted[257];
- if(!conn || !playername || !msg) {
- flib_log_e("null parameter in flib_gameconn_send_chatmsg");
- } else if(format_chatmessage(converted, playername, msg)) {
- flib_log_e("Error formatting message in flib_gameconn_send_chatmsg");
- } else if(!flib_ipcbase_send_raw(conn->ipcBase, converted, converted[0]+1)) {
- demo_append(conn, converted, converted[0]+1);
- result = 0;
+ if(log_badargs_if3(conn==NULL, playername==NULL, msg==NULL)) {
+ return -1;
}
- return result;
-}
-
-void flib_gameconn_onConnect(flib_gameconn *conn, void (*callback)(void* context), void* context) {
- if(!conn) {
- flib_log_e("null parameter in flib_gameconn_onConnect");
- } else {
- conn->onConnectCb = callback ? callback : &defaultCallback_onConnect;
- conn->onConnectCtx = context;
+ uint8_t converted[257];
+ if(!format_chatmessage(converted, playername, msg)
+ && !flib_ipcbase_send_raw(conn->ipcBase, converted, converted[0]+1)) {
+ demo_append(conn, converted, converted[0]+1);
+ return 0;
}
-}
-
-void flib_gameconn_onDisconnect(flib_gameconn *conn, void (*callback)(void* context, int reason), void* context) {
- if(!conn) {
- flib_log_e("null parameter in flib_gameconn_onDisconnect");
- } else {
- conn->onDisconnectCb = callback ? callback : &defaultCallback_onDisconnect;
- conn->onDisconnectCtx = context;
- }
+ return -1;
}
-void flib_gameconn_onErrorMessage(flib_gameconn *conn, void (*callback)(void* context, const char *msg), void* context) {
- if(!conn) {
- flib_log_e("null parameter in flib_gameconn_onErrorMessage");
- } else {
- conn->onErrorMessageCb = callback ? callback : &defaultCallback_onErrorMessage;
- conn->onErrorMessageCtx = context;
+/**
+ * This macro generates a callback setter function. It uses the name of the callback to
+ * automatically generate the function name and the fields to set, so a consistent naming
+ * convention needs to be enforced (not that that is a bad thing). If null is passed as
+ * callback to the generated function, the defaultCb will be set instead (with conn
+ * as the context).
+ */
+#define GENERATE_CB_SETTER(cbName, cbParameterTypes, defaultCb) \
+ void flib_gameconn_##cbName(flib_gameconn *conn, void (*callback)cbParameterTypes, void *context) { \
+ if(!log_badargs_if(conn==NULL)) { \
+ conn->cbName##Cb = callback ? callback : &defaultCb; \
+ conn->cbName##Ctx = callback ? context : conn; \
+ } \
}
-}
-
-void flib_gameconn_onChat(flib_gameconn *conn, void (*callback)(void* context, const char *msg, bool teamchat), void* context) {
- if(!conn) {
- flib_log_e("null parameter in flib_gameconn_onChat");
- } else {
- conn->onChatCb = callback ? callback : &defaultCallback_onChat;
- conn->onChatCtx = context;
- }
-}
-void flib_gameconn_onGameRecorded(flib_gameconn *conn, void (*callback)(void *context, const uint8_t *record, int size, bool isSavegame), void* context) {
- if(!conn) {
- flib_log_e("null parameter in flib_gameconn_onGameRecorded");
- } else {
- conn->onGameRecordedCb = callback ? callback : &defaultCallback_onGameRecorded;
- conn->onGameRecordedCtx = context;
- }
-}
+/**
+ * Generate a callback setter function like GENERATE_CB_SETTER, and automatically generate a
+ * no-op callback function as well that is used as default.
+ */
+#define GENERATE_CB_SETTER_AND_DEFAULT(cbName, cbParameterTypes) \
+ static void _noop_callback_##cbName cbParameterTypes {} \
+ GENERATE_CB_SETTER(cbName, cbParameterTypes, _noop_callback_##cbName)
-void flib_gameconn_onEngineMessage(flib_gameconn *conn, void (*callback)(void *context, const uint8_t *em, size_t size), void* context) {
- if(!conn) {
- flib_log_e("null parameter in flib_gameconn_onEngineMessage");
- } else {
- conn->onEngineMessageCb = callback ? callback : &defaultCallback_onEngineMessage;
- conn->onEngineMessageCtx = context;
- }
-}
+GENERATE_CB_SETTER_AND_DEFAULT(onConnect, (void *context));
+GENERATE_CB_SETTER_AND_DEFAULT(onDisconnect, (void* context, int reason));
+GENERATE_CB_SETTER(onErrorMessage, (void* context, const char *msg), defaultCallback_onErrorMessage);
+GENERATE_CB_SETTER_AND_DEFAULT(onChat, (void* context, const char *msg, bool teamchat));
+GENERATE_CB_SETTER_AND_DEFAULT(onGameRecorded, (void *context, const uint8_t *record, int size, bool isSavegame));
+GENERATE_CB_SETTER_AND_DEFAULT(onEngineMessage, (void *context, const uint8_t *em, size_t size));
+
+#undef GENERATE_CB_SETTER_AND_DEFAULT
+#undef GENERATE_CB_SETTER
static void flib_gameconn_wrappedtick(flib_gameconn *conn) {
if(conn->state == AWAIT_CONNECTION) {
@@ -432,13 +420,9 @@
}
void flib_gameconn_tick(flib_gameconn *conn) {
- if(!conn) {
- flib_log_e("null parameter in flib_gameconn_tick");
- } else if(conn->running) {
- flib_log_w("Call to flib_gameconn_tick from a callback");
- } else if(conn->state == FINISHED) {
- flib_log_w("Call to flib_gameconn_tick, but we are already done.");
- } else {
+ if(!log_badargs_if(conn == NULL)
+ && !log_w_if(conn->running, "Call to flib_gameconn_tick from a callback")
+ && !log_w_if(conn->state == FINISHED, "We are already done.")) {
conn->running = true;
flib_gameconn_wrappedtick(conn);
conn->running = false;
--- a/project_files/frontlib/ipc/gameconn.h Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/ipc/gameconn.h Thu Jul 05 00:33:24 2012 +0200
@@ -31,12 +31,11 @@
#define GAME_END_HALTED 2
#define GAME_END_ERROR 3
-struct _flib_gameconn;
typedef struct _flib_gameconn flib_gameconn;
flib_gameconn *flib_gameconn_create(const char *playerName, const flib_gamesetup *setup, bool netgame);
-flib_gameconn *flib_gameconn_create_playdemo(const uint8_t *demo, int size);
-flib_gameconn *flib_gameconn_create_loadgame(const char *playerName, const uint8_t *save, int size);
+flib_gameconn *flib_gameconn_create_playdemo(const uint8_t *demo, size_t size);
+flib_gameconn *flib_gameconn_create_loadgame(const char *playerName, const uint8_t *save, size_t size);
flib_gameconn *flib_gameconn_create_campaign(const char *playerName, const char *seed, const char *script);
void flib_gameconn_destroy(flib_gameconn *conn);
--- a/project_files/frontlib/ipc/ipcbase.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/ipc/ipcbase.c Thu Jul 05 00:33:24 2012 +0200
@@ -64,8 +64,7 @@
}
uint16_t flib_ipcbase_port(flib_ipcbase *ipc) {
- if(!ipc) {
- flib_log_e("null parameter in flib_ipcbase_port");
+ if(log_badargs_if(ipc==NULL)) {
return 0;
}
return ipc->port;
@@ -80,8 +79,7 @@
}
IpcState flib_ipcbase_state(flib_ipcbase *ipc) {
- if(!ipc) {
- flib_log_e("null parameter in flib_ipcbase_state");
+ if(log_badargs_if(ipc==NULL)) {
return IPC_NOT_CONNECTED;
} else if(ipc->sock) {
return IPC_CONNECTED;
@@ -109,8 +107,7 @@
}
int flib_ipcbase_recv_message(flib_ipcbase *ipc, void *data) {
- if(!ipc || !data) {
- flib_log_e("null parameter in flib_ipcbase_recv_message");
+ if(log_badargs_if2(ipc==NULL, data==NULL)) {
return -1;
}
@@ -134,8 +131,7 @@
}
int flib_ipcbase_recv_map(flib_ipcbase *ipc, void *data) {
- if(!ipc || !data) {
- flib_log_e("null parameter in flib_ipcbase_recv_map");
+ if(log_badargs_if2(ipc==NULL, data==NULL)) {
return -1;
}
@@ -167,15 +163,10 @@
}
int flib_ipcbase_send_raw(flib_ipcbase *ipc, const void *data, size_t len) {
- if(!ipc || (!data && len>0)) {
- flib_log_e("null parameter in flib_ipcbase_send_raw");
+ if(log_badargs_if2(ipc==NULL, data==NULL && len>0)
+ || log_w_if(!ipc->sock, "flib_ipcbase_send_raw: Not connected.")) {
return -1;
}
- if(!ipc->sock) {
- flib_log_w("flib_ipcbase_send_raw: Not connected.");
- return -1;
- }
-
if(flib_socket_send(ipc->sock, data, len) == len) {
logSentMsg(data, len);
return 0;
@@ -188,11 +179,7 @@
}
int flib_ipcbase_send_message(flib_ipcbase *ipc, void *data, size_t len) {
- if(!ipc || (!data && len>0)) {
- flib_log_e("null parameter in flib_ipcbase_send_message");
- return -1;
- } else if(len>255) {
- flib_log_e("Overlong message (%zu bytes) in flib_ipcbase_send_message", len);
+ if(log_badargs_if3(ipc==NULL, data==NULL && len>0, len>255)) {
return -1;
}
@@ -203,9 +190,7 @@
}
void flib_ipcbase_accept(flib_ipcbase *ipc) {
- if(!ipc) {
- flib_log_e("null parameter in flib_ipcbase_accept");
- } else if(!ipc->sock && ipc->acceptor) {
+ if(!log_badargs_if(ipc==NULL) && !ipc->sock && ipc->acceptor) {
ipc->sock = flib_socket_accept(ipc->acceptor, true);
if(ipc->sock) {
flib_acceptor_close(ipc->acceptor);
--- a/project_files/frontlib/ipc/ipcprotocol.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/ipc/ipcprotocol.c Thu Jul 05 00:33:24 2012 +0200
@@ -30,7 +30,7 @@
int flib_ipc_append_message(flib_vector *vec, const char *fmt, ...) {
int result = -1;
- if(!log_badparams_if(!vec || !fmt)) {
+ if(!log_badargs_if2(vec==NULL, fmt==NULL)) {
// 1 byte size prefix, 255 bytes max message length, 1 0-byte for vsnprintf
char msgbuffer[257];
@@ -55,7 +55,7 @@
int flib_ipc_append_mapconf(flib_vector *vec, const flib_map *map, bool mappreview) {
int result = -1;
flib_vector *tempvector = flib_vector_create();
- if(!log_badparams_if(!vec || !map)) {
+ if(!log_badargs_if2(vec==NULL, map==NULL)) {
bool error = false;
if(map->mapgen == MAPGEN_NAMED) {
@@ -103,16 +103,16 @@
}
int flib_ipc_append_seed(flib_vector *vec, const char *seed) {
- if(!log_badparams_if(!vec || !seed)) {
- return flib_ipc_append_message(vec, "eseed %s", seed);
+ if(log_badargs_if2(vec==NULL, seed==NULL)) {
+ return -1;
}
- return -1;
+ return flib_ipc_append_message(vec, "eseed %s", seed);
}
int flib_ipc_append_script(flib_vector *vec, const char *script) {
int result = -1;
char *copy = flib_strdupnull(script);
- if(!log_badparams_if(!vec) && copy) {
+ if(!log_badargs_if(vec==NULL) && copy) {
if(!strcmp("Normal", copy)) {
// "Normal" means no gametype script
result = 0;
@@ -131,7 +131,7 @@
return result;
}
-uint32_t buildModFlags(const flib_cfg *scheme) {
+static uint32_t buildModFlags(const flib_cfg *scheme) {
uint32_t result = 0;
for(int i=0; i<scheme->meta->modCount; i++) {
if(scheme->mods[i]) {
@@ -145,7 +145,7 @@
int flib_ipc_append_gamescheme(flib_vector *vec, const flib_cfg *scheme) {
int result = -1;
flib_vector *tempvector = flib_vector_create();
- if(!log_badparams_if(!vec || !scheme) && tempvector) {
+ if(!log_badargs_if2(vec==NULL, scheme==NULL) && tempvector) {
const flib_cfg_meta *meta = scheme->meta;
bool error = false;
error |= flib_ipc_append_message(tempvector, "e$gmflags %"PRIu32, buildModFlags(scheme));
@@ -182,22 +182,20 @@
}
static void calculateMd5Hex(const char *in, char out[33]) {
- if(!log_badparams_if(!in)) {
- md5_state_t md5state;
- uint8_t md5bytes[16];
- md5_init(&md5state);
- md5_append(&md5state, (unsigned char*)in, strlen(in));
- md5_finish(&md5state, md5bytes);
- for(int i=0;i<sizeof(md5bytes); i++) {
- snprintf(out+i*2, 3, "%02x", (unsigned)md5bytes[i]);
- }
+ md5_state_t md5state;
+ uint8_t md5bytes[16];
+ md5_init(&md5state);
+ md5_append(&md5state, (unsigned char*)in, strlen(in));
+ md5_finish(&md5state, md5bytes);
+ for(int i=0;i<sizeof(md5bytes); i++) {
+ snprintf(out+i*2, 3, "%02x", (unsigned)md5bytes[i]);
}
}
int flib_ipc_append_addteam(flib_vector *vec, const flib_team *team, bool perHogAmmo, bool noAmmoStore) {
int result = -1;
flib_vector *tempvector = flib_vector_create();
- if(!log_badparams_if(!vec || !team) && tempvector) {
+ if(!log_badargs_if2(vec==NULL, team==NULL) && tempvector) {
bool error = false;
if(!perHogAmmo && !noAmmoStore) {
@@ -251,7 +249,7 @@
int flib_ipc_append_fullconfig(flib_vector *vec, const flib_gamesetup *setup, bool netgame) {
int result = -1;
flib_vector *tempvector = flib_vector_create();
- if(!log_badparams_if(!vec || !setup) && tempvector) {
+ if(!log_badargs_if2(vec==NULL, setup==NULL) && tempvector) {
bool error = false;
bool perHogAmmo = false;
bool sharedAmmo = false;
--- a/project_files/frontlib/ipc/mapconn.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/ipc/mapconn.c Thu Jul 05 00:33:24 2012 +0200
@@ -75,6 +75,9 @@
}
flib_mapconn *flib_mapconn_create(const flib_map *mapdesc) {
+ if(log_badargs_if(mapdesc==NULL)) {
+ return NULL;
+ }
flib_mapconn *result = NULL;
flib_mapconn *tempConn = flib_calloc(1, sizeof(flib_mapconn));
if(tempConn) {
@@ -110,27 +113,21 @@
}
int flib_mapconn_getport(flib_mapconn *conn) {
- if(!conn) {
- flib_log_e("null parameter in flib_mapconn_getport");
+ if(log_badargs_if(conn==NULL)) {
return 0;
- } else {
- return flib_ipcbase_port(conn->ipcBase);
}
+ return flib_ipcbase_port(conn->ipcBase);
}
void flib_mapconn_onSuccess(flib_mapconn *conn, void (*callback)(void* context, const uint8_t *bitmap, int numHedgehogs), void *context) {
- if(!conn) {
- flib_log_e("null parameter in flib_mapconn_onSuccess");
- } else {
+ if(!log_badargs_if(conn==NULL)) {
conn->onSuccessCb = callback ? callback : &noop_handleSuccess;
conn->onSuccessCtx = context;
}
}
void flib_mapconn_onFailure(flib_mapconn *conn, void (*callback)(void* context, const char *errormessage), void *context) {
- if(!conn) {
- flib_log_e("null parameter in flib_mapconn_onError");
- } else {
+ if(!log_badargs_if(conn==NULL)) {
conn->onFailureCb = callback ? callback : &noop_handleFailure;
conn->onFailureCtx = context;
}
@@ -175,13 +172,9 @@
}
void flib_mapconn_tick(flib_mapconn *conn) {
- if(!conn) {
- flib_log_e("null parameter in flib_mapconn_tick");
- } else if(conn->running) {
- flib_log_w("Call to flib_mapconn_tick from a callback");
- } else if(conn->progress == FINISHED) {
- flib_log_w("Call to flib_mapconn_tick, but we are already done. Best destroy your flib_mapconn object in the callbacks.");
- } else {
+ if(!log_badargs_if(conn==NULL)
+ && !log_w_if(conn->running, "Call to flib_mapconn_tick from a callback")
+ && !log_w_if(conn->progress == FINISHED, "We are already done.")) {
conn->running = true;
flib_mapconn_wrappedtick(conn);
conn->running = false;
--- a/project_files/frontlib/model/cfg.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/model/cfg.c Thu Jul 05 00:33:24 2012 +0200
@@ -118,8 +118,7 @@
}
flib_cfg_meta *flib_cfg_meta_from_ini(const char *filename) {
- if(!filename) {
- flib_log_e("null parameter in flib_cfg_meta_from_ini");
+ if(log_badargs_if(filename==NULL)) {
return NULL;
}
flib_cfg_meta *result = flib_cfg_meta_retain(flib_calloc(1, sizeof(flib_cfg_meta)));
@@ -168,8 +167,7 @@
flib_cfg *flib_cfg_create(flib_cfg_meta *meta, const char *schemeName) {
flib_cfg *result = flib_cfg_retain(flib_calloc(1, sizeof(flib_cfg)));
- if(!meta || !result || !schemeName) {
- flib_log_e("null parameter in flib_cfg_create");
+ if(log_badargs_if2(meta==NULL, schemeName==NULL) || result==NULL) {
return NULL;
}
@@ -215,21 +213,25 @@
}
bool flib_cfg_get_mod(flib_cfg *cfg, const char *name) {
- for(int i=0; i<cfg->meta->modCount; i++) {
- if(!strcmp(cfg->meta->mods[i].name, name)) {
- return cfg->mods[i];
+ if(!log_badargs_if2(cfg==NULL, name==NULL)) {
+ for(int i=0; i<cfg->meta->modCount; i++) {
+ if(!strcmp(cfg->meta->mods[i].name, name)) {
+ return cfg->mods[i];
+ }
}
+ flib_log_e("Unable to find game mod %s", name);
}
- flib_log_e("Unable to find game mod %s", name);
return false;
}
int flib_cfg_get_setting(flib_cfg *cfg, const char *name, int def) {
- for(int i=0; i<cfg->meta->settingCount; i++) {
- if(!strcmp(cfg->meta->settings[i].name, name)) {
- return cfg->settings[i];
+ if(!log_badargs_if2(cfg==NULL, name==NULL)) {
+ for(int i=0; i<cfg->meta->settingCount; i++) {
+ if(!strcmp(cfg->meta->settings[i].name, name)) {
+ return cfg->settings[i];
+ }
}
+ flib_log_e("Unable to find game setting %s", name);
}
- flib_log_e("Unable to find game setting %s", name);
return def;
}
--- a/project_files/frontlib/model/gamesetup.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/model/gamesetup.c Thu Jul 05 00:33:24 2012 +0200
@@ -18,6 +18,7 @@
*/
#include "gamesetup.h"
+#include "../util/util.h"
#include <stdlib.h>
@@ -30,3 +31,25 @@
free(gamesetup);
}
}
+
+flib_gamesetup *flib_gamesetup_copy(flib_gamesetup *setup) {
+ if(!setup) {
+ return NULL;
+ }
+
+ flib_gamesetup *result = flib_calloc(1, sizeof(flib_gamesetup));
+ if(result) {
+ result->script = flib_strdupnull(setup->script);
+ result->gamescheme = flib_cfg_copy(setup->gamescheme);
+ result->map = flib_map_copy(setup->map);
+ result->teamlist = flib_teamlist_copy(setup->teamlist);
+ if((setup->script && !result->script)
+ || (setup->gamescheme && !result->gamescheme)
+ || (setup->map && !result->map)
+ || (setup->teamlist && !result->teamlist)) {
+ flib_gamesetup_destroy(result);
+ result = NULL;
+ }
+ }
+ return result;
+}
--- a/project_files/frontlib/model/gamesetup.h Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/model/gamesetup.h Thu Jul 05 00:33:24 2012 +0200
@@ -39,4 +39,10 @@
void flib_gamesetup_destroy(flib_gamesetup *gamesetup);
+/**
+ * Deep-copy of the flib_gamesetup. Copies everything except the weaponsets
+ * of the hogs; those are kept as references.
+ */
+flib_gamesetup *flib_gamesetup_copy(flib_gamesetup *gamesetup);
+
#endif
--- a/project_files/frontlib/model/map.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/model/map.c Thu Jul 05 00:33:24 2012 +0200
@@ -37,66 +37,54 @@
}
flib_map *flib_map_create_regular(const char *seed, const char *theme, int templateFilter) {
- flib_map *result = NULL;
- if(!seed || !theme) {
- flib_log_e("null parameter in flib_map_create_regular");
- } else {
- flib_map newmap = {0};
- newmap.mapgen = MAPGEN_REGULAR;
- newmap.name = "+rnd+";
- newmap.seed = (char*)seed;
- newmap.theme = (char*)theme;
- newmap.templateFilter = templateFilter;
- result = flib_map_copy(&newmap);
+ if(log_badargs_if2(seed==NULL, theme==NULL)) {
+ return NULL;
}
- return result;
+ flib_map newmap = {0};
+ newmap.mapgen = MAPGEN_REGULAR;
+ newmap.name = "+rnd+";
+ newmap.seed = (char*)seed;
+ newmap.theme = (char*)theme;
+ newmap.templateFilter = templateFilter;
+ return flib_map_copy(&newmap);
}
flib_map *flib_map_create_maze(const char *seed, const char *theme, int mazeSize) {
- flib_map *result = NULL;
- if(!seed || !theme) {
- flib_log_e("null parameter in flib_map_create_maze");
- } else {
- flib_map newmap = {0};
- newmap.mapgen = MAPGEN_MAZE;
- newmap.name = "+maze+";
- newmap.seed = (char*)seed;
- newmap.theme = (char*)theme;
- newmap.mazeSize = mazeSize;
- result = flib_map_copy(&newmap);
+ if(log_badargs_if2(seed==NULL, theme==NULL)) {
+ return NULL;
}
- return result;
+ flib_map newmap = {0};
+ newmap.mapgen = MAPGEN_MAZE;
+ newmap.name = "+maze+";
+ newmap.seed = (char*)seed;
+ newmap.theme = (char*)theme;
+ newmap.mazeSize = mazeSize;
+ return flib_map_copy(&newmap);
}
flib_map *flib_map_create_named(const char *seed, const char *name) {
- flib_map *result = NULL;
- if(!seed || !name) {
- flib_log_e("null parameter in flib_map_create_named");
- } else {
- flib_map newmap = {0};
- newmap.mapgen = MAPGEN_NAMED;
- newmap.name = (char*)name;
- newmap.seed = (char*)seed;
- result = flib_map_copy(&newmap);
+ if(log_badargs_if2(seed==NULL, name==NULL)) {
+ return NULL;
}
- return result;
+ flib_map newmap = {0};
+ newmap.mapgen = MAPGEN_NAMED;
+ newmap.name = (char*)name;
+ newmap.seed = (char*)seed;
+ return flib_map_copy(&newmap);
}
-flib_map *flib_map_create_drawn(const char *seed, const char *theme, const uint8_t *drawData, int drawDataSize) {
- flib_map *result = NULL;
- if(!seed || !theme || (!drawData && drawDataSize)) {
- flib_log_e("null parameter in flib_map_create_drawn");
- } else {
- flib_map newmap = {0};
- newmap.mapgen = MAPGEN_DRAWN;
- newmap.name = "+drawn+";
- newmap.seed = (char*)seed;
- newmap.theme = (char*)theme;
- newmap.drawData = (uint8_t*) drawData;
- newmap.drawDataSize = drawDataSize;
- result = flib_map_copy(&newmap);
+flib_map *flib_map_create_drawn(const char *seed, const char *theme, const uint8_t *drawData, size_t drawDataSize) {
+ if(log_badargs_if3(seed==NULL, theme==NULL, drawData==NULL && drawDataSize>0)) {
+ return NULL;
}
- return result;
+ flib_map newmap = {0};
+ newmap.mapgen = MAPGEN_DRAWN;
+ newmap.name = "+drawn+";
+ newmap.seed = (char*)seed;
+ newmap.theme = (char*)theme;
+ newmap.drawData = (uint8_t*) drawData;
+ newmap.drawDataSize = drawDataSize;
+ return flib_map_copy(&newmap);
}
flib_map *flib_map_copy(const flib_map *map) {
--- a/project_files/frontlib/model/map.h Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/model/map.h Thu Jul 05 00:33:24 2012 +0200
@@ -20,6 +20,7 @@
#ifndef MODEL_MAP_H_
#define MODEL_MAP_H_
+#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
@@ -57,7 +58,7 @@
char *seed; // Used for all maps
char *theme; // Used for all maps
uint8_t *drawData; // Used for MAPGEN_DRAWN
- int drawDataSize; // Used for MAPGEN_DRAWN
+ int drawDataSize; // Used for MAPGEN_DRAWN TODO size_t
int templateFilter; // Used for MAPGEN_REGULAR
int mazeSize; // Used for MAPGEN_MAZE
} flib_map;
@@ -99,7 +100,7 @@
* Create a hand-drawn map. Use flib_map_destroy to free the returned object.
* No NULL parameters allowed, returns NULL on failure.
*/
-flib_map *flib_map_create_drawn(const char *seed, const char *theme, const uint8_t *drawData, int drawDataSize);
+flib_map *flib_map_create_drawn(const char *seed, const char *theme, const uint8_t *drawData, size_t drawDataSize);
/**
* Create a deep copy of the map. Returns NULL on failure or if NULL was passed.
--- a/project_files/frontlib/model/mapcfg.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/model/mapcfg.c Thu Jul 05 00:33:24 2012 +0200
@@ -38,8 +38,7 @@
int flib_mapcfg_read(const char *dataDirPath, const char *mapname, flib_mapcfg *out) {
int result = -1;
- if(!log_badparams_if(!dataDirPath || !mapname || !out)
- && !log_e_if(flib_contains_dir_separator(mapname), "Illegal character in mapname %s", mapname)) {
+ if(!log_badargs_if4(dataDirPath==NULL, mapname==NULL, out==NULL, flib_contains_dir_separator(mapname))) {
char *path = flib_asprintf("%sMaps/%s/map.cfg", dataDirPath, mapname);
if(path) {
FILE *file = fopen(path, "rb");
--- a/project_files/frontlib/model/roomlist.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/model/roomlist.c Thu Jul 05 00:33:24 2012 +0200
@@ -86,9 +86,7 @@
int flib_roomlist_add(flib_roomlist *list, char **params) {
int result = -1;
- if(!list || !params) {
- flib_log_e("null parameter in flib_roomlist_add");
- } else {
+ if(!log_badargs_if2(list==NULL, params==NULL)) {
flib_room *tmpRoom = fillRoomFromParams(params);
if(tmpRoom) {
if(!insertRoom(&list->rooms, &list->roomCount, tmpRoom, 0)) {
@@ -103,9 +101,7 @@
int flib_roomlist_delete(flib_roomlist *list, const char *name) {
int result = -1;
- if(!list || !name) {
- flib_log_e("null parameter in flib_roomlist_delete");
- } else {
+ if(!log_badargs_if2(list==NULL, name==NULL)) {
int roomid = findRoom(list, name);
if(roomid<0) {
flib_log_w("Attempt to delete unknown room %s", name);
@@ -122,9 +118,7 @@
int flib_roomlist_update(flib_roomlist *list, const char *name, char **params) {
int result = -1;
- if(!list || !name || !params) {
- flib_log_e("null parameter in flib_roomlist_update");
- } else {
+ if(!log_badargs_if3(list==NULL, name==NULL, params==NULL)) {
flib_room *tmpRoom = fillRoomFromParams(params);
int roomid = findRoom(list, name);
if(tmpRoom && roomid>=0) {
@@ -140,9 +134,7 @@
flib_room *flib_roomlist_find(const flib_roomlist *list, const char *name) {
flib_room *result = NULL;
- if(!list || !name) {
- flib_log_e("null parameter in flib_roomlist_find");
- } else {
+ if(!log_badargs_if2(list==NULL, name==NULL)) {
int roomid = findRoom(list, name);
if(roomid>=0) {
result = list->rooms[roomid];
@@ -152,9 +144,7 @@
}
void flib_roomlist_clear(flib_roomlist *list) {
- if(!list) {
- flib_log_e("null parameter in flib_roomlist_clear");
- } else {
+ if(!log_badargs_if(list==NULL)) {
for(int i=0; i<list->roomCount; i++) {
flib_roomlist_room_destroy(list->rooms[i]);
}
--- a/project_files/frontlib/model/schemelist.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/model/schemelist.c Thu Jul 05 00:33:24 2012 +0200
@@ -103,11 +103,11 @@
}
flib_schemelist *flib_schemelist_from_ini(flib_cfg_meta *meta, const char *filename) {
- flib_schemelist *list = NULL;
- if(!meta || !filename) {
- flib_log_e("null parameter in flib_schemelist_from_ini");
+ if(log_badargs_if2(meta==NULL, filename==NULL)) {
return NULL;
}
+
+ flib_schemelist *list = NULL;
flib_ini *ini = flib_ini_load(filename);
if(!ini || flib_ini_enter_section(ini, "schemes")) {
flib_log_e("Missing file or missing section \"schemes\" in file %s.", filename);
@@ -164,9 +164,7 @@
int flib_schemelist_to_ini(const char *filename, const flib_schemelist *schemes) {
int result = -1;
- if(!filename || !schemes) {
- flib_log_e("null parameter in flib_schemelist_to_ini");
- } else {
+ if(!log_badargs_if2(filename==NULL, schemes==NULL)) {
flib_ini *ini = flib_ini_create(NULL);
if(ini && !flib_ini_create_section(ini, "schemes")) {
bool error = false;
@@ -202,7 +200,7 @@
}
flib_cfg *flib_schemelist_find(flib_schemelist *list, const char *name) {
- if(list && name) {
+ if(!log_badargs_if2(list==NULL, name==NULL)) {
for(int i=0; i<list->schemeCount; i++) {
if(!strcmp(name, list->schemes[i]->name)) {
return list->schemes[i];
@@ -216,9 +214,8 @@
GENERATE_STATIC_LIST_DELETE(deleteScheme, flib_cfg*)
int flib_schemelist_insert(flib_schemelist *list, flib_cfg *cfg, int pos) {
- if(!list) {
- flib_log_e("Invalid parameter in flib_schemelist_insert");
- } else if(!insertScheme(&list->schemes, &list->schemeCount, cfg, pos)) {
+ if(!log_badargs_if2(list==NULL, cfg==NULL)
+ && !insertScheme(&list->schemes, &list->schemeCount, cfg, pos)) {
flib_cfg_retain(cfg);
return 0;
}
@@ -226,9 +223,7 @@
}
int flib_schemelist_delete(flib_schemelist *list, int pos) {
- if(!list) {
- flib_log_e("Invalid parameter in flib_schemelist_delete");
- } else {
+ if(!log_badargs_if(list==NULL)) {
flib_cfg *elem = list->schemes[pos];
if(!deleteScheme(&list->schemes, &list->schemeCount, pos)) {
flib_cfg_release(elem);
--- a/project_files/frontlib/model/team.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/model/team.c Thu Jul 05 00:33:24 2012 +0200
@@ -34,14 +34,13 @@
}
flib_team *flib_team_from_ini(const char *filename) {
+ if(log_badargs_if(filename==NULL)) {
+ return NULL;
+ }
+
flib_team *result = flib_team_retain(flib_calloc(1, sizeof(flib_team)));
flib_ini *ini = NULL;
- if(!filename) {
- flib_log_e("null parameter in flib_team_from_ini");
- return from_ini_handleError(result, ini);
- }
-
if(!result) {
return from_ini_handleError(result, ini);
}
@@ -194,9 +193,7 @@
int flib_team_to_ini(const char *filename, const flib_team *team) {
int result = -1;
- if(!filename || !team) {
- flib_log_e("null parameter in flib_team_to_ini");
- } else {
+ if(!log_badargs_if2(filename==NULL, team==NULL)) {
flib_ini *ini = flib_ini_create(filename);
bool error = false;
error |= writeTeamSection(team, ini);
@@ -258,7 +255,7 @@
}
}
-char *strdupWithError(const char *in, bool *error) {
+static char *strdupWithError(const char *in, bool *error) {
char *out = flib_strdupnull(in);
if(in && !out) {
*error = true;
--- a/project_files/frontlib/model/teamlist.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/model/teamlist.c Thu Jul 05 00:33:24 2012 +0200
@@ -53,9 +53,8 @@
}
int flib_teamlist_insert(flib_teamlist *list, flib_team *team, int pos) {
- if(!list || !team) {
- flib_log_e("null parameter in flib_teamlist_insert");
- } else if(!insertTeam(&list->teams, &list->teamCount, team, pos)) {
+ if(!log_badargs_if2(list==NULL, team==NULL)
+ && !insertTeam(&list->teams, &list->teamCount, team, pos)) {
flib_team_retain(team);
return 0;
}
@@ -64,9 +63,7 @@
int flib_teamlist_delete(flib_teamlist *list, const char *name) {
int result = -1;
- if(!list || !name) {
- flib_log_e("null parameter in flib_teamlist_delete");
- } else {
+ if(!log_badargs_if2(list==NULL, name==NULL)) {
int itemid = findTeam(list, name);
if(itemid>=0) {
flib_team *team = list->teams[itemid];
@@ -81,9 +78,7 @@
flib_team *flib_teamlist_find(const flib_teamlist *list, const char *name) {
flib_team *result = NULL;
- if(!list || !name) {
- flib_log_e("null parameter in flib_teamlist_find");
- } else {
+ if(!log_badargs_if2(list==NULL, name==NULL)) {
int itemid = findTeam(list, name);
if(itemid>=0) {
result = list->teams[itemid];
@@ -93,9 +88,7 @@
}
void flib_teamlist_clear(flib_teamlist *list) {
- if(!list) {
- flib_log_e("null parameter in flib_teamlist_clear");
- } else {
+ if(!log_badargs_if(list==NULL)) {
for(int i=0; i<list->teamCount; i++) {
flib_team_release(list->teams[i]);
}
@@ -104,3 +97,27 @@
list->teamCount = 0;
}
}
+
+flib_teamlist *flib_teamlist_copy(flib_teamlist *list) {
+ if(!list) {
+ return NULL;
+ }
+ flib_teamlist *result = flib_teamlist_create();
+ if(result) {
+ bool error = false;
+ for(int i=0; !error && i<list->teamCount; i++) {
+ flib_team *teamcopy = flib_team_copy(list->teams[i]);
+ if(!teamcopy) {
+ error = true;
+ } else {
+ error |= flib_teamlist_insert(result, teamcopy, i);
+ }
+ flib_team_release(teamcopy);
+ }
+ if(error) {
+ flib_teamlist_destroy(result);
+ result = NULL;
+ }
+ }
+ return result;
+}
--- a/project_files/frontlib/model/teamlist.h Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/model/teamlist.h Thu Jul 05 00:33:24 2012 +0200
@@ -52,4 +52,10 @@
*/
void flib_teamlist_clear(flib_teamlist *list);
+/**
+ * Create a copy of the list and all the teams it contains. Weaponsets are not copied, but
+ * kept as references
+ */
+flib_teamlist *flib_teamlist_copy(flib_teamlist *list);
+
#endif
--- a/project_files/frontlib/model/weapon.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/model/weapon.c Thu Jul 05 00:33:24 2012 +0200
@@ -59,9 +59,7 @@
flib_weaponset *flib_weaponset_create(const char *name) {
flib_weaponset *result = NULL;
- if(!name) {
- flib_log_e("null parameter in flib_weaponset_create_str");
- } else {
+ if(!log_badargs_if(name==NULL)) {
flib_weaponset *newSet = flib_weaponset_retain(flib_calloc(1, sizeof(flib_weaponset)));
if(newSet) {
newSet->name = flib_strdupnull(name);
@@ -119,9 +117,7 @@
flib_weaponset *flib_weaponset_from_ammostring(const char *name, const char *ammostring) {
flib_weaponset *result = NULL;
- if(!name || !ammostring) {
- flib_log_e("null parameter in flib_weaponset_from_ammostring");
- } else {
+ if(!log_badargs_if2(name==NULL, ammostring==NULL)) {
result = flib_weaponset_create(name);
if(result) {
int fieldlen = strlen(ammostring)/4;
@@ -164,9 +160,7 @@
flib_weaponsetlist *flib_weaponsetlist_from_ini(const char *filename) {
flib_weaponsetlist *result = NULL;
- if(!filename) {
- flib_log_e("null parameter in flib_weaponsetlist_from_ini");
- } else {
+ if(!log_badargs_if(filename==NULL)) {
flib_ini *ini = flib_ini_load(filename);
if(!ini) {
flib_log_e("Missing file %s.", filename);
@@ -189,7 +183,6 @@
static bool needsEscape(char c) {
return !((c>='0' && c<='9') || (c>='a' && c <='z'));
}
-
static int writeWeaponsetToIni(flib_ini *ini, flib_weaponset *set) {
int result = -1;
@@ -209,9 +202,7 @@
int flib_weaponsetlist_to_ini(const char *filename, const flib_weaponsetlist *list) {
int result = -1;
- if(!filename || !list) {
- flib_log_e("null parameter in flib_weaponsetlist_to_ini");
- } else {
+ if(!log_badargs_if2(filename==NULL, list==NULL)) {
flib_ini *ini = flib_ini_create(NULL);
if(ini && !flib_ini_create_section(ini, "General")) {
bool error = false;
@@ -236,9 +227,8 @@
GENERATE_STATIC_LIST_DELETE(deleteWeaponset, flib_weaponset*)
int flib_weaponsetlist_insert(flib_weaponsetlist *list, flib_weaponset *set, int pos) {
- if(!list) {
- flib_log_e("Invalid parameter in flib_weaponsetlist_insert");
- } else if(!insertWeaponset(&list->weaponsets, &list->weaponsetCount, set, pos)) {
+ if(!log_badargs_if2(list==NULL, set==NULL)
+ && !insertWeaponset(&list->weaponsets, &list->weaponsetCount, set, pos)) {
flib_weaponset_retain(set);
return 0;
}
@@ -246,9 +236,7 @@
}
int flib_weaponsetlist_delete(flib_weaponsetlist *list, int pos) {
- if(!list) {
- flib_log_e("Invalid parameter in flib_weaponsetlist_delete");
- } else {
+ if(!log_badargs_if(list==NULL)) {
flib_weaponset *elem = list->weaponsets[pos];
if(!deleteWeaponset(&list->weaponsets, &list->weaponsetCount, pos)) {
flib_weaponset_release(elem);
--- a/project_files/frontlib/net/netbase.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/net/netbase.c Thu Jul 05 00:33:24 2012 +0200
@@ -36,6 +36,10 @@
};
flib_netbase *flib_netbase_create(const char *server, uint16_t port) {
+ if(log_badargs_if2(server==NULL, port==0)) {
+ return NULL;
+ }
+
flib_netbase *result = NULL;
flib_netbase *newNet = flib_calloc(1, sizeof(flib_netbase));
@@ -62,14 +66,10 @@
}
bool flib_netbase_connected(flib_netbase *net) {
- if(!net) {
- flib_log_e("null parameter in flib_netbase_connected");
- return false;
- } else if(net->sock) {
+ if(!log_badargs_if(net==NULL) && net->sock) {
return true;
- } else {
- return false;
}
+ return false;
}
/**
@@ -135,8 +135,7 @@
}
flib_netmsg *flib_netbase_recv_message(flib_netbase *net) {
- if(!net) {
- flib_log_e("null parameter in flib_netbase_recv_message");
+ if(log_badargs_if(net==NULL)) {
return NULL;
}
@@ -160,8 +159,7 @@
}
int flib_netbase_send_raw(flib_netbase *net, const void *data, size_t len) {
- if(!net || (!data && len>0)) {
- flib_log_e("null parameter in flib_netbase_send_raw");
+ if(log_badargs_if2(net==NULL, data==NULL && len>0)) {
return -1;
}
if(!net->sock) {
@@ -181,8 +179,7 @@
}
int flib_netbase_send_message(flib_netbase *net, flib_netmsg *msg) {
- if(!net || !msg) {
- flib_log_e("null parameter in flib_netbase_send_message");
+ if(log_badargs_if2(net==NULL, msg==NULL)) {
return -1;
}
@@ -209,9 +206,7 @@
int flib_netbase_sendf(flib_netbase *net, const char *format, ...) {
int result = -1;
- if(!net || !format) {
- flib_log_e("null parameter in flib_netbase_sendf");
- } else {
+ if(!log_badargs_if2(net==NULL, format==NULL)) {
va_list argp;
va_start(argp, format);
char *buffer = flib_vasprintf(format, argp);
@@ -247,9 +242,7 @@
int flib_netmsg_append_part(flib_netmsg *msg, const void *part, size_t partlen) {
int result = -1;
- if(!msg) {
- flib_log_e("null parameter in flib_netmsg_append_part");
- } else {
+ if(!log_badargs_if2(msg==NULL, part==NULL && partlen>0)) {
char **newParts = realloc(msg->parts, (msg->partCount+1)*sizeof(*msg->parts));
if(newParts) {
msg->parts = newParts;
--- a/project_files/frontlib/net/netconn.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/net/netconn.c Thu Jul 05 00:33:24 2012 +0200
@@ -36,9 +36,7 @@
flib_netconn *flib_netconn_create(const char *playerName, flib_cfg_meta *metacfg, const char *dataDirPath, const char *host, uint16_t port) {
flib_netconn *result = NULL;
- if(!playerName || !metacfg || !host) {
- flib_log_e("null parameter in flib_netconn_create");
- } else {
+ if(!log_badargs_if3(playerName==NULL, metacfg==NULL, host==NULL)) {
flib_netconn *newConn = flib_calloc(1, sizeof(flib_netconn));
if(newConn) {
newConn->netBase = flib_netbase_create(host, port);
@@ -105,23 +103,17 @@
}
const flib_roomlist *flib_netconn_get_roomlist(flib_netconn *conn) {
- const flib_roomlist *result = NULL;
- if(!conn) {
- flib_log_e("null parameter in flib_netconn_get_roomlist");
- } else {
- result = &conn->roomList;
+ if(!log_badargs_if(conn==NULL)) {
+ return &conn->roomList;
}
- return result;
+ return NULL;
}
bool flib_netconn_is_chief(flib_netconn *conn) {
- bool result = false;
- if(!conn) {
- flib_log_e("null parameter in flib_netconn_is_chief");
- } else if(conn->netconnState == NETCONN_STATE_ROOM || conn->netconnState == NETCONN_STATE_INGAME) {
- result = conn->isChief;
+ if(!log_badargs_if(conn==NULL) && flib_netconn_is_in_room_context(conn)) {
+ return conn->isChief;
}
- return result;
+ return false;
}
void netconn_leaveRoom(flib_netconn *conn) {
@@ -177,35 +169,30 @@
flib_gamesetup *flib_netconn_create_gamesetup(flib_netconn *conn) {
flib_gamesetup *result = NULL;
- if(!conn) {
- flib_log_e("null parameter in flib_netconn_create_gameSetup");
- } else {
+ if(!log_badargs_if(conn==NULL)) {
if(conn->teamlist.teamCount==0 || !conn->scheme || !conn->weaponset) {
- flib_log_e("Incomplete room state to create game setup.");
+ flib_log_e("Incomplete room state");
} else {
- result = flib_calloc(1, sizeof(flib_gamesetup));
- if(result) {
- result->gamescheme = flib_cfg_copy(conn->scheme);
- result->map = flib_map_copy(conn->map);
- result->script = flib_strdupnull(conn->script);
- result->teamlist = flib_teamlist_create();
- for(int i=0; i<conn->teamlist.teamCount; i++) {
- flib_team *copy = flib_team_copy(conn->teamlist.teams[i]);
- if(copy) {
- flib_team_set_weaponset(copy, conn->weaponset);
- flib_team_set_health(copy, flib_cfg_get_setting(conn->scheme, "health", 100));
- flib_teamlist_insert(result->teamlist, copy, result->teamlist->teamCount);
- }
- flib_team_release(copy);
+ flib_gamesetup stackSetup = {0};
+ stackSetup.gamescheme = conn->scheme;
+ stackSetup.map = conn->map;
+ stackSetup.script = conn->script;
+ stackSetup.teamlist = &conn->teamlist;
+ flib_gamesetup *tmpSetup = flib_gamesetup_copy(&stackSetup);
+ if(tmpSetup) {
+ for(int i=0; i<tmpSetup->teamlist->teamCount; i++) {
+ flib_team_set_weaponset(tmpSetup->teamlist->teams[i], conn->weaponset);
+ flib_team_set_health(tmpSetup->teamlist->teams[i], flib_cfg_get_setting(conn->scheme, "health", 100));
}
- if(result->map->mapgen == MAPGEN_NAMED && result->map->name) {
+ if(tmpSetup->map->mapgen == MAPGEN_NAMED && tmpSetup->map->name) {
flib_mapcfg mapcfg;
- if(!flib_mapcfg_read(conn->dataDirPath, result->map->name, &mapcfg)) {
- free(result->map->theme);
- result->map->theme = flib_strdupnull(mapcfg.theme);
+ if(!flib_mapcfg_read(conn->dataDirPath, tmpSetup->map->name, &mapcfg)) {
+ free(tmpSetup->map->theme);
+ tmpSetup->map->theme = flib_strdupnull(mapcfg.theme);
+ } else {
+ flib_log_e("Unable to read map config for map %s", tmpSetup->map->name);
}
}
- // TODO handle errors
}
}
}
@@ -640,13 +627,9 @@
}
void flib_netconn_tick(flib_netconn *conn) {
- if(!conn) {
- flib_log_e("null parameter in flib_netconn_tick");
- } else if(conn->running) {
- flib_log_w("Call to flib_netconn_tick from a callback");
- } else if(conn->netconnState == NETCONN_STATE_DISCONNECTED) {
- flib_log_w("Call to flib_netconn_tick, but we are already done.");
- } else {
+ if(!log_badargs_if(conn==NULL)
+ && !log_w_if(conn->running, "Call to flib_netconn_tick from a callback")
+ && !log_w_if(conn->netconnState == NETCONN_STATE_DISCONNECTED, "We are already done.")) {
conn->running = true;
flib_netconn_wrappedtick(conn);
conn->running = false;
--- a/project_files/frontlib/net/netconn.h Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/net/netconn.h Thu Jul 05 00:33:24 2012 +0200
@@ -36,7 +36,7 @@
#define NETCONN_DISCONNECT_NORMAL 0
#define NETCONN_DISCONNECT_SERVER_TOO_OLD 1
-#define NETCONN_DISCONNECT_AUTH_FAILED 2
+#define NETCONN_DISCONNECT_AUTH_FAILED 2 // TODO can you retry instead?
#define NETCONN_DISCONNECT_INTERNAL_ERROR 100
#define NETCONN_ROOMLEAVE_ABANDONED 0
--- a/project_files/frontlib/net/netconn_callbacks.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/net/netconn_callbacks.c Thu Jul 05 00:33:24 2012 +0200
@@ -102,9 +102,7 @@
*/
#define GENERATE_CB_SETTER(cbName, cbParameterTypes, defaultCb) \
void flib_netconn_##cbName(flib_netconn *conn, void (*callback)cbParameterTypes, void *context) { \
- if(!conn) { \
- flib_log_e("null parameter in flib_netconn_%s", #cbName); \
- } else { \
+ if(!log_badargs_if(conn==NULL)) { \
conn->cbName##Cb = callback ? callback : &defaultCb; \
conn->cbName##Ctx = callback ? context : conn; \
} \
--- a/project_files/frontlib/net/netconn_send.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/net/netconn_send.c Thu Jul 05 00:33:24 2012 +0200
@@ -25,9 +25,11 @@
#include "../md5/md5.h"
#include "../base64/base64.h"
+#include <zlib.h>
+
#include <stdlib.h>
#include <string.h>
-#include <zlib.h>
+#include <limits.h>
// cmdname is always given as literal from functions in this file, so it is never null.
static int sendVoid(flib_netconn *conn, const char *cmdname) {
@@ -39,7 +41,7 @@
// Testing for !*str prevents sending 0-length parameters (they trip up the protocol)
static int sendStr(flib_netconn *conn, const char *cmdname, const char *str) {
- if(log_e_if(!conn || !str || !*str, "Invalid parameter sending %s command", cmdname)) {
+ if(log_e_if(!conn || flib_strempty(str), "Invalid parameter sending %s command", cmdname)) {
return -1;
}
return flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", cmdname, str);
@@ -57,14 +59,14 @@
}
int flib_netconn_send_chat(flib_netconn *conn, const char *chat) {
- if(chat && *chat) {
+ if(!flib_strempty(chat)) {
return sendStr(conn, "CHAT", chat);
}
return 0;
}
int flib_netconn_send_teamchat(flib_netconn *conn, const char *chat) {
- if(chat && *chat) {
+ if(!flib_strempty(chat)) {
return sendStr(conn, "TEAMCHAT", chat);
}
return 0;
@@ -72,7 +74,7 @@
int flib_netconn_send_nick(flib_netconn *conn, const char *nick) {
int result = -1;
- if(!log_badparams_if(!conn || !nick || !*nick)) {
+ if(!log_badargs_if2(conn==NULL, flib_strempty(nick))) {
char *tmpName = flib_strdupnull(nick);
if(tmpName) {
if(!flib_netbase_sendf(conn->netBase, "%s\n%s\n\n", "NICK", nick)) {
@@ -89,7 +91,7 @@
int flib_netconn_send_password(flib_netconn *conn, const char *passwd) {
int result = -1;
- if(!log_badparams_if(!conn || !passwd)) {
+ if(!log_badargs_if2(conn==NULL, passwd==NULL)) {
md5_state_t md5state;
uint8_t md5bytes[16];
char md5hex[33];
@@ -156,10 +158,10 @@
int flib_netconn_send_addTeam(flib_netconn *conn, const flib_team *team) {
int result = -1;
- if(!log_badparams_if(!conn || !team)) {
- bool missingInfo = !team->name || !team->grave || !team->fort || !team->voicepack || !team->flag;
+ if(!log_badargs_if2(conn==NULL, team==NULL)) {
+ bool missingInfo = flib_strempty(team->name) || flib_strempty(team->grave) || flib_strempty(team->fort) || flib_strempty(team->voicepack) || flib_strempty(team->flag);
for(int i=0; i<HEDGEHOGS_PER_TEAM; i++) {
- missingInfo |= !team->hogs[i].name || !team->hogs[i].hat;
+ missingInfo |= flib_strempty(team->hogs[i].name) || flib_strempty(team->hogs[i].hat);
}
if(!log_e_if(missingInfo, "Incomplete team definition")) {
flib_vector *vec = flib_vector_create();
@@ -194,7 +196,7 @@
int flib_netconn_send_engineMessage(flib_netconn *conn, const uint8_t *message, size_t size) {
int result = -1;
- if(!log_badparams_if(!conn || (!message && size>0))) {
+ if(!log_badargs_if2(conn==NULL, message==NULL && size>0)) {
char *base64encout = NULL;
base64_encode_alloc((const char*)message, size, &base64encout);
if(base64encout) {
@@ -206,7 +208,7 @@
}
int flib_netconn_send_teamHogCount(flib_netconn *conn, const char *teamname, int hogcount) {
- if(!log_badparams_if(!conn || !teamname || hogcount<1 || hogcount>HEDGEHOGS_PER_TEAM)
+ if(!log_badargs_if4(conn==NULL, flib_strempty(teamname), hogcount<1, hogcount>HEDGEHOGS_PER_TEAM)
&& !flib_netbase_sendf(conn->netBase, "HH_NUM\n%s\n%i\n\n", teamname, hogcount)) {
if(conn->isChief) {
flib_team *team = flib_teamlist_find(&conn->teamlist, teamname);
@@ -220,7 +222,7 @@
}
int flib_netconn_send_teamColor(flib_netconn *conn, const char *teamname, int colorIndex) {
- if(!log_badparams_if(!conn || !teamname)
+ if(!log_badargs_if2(conn==NULL, flib_strempty(teamname))
&& !flib_netbase_sendf(conn->netBase, "TEAM_COLOR\n%s\n%i\n\n", teamname, colorIndex)) {
if(conn->isChief) {
flib_team *team = flib_teamlist_find(&conn->teamlist, teamname);
@@ -234,7 +236,7 @@
}
int flib_netconn_send_weaponset(flib_netconn *conn, const flib_weaponset *weaponset) {
- if(!log_badparams_if(!conn || !weaponset)) {
+ if(!log_badargs_if3(conn==NULL, weaponset==NULL, flib_strempty(weaponset->name))) {
char ammostring[WEAPONS_COUNT*4+1];
strcpy(ammostring, weaponset->loadout);
strcat(ammostring, weaponset->crateprob);
@@ -251,7 +253,7 @@
}
int flib_netconn_send_map(flib_netconn *conn, const flib_map *map) {
- if(log_badparams_if(!conn || !map)) {
+ if(log_badargs_if2(conn==NULL, map==NULL)) {
return -1;
}
bool error = false;
@@ -348,7 +350,7 @@
int flib_netconn_send_mapDrawdata(flib_netconn *conn, const uint8_t *drawData, size_t size) {
int result = -1;
- if(!log_badparams_if(!conn || (!drawData && size>0) || size>SIZE_MAX/2)) {
+ if(!log_badargs_if3(conn==NULL, drawData==NULL && size>0, size>SIZE_MAX/2)) {
uLongf zippedSize = compressBound(size);
uint8_t *zipped = flib_malloc(zippedSize+4); // 4 extra bytes for header
if(zipped) {
@@ -397,7 +399,7 @@
int flib_netconn_send_scheme(flib_netconn *conn, const flib_cfg *scheme) {
int result = -1;
- if(!log_badparams_if(!conn || !scheme)) {
+ if(!log_badargs_if3(conn==NULL, scheme==NULL, flib_strempty(scheme->name))) {
flib_vector *vec = flib_vector_create();
if(vec) {
bool error = false;
@@ -465,7 +467,7 @@
}
int flib_netconn_send_setServerVar(flib_netconn *conn, const char *name, const char *value) {
- if(log_badparams_if(!conn || !name || !value)) {
+ if(log_badargs_if3(conn==NULL, flib_strempty(name), flib_strempty(value))) {
return -1;
}
return flib_netbase_sendf(conn->netBase, "%s\n%s\n%s\n\n", "SET_SERVER_VAR", name, value);
--- a/project_files/frontlib/test.c.nocompile Wed Jun 27 22:52:19 2012 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,338 +0,0 @@
-/*
- * Hedgewars, a free turn based strategy game
- * Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
- #include "frontlib.h"
-#include "util/logging.h"
-#include "util/buffer.h"
-#include "util/util.h"
-#include "util/list.h"
-#include "model/map.h"
-#include "model/weapon.h"
-#include "model/schemelist.h"
-#include "ipc/mapconn.h"
-#include "ipc/gameconn.h"
-#include "net/netconn.h"
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <assert.h>
-#include <string.h>
-
-// Callback function that will be called when the map is rendered
-static void handleMapSuccess(void *context, const uint8_t *bitmap, int numHedgehogs) {
- printf("Drawing map for %i brave little hogs...", numHedgehogs);
-
- // Draw the map as ASCII art
- for(int y=0; y<MAPIMAGE_HEIGHT; y++) {
- for(int x=0; x<MAPIMAGE_WIDTH; x++) {
- int pixelnum = x + y*MAPIMAGE_WIDTH;
- bool pixel = bitmap[pixelnum>>3] & (1<<(7-(pixelnum&7)));
- printf(pixel ? "#" : " ");
- }
- printf("\n");
- }
-
- // Destroy the connection object (this will end the "tick" loop below)
- flib_mapconn **connptr = context;
- flib_mapconn_destroy(*connptr);
- *connptr = NULL;
-}
-
-static void onDisconnect(void *context, int reason) {
- flib_log_i("Connection closed. Reason: %i", reason);
- flib_gameconn **connptr = context;
- flib_gameconn_destroy(*connptr);
- *connptr = NULL;
-}
-
-static void onGameRecorded(void *context, const uint8_t *record, int size, bool isSavegame) {
- flib_log_i("Writing %s (%i bytes)...", isSavegame ? "savegame" : "demo", size);
- FILE *file = fopen(isSavegame ? "testsave.42.hws" : "testdemo.42.hwd", "wb");
- fwrite(record, 1, size, file);
- fclose(file);
-}
-
-// Callback function that will be called on error
-static void handleMapFailure(void *context, const char *errormessage) {
- flib_log_e("Map rendering failed: %s", errormessage);
-
- // Destroy the connection object (this will end the "tick" loop below)
- flib_mapconn **connptr = context;
- flib_mapconn_destroy(*connptr);
- *connptr = NULL;
-}
-
-static void startEngineMap(int port) {
- char commandbuffer[255];
- const char *enginePath = "C:\\Programmieren\\Hedgewars\\bin";
- const char *configPath = "C:\\Programmieren\\Hedgewars\\share\\hedgewars";
- snprintf(commandbuffer, 255, "start %s\\hwengine.exe %s %i landpreview", enginePath, configPath, port);
- system(commandbuffer);
-}
-
-static void startEngineGame(int port) {
- char commandbuffer[255];
- const char *enginePath = "C:\\Programmieren\\Hedgewars\\bin";
- const char *configPath = "C:\\Programmieren\\Hedgewars\\share\\hedgewars";
- const char *dataPath = "C:\\Programmieren\\Hedgewars\\share\\hedgewars\\Data";
- snprintf(commandbuffer, 255, "start %s\\hwengine.exe %s 1024 768 32 %i 0 0 0 10 10 %s 0 0 TWVkbzQy 0 0 en.txt", enginePath, configPath, port, dataPath);
- flib_log_d("Starting engine with CMD: %s", commandbuffer);
- system(commandbuffer);
-}
-
-void testMapPreview() {
- // Create a map description and check that there was no error
- flib_map *map = flib_map_create_maze("This is the seed value", "Jungle", MAZE_SIZE_SMALL_TUNNELS);
- assert(map);
-
- // Create a new connection to the engine and check that there was no error
- flib_mapconn *mapConnection = flib_mapconn_create(map);
- assert(mapConnection);
-
- // We don't need the map description anymore
- flib_map_release(map);
- map = NULL;
-
- // Register the callback functions
- flib_mapconn_onFailure(mapConnection, &handleMapFailure, &mapConnection);
- flib_mapconn_onSuccess(mapConnection, &handleMapSuccess, &mapConnection);
-
- // Start the engine process and tell it which port the frontlib is listening on
- startEngineMap(flib_mapconn_getport(mapConnection));
-
- // Usually, flib_mapconn_tick will be called in an event loop that runs several
- // times per second. It handles I/O operations and progress, and calls
- // callbacks when something interesting happens.
- while(mapConnection) {
- flib_mapconn_tick(mapConnection);
- }
-}
-
-/*void testGame() {
- flib_cfg_meta *metaconf = flib_cfg_meta_from_ini("metasettings.ini");
- assert(metaconf);
- flib_weaponset *weapons = flib_weaponset_create("Defaultweaps");
- flib_schemelist *schemelist = flib_schemelist_from_ini(metaconf, "schemes.ini");
-
- flib_gamesetup setup;
- setup.gamescheme = flib_schemelist_find(schemelist, "Default");
- setup.map = flib_map_create_maze("asparagus", "Jungle", MAZE_SIZE_MEDIUM_TUNNELS);
- setup.script = NULL;
- setup.teamCount = 2;
- setup.teams = calloc(2, sizeof(flib_team*));
- setup.teams[0] = calloc(1, sizeof(flib_team));
- setup.teams[0]->color = 0xffff0000;
- setup.teams[0]->flag = "australia";
- setup.teams[0]->fort = "Plane";
- setup.teams[0]->grave = "Bone";
- setup.teams[0]->hogsInGame = 2;
- setup.teams[0]->name = "Team Awesome";
- setup.teams[0]->voicepack = "British";
- setup.teams[0]->hogs[0].difficulty = 2;
- setup.teams[0]->hogs[0].hat = "NoHat";
- setup.teams[0]->hogs[0].initialHealth = 100;
- setup.teams[0]->hogs[0].name = "Harry 120";
- setup.teams[0]->hogs[1].difficulty = 2;
- setup.teams[0]->hogs[1].hat = "chef";
- setup.teams[0]->hogs[1].initialHealth = 100;
- setup.teams[0]->hogs[1].name = "Chefkoch";
- setup.teams[1] = flib_team_from_ini("Cave Dwellers.hwt");
- setup.teams[1]->color = 0xFF0000F0;
- setup.teams[1]->hogsInGame = 8;
- flib_team_set_weaponset(setup.teams[0], weapons);
- flib_team_set_weaponset(setup.teams[1], weapons);
- flib_weaponset_release(weapons);
-
- flib_gameconn *gameconn = flib_gameconn_create("Medo42", &setup, false);
- assert(gameconn);
-
- flib_gameconn_onDisconnect(gameconn, &onDisconnect, &gameconn);
- //flib_gameconn_onGameRecorded(gameconn, &onGameRecorded, &gameconn);
-
- startEngineGame(flib_gameconn_getport(gameconn));
-
- while(gameconn) {
- flib_gameconn_tick(gameconn);
- }
-}*/
-
-void testDemo() {
- FILE *demofile = fopen("testdemo.42.hwd", "rb");
- assert(demofile);
- flib_vector *vec = flib_vector_create();
- uint8_t demobuf[512];
- int len;
- while((len=fread(demobuf, 1, 512, demofile))>0) {
- flib_vector_append(vec, demobuf, len);
- }
- fclose(demofile);
- flib_constbuffer constbuf = flib_vector_as_constbuffer(vec);
- flib_gameconn *gameconn = flib_gameconn_create_playdemo(constbuf.data, constbuf.size);
- flib_vector_destroy(vec);
- assert(gameconn);
- flib_gameconn_onDisconnect(gameconn, &onDisconnect, &gameconn);
- flib_gameconn_onGameRecorded(gameconn, &onGameRecorded, &gameconn);
- startEngineGame(flib_gameconn_getport(gameconn));
-
- while(gameconn) {
- flib_gameconn_tick(gameconn);
- }
-}
-
-void testSave() {
- FILE *demofile = fopen("testsave.42.hws", "rb");
- assert(demofile);
- flib_vector *vec = flib_vector_create();
- uint8_t demobuf[512];
- int len;
- while((len=fread(demobuf, 1, 512, demofile))>0) {
- flib_vector_append(vec, demobuf, len);
- }
- fclose(demofile);
- flib_constbuffer constbuf = flib_vector_as_constbuffer(vec);
- flib_gameconn *gameconn = flib_gameconn_create_loadgame("Medo42", constbuf.data, constbuf.size);
- flib_vector_destroy(vec);
- assert(gameconn);
- flib_gameconn_onDisconnect(gameconn, &onDisconnect, &gameconn);
- flib_gameconn_onGameRecorded(gameconn, &onGameRecorded, &gameconn);
- startEngineGame(flib_gameconn_getport(gameconn));
-
- while(gameconn) {
- flib_gameconn_tick(gameconn);
- }
-}
-
-void handleNetDisconnect(void *context, int reason, const char *message) {
- flib_log_i("Disconnected: %s", message);
- flib_netconn_destroy(*(flib_netconn**)context);
- *(flib_netconn**)context = NULL;
-}
-
-void handleNetConnected(void *context) {
- const flib_roomlist *roomlist = flib_netconn_get_roomlist(*(flib_netconn**)context);
- flib_log_i("List of rooms:");
- for(int i=0; i<roomlist->roomCount; i++) {
- flib_roomlist_room *room = roomlist->rooms[i];
- flib_log_i("%1s %20s %20s %2i %2i %20s %20s %20s", room->inProgress ? "X" : " ", room->name, room->owner, room->playerCount, room->teamCount, room->map, room->scheme, room->weapons);
- }
- flib_netconn_send_joinRoom(*(flib_netconn**)context, "frontlib test");
-}
-
-void handleLobbyJoin(void *context, const char *nick) {
- flib_log_i("%s joined", nick);
-}
-
-void handleChat(void *context, const char *nick, const char *msg) {
- flib_log_i("%s: %s", nick, msg);
- if(!memcmp("frontbot ", msg, strlen("frontbot "))) {
- const char *command = msg+strlen("frontbot ");
- if(!memcmp("quit", command, strlen("quit"))) {
- flib_netconn_send_quit(*(flib_netconn**)context, "Yeth Mathter");
- } else if(!memcmp("describe ", command, strlen("describe "))) {
- const char *roomname = command+strlen("describe ");
- const flib_roomlist *roomlist = flib_netconn_get_roomlist(*(flib_netconn**)context);
- flib_roomlist_room *room = flib_roomlist_find((flib_roomlist*)roomlist, roomname);
- if(!room) {
- flib_netconn_send_chat(*(flib_netconn**)context, "Unknown room.");
- } else {
- char *text = flib_asprintf(
- "%s is a room created by %s, where %i players (%i teams) are %s on %s%s, using the %s scheme and %s weaponset.",
- room->name,
- room->owner,
- room->playerCount,
- room->teamCount,
- room->inProgress ? "fighting" : "preparing to fight",
- room->map[0]=='+' ? "" : "the map ",
- !strcmp("+rnd+", room->map) ? "a random map" :
- !strcmp("+maze+", room->map) ? "a random maze" :
- !strcmp("+drawn+", room->map) ? "a hand-drawn map" :
- room->map,
- room->scheme,
- room->weapons);
- if(text) {
- flib_netconn_send_chat(*(flib_netconn**)context, text);
- }
- free(text);
- }
- } else if(!memcmp("join ", command, strlen("join "))) {
- const char *roomname = command+strlen("join ");
- flib_netconn_send_joinRoom(*(flib_netconn**)context, roomname);
- } else if(!memcmp("ready", command, strlen("ready"))) {
- flib_netconn_send_toggleReady(*(flib_netconn**)context);
- }
- }
-}
-
-void handleEnterRoom(void *context, bool isChief) {
- flib_netconn_send_toggleReady(*(flib_netconn**)context);
-}
-
-flib_gameconn *gameconn = NULL;
-
-void emFromNetHandler(void *context, const char *em, int size) {
- flib_gameconn_send_enginemsg(gameconn, (const uint8_t*)em, size);
-}
-
-void emFromEngineHandler(void *context, const uint8_t *em, int size) {
- flib_netconn_send_engineMessage((flib_netconn*)context, em, size);
-}
-
-void handleRunGame(void *context) {
- flib_gamesetup *gamesetup = flib_netconn_create_gameSetup((flib_netconn*)context);
- if(gamesetup) {
- gameconn = flib_gameconn_create("frontbot", gamesetup, true);
- flib_gameconn_onEngineMessage(gameconn, emFromEngineHandler, context);
- flib_gameconn_onDisconnect(gameconn, onDisconnect, &gameconn);
- startEngineGame(flib_gameconn_getport(gameconn));
- }
-}
-
-int main(int argc, char *argv[]) {
- flib_init(0);
- flib_log_setLevel(FLIB_LOGLEVEL_ALL);
-
- //testMapPreview();
- //testDemo();
- //testSave();
- //testGame();
-
- flib_cfg_meta *meta = flib_cfg_meta_from_ini("metasettings.ini");
- assert(meta);
- flib_netconn *conn = flib_netconn_create("frontbot", meta, "140.247.62.101", 46631);
- assert(conn);
- flib_cfg_meta_release(meta);
-
- flib_netconn_onConnected(conn, handleNetConnected, &conn);
- flib_netconn_onDisconnected(conn, handleNetDisconnect, &conn);
- flib_netconn_onLobbyJoin(conn, handleLobbyJoin, &conn);
- flib_netconn_onChat(conn, handleChat, &conn);
- flib_netconn_onEnterRoom(conn, handleEnterRoom, conn);
- flib_netconn_onRunGame(conn, handleRunGame, conn);
- flib_netconn_onEngineMessage(conn, emFromNetHandler, NULL);
-
- while(conn) {
- flib_netconn_tick(conn);
- if(gameconn) {
- flib_gameconn_tick(gameconn);
- }
- }
-
- flib_quit();
- return 0;
-}
--- a/project_files/frontlib/util/buffer.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/util/buffer.c Thu Jul 05 00:33:24 2012 +0200
@@ -79,8 +79,7 @@
}
int flib_vector_resize(flib_vector *vec, size_t newSize) {
- if(!vec) {
- flib_log_e("null parameter in flib_vector_resize");
+ if(log_badargs_if(vec==NULL)) {
return -1;
}
@@ -113,7 +112,7 @@
}
int flib_vector_append(flib_vector *vec, const void *data, size_t len) {
- if(!log_badparams_if(!vec || (!data && len>0))
+ if(!log_badargs_if2(vec==NULL, data==NULL && len>0)
&& !log_oom_if(len > SIZE_MAX-vec->size)) {
size_t oldSize = vec->size;
if(!log_oom_if(flib_vector_resize(vec, vec->size+len))) {
@@ -126,7 +125,7 @@
int flib_vector_appendf(flib_vector *vec, const char *fmt, ...) {
int result = -1;
- if(!log_badparams_if(!vec || !fmt)) {
+ if(!log_badargs_if2(vec==NULL, fmt==NULL)) {
va_list argp;
va_start(argp, fmt);
char *formatted = flib_vasprintf(fmt, argp);
@@ -142,8 +141,7 @@
}
flib_buffer flib_vector_as_buffer(flib_vector *vec) {
- if(!vec) {
- flib_log_e("null parameter in flib_vector_as_buffer");
+ if(log_badargs_if(vec==NULL)) {
flib_buffer result = {NULL, 0};
return result;
} else {
@@ -153,8 +151,7 @@
}
flib_constbuffer flib_vector_as_constbuffer(flib_vector *vec) {
- if(!vec) {
- flib_log_e("null parameter in flib_vector_as_constbuffer");
+ if(log_badargs_if(vec==NULL)) {
flib_constbuffer result = {NULL, 0};
return result;
} else {
@@ -164,8 +161,7 @@
}
void *flib_vector_data(flib_vector *vec) {
- if(!vec) {
- flib_log_e("null parameter in flib_vector_data");
+ if(log_badargs_if(vec==NULL)) {
return NULL;
} else {
return vec->data;
@@ -173,8 +169,7 @@
}
size_t flib_vector_size(flib_vector *vec) {
- if(!vec) {
- flib_log_e("null parameter in flib_vector_size");
+ if(log_badargs_if(vec==NULL)) {
return 0;
} else {
return vec->size;
--- a/project_files/frontlib/util/inihelper.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/util/inihelper.c Thu Jul 05 00:33:24 2012 +0200
@@ -73,9 +73,7 @@
flib_ini *flib_ini_load(const char *filename) {
flib_ini *result = NULL;
- if(!filename) {
- flib_log_e("null parameter in flib_ini_load");
- } else {
+ if(!log_badargs_if(filename==NULL)) {
flib_ini *tmpIni = flib_calloc(1, sizeof(flib_ini));
if(tmpIni) {
tmpIni->inidict = iniparser_load(filename);
@@ -91,9 +89,7 @@
int flib_ini_save(flib_ini *ini, const char *filename) {
int result = INI_ERROR_OTHER;
- if(!ini || !filename) {
- flib_log_e("null parameter in flib_ini_save");
- } else {
+ if(!log_badargs_if2(ini==NULL, filename==NULL)) {
FILE *file = fopen(filename, "wb");
if(!file) {
flib_log_e("Error opening file \"%s\" for writing.", filename);
@@ -125,9 +121,7 @@
free(ini->currentSection);
ini->currentSection = NULL;
}
- if(!ini || !section) {
- flib_log_e("null parameter in flib_ini_enter_section");
- } else {
+ if(!log_badargs_if2(ini==NULL, section==NULL)) {
if(!iniparser_find_entry(ini->inidict, section)) {
result = INI_ERROR_NOTFOUND;
} else {
@@ -145,9 +139,7 @@
int flib_ini_create_section(flib_ini *ini, const char *section) {
int result = INI_ERROR_OTHER;
- if(!ini || !section) {
- flib_log_e("null parameter in flib_ini_create_section");
- } else {
+ if(!log_badargs_if2(ini==NULL, section==NULL)) {
result = flib_ini_enter_section(ini, section);
if(result == INI_ERROR_NOTFOUND) {
if(iniparser_set(ini->inidict, section, NULL)) {
@@ -190,9 +182,7 @@
int flib_ini_get_str_opt(flib_ini *ini, char **outVar, const char *key, const char *def) {
int result = INI_ERROR_OTHER;
- if(!ini || !outVar || !key || !ini->currentSection) {
- flib_log_e("null parameter or no current section in flib_ini_get_str_opt");
- } else {
+ if(!log_badargs_if4(ini==NULL, ini->currentSection==NULL, outVar==NULL, key==NULL)) {
const char *value = findValue(ini->inidict, ini->currentSection, key);
if(!value) {
value = def;
@@ -266,9 +256,7 @@
int flib_ini_set_str(flib_ini *ini, const char *key, const char *value) {
int result = INI_ERROR_OTHER;
- if(!ini || !key || !value || !ini->currentSection) {
- flib_log_e("null parameter or no current section in flib_ini_set_str");
- } else {
+ if(log_badargs_if4(ini==NULL, ini->currentSection==NULL, key==NULL, value==NULL)) {
char *dictKey = createDictKey(ini->currentSection, key);
if(dictKey) {
result = iniparser_set(ini->inidict, dictKey, value);
@@ -293,40 +281,29 @@
}
int flib_ini_get_sectioncount(flib_ini *ini) {
- int result = INI_ERROR_OTHER;
- if(!ini) {
- flib_log_e("null parameter in flib_ini_get_sectioncount");
- } else {
- result = iniparser_getnsec(ini->inidict);
+ if(!log_badargs_if(ini==NULL)) {
+ return iniparser_getnsec(ini->inidict);
}
- return result;
+ return INI_ERROR_OTHER;
}
char *flib_ini_get_sectionname(flib_ini *ini, int number) {
- char *result = NULL;
- if(!ini || number<0) {
- flib_log_e("bad parameter in flib_ini_get_sectionname");
- } else {
- result = flib_strdupnull(iniparser_getsecname(ini->inidict, number));
+ if(!log_badargs_if2(ini==NULL, number<0)) {
+ return flib_strdupnull(iniparser_getsecname(ini->inidict, number));
}
- return result;
+ return NULL;
}
int flib_ini_get_keycount(flib_ini *ini) {
- int result = INI_ERROR_OTHER;
- if(!ini || !ini->currentSection) {
- flib_log_e("null parameter or no current section in flib_ini_get_keycount");
- } else {
- result = iniparser_getsecnkeys(ini->inidict, ini->currentSection);
+ if(!log_badargs_if2(ini==NULL, ini->currentSection==NULL)) {
+ return iniparser_getsecnkeys(ini->inidict, ini->currentSection);
}
- return result;
+ return INI_ERROR_OTHER;
}
char *flib_ini_get_keyname(flib_ini *ini, int number) {
char *result = NULL;
- if(!ini || number<0 || !ini->currentSection) {
- flib_log_e("bad parameter or no current section in flib_ini_get_keyname");
- } else {
+ if(!log_badargs_if3(ini==NULL, ini->currentSection==NULL, number<0)) {
int keyCount = iniparser_getsecnkeys(ini->inidict, ini->currentSection);
char **keys = iniparser_getseckeys(ini->inidict, ini->currentSection);
if(keys && keyCount>number) {
--- a/project_files/frontlib/util/list.h Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/util/list.h Thu Jul 05 00:33:24 2012 +0200
@@ -40,9 +40,7 @@
#define GENERATE_STATIC_LIST_INSERT(fname, type) \
static int fname(type **listptr, int *listSizePtr, type element, int pos) { \
int result = -1; \
- if(!listptr || !listSizePtr || pos < 0 || pos > *listSizePtr) { \
- flib_log_e("Invalid parameter in "#fname); \
- } else { \
+ if(!log_badargs_if4(listptr==NULL, listSizePtr==NULL, pos < 0, pos > *listSizePtr)) { \
type *newList = flib_realloc(*listptr, ((*listSizePtr)+1)*sizeof(type)); \
if(newList) { \
memmove(newList + (pos+1), newList + pos, ((*listSizePtr)-pos)*sizeof(type)); \
@@ -65,9 +63,7 @@
#define GENERATE_STATIC_LIST_DELETE(fname, type) \
static int fname(type **listPtr, int *listSizePtr, int pos) { \
int result = -1; \
- if(!listPtr || !listSizePtr || pos < 0 || pos >= *listSizePtr) { \
- flib_log_e("Invalid parameter in "#fname); \
- } else { \
+ if(!log_badargs_if4(listPtr==NULL, listSizePtr==NULL, pos < 0, pos >= *listSizePtr)) { \
memmove((*listPtr) + pos, (*listPtr) + (pos+1), ((*listSizePtr)-(pos+1))*sizeof(type)); \
(*listSizePtr)--; \
\
--- a/project_files/frontlib/util/logging.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/util/logging.c Thu Jul 05 00:33:24 2012 +0200
@@ -92,10 +92,6 @@
return !cond;
}
-bool _flib_assert_params(const char *func, bool cond) {
- return _flib_fassert(func, FLIB_LOGLEVEL_ERROR, cond, "Invalid parameter to function");
-}
-
int flib_log_getLevel() {
return flib_loglevel;
}
--- a/project_files/frontlib/util/logging.h Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/util/logging.h Thu Jul 05 00:33:24 2012 +0200
@@ -44,9 +44,31 @@
#define log_w_if(cond, ...) _flib_fassert(__func__, FLIB_LOGLEVEL_WARNING, !(bool)(cond), __VA_ARGS__)
/**
- * Shorthand for some common error types
+ * Helper macros for log_badargs_if
+ * The t parameters are the textual representation of the c parameters. They need to be passed
+ * explicitly, to prevent them from being expanded in prescan.
*/
-#define log_badparams_if(cond) log_e_if(cond, "Invalid Parameters")
+#define _flib_lbi(c1,t1) log_e_if(c1, "Invalid Argument (%s)", t1)
+#define _flib_lbi2(c1,t1,c2,t2) (_flib_lbi(c1,t1) || _flib_lbi(c2,t2))
+#define _flib_lbi3(c1,t1,c2,t2,c3,t3) (_flib_lbi(c1,t1) || _flib_lbi2(c2,t2,c3,t3))
+#define _flib_lbi4(c1,t1,c2,t2,c3,t3,c4,t4) (_flib_lbi(c1,t1) || _flib_lbi3(c2,t2,c3,t3,c4,t4))
+#define _flib_lbi5(c1,t1,c2,t2,c3,t3,c4,t4,c5,t5) (_flib_lbi(c1,t1) || _flib_lbi4(c2,t2,c3,t3,c4,t4,c5,t5))
+#define _flib_lbi6(c1,t1,c2,t2,c3,t3,c4,t4,c5,t5,c6,t6) (_flib_lbi(c1,t1) || _flib_lbi5(c2,t2,c3,t3,c4,t4,c5,t5,c6,t6))
+
+/**
+ * These macros log an "Invalid Argument" error for the first of their arguments that evaluates to true.
+ * The text of the argument is included in the log message.
+ * The expression returns true if any of its arguments is true (i.e. if an argument error was logged).
+ *
+ * For example, log_badargs_if(x==NULL) will log "Invalid Argument (x==NULL)" and return true if x is NULL.
+ */
+#define log_badargs_if(c1) _flib_lbi(c1,#c1)
+#define log_badargs_if2(c1, c2) _flib_lbi2(c1,#c1,c2,#c2)
+#define log_badargs_if3(c1, c2, c3) _flib_lbi3(c1,#c1,c2,#c2,c3,#c3)
+#define log_badargs_if4(c1, c2, c3, c4) _flib_lbi4(c1,#c1,c2,#c2,c3,#c3,c4,#c4)
+#define log_badargs_if5(c1, c2, c3, c4, c5) _flib_lbi5(c1,#c1,c2,#c2,c3,#c3,c4,#c4,c5,#c5)
+#define log_badargs_if6(c1, c2, c3, c4, c5, c6) _flib_lbi6(c1,#c1,c2,#c2,c3,#c3,c4,#c4,c5,#c5,c6,#c6)
+
#define log_oom_if(cond) log_e_if(cond, "Out of Memory")
#define flib_log_e(...) _flib_flog(__func__, FLIB_LOGLEVEL_ERROR, __VA_ARGS__)
@@ -54,7 +76,6 @@
#define flib_log_i(...) _flib_flog(__func__, FLIB_LOGLEVEL_INFO, __VA_ARGS__)
#define flib_log_d(...) _flib_flog(__func__, FLIB_LOGLEVEL_DEBUG, __VA_ARGS__)
-bool _flib_assert_params(const char *func, bool cond);
bool _flib_fassert(const char *func, int level, bool cond, const char *fmt, ...);
void _flib_flog(const char *func, int level, const char *fmt, ...);
--- a/project_files/frontlib/util/refcounter.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/util/refcounter.c Thu Jul 05 00:33:24 2012 +0200
@@ -22,9 +22,7 @@
#include "logging.h"
void flib_retain(int *referenceCountPtr, const char *objName) {
- if(!referenceCountPtr || !objName) {
- flib_log_e("null parameter to flib_retain");
- } else {
+ if(!log_badargs_if2(referenceCountPtr==NULL, objName==NULL)) {
if((*referenceCountPtr) >= 0) {
(*referenceCountPtr)++;
flib_log_d("retaining %s, now %i references", objName, (*referenceCountPtr));
@@ -40,17 +38,17 @@
*/
bool flib_release(int *referenceCountPtr, const char *objName) {
bool result = false;
- if(!referenceCountPtr) {
- flib_log_e("null parameter to flib_release");
- } else if((*referenceCountPtr) > 0) {
- if(--(*referenceCountPtr) == 0) {
- flib_log_d("releasing and destroying %s", objName);
- result = true;
- } else {
- flib_log_d("releasing %s, now %i references", objName, (*referenceCountPtr));
+ if(!log_badargs_if2(referenceCountPtr==NULL, objName==NULL)) {
+ if((*referenceCountPtr) > 0) {
+ if(--(*referenceCountPtr) == 0) {
+ flib_log_d("releasing and destroying %s", objName);
+ result = true;
+ } else {
+ flib_log_d("releasing %s, now %i references", objName, *referenceCountPtr);
+ }
+ } else if((*referenceCountPtr) == 0) {
+ flib_log_e("Attempt to release a %s with zero references!", objName);
}
- } else if((*referenceCountPtr) == 0) {
- flib_log_e("Attempt to release a %s with zero references!", objName);
}
return result;
}
--- a/project_files/frontlib/util/util.c Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/util/util.c Thu Jul 05 00:33:24 2012 +0200
@@ -26,6 +26,7 @@
#include <string.h>
#include <stdio.h>
#include <ctype.h>
+#include <limits.h>
char *flib_asprintf(const char *fmt, ...) {
va_list argp;
@@ -37,13 +38,9 @@
char *flib_vasprintf(const char *fmt, va_list args) {
char *result = NULL;
- if(!fmt) {
- flib_log_e("null parameter in flib_vasprintf");
- } else {
+ if(!log_badargs_if(fmt==NULL)) {
int requiredSize = vsnprintf(NULL, 0, fmt, args)+1; // Figure out how much memory we need,
- if(requiredSize<0) {
- flib_log_e("Error formatting string with template \"%s\" in flib_vasprintf", fmt);
- } else {
+ if(!log_e_if(requiredSize<0, "Error formatting string with template \"%s\"", fmt)) {
char *tmpbuf = flib_malloc(requiredSize); // allocate it
if(tmpbuf && vsnprintf(tmpbuf, requiredSize, fmt, args)>=0) { // and then do the actual formatting.
result = tmpbuf;
@@ -56,41 +53,41 @@
}
char *flib_join(char **parts, int partCount, const char *delimiter) {
- size_t totalSize = 1;
- size_t delimLen = strlen(delimiter);
- for(int i=0; i<partCount; i++) {
- totalSize += strlen(parts[i]) + delimLen;
- }
+ char *result = NULL;
+ if(!log_badargs_if2(parts==NULL, delimiter==NULL)) {
+ size_t totalSize = 1;
+ size_t delimLen = strlen(delimiter);
+ for(int i=0; i<partCount; i++) {
+ totalSize += strlen(parts[i]) + delimLen;
+ }
+ result = flib_malloc(totalSize);
- char *result = flib_malloc(totalSize);
- if(result) {
- size_t outpos = 0;
- for(int i=0; i<partCount; i++) {
- if(i>0) {
- strcpy(result+outpos, delimiter);
- outpos += delimLen;
+ if(result) {
+ size_t outpos = 0;
+ for(int i=0; i<partCount; i++) {
+ if(i>0) {
+ strcpy(result+outpos, delimiter);
+ outpos += delimLen;
+ }
+ strcpy(result+outpos, parts[i]);
+ outpos += strlen(parts[i]);
}
- strcpy(result+outpos, parts[i]);
- outpos += strlen(parts[i]);
}
}
return result;
}
char *flib_strdupnull(const char *str) {
- if(!str) {
- return NULL;
- }
- return flib_asprintf("%s", str);
+ return str==NULL ? NULL : flib_asprintf("%s", str);
}
void *flib_bufdupnull(const void *buf, size_t size) {
- if(!buf || size==0) {
- return NULL;
- }
- void *result = flib_malloc(size);
- if(result) {
- memcpy(result, buf, size);
+ void *result = NULL;
+ if(!log_badargs_if(buf==NULL && size>0)) {
+ result = flib_malloc(size);
+ if(result) {
+ memcpy(result, buf, size);
+ }
}
return result;
}
@@ -127,41 +124,45 @@
return flib_urlencode_pred(inbuf, isAsciiAlnum);
}
+static size_t countCharsToEscape(const char *inbuf, bool (*needsEscaping)(char c)) {
+ size_t result = 0;
+ for(const char *c=inbuf; *c; c++) {
+ if(needsEscaping(*c)) {
+ result++;
+ }
+ }
+ return result;
+}
+
char *flib_urlencode_pred(const char *inbuf, bool (*needsEscaping)(char c)) {
+ char *result = NULL;
+ if(inbuf && !log_badargs_if(needsEscaping == NULL)) {
+ size_t insize = strlen(inbuf);
+ if(!log_e_if(insize > SIZE_MAX/4, "String too long: %zu bytes.", insize)) {
+ size_t escapeCount = countCharsToEscape(inbuf, needsEscaping);
+ result = flib_malloc(insize + escapeCount*2 + 1);
+ }
+ if(result) {
+ char *out = result;
+ for(const char *in = inbuf; *in; in++) {
+ if(!needsEscaping(*in)) {
+ *out = *in;
+ out++;
+ } else {
+ snprintf(out, 4, "%%%02x", (unsigned)(*(uint8_t*)in));
+ out += 3;
+ }
+ }
+ *out = 0;
+ }
+ }
+ return result;
+}
+
+char *flib_urldecode(const char *inbuf) {
if(!inbuf) {
return NULL;
}
- size_t insize = strlen(inbuf);
- if(insize > SIZE_MAX/4) {
- flib_log_e("String too long in flib_urlencode: %zu bytes.", insize);
- return NULL;
- }
-
- char *outbuf = flib_malloc(insize*3+1);
- if(!outbuf) {
- return NULL;
- }
-
- size_t inpos = 0, outpos = 0;
- while(inbuf[inpos]) {
- if(!needsEscaping(inbuf[inpos])) {
- outbuf[outpos++] = inbuf[inpos++];
- } else {
- if(snprintf(outbuf+outpos, 4, "%%%02X", (unsigned)((uint8_t*)inbuf)[inpos])<0) {
- flib_log_e("printf error in flib_urlencode");
- free(outbuf);
- return NULL;
- }
- inpos++;
- outpos += 3;
- }
- }
- outbuf[outpos] = 0;
- char *shrunk = realloc(outbuf, outpos+1);
- return shrunk ? shrunk : outbuf;
-}
-
-char *flib_urldecode(const char *inbuf) {
char *outbuf = flib_malloc(strlen(inbuf)+1);
if(!outbuf) {
return NULL;
@@ -183,7 +184,7 @@
}
bool flib_contains_dir_separator(const char *str) {
- if(!log_badparams_if(!str)) {
+ if(!log_badargs_if(!str)) {
for(;*str;str++) {
if(*str=='\\' || *str=='/') {
return true;
@@ -193,6 +194,10 @@
return false;
}
+bool flib_strempty(const char *str) {
+ return !str || !*str;
+}
+
int flib_gets(char *str, size_t strlen) {
if(fgets(str, strlen, stdin)) {
for(char *s=str; *s; s++) {
--- a/project_files/frontlib/util/util.h Wed Jun 27 22:52:19 2012 +0200
+++ b/project_files/frontlib/util/util.h Thu Jul 05 00:33:24 2012 +0200
@@ -112,6 +112,11 @@
*/
bool flib_contains_dir_separator(const char *str);
+/**
+ * Returns true if str is either NULL or points to a 0-length string
+ */
+bool flib_strempty(const char *str);
+
int flib_gets(char *str, size_t strlen);
#endif