source: cpp/common/util-string.cpp @ 840

Last change on this file since 840 was 840, checked in by Maciej Komosinski, 12 months ago

Split stl-util into util-stl, util-file and util-string

  • Property svn:eol-style set to native
File size: 2.7 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#include "util-file.h"
6#include <stdarg.h>
7#include "nonstd_stdio.h"
8#include "nonstd.h"
9#include <assert.h>
10#ifdef USE_VIRTFILE
11#include <common/virtfile/virtfile.h>
12#endif
13
14string ssprintf_va(const char* format, va_list ap)
15{
16        string s; //clang crashed when this declaration was in s=buf
17        int size = 256;
18        char* buf;
19        va_list ap_copy; // "va_list ap" can only by used once by printf-type functions as they advance the current argument pointer (crashed on linux x86_64)
20        // (does not apply to SString::sprintf, it does not have the va_list variant)
21
22        //almost like SString::sprintf, but there is no common code to share because SString can use its directWrite to avoid double allocating/copying
23#ifdef USE_VSCPRINTF
24        va_copy(ap_copy, ap);
25        size = _vscprintf(format, ap_copy) + 1; //+1 for terminating null character
26        va_end(ap_copy);
27#endif
28
29        while (1)
30        {
31                buf = (char*)malloc(size);
32                assert(buf != NULL);
33                va_copy(ap_copy, ap);
34                int n = vsnprintf(buf, size, format, ap_copy);
35                va_end(ap_copy);
36                if (n > -1 && n < size)
37                {
38                        s = buf;
39                        free(buf);
40                        return s;
41                }
42#ifdef VSNPRINTF_RETURNS_REQUIRED_SIZE
43                if (n > -1)    /* glibc 2.1 */
44                        size = n+1; /* precisely what is needed */
45                else           /* glibc 2.0 */
46#endif
47                        size *= 2;  /* twice the old size */
48                free(buf);
49        }
50}
51
52char* strmove(char *a, char *b) //strcpy that works well for overlapping strings ("Source and destination overlap")
53{
54        if (a == NULL || b == NULL)
55                return NULL;
56        memmove(a, b, strlen(b) + 1);
57        return a;
58}
59
60string ssprintf(const char* format, ...)
61{
62        va_list ap;
63        va_start(ap, format);
64        string ret = ssprintf_va(format, ap); //is it too wasteful? copying the string again... unless the compiler can handle it better
65        va_end(ap);
66        return ret;
67}
68
69string stripExt(const string& filename)
70{
71        size_t dot = filename.rfind('.');
72        if (dot == string::npos) return filename;
73        size_t sep = filename.rfind(PATH_SEPARATOR_CHAR);
74        if ((sep == string::npos) || (sep < dot))
75                return filename.substr(0, dot);
76        return filename;
77}
78
79string stripFileDir(const string& filename)
80{
81        size_t sep = filename.rfind(PATH_SEPARATOR_CHAR);
82        if (sep == string::npos) return filename;
83        return filename.substr(sep+1);
84}
85
86string getFileExt(const string& filename)
87{
88        size_t dot = filename.rfind('.');
89        if (dot == string::npos) return string("");
90        size_t sep = filename.rfind(PATH_SEPARATOR_CHAR);
91        if ((sep == string::npos) || (sep < dot))
92                return filename.substr(dot);
93        return string("");
94}
95
96string getFileDir(const string& filename)
97{
98        size_t slash = filename.rfind(PATH_SEPARATOR_CHAR);
99        if (slash == string::npos) return string("");
100        return filename.substr(0, slash);
101}
Note: See TracBrowser for help on using the repository browser.