# HG changeset patch # User Medo # Date 1341441204 -7200 # Node ID f7b49b2c5d842e78a4d16942946b42be11360aa9 # Parent 6171f0bad318c730a0ccf2c361266eb37033f591 frontlib: Improved and unified parameter checking, moved the cmdlineClient out of the frontlib code. diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/base64/base64.c --- 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 . - * - * 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 - -/* Get UCHAR_MAX. */ -#include - -/* 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 . */ + +/* 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 . + * + * 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 + +/* Get UCHAR_MAX. */ +#include + +#include + +/* 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; +} diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/base64/base64.h --- 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 - -/* Get bool. */ -# include - -/* 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 . */ + +#ifndef BASE64_H +# define BASE64_H + +/* Get size_t. */ +# include + +/* Get bool. */ +# include + +/* 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 */ diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/cmdlineClient.c --- 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 - * - * 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 -#include -#include -#include -#include -#include - -#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>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; iroomCount; 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; iteamlist->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 ."); - printf(" You can also /quit or let me /describe . Once in a room, you can /add 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; -} diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/frontlib.c --- 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 #include -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(); - } } diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/frontlib.h --- 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 /** diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/ipc/gameconn.c --- 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; diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/ipc/gameconn.h --- 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); diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/ipc/ipcbase.c --- 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); diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/ipc/ipcprotocol.c --- 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; imeta->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;iipcBase); } + 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; diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/model/cfg.c --- 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; imeta->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; imeta->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; imeta->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; imeta->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; } diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/model/gamesetup.c --- 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 @@ -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; +} diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/model/gamesetup.h --- 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 diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/model/map.c --- 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) { diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/model/map.h --- 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 #include #include @@ -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. diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/model/mapcfg.c --- 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"); diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/model/roomlist.c --- 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; iroomCount; i++) { flib_roomlist_room_destroy(list->rooms[i]); } diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/model/schemelist.c --- 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; ischemeCount; 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); diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/model/team.c --- 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; diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/model/teamlist.c --- 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; iteamCount; 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 && iteamCount; 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; +} diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/model/teamlist.h --- 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 diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/model/weapon.c --- 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); diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/net/netbase.c --- 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; diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/net/netconn.c --- 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; iteamlist.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; iteamlist->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; diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/net/netconn.h --- 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 diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/net/netconn_callbacks.c --- 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; \ } \ diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/net/netconn_send.c --- 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 + #include #include -#include +#include // 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; ihogs[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); diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/test.c.nocompile --- 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 - * - * 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 -#include -#include -#include - -// 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>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; iroomCount; 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; -} diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/util/buffer.c --- 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; diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/util/inihelper.c --- 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) { diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/util/list.h --- 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)--; \ \ diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/util/logging.c --- 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; } diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/util/logging.h --- 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, ...); diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/util/refcounter.c --- 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; } diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/util/util.c --- 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 #include #include +#include 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; i0) { - strcpy(result+outpos, delimiter); - outpos += delimLen; + if(result) { + size_t outpos = 0; + for(int i=0; i0) { + 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++) { diff -r 6171f0bad318 -r f7b49b2c5d84 project_files/frontlib/util/util.h --- 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