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

Last change on this file since 840 was 840, checked in by Maciej Komosinski, 5 years ago

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

  • Property svn:eol-style set to native
File size: 2.7 KB
RevLine 
[286]1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
[837]2// Copyright (C) 1999-2018  Maciej Komosinski and Szymon Ulatowski.
[286]3// See LICENSE.txt for details.
[196]4
[840]5#include "util-file.h"
[180]6#include <stdarg.h>
7#include "nonstd_stdio.h"
8#include "nonstd.h"
[220]9#include <assert.h>
[247]10#ifdef USE_VIRTFILE
[382]11#include <common/virtfile/virtfile.h>
[247]12#endif
[180]13
14string ssprintf_va(const char* format, va_list ap)
15{
[220]16        string s; //clang crashed when this declaration was in s=buf
[319]17        int size = 256;
[180]18        char* buf;
[247]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)
[220]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
[257]24        va_copy(ap_copy, ap);
[247]25        size = _vscprintf(format, ap_copy) + 1; //+1 for terminating null character
26        va_end(ap_copy);
[220]27#endif
28
[246]29        while (1)
30        {
31                buf = (char*)malloc(size);
32                assert(buf != NULL);
[257]33                va_copy(ap_copy, ap);
[247]34                int n = vsnprintf(buf, size, format, ap_copy);
35                va_end(ap_copy);
[246]36                if (n > -1 && n < size)
[220]37                {
[246]38                        s = buf;
[220]39                        free(buf);
40                        return s;
[246]41                }
[220]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);
[246]49        }
[180]50}
51
[257]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
[180]60string ssprintf(const char* format, ...)
61{
62        va_list ap;
63        va_start(ap, format);
[246]64        string ret = ssprintf_va(format, ap); //is it too wasteful? copying the string again... unless the compiler can handle it better
[180]65        va_end(ap);
66        return ret;
67}
68
[246]69string stripExt(const string& filename)
[180]70{
[319]71        size_t dot = filename.rfind('.');
[246]72        if (dot == string::npos) return filename;
[319]73        size_t sep = filename.rfind(PATH_SEPARATOR_CHAR);
[246]74        if ((sep == string::npos) || (sep < dot))
75                return filename.substr(0, dot);
[180]76        return filename;
77}
78
[460]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
[246]86string getFileExt(const string& filename)
[180]87{
[319]88        size_t dot = filename.rfind('.');
[246]89        if (dot == string::npos) return string("");
[319]90        size_t sep = filename.rfind(PATH_SEPARATOR_CHAR);
[246]91        if ((sep == string::npos) || (sep < dot))
[180]92                return filename.substr(dot);
93        return string("");
94}
[246]95
96string getFileDir(const string& filename)
97{
[319]98        size_t slash = filename.rfind(PATH_SEPARATOR_CHAR);
[246]99        if (slash == string::npos) return string("");
100        return filename.substr(0, slash);
101}
Note: See TracBrowser for help on using the repository browser.