fis-gtm/sr_port/cli_port.c

345 lines
8.9 KiB
C

/****************************************************************
* *
* Copyright 2001, 2010 Fidelity Information Services, Inc. *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_ctype.h"
#include "gtm_stdio.h"
#include "gtm_stdlib.h"
#include "gtm_string.h"
#include "gtm_limits.h"
#include <errno.h>
#include "cli.h"
#include "util.h"
/* A lot of stuff that can be made portable across unix and vvms cli.c needs to be moved into this module.
* For a start, cli_str_to_hex() is moved in. At least cli_get_str(), cli_get_int(), cli_get_num() can be moved in later.
*/
/*
*-------------------------------------------------------
* Check if string is a decimal number
*
* Return:
* TRUE - only decimal digits
* FALSE - otherwise
* -------------------------------------------------------
*/
int cli_is_dcm(char *p)
{
while (*p && ISDIGIT_ASCII(*p))
p++;
if (*p) return (FALSE);
else return (TRUE);
}
/*
* --------------------------------------------------
* Convert string to hex.
*
* Return:
* TRUE - OK
* FALSE - Could not convert to hex
* --------------------------------------------------
*/
boolean_t cli_str_to_hex(char *str, uint4 *dst)
{
unsigned long result;
int save_errno;
save_errno = errno;
errno = 0;
result = STRTOUL(str, NULL, 16);
if (
#if INT_MAX < LONG_MAX
(UINT_MAX < result) || /* outside UINT range */
#endif
(ERANGE == errno && ULONG_MAX == result) || (0 == result && 0 != errno))
{ /* out of range or other error */
*dst = 0;
errno = save_errno;
return FALSE;
} else
{
*dst = (uint4)result;
errno = save_errno;
return TRUE;
}
}
/*
* --------------------------------------------------
* Convert string to 64 bit hex.
*
* Return:
* TRUE - OK
* FALSE - Could not convert to hex
* --------------------------------------------------
*/
boolean_t cli_str_to_hex64(char *str, gtm_uint64_t *dst)
{
gtm_uint64_t result;
int save_errno;
save_errno = errno;
errno = 0;
result = STRTOU64L(str, NULL, 16);
if ((ERANGE == errno && GTM_UINT64_MAX == result) || (0 == result && 0 != errno))
{ /* out of range or other error */
*dst = 0;
errno = save_errno;
return FALSE;
} else
{
*dst = result;
errno = save_errno;
return TRUE;
}
}
/*
* --------------------------------------------------
* Convert string to 64 bit unsigned int.
*
* Return:
* TRUE - OK
* FALSE - Could not convert to int
* --------------------------------------------------
*/
boolean_t cli_str_to_uint64(char *str, gtm_uint64_t *dst)
{
gtm_uint64_t result;
int save_errno;
save_errno = errno;
errno = 0;
result = STRTOU64L(str, NULL, 10);
if ((ERANGE == errno && GTM_UINT64_MAX == result) || (0 == result && 0 != errno))
{ /* out of range or other error */
*dst = 0;
errno = save_errno;
return FALSE;
} else
{
*dst = result;
errno = save_errno;
return TRUE;
}
}
/*
* --------------------------------------------------
* Convert string to int.
*
* Return:
* TRUE - OK
* FALSE - Could not convert to int
* --------------------------------------------------
*/
boolean_t cli_str_to_int(char *str, int4 *dst)
{
long result;
int save_errno;
save_errno = errno;
errno = 0;
result = STRTOL(str, NULL, 10);
if (
#if INT_MAX < LONG_MAX
(INT_MIN > result || INT_MAX < result) || /* outside INT range */
#endif
(ERANGE == errno && (LONG_MIN == result || LONG_MAX == result)) || (0 == result && 0 != errno))
{ /* out of range or other error */
*dst = 0;
errno = save_errno;
return FALSE;
} else
{
*dst = (int4)result;
errno = save_errno;
return TRUE;
}
}
/*
* --------------------------------------------------
* Convert string to 64 bit int.
*
* Return:
* TRUE - OK
* FALSE - Could not convert to int
* --------------------------------------------------
*/
boolean_t cli_str_to_int64(char *str, gtm_int64_t *dst)
{
gtm_int64_t result;
int save_errno;
save_errno = errno;
errno = 0;
result = STRTO64L(str, NULL, 10);
if ((ERANGE == errno && (GTM_INT64_MIN == result || GTM_INT64_MAX == result)) || (0 == result && 0 != errno))
{ /* out of range or other error */
*dst = 0;
errno = save_errno;
return FALSE;
} else
{
*dst = result;
errno = save_errno;
return TRUE;
}
}
/*
* --------------------------------------------------
* Convert string to number.
*
* Return:
* TRUE - OK
* FALSE - Could not convert to number
* --------------------------------------------------
*/
boolean_t cli_str_to_num(char *str, int4 *dst)
{
long result;
int save_errno, base;
save_errno = errno;
errno = 0;
if (cli_is_dcm(str))
base = 10;
else
base = 16;
result = STRTOL(str, NULL, base);
if (
#if INT_MAX < LONG_MAX
(INT_MIN > result || INT_MAX < result) || /* outside INT range */
#endif
(ERANGE == errno && (LONG_MIN == result || LONG_MAX == result)) || (0 == result && 0 != errno))
{ /* out of range or other error */
*dst = 0;
errno = save_errno;
return FALSE;
} else
{
*dst = (int4)result;
errno = save_errno;
return TRUE;
}
}
/*
* --------------------------------------------------
* Convert string to 64 bit number.
*
* Return:
* TRUE - OK
* FALSE - Could not convert to number
* --------------------------------------------------
*/
boolean_t cli_str_to_num64(char *str, gtm_int64_t *dst)
{
gtm_int64_t result;
int save_errno, base;
save_errno = errno;
errno = 0;
if (cli_is_dcm(str))
base = 10;
else
base = 16;
result = STRTO64L(str, NULL, base);
if ((ERANGE == errno && (GTM_INT64_MIN == result || GTM_INT64_MAX == result)) || (0 == result && 0 != errno))
{ /* out of range or other error */
*dst = 0;
errno = save_errno;
return FALSE;
} else
{
*dst = result;
errno = save_errno;
return TRUE;
}
}
int cli_parse_two_numbers(char *qual_name, const char delimiter, uint4 *first_num, uint4 *second_num)
{ /* Parse two unsigned base 10 numbers separated by the given delimiter. Eg. -LOG_INTERVAL=10,20 (on VMS, -LOG_INTERVAL="10,20").
* Both Unix and VMS accept the qualifier as a string. NOTE: On VMS, such qualifiers are quoted strings.
* Both numbers are optional (eg. -LOG_INTERVAL=10, or -LOG_INTERVAL=",20", or -LOG_INTERVAL=,).
* Return values:
* CLI_2NUM_FIRST_SPECIFIED (binary 10), first number specified, second not
* CLI_2NUM_SECOND_SPECIFIED (binary 01), first number not specified, second is
* CLI_2NUM_BOTH_SPECIFIED (binary 11) (CLI_2NUM_FIRST_SPECIFIED | CLI_2NUM_SECOND_SPECIFIED), both specified
* 0 (binary 00), error in parsing either number
*/
char *first_num_str, *second_num_str, *two_num_str_top, *num_endptr;
char two_num_qual_str[128];
unsigned short two_num_qual_len;
uint4 num;
int retval = 0;
two_num_qual_len = SIZEOF(two_num_qual_str);
if (!cli_get_str(qual_name, two_num_qual_str, &two_num_qual_len))
{
util_out_print("Error parsing !AZ qualifier", TRUE, qual_name);
return 0;
}
#ifdef VMS
/* DCL does not strip quotes included in the command line. However, the DEFAULT value (see mupip_cmd.cld) is stripped
* of quotes. */
if ('"' == two_num_qual_str[0])
{
assert('"' == two_num_qual_str[two_num_qual_len - 1]); /* end quote should exist */
first_num_str = &two_num_qual_str[1]; /* Skip begin quote */
two_num_qual_str[two_num_qual_len - 1] = '\0'; /* Zap end quote */
two_num_qual_len -= 2; /* Quotes gone */
} else
#endif
first_num_str = two_num_qual_str;
for (second_num_str = first_num_str, two_num_str_top = first_num_str + two_num_qual_len;
second_num_str < two_num_str_top && delimiter != *second_num_str;
second_num_str++)
;
if (delimiter == *second_num_str)
*second_num_str++ = '\0';
if (*first_num_str != '\0') /* VMS issues EINVAL if strtoul is passed null string */
{
errno = 0;
num = (uint4)STRTOUL(first_num_str, &num_endptr, 10);
if ((0 == num && (0 != errno || (num_endptr == first_num_str && *first_num_str != '\0'))) ||
(0 != errno && GTM64_ONLY(UINT_MAX == num) NON_GTM64_ONLY(ULONG_MAX == num)))
{
util_out_print("Error parsing or invalid parameter for !AZ", TRUE, qual_name);
return 0;
}
*first_num = num;
retval |= CLI_2NUM_FIRST_SPECIFIED;
} /* else, first number not specified */
if (second_num_str < two_num_str_top && *second_num_str != '\0')
{
errno = 0;
num = (uint4)STRTOUL(second_num_str, &num_endptr, 10);
if ((0 == num && (0 != errno || (num_endptr == second_num_str && *second_num_str != '\0'))) ||
(0 != errno && GTM64_ONLY(UINT_MAX == num) NON_GTM64_ONLY(ULONG_MAX == num)))
{
util_out_print("Error parsing or invalid parameter for LOG_INTERVAL", TRUE);
return 0;
}
*second_num = num;
retval |= CLI_2NUM_SECOND_SPECIFIED;
} /* else, second number not specified */
return retval;
}