8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-31 04:03:03 +01:00
firebird-mirror/src/common/utils.cpp

226 lines
5.4 KiB
C++
Raw Normal View History

/*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Claudio Valderrama on 25-Dec-2003
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2003 Claudio Valderrama
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*
*/
// =====================================
// Utility functions
#include "../jrd/common.h"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#else
#define __need_size_t
#include <stddef.h>
#undef __need_size_t
#endif
#include <stdarg.h>
#include "../jrd/gdsassert.h"
2004-03-31 20:10:22 +02:00
#include "../common/utils_proto.h"
#include "../jrd/constants.h"
2004-03-31 20:10:22 +02:00
namespace fb_utils
{
char* exact_name(char* const str)
{
/**************************************
*
2005-09-27 09:47:11 +02:00
* e x a c t _ n a m e
*
**************************************
*
* Functional description
* Trim off trailing spaces from a metadata name.
* eg: insert a null after the last non-blank character.
*
* SQL delimited identifier may have blank as part of the name
*
* Parameters: str - the string to terminate
* Returns: str
*
**************************************/
char* p = str;
while (*p)
++p;
// Now, let's go back
--p;
while (p >= str && *p == '\x20') // blank character, ASCII(32)
--p;
*(p + 1) = '\0';
return str;
}
char* exact_name_limit(char* const str, size_t bufsize)
{
/**************************************
*
2005-09-27 09:47:11 +02:00
* e x a c t _ n a m e _ l i m i t
*
**************************************
*
* Functional description
* Trim off trailing spaces from a metadata name.
* eg: insert a null after the last non-blank character.
* It has a maximum length to ensure working between bounds.
*
* SQL delimited identifier may have blank as part of the name
*
* Parameters: str - the string to terminate
* bufsize - the size of the variable containing the string.
* Returns: str
*
**************************************/
const char* const end = str + bufsize - 1;
char* p = str;
while (*p && p < end)
++p;
// Now, let's go back
--p;
while (p >= str && *p == '\x20') // blank character, ASCII(32)
--p;
*(p + 1) = '\0';
return str;
}
// *****************************
// i m p l i c i t _ d o m a i n
// *****************************
// Determines if a domain is of the form RDB$<n[...n]>[<spaces>]
bool implicit_domain(const char* domain_name)
{
2006-09-01 03:27:55 +02:00
if (strncmp(domain_name, IMPLICIT_DOMAIN_PREFIX, IMPLICIT_DOMAIN_PREFIX_LEN) != 0)
return false;
int i = IMPLICIT_DOMAIN_PREFIX_LEN;
while (domain_name[i] >= '0' && domain_name[i] <= '9')
++i;
if (i == IMPLICIT_DOMAIN_PREFIX_LEN) // 'RDB$' alone isn't valid
return false;
while (domain_name[i] == ' ')
++i;
return !domain_name[i]; // we reached null term
}
int name_length(const TEXT* const name)
{
/**************************************
*
* n a m e _ l e n g t h
*
**************************************
*
* Functional description
* Compute effective length of system relation name and others.
* SQL delimited identifier may contain blanks. Trailing blanks are ignored.
* Assumes input is null terminated.
*
**************************************/
const TEXT* q = name - 1;
for (const TEXT* p = name; *p; p++) {
if (*p != ' ') {
q = p;
}
}
return (q + 1) - name;
}
//***************
// r e a d e n v
//***************
// Goes to read directly the environment variables from the operating system on Windows
// and provides a stub for UNIX.
bool readenv(const char* env_name, Firebird::string& env_value)
{
#ifdef WIN_NT
const DWORD rc = GetEnvironmentVariable(env_name, NULL, 0);
if (rc)
{
env_value.reserve(rc - 1);
DWORD rc2 = GetEnvironmentVariable(env_name, env_value.begin(), rc);
if (rc2 < rc && rc2 != 0)
{
env_value.recalculate_length();
return true;
}
}
#else
const char* p = getenv(env_name);
if (p)
return env_value.assign(p).length() != 0;
#endif
// Not found, clear the output var.
env_value.begin()[0] = 0;
env_value.recalculate_length();
return false;
}
bool readenv(const char* env_name, Firebird::PathName& env_value)
{
Firebird::string result;
bool rc = readenv(env_name, result);
env_value.assign(result.c_str(), result.length());
return rc;
}
2005-09-27 09:47:11 +02:00
// ***************
// s n p r i n t f
// ***************
// Provide a single place to deal with vsnprintf and error detection.
int snprintf(char* buffer, size_t count, const char* format...)
{
va_list args;
va_start(args, format);
const int rc = VSNPRINTF(buffer, count, format, args);
buffer[count - 1] = 0;
va_end(args);
#if defined(DEV_BUILD) && !defined(HAVE_VSNPRINTF)
// We don't have the safe functions, then check if we overflowed the buffer.
// I would prefer to make this functionality available in prod build, too.
// If the docs are right, the null terminator is not counted => rc < count.
#if defined(fb_assert_continue)
fb_assert_continue(rc >= 0 && rc < count);
#else
fb_assert(rc >= 0 && rc < count);
#endif
#endif
return rc;
}
} // namespace fb_utils