1 /**
2  * @file
3  */
4 
5 /*
6 All original material Copyright (C) 2002-2013 UFO: Alien Invasion.
7 
8 Copyright (C) 1997-2001 Id Software, Inc.
9 
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2
13 of the License, or (at your option) any later version.
14 
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 
19 See the GNU General Public License for more details.
20 
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24 */
25 
26 #pragma once
27 
28 #ifdef HAVE_CONFIG_H
29 # ifdef ANDROID
30 #  include "../ports/android/config_android.h"
31 # else
32 #  include "../../config.h"
33 # endif
34 #endif
35 
36 #define MAX_VAR     64
37 
38 #include <errno.h>
39 #include <assert.h>
40 #include <math.h>
41 #include <stdio.h>
42 #include <stdarg.h>
43 #include <string.h>
44 #include <stdlib.h>
45 #include <time.h>
46 #include <ctype.h>
47 #include <limits.h>
48 #include <stddef.h>
49 #include "ufotypes.h"	/* needed for Com_sprintf */
50 #include <algorithm>
51 
52 #include "sharedptr.h"
53 #include "autoptr.h"
54 #include "cxx.h"
55 
56 /* to support the gnuc __attribute__ command */
57 #if defined __ICC || !defined __GNUC__
58 #  define __attribute__(x)  /*NOTHING*/
59 #endif
60 
61 #if defined(__GNUC__)
62 #define UFO_DEPRECATED __attribute__ ((deprecated))
63 #else
64 #define UFO_DEPRECATED
65 #endif
66 
67 #ifdef _WIN32
68 # ifndef snprintf
69 #  define snprintf _snprintf
70 # endif
71 # define EXPORT
72 # define IMPORT
73 #else
74 # define EXPORT
75 # define IMPORT
76 #endif
77 
78 #if !defined __cplusplus && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L)
79 /* if we are using ansi - the compiler doesn't know about inline */
80 #  if defined __GNUC__
81 #    define inline __inline__
82 #  elif defined _MSVC
83 #    define inline __inline
84 #  else
85 #    define inline
86 #  endif
87 #endif
88 
89 #define STRINGIFY(x) #x
90 #define DOUBLEQUOTE(x) STRINGIFY(x)
91 
92 const char* Com_SkipPath(const char* pathname);
93 void Com_ReplaceFilename(const char* fileName, const char* name, char* path, size_t size);
94 void Com_StripExtension(const char* in, char* out, size_t size);
95 void Com_FilePath(const char* in, char* out, size_t size);
96 const char* Com_GetExtension(const char* path);
97 void Com_DefaultExtension(char* path, size_t len, const char* extension);
98 int Com_Filter(const char* pattern, const char* text);
99 char* Com_Trim(char* s);
100 char* Com_ConvertToASCII7(char* s);
101 char* Com_Chop(char* s);
102 bool Com_IsValidName(const char* input);
103 
104 /** returns the amount of elements - not the amount of bytes */
105 #define lengthof(x) (sizeof(x) / sizeof(*(x)))
106 #define endof(x)    ((x) + lengthof((x)))
107 #define CASSERT(x) extern int ASSERT_COMPILE[((x) != 0) * 2 - 1]
108 
109 const char* va(const char* format, ...) __attribute__((format(__printf__, 1, 2)));
110 int Q_FloatSort(const void* float1, const void* float2);
111 int Q_StringSort(const void* string1, const void* string2) __attribute__((nonnull));
112 
113 unsigned int Com_HashKey(const char* name, int hashsize);
114 void Com_MakeTimestamp(char* ts, const size_t tslen);
115 bool Com_sprintf(char* dest, size_t size, const char* fmt, ...) __attribute__((format(__printf__, 3, 4)));
116 
117 /** @todo is this still the case in most recent mingw versions? */
118 #if defined(__MINGW32_VERSION) && defined(__STRICT_ANSI__)
119 /* function exists but are not defined */
120 _CRTIMP char* __cdecl	strdup (const char*) __MINGW_ATTRIB_MALLOC;
121 _CRTIMP int __cdecl	_stricmp (const char*, const char*);
122 _CRTIMP int __cdecl	_strnicmp (const char*, const char*, size_t);
123 #define strncasecmp _strnicmp
124 #endif
125 
126 /* portable case sensitive compare */
127 #if defined(_WIN32)
128 #	define Q_strcasecmp(a, b) _stricmp((a), (b))
129 #	define Q_strncasecmp(s1, s2, n) _strnicmp((s1), (s2), (n))
130 #else
131 #	define Q_strcasecmp(a, b) strcasecmp((a), (b))
132 #	define Q_strncasecmp(s1, s2, n) strncasecmp((s1), (s2), (n))
133 #endif
134 
135 #define Q_strcaseeq(a, b) (Q_strcasecmp(a, b) == 0)
136 #define Q_streq(a, b) (strcmp(a, b) == 0)
Q_strnull(const char * string)137 inline bool Q_strnull (const char* string) {
138 	return string == nullptr || string[0] == '\0';
139 }
140 #define Q_strvalid(string) !Q_strnull(string)
141 
142 #ifndef DEBUG
143 void Q_strncpyz(char* dest, const char* src, size_t destsize) __attribute__((nonnull));
144 #else
145 #define Q_strncpyz(string1,string2,length) Q_strncpyzDebug( string1, string2, length, __FILE__, __LINE__ )
146 void Q_strncpyzDebug(char* dest, const char* src, size_t destsize, const char* file, int line) __attribute__((nonnull));
147 #endif
148 
149 int Q_vsnprintf(char* str, size_t size, const char* format, va_list ap);
150 void Q_strcat(char* dest, size_t destsize, const char* src, ...) __attribute__((nonnull, format(__printf__, 3, 4)));
151 char* Q_strlwr(char* str) __attribute__((nonnull));
152 const char* Q_stristr(const char* str, const char* substr) __attribute__((nonnull));
153 
154 /**
155  * @brief Replaces the first occurence of the given pattern in the source string with the given replace string.
156  * @param source The source string
157  * @param pattern The pattern that should be replaced
158  * @param replace The replacement string
159  * @param dest The target buffer
160  * @param destsize The size of the target buffer
161  * @note If this function returns @c false, the target string might be in an undefined stage. E.g. don't
162  * rely on it being 0-terminated.
163  * @return @c false if the pattern wasn't found or the target buffer is to small to store the resulting
164  * string, @c if the replacement was successful.
165  */
166 bool Q_strreplace(const char* source, const char* pattern, const char* replace, char* dest, size_t destsize);
167 
168 /** Returns a pointer just past the prefix in str, if start is a prefix of str,
169  * otherwise a null pointer is returned */
170 char const* Q_strstart(char const* str, char const* start) __attribute__((nonnull));
171 
172 void Com_Printf(const char* fmt, ...) __attribute__((format(__printf__, 1, 2)));
173 void Com_DPrintf(int level, const char* msg, ...) __attribute__((format(__printf__, 2, 3)));
174 void Com_Error(int code, const char* fmt, ...) __attribute__((noreturn, format(__printf__, 2, 3)));
175 
176 #define OBJSET(obj, val) (memset(&(obj), (val), sizeof(obj)))
177 #define OBJZERO(obj)     OBJSET((obj), 0)
178 
179 #ifdef NDEBUG
180 #define UFO_assert(condition, ...)
181 #else
182 void UFO_assert(bool condition, const char* fmt, ...) __attribute__((format(__printf__, 2, 3)));
183 #endif
184