shared.c

Go to the documentation of this file.
00001 
00006 /*
00007 All original material Copyright (C) 2002-2010 UFO: Alien Invasion.
00008 
00009 Copyright (C) 1997-2001 Id Software, Inc.
00010 
00011 This program is free software; you can redistribute it and/or
00012 modify it under the terms of the GNU General Public License
00013 as published by the Free Software Foundation; either version 2
00014 of the License, or (at your option) any later version.
00015 
00016 This program is distributed in the hope that it will be useful,
00017 but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00019 
00020 See the GNU General Public License for more details.
00021 
00022 You should have received a copy of the GNU General Public License
00023 along with this program; if not, write to the Free Software
00024 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00025 
00026 */
00027 
00028 #include "../common/common.h"
00029 #include "utf8.h"
00030 
00035 const char *Com_SkipPath (const char *pathname)
00036 {
00037     char const* const last = strrchr(pathname, '/');
00038     return last ? last + 1 : pathname;
00039 }
00040 
00041 char *Com_Trim (char *s)
00042 {
00043     char *left, *right;
00044 
00045     left = s;
00046 
00047     while (isspace(*left))
00048         left++;
00049 
00050     right = left + strlen(left) - 1;
00051 
00052     while (isspace(*right))
00053         *right-- = 0;
00054 
00055     return left;
00056 }
00057 
00061 static int Com_FilterAfterStar (const char *pattern, const char *text)
00062 {
00063     register const char *p = pattern, *t = text;
00064     register char c, c1;
00065 
00066     while ((c = *p++) == '?' || c == '*')
00067         if (c == '?' && *t++ == '\0')
00068             return 0;
00069 
00070     if (c == '\0')
00071         return 1;
00072 
00073     if (c == '\\')
00074         c1 = *p;
00075     else
00076         c1 = c;
00077 
00078     while (1) {
00079         if ((c == '[' || *t == c1) && Com_Filter(p - 1, t))
00080             return 1;
00081         if (*t++ == '\0')
00082             return 0;
00083     }
00084 }
00085 
00100 int Com_Filter (const char *pattern, const char *text)
00101 {
00102     register const char *p = pattern, *t = text;
00103     register char c;
00104 
00105     while ((c = *p++) != '\0')
00106         switch (c) {
00107         case '?':
00108             if (*t == '\0')
00109                 return 0;
00110             else
00111                 ++t;
00112             break;
00113 
00114         case '\\':
00115             if (*p++ != *t++)
00116                 return 0;
00117             break;
00118 
00119         case '*':
00120             return Com_FilterAfterStar(p, t);
00121 
00122         case '[':
00123             {
00124                 register char c1 = *t++;
00125                 int invert;
00126 
00127                 if (!c1)
00128                     return (0);
00129 
00130                 invert = ((*p == '!') || (*p == '^'));
00131                 if (invert)
00132                     p++;
00133 
00134                 c = *p++;
00135                 while (1) {
00136                     register char cstart = c, cend = c;
00137 
00138                     if (c == '\\') {
00139                         cstart = *p++;
00140                         cend = cstart;
00141                     }
00142                     if (c == '\0')
00143                         return 0;
00144 
00145                     c = *p++;
00146                     if (c == '-' && *p != ']') {
00147                         cend = *p++;
00148                         if (cend == '\\')
00149                             cend = *p++;
00150                         if (cend == '\0')
00151                             return 0;
00152                         c = *p++;
00153                     }
00154                     if (c1 >= cstart && c1 <= cend)
00155                         goto match;
00156                     if (c == ']')
00157                         break;
00158                 }
00159                 if (!invert)
00160                     return 0;
00161                 break;
00162 
00163               match:
00164                 /* Skip the rest of the [...] construct that already matched. */
00165                 while (c != ']') {
00166                     if (c == '\0')
00167                         return 0;
00168                     c = *p++;
00169                     if (c == '\0')
00170                         return 0;
00171                     else if (c == '\\')
00172                         ++p;
00173                 }
00174                 if (invert)
00175                     return 0;
00176                 break;
00177             }
00178 
00179         default:
00180             if (c != *t++)
00181                 return 0;
00182         }
00183 
00184     return *t == '\0';
00185 }
00186 
00194 void Com_ReplaceFilename (const char *fileName, const char *name, char *path, size_t size)
00195 {
00196     char *slash, *end;
00197 
00198     Q_strncpyz(path, fileName, size);
00199 
00200     end = path;
00201     while ((slash = strchr(end, '/')) != 0)
00202         end = slash + 1;
00203 
00204     strcpy(end, name + 1);
00205 }
00206 
00214 void Com_StripExtension (const char *in, char *out, const size_t size)
00215 {
00216     char *out_ext = NULL;
00217     int i = 1;
00218 
00219     while (*in && i < size) {
00220         *out++ = *in++;
00221         i++;
00222 
00223         if (*in == '.')
00224             out_ext = out;
00225     }
00226 
00227     if (out_ext)
00228         *out_ext = 0;
00229     else
00230         *out = 0;
00231 }
00232 
00237 const char *Com_GetExtension (const char *path)
00238 {
00239     const char *src = path + strlen(path) - 1;
00240     while (*src != '/' && src != path) {
00241         if (*src == '.')
00242             return src + 1;
00243         src--;
00244     }
00245 
00246     return NULL;
00247 }
00248 
00252 void Com_DefaultExtension (char *path, size_t len, const char *extension)
00253 {
00254     char oldPath[MAX_OSPATH];
00255     const char *src;
00256 
00257     /* if path doesn't have a .EXT, append extension
00258      * (extension should include the .) */
00259     src = path + strlen(path) - 1;
00260 
00261     while (*src != '/' && src != path) {
00262         if (*src == '.')
00263             return;
00264         src--;
00265     }
00266 
00267     Q_strncpyz(oldPath, path, sizeof(oldPath));
00268     Com_sprintf(path, len, "%s%s", oldPath, extension);
00269 }
00270 
00275 void Com_FilePath (const char *in, char *out)
00276 {
00277     const char *s = in + strlen(in) - 1;
00278 
00279     while (s != in && *s != '/')
00280         s--;
00281 
00282     Q_strncpyz(out, in, s - in + 1);
00283 }
00284 
00293 int Q_FloatSort (const void *float1, const void *float2)
00294 {
00295     return (*(const float *)float1 - *(const float *)float2);
00296 }
00297 
00306 int Q_StringSort (const void *string1, const void *string2)
00307 {
00308     const char *s1 = (const char *)string1;
00309     const char *s2 = (const char *)string2;
00310     if (*s1 < *s2)
00311         return -1;
00312     else if (*s1 == *s2) {
00313         while (*s1) {
00314             s1++;
00315             s2++;
00316             if (*s1 < *s2)
00317                 return -1;
00318             if (*s1 > *s2)
00319                 return 1;
00320         }
00321         return 0;
00322     } else
00323         return 1;
00324 }
00325 
00326 #define VA_BUFSIZE 4096
00327 
00331 char *va (const char *format, ...)
00332 {
00333     va_list argptr;
00334     /* in case va is called by nested functions */
00335     static char string[16][VA_BUFSIZE];
00336     static unsigned int index = 0;
00337     char *buf;
00338 
00339     buf = string[index & 0x0F];
00340     index++;
00341 
00342     va_start(argptr, format);
00343     Q_vsnprintf(buf, VA_BUFSIZE, format, argptr);
00344     va_end(argptr);
00345 
00346     return buf;
00347 }
00348 
00349 /*
00350 ============================================================================
00351 LIBRARY REPLACEMENT FUNCTIONS
00352 ============================================================================
00353 */
00354 
00355 char *Q_strlwr (char *str)
00356 {
00357     char* origs = str;
00358     while (*str) {
00359         *str = tolower(*str);
00360         str++;
00361     }
00362     return origs;
00363 }
00364 
00365 #ifndef HAVE_STRNCASECMP
00366 int Q_strncasecmp (const char *s1, const char *s2, size_t n)
00367 {
00368     while (n-- != 0) {
00369         int c1 = *s1++;
00370         int c2 = *s2++;
00371 
00372         if (c1 != c2) {
00373             if ('a' <= c1 && c1 <= 'z')
00374                 c1 += 'a' - 'A';
00375             if ('a' <= c2 && c2 <= 'z')
00376                 c2 += 'a' - 'A';
00377             if (c1 != c2)
00378                 return (unsigned char)c1 - (unsigned char)c2; /* strings not equal */
00379         }
00380 
00381         if (c1 == '\0')
00382             break;
00383     }
00384 
00385     return 0;                   /* strings are equal */
00386 }
00387 #endif /* HAVE_STRNCASECMP */
00388 
00395 #ifdef DEBUG
00396 void Q_strncpyzDebug (char *dest, const char *src, size_t destsize, const char *file, int line)
00397 #else
00398 void Q_strncpyz (char *dest, const char *src, size_t destsize)
00399 #endif
00400 {
00401 #ifdef DEBUG
00402     if (!dest)
00403         Sys_Error("Q_strncpyz: NULL dest (%s, %i)", file, line);
00404     if (!src)
00405         Sys_Error("Q_strncpyz: NULL src (%s, %i)", file, line);
00406     if (destsize < 1)
00407         Sys_Error("Q_strncpyz: destsize < 1 (%s, %i)", file, line);
00408 #endif
00409     UTF8_strncpyz(dest, src, destsize);
00410 }
00411 
00420 void Q_strcat (char *dest, const char *src, size_t destsize)
00421 {
00422     size_t dest_length;
00423     dest_length = strlen(dest);
00424     if (dest_length >= destsize)
00425         Sys_Error("Q_strcat: already overflowed");
00426     Q_strncpyz(dest + dest_length, src, destsize - dest_length);
00427 }
00428 
00436 qboolean Com_sprintf (char *dest, size_t size, const char *fmt, ...)
00437 {
00438     va_list ap;
00439     int len;
00440 
00441     if (!fmt)
00442         return qfalse;
00443 
00444     va_start(ap, fmt);
00445     len = Q_vsnprintf(dest, size, fmt, ap);
00446     va_end(ap);
00447 
00448     if (len <= size - 1)
00449         return qtrue;
00450 
00451     /* number of char */
00452     len = size - 1;
00453 
00454     /* check for UTF8 multibyte sequences */
00455     if (len > 0 && (unsigned char) dest[len - 1] >= 0x80) {
00456         int i = len - 1;
00457         while ((i > 0) && ((unsigned char) dest[i] & 0xc0) == 0x80)
00458             i--;
00459         if (UTF8_char_len(dest[i]) + i > len) {
00460             dest[i] = '\0';
00461         }
00462 #ifdef DEBUG
00463         else {
00464             /* the '\0' is already at the right place */
00465             len = i + UTF8_char_len(dest[i]);
00466             assert(dest[len] == '\0');
00467         }
00468 #endif
00469     }
00470 
00471     return qfalse;
00472 }
00473 
00477 int Q_vsnprintf (char *str, size_t size, const char *format, va_list ap)
00478 {
00479     int len;
00480 
00481 #if defined(_WIN32)
00482     len = _vsnprintf(str, size, format, ap);
00483     str[size - 1] = '\0';
00484 #ifdef DEBUG
00485     if (len == -1)
00486         Com_Printf("Q_vsnprintf: string (%.32s...) was truncated (%i) - target buffer too small ("UFO_SIZE_T")\n", str, len, size);
00487 #endif
00488 #else
00489     len = vsnprintf(str, size, format, ap);
00490 #ifdef DEBUG
00491     if ((size_t)len >= size)
00492         Com_Printf("Q_vsnprintf: string (%.32s...) was truncated (%i) - target buffer too small ("UFO_SIZE_T")\n", str, len, size);
00493 #endif
00494 #endif
00495 
00496     return len;
00497 }
00498 
00499 const char *Q_stristr (const char *str, const char *substr)
00500 {
00501     const size_t sublen = strlen(substr);
00502     while (*str) {
00503         if (!Q_strncasecmp(str, substr, sublen))
00504             break;
00505         str++;
00506     }
00507     if (!(*str))
00508         str = NULL;
00509     return str;
00510 }

Generated by  doxygen 1.6.2