#endif
#include <stddef.h>
-#ifdef HAVE_ERRNO_H
+#if defined( HAVE_ERRNO_H ) || defined( __VMS )
#include <errno.h>
#endif
# define TRIO_ERROR_RETURN(x,y) (-1)
#endif
+#ifndef VA_LIST_IS_ARRAY
+#define TRIO_VA_LIST_PTR va_list *
+#define TRIO_VA_LIST_ADDR(l) (&(l))
+#define TRIO_VA_LIST_DEREF(l) (*(l))
+#else
+#define TRIO_VA_LIST_PTR va_list
+#define TRIO_VA_LIST_ADDR(l) (l)
+#define TRIO_VA_LIST_DEREF(l) (l)
+#endif
+
typedef unsigned long trio_flags_t;
/*************************************************************************
* Platform specific definitions
*/
-#if defined(TRIO_PLATFORM_UNIX)
+#if defined(TRIO_PLATFORM_UNIX) || defined(TRIO_PLATFORM_OS400)
# include <unistd.h>
# include <signal.h>
# include <locale.h>
#endif
/* Maximal and fixed integer types */
-#if defined(TRIO_COMPILER_SUPPORTS_C99)
+#if defined(TRIO_COMPILER_SUPPORTS_C99) && !defined( __VMS )
# include <stdint.h>
typedef intmax_t trio_intmax_t;
typedef uintmax_t trio_uintmax_t;
typedef int16_t trio_int16_t;
typedef int32_t trio_int32_t;
typedef int64_t trio_int64_t;
-#elif defined(TRIO_COMPILER_SUPPORTS_UNIX98)
+#elif defined(TRIO_COMPILER_SUPPORTS_UNIX98) || defined( __VMS )
# include <inttypes.h>
+#ifdef __VMS
+typedef long long int intmax_t;
+typedef unsigned long long int uintmax_t;
+#endif
typedef intmax_t trio_intmax_t;
typedef uintmax_t trio_uintmax_t;
typedef int8_t trio_int8_t;
#define NAN_LOWER "nan"
#define NAN_UPPER "NAN"
+#if !defined(HAVE_ISASCII) && !defined(isascii)
+#ifndef __VMS
+# define isascii(x) ((unsigned int)(x) < 128)
+#endif
+#endif
+
/* Various constants */
enum {
TYPE_PRINT = 1,
/* Maximal string lengths for user-defined specifiers */
MAX_USER_NAME = 64,
MAX_USER_DATA = 256,
-
+
/* Maximal length of locale separator strings */
MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX,
/* Maximal number of integers in grouping */
trio_userdef_t **prev)
{
trio_userdef_t *def;
-
+
if (internalEnterCriticalRegion)
(void)internalEnterCriticalRegion(NULL);
-
+
for (def = internalUserDef; def; def = def->next)
{
/* Case-sensitive string comparison */
if (trio_equal_case(def->name, name))
break;
-
+
if (prev)
*prev = def;
}
-
+
if (internalLeaveCriticalRegion)
(void)internalLeaveCriticalRegion(NULL);
-
+
return def;
}
#endif
int type,
TRIO_CONST char *format,
trio_parameter_t *parameters,
- va_list *arglist,
+ TRIO_VA_LIST_PTR arglist,
trio_pointer_t *argarray)
{
/* Count the number of times a parameter is referenced */
/* One and only one of arglist and argarray must be used */
assert((arglist != NULL) ^ (argarray != NULL));
-
+
/*
* The 'parameters' array is not initialized, but we need to
* know which entries we have used.
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
(void)mblen(NULL, 0);
#endif
-
+
while (format[index])
{
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
/* Skip if no precision */
if (QUALIFIER_DOT == format[index])
break;
-
+
/* After the first dot we have the precision */
flags |= FLAGS_PRECISION;
if ((QUALIFIER_STAR == format[index])
else if (dots == 1) /* Base */
{
dots++;
-
+
/* After the second dot we have the base */
flags |= FLAGS_BASE;
if ((QUALIFIER_STAR == format[index])
}
else
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
-
+
flags |= FLAGS_FIXED_SIZE;
break;
#endif
gotSticky = TRUE;
break;
#endif
-
+
#if defined(QUALIFIER_VARSIZE)
case QUALIFIER_VARSIZE:
flags |= FLAGS_VARSIZE_PARAMETER;
indices[varsize] = pos;
varsize = pos++;
}
-
+
indices[currentParam] = pos;
-
+
switch (format[index++])
{
#if defined(SPECIFIER_CHAR_UPPER)
}
}
break;
-
+
case SPECIFIER_INTEGER:
parameters[pos].type = FORMAT_INT;
break;
-
+
case SPECIFIER_UNSIGNED:
flags |= FLAGS_UNSIGNED;
parameters[pos].type = FORMAT_INT;
{
unsigned int max;
int without_namespace = TRUE;
-
+
parameters[pos].type = FORMAT_USER_DEFINED;
parameters[pos].user_name[0] = NIL;
tmpformat = (char *)&format[index];
-
+
while ((ch = format[index]))
{
index++;
}
break;
#endif /* defined(SPECIFIER_USER_DEFINED_BEGIN) */
-
+
default:
/* Bail out completely to make the error more obvious */
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
/* Count the number of times this entry has been used */
usedEntries[currentParam] += 1;
-
+
/* Find last sticky parameters */
if (gotSticky && !(flags & FLAGS_STICKY))
{
}
}
}
-
+
parameters[pos].indexAfterSpecifier = index;
parameters[pos].flags = flags;
parameters[pos].width = width;
parameters[pos].base = (base == NO_BASE) ? BASE_DECIMAL : base;
parameters[pos].varsize = varsize;
pos++;
-
+
if (! positional)
parameterPosition++;
-
+
} /* if identifier */
-
+
} /* while format characters left */
for (num = 0; num <= maxParam; num++)
else /* double references detected */
return TRIO_ERROR_RETURN(TRIO_EDBLREF, num);
}
-
+
i = indices[num];
/*
if (flags & FLAGS_WIDECHAR)
{
parameters[i].data.wstring = (argarray == NULL)
- ? va_arg(*arglist, trio_wchar_t *)
+ ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_wchar_t *)
: (trio_wchar_t *)(argarray[num]);
}
else
#endif
{
parameters[i].data.string = (argarray == NULL)
- ? va_arg(*arglist, char *)
+ ? va_arg(TRIO_VA_LIST_DEREF(arglist), char *)
: (char *)(argarray[num]);
}
break;
case FORMAT_COUNT:
case FORMAT_UNKNOWN:
parameters[i].data.pointer = (argarray == NULL)
- ? va_arg(*arglist, trio_pointer_t )
+ ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t )
: argarray[num];
break;
if (TYPE_SCAN == type)
{
if (argarray == NULL)
- parameters[i].data.pointer =
- (trio_pointer_t)va_arg(*arglist, trio_pointer_t);
+ parameters[i].data.pointer =
+ (trio_pointer_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t);
else
{
if (parameters[i].type == FORMAT_CHAR)
varsize = parameters[i].varsize;
}
parameters[i].flags &= ~FLAGS_ALL_VARSIZES;
-
+
if (varsize <= (int)sizeof(int))
;
else if (varsize <= (int)sizeof(long))
#if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
if (parameters[i].flags & FLAGS_SIZE_T)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, size_t)
+ ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), size_t)
: (trio_uintmax_t)(*((size_t *)argarray[num]));
else
#endif
#if defined(QUALIFIER_PTRDIFF_T)
if (parameters[i].flags & FLAGS_PTRDIFF_T)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, ptrdiff_t)
+ ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), ptrdiff_t)
: (trio_uintmax_t)(*((ptrdiff_t *)argarray[num]));
else
#endif
#if defined(QUALIFIER_INTMAX_T)
if (parameters[i].flags & FLAGS_INTMAX_T)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, trio_intmax_t)
+ ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_intmax_t)
: (trio_uintmax_t)(*((trio_intmax_t *)argarray[num]));
else
#endif
if (parameters[i].flags & FLAGS_QUAD)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, trio_ulonglong_t)
+ ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_ulonglong_t)
: (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num]));
else if (parameters[i].flags & FLAGS_LONG)
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, long)
+ ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), long)
: (trio_uintmax_t)(*((long *)argarray[num]));
else
{
if (argarray == NULL)
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(*arglist, int);
+ parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), int);
else
{
if (parameters[i].type == FORMAT_CHAR)
*/
if (parameters[i].flags & FLAGS_USER_DEFINED)
parameters[i].data.pointer = (argarray == NULL)
- ? va_arg(*arglist, trio_pointer_t )
+ ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t )
: argarray[num];
else
parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(*arglist, int)
+ ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), int)
: (trio_uintmax_t)(*((int *)argarray[num]));
break;
{
if (parameters[i].flags & FLAGS_LONGDOUBLE)
parameters[i].data.longdoublePointer = (argarray == NULL)
- ? va_arg(*arglist, trio_long_double_t *)
+ ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_long_double_t *)
: (trio_long_double_t *)argarray[num];
else
{
if (parameters[i].flags & FLAGS_LONG)
parameters[i].data.doublePointer = (argarray == NULL)
- ? va_arg(*arglist, double *)
+ ? va_arg(TRIO_VA_LIST_DEREF(arglist), double *)
: (double *)argarray[num];
else
parameters[i].data.doublePointer = (argarray == NULL)
- ? (double *)va_arg(*arglist, float *)
+ ? (double *)va_arg(TRIO_VA_LIST_DEREF(arglist), float *)
: (double *)((float *)argarray[num]);
}
}
{
if (parameters[i].flags & FLAGS_LONGDOUBLE)
parameters[i].data.longdoubleNumber = (argarray == NULL)
- ? va_arg(*arglist, trio_long_double_t)
+ ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_long_double_t)
: (trio_long_double_t)(*((trio_long_double_t *)argarray[num]));
else
{
if (argarray == NULL)
parameters[i].data.longdoubleNumber =
- (trio_long_double_t)va_arg(*arglist, double);
+ (trio_long_double_t)va_arg(TRIO_VA_LIST_DEREF(arglist), double);
else
{
if (parameters[i].flags & FLAGS_SHORT)
number &= (unsigned long)-1;
else
number &= (unsigned int)-1;
-
+
/* Build number */
pointer = bufferend = &buffer[sizeof(buffer) - 1];
*pointer-- = NIL;
count = (! ((flags & FLAGS_LEFTADJUST) || (precision == NO_PRECISION)))
? precision
: 0;
-
+
/* Adjust width further */
if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))
width--;
if (width == NO_WIDTH)
width = sizeof(buffer);
-
+
size = wctomb(buffer, wch);
if ((size <= 0) || (size > width) || (buffer[0] == NIL))
return 0;
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
(void)mblen(NULL, 0);
#endif
-
+
if (wstring == NULL)
{
TrioWriteString(self, NULL, flags, width, precision);
return;
}
-
+
if (NO_PRECISION == precision)
{
length = INT_MAX;
BOOLEAN_T keepTrailingZeroes;
BOOLEAN_T keepDecimalPoint;
trio_long_double_t epsilon;
-
+
assert(VALID(self));
assert(VALID(self->OutStream));
assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
: NAN_LOWER,
flags, width, precision);
return;
-
+
case TRIO_FP_INFINITE:
if (isNegative)
{
/* Finitude */
break;
}
-
+
/* Normal numbers */
if (flags & FLAGS_LONGDOUBLE)
{
precision = FLT_DIG;
}
}
-
+
if (isNegative)
number = -number;
if (isHex)
flags |= FLAGS_FLOAT_E;
-
+
if (flags & FLAGS_FLOAT_G)
{
if (precision == 0)
integerNumber = floorl(number);
fractionNumber = number - integerNumber;
-
+
/*
* Truncated number.
*
: zeroes + precision;
dblFractionBase = TrioPower(base, fractionDigits);
-
+
workNumber = number + 0.5 / dblFractionBase;
if (floorl(number) != floorl(workNumber))
{
integerThreshold = INT_MAX;
fractionThreshold = INT_MAX;
}
-
+
/*
* Calculate expected width.
* sign + integer part + thousands separators + decimal point
((requireTwoDigitExponent ? sizeof("E+0") : sizeof("E+")) - 1);
if (isHex)
expectedWidth += sizeof("0X") - 1;
-
+
/* Output prefixing */
if (flags & FLAGS_NILPADDING)
{
self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
}
}
-
+
/* Output the integer part and thousand separators */
dblIntegerBase = 1.0 / TrioPower(base, integerDigits - 1);
for (i = 0; i < integerDigits; i++)
self->OutStream(self, digits[(int)fmodl(workNumber, dblBase)]);
}
dblIntegerBase *= dblBase;
-
+
if (((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE)
&& TrioFollowedBySeparator(integerDigits - i))
{
}
}
}
-
+
/* Insert decimal point and build the fraction part */
trailingZeroes = 0;
}
}
}
-
+
if (keepTrailingZeroes)
{
while (trailingZeroes > 0)
trailingZeroes--;
}
}
-
+
/* Output exponent */
if (exponentDigits > 0)
{
int precision;
int base;
int index;
-
+
index = 0;
i = 0;
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
(void)mblen(NULL, 0);
#endif
-
+
while (format[index])
{
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
/* Skip the parameter entries */
while (parameters[i].type == FORMAT_PARAMETER)
i++;
-
+
flags = parameters[i].flags;
/* Find width */
width = -width;
}
}
-
+
/* Find precision */
if (flags & FLAGS_PRECISION)
{
/* Get base from parameter list */
base = (int)parameters[base].data.number.as_signed;
}
-
+
switch (parameters[i].type)
{
case FORMAT_CHAR:
case FORMAT_POINTER:
{
trio_reference_t reference;
-
+
reference.data = data;
reference.parameter = ¶meters[i];
trio_print_pointer(&reference, parameters[i].data.pointer);
}
break;
#endif /* defined(FORMAT_USER_DEFINED) */
-
+
default:
break;
} /* switch parameter type */
TRIO_ARGS4((reference, format, arglist, argarray),
trio_reference_t *reference,
TRIO_CONST char *format,
- va_list *arglist,
+ TRIO_VA_LIST_PTR arglist,
trio_pointer_t *argarray)
{
int status;
size_t destinationSize,
void (*OutStream) TRIO_PROTO((trio_class_t *, int)),
TRIO_CONST char *format,
- va_list *arglist,
+ TRIO_VA_LIST_PTR arglist,
trio_pointer_t *argarray)
{
int status;
assert(VALID(self));
assert(VALID(self->location));
-
+
buffer = (char **)self->location;
if (self->processed < self->max)
va_list args;
assert(VALID(format));
-
+
TRIO_VA_START(args, format);
- status = TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL);
+ status = TrioFormat(stdout, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
{
assert(VALID(format));
- return TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL);
+ return TrioFormat(stdout, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
}
/**
assert(VALID(file));
assert(VALID(format));
-
+
TRIO_VA_START(args, format);
- status = TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL);
+ status = TrioFormat(file, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
{
assert(VALID(file));
assert(VALID(format));
-
- return TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL);
+
+ return TrioFormat(file, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
}
/**
{
assert(VALID(file));
assert(VALID(format));
-
+
return TrioFormat(file, 0, TrioOutStreamFile, format, NULL, args);
}
va_list args;
assert(VALID(format));
-
+
TRIO_VA_START(args, format);
- status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL);
+ status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
va_list args)
{
assert(VALID(format));
-
- return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL);
+
+ return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, TRIO_VA_LIST_ADDR(args), NULL);
}
/**
trio_pointer_t *args)
{
assert(VALID(format));
-
+
return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, NULL, args);
}
TRIO_VA_START(args, format);
data.stream.out = stream;
data.closure = closure;
- status = TrioFormat(&data, 0, TrioOutStreamCustom, format, &args, NULL);
+ status = TrioFormat(&data, 0, TrioOutStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
data.stream.out = stream;
data.closure = closure;
- return TrioFormat(&data, 0, TrioOutStreamCustom, format, &args, NULL);
+ return TrioFormat(&data, 0, TrioOutStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
}
TRIO_PUBLIC int
assert(VALID(buffer));
assert(VALID(format));
-
+
TRIO_VA_START(args, format);
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL);
+ status = TrioFormat(&buffer, 0, TrioOutStreamString, format, TRIO_VA_LIST_ADDR(args), NULL);
*buffer = NIL; /* Terminate with NIL character */
TRIO_VA_END(args);
return status;
assert(VALID(buffer));
assert(VALID(format));
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL);
+ status = TrioFormat(&buffer, 0, TrioOutStreamString, format, TRIO_VA_LIST_ADDR(args), NULL);
*buffer = NIL;
return status;
}
TRIO_VA_START(args, format);
status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, &args, NULL);
+ TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
if (max > 0)
*buffer = NIL;
TRIO_VA_END(args);
assert(VALID(format));
status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, &args, NULL);
+ TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
if (max > 0)
*buffer = NIL;
return status;
buffer = &buffer[buf_len];
status = TrioFormat(&buffer, max - 1 - buf_len,
- TrioOutStreamStringMax, format, &args, NULL);
+ TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
*buffer = NIL;
return status;
{
int status;
size_t buf_len;
-
+
assert(VALID(buffer));
assert(VALID(format));
buf_len = trio_length(buffer);
buffer = &buffer[buf_len];
status = TrioFormat(&buffer, max - 1 - buf_len,
- TrioOutStreamStringMax, format, &args, NULL);
+ TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
*buffer = NIL;
return status;
}
char *result = NULL;
assert(VALID(format));
-
+
info = trio_xstring_duplicate("");
if (info)
{
TRIO_VA_START(args, format);
(void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
trio_string_terminate(info);
{
trio_string_t *info;
char *result = NULL;
-
+
assert(VALID(format));
-
+
info = trio_xstring_duplicate("");
if (info)
{
(void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
trio_string_terminate(info);
result = trio_string_extract(info);
trio_string_destroy(info);
assert(VALID(format));
*result = NULL;
-
+
info = trio_xstring_duplicate("");
if (info == NULL)
{
{
TRIO_VA_START(args, format);
status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
if (status >= 0)
{
{
int status;
trio_string_t *info;
-
+
assert(VALID(format));
*result = NULL;
-
+
info = trio_xstring_duplicate("");
if (info == NULL)
{
else
{
status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
if (status >= 0)
{
trio_string_terminate(info);
@param name
@return Handle.
*/
-TRIO_PUBLIC trio_pointer_t
+TRIO_PUBLIC trio_pointer_t
trio_register
TRIO_ARGS2((callback, name),
trio_callback_t callback,
}
return NULL;
}
-
+
/* Bail out if namespace is too long */
if (trio_length(name) >= MAX_USER_NAME)
return NULL;
-
+
/* Bail out if namespace already is registered */
def = TrioFindNamespace(name, &prev);
if (def)
return NULL;
}
-
+
def = (trio_userdef_t *)TRIO_MALLOC(sizeof(trio_userdef_t));
if (def)
{
if (internalEnterCriticalRegion)
(void)internalEnterCriticalRegion(NULL);
-
+
if (name)
{
/* Link into internal list */
{
if (internalEnterCriticalRegion)
(void)internalEnterCriticalRegion(NULL);
-
+
if (prev == NULL)
internalUserDef = NULL;
else
prev->next = def->next;
-
+
if (internalLeaveCriticalRegion)
(void)internalLeaveCriticalRegion(NULL);
}
#if defined(FORMAT_USER_DEFINED)
assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
#endif
-
+
return (((trio_reference_t *)ref)->parameter->user_data);
}
/*************************************************************************
* trio_get_argument [public]
*/
-trio_pointer_t
+trio_pointer_t
trio_get_argument
TRIO_ARGS1((ref),
trio_pointer_t ref)
#if defined(FORMAT_USER_DEFINED)
assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
#endif
-
+
return ((trio_reference_t *)ref)->parameter->data.pointer;
}
va_list arglist;
assert(VALID(format));
-
+
TRIO_VA_START(arglist, format);
- status = TrioFormatRef((trio_reference_t *)ref, format, &arglist, NULL);
+ status = TrioFormatRef((trio_reference_t *)ref, format, TRIO_VA_LIST_ADDR(arglist), NULL);
TRIO_VA_END(arglist);
return status;
}
va_list arglist)
{
assert(VALID(format));
-
- return TrioFormatRef((trio_reference_t *)ref, format, &arglist, NULL);
+
+ return TrioFormatRef((trio_reference_t *)ref, format, TRIO_VA_LIST_ADDR(arglist), NULL);
}
/*************************************************************************
trio_pointer_t *argarray)
{
assert(VALID(format));
-
+
return TrioFormatRef((trio_reference_t *)ref, format, NULL, argarray);
}
switch (ch)
{
case QUALIFIER_MINUS: /* Scanlist ranges */
-
+
/*
* Both C99 and UNIX98 describes ranges as implementation-
* defined.
return TRIO_ERROR_RETURN(TRIO_EINVAL, index);
if (range_begin > range_end)
return TRIO_ERROR_RETURN(TRIO_ERANGE, index);
-
+
for (i = (int)range_begin; i <= (int)range_end; i++)
characterclass[i]++;
-
+
ch = range_end;
break;
-
+
#if TRIO_EXTENSION
case SPECIFIER_GROUP:
-
+
switch (format[index + 1])
{
case QUALIFIER_DOT: /* Collating symbol */
}
if (format[++i] != SPECIFIER_UNGROUP)
return -1;
-
+
index = i;
break;
-
+
case QUALIFIER_EQUAL: /* Equivalence class expressions */
{
unsigned int j;
unsigned int k;
-
+
if (internalCollationUnconverted)
{
/* Lazy evaluation of collation array */
}
if (format[++i] != SPECIFIER_UNGROUP)
return -1;
-
+
index = i;
}
break;
-
+
case QUALIFIER_COLON: /* Character class expressions */
-
+
if (trio_equal_max(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1,
&format[index]))
{
break;
}
break;
-
+
#endif /* TRIO_EXTENSION */
-
+
default:
characterclass[(int)ch]++;
break;
}
internalDigitsUnconverted = FALSE;
}
-
+
TrioSkipWhitespaces(self);
-
+
if (!(flags & FLAGS_UNSIGNED))
{
/* Leading sign */
isNegative = TRUE;
}
}
-
+
count = self->processed;
-
+
if (flags & FLAGS_ALTERNATIVE)
{
switch (base)
}
else
break;
-
+
number *= base;
number += digit;
gotNumber = TRUE; /* we need at least one digit */
/* Was anything read at all? */
if (!gotNumber)
return FALSE;
-
+
if (target)
*target = (isNegative) ? -((trio_intmax_t)number) : number;
return TRUE;
int i;
char ch;
trio_uintmax_t number;
-
+
assert(VALID(self));
assert(VALID(self->InStream));
break;
}
}
-
+
if (target)
target[i] = ch;
}
int width)
{
int i;
-
+
assert(VALID(self));
assert(VALID(self->InStream));
TrioSkipWhitespaces(self);
-
+
/*
* Continue until end of string is reached, a whitespace is encountered,
* or width is exceeded
int amount = 0;
trio_wchar_t wch;
char buffer[MB_LEN_MAX + 1];
-
+
assert(VALID(self));
assert(VALID(self->InStream));
{
int i;
int size;
-
+
assert(VALID(self));
assert(VALID(self->InStream));
#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
(void)mblen(NULL, 0);
#endif
-
+
/*
* Continue until end of string is reached, a whitespace is encountered,
* or width is exceeded
{
int ch;
int i;
-
+
assert(VALID(self));
assert(VALID(self->InStream));
target[i] = (char)ch;
self->InStream(self, &ch);
}
-
+
if (target)
target[i] = NIL;
return TRUE;
BOOLEAN_T isHex = FALSE;
doubleString[0] = 0;
-
+
if ((width == NO_WIDTH) || (width > (int)sizeof(doubleString) - 1))
width = sizeof(doubleString) - 1;
-
+
TrioSkipWhitespaces(self);
-
+
/*
* Read entire double number from stream. trio_to_double requires
* a string as input, but InStream can be anything, so we have to
self->InStream(self, &ch);
}
break;
-
+
default:
break;
}
-
+
while ((ch != EOF) && (index - start < width))
{
/* Integer part */
return FALSE;
doubleString[index] = 0;
-
+
if (flags & FLAGS_LONGDOUBLE)
{
*((trio_long_double_t *)target) = trio_to_long_double(doubleString, NULL);
char buffer[sizeof(internalNullString)];
flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING);
-
+
if (TrioReadNumber(self,
&number,
flags,
: buffer,
0,
sizeof(internalNullString) - 1))
- {
+ {
if (trio_equal_case(buffer, internalNullString))
{
if (target)
}
}
#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
-
+
if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT))
{
return (assignment > 0) ? assignment : EOF;
}
-
+
if (CHAR_IDENTIFIER == format[index])
{
if (CHAR_IDENTIFIER == format[index + 1])
/* Skip the parameter entries */
while (parameters[i].type == FORMAT_PARAMETER)
i++;
-
+
flags = parameters[i].flags;
/* Find width */
width = parameters[i].width;
/* Get base from parameter list */
base = (int)parameters[base].data.number.as_signed;
}
-
+
switch (parameters[i].type)
{
case FORMAT_INT:
}
}
break; /* FORMAT_INT */
-
+
case FORMAT_STRING:
#if TRIO_WIDECHAR
if (flags & FLAGS_WIDECHAR)
}
/* Skip over group specifier */
index++;
-
+
memset(characterclass, 0, sizeof(characterclass));
rc = TrioGetCharacterClass(format,
&index,
}
}
break; /* FORMAT_COUNT */
-
+
case FORMAT_CHAR:
#if TRIO_WIDECHAR
if (flags & FLAGS_WIDECHAR)
}
else
return assignment;
-
+
index++;
}
}
size_t sourceSize,
void (*InStream) TRIO_PROTO((trio_class_t *, int *)),
TRIO_CONST char *format,
- va_list *arglist,
+ TRIO_VA_LIST_PTR arglist,
trio_pointer_t *argarray)
{
int status;
TrioSetLocale();
}
#endif
-
+
status = TrioParse(TYPE_SCAN, format, parameters, arglist, argarray);
if (status < 0)
return status;
trio_class_t *self,
int *intPointer)
{
- FILE *file = (FILE *)self->location;
+ FILE *file;
assert(VALID(self));
+ assert(VALID(self->location));
assert(VALID(file));
+ file = (FILE *)self->location;
+
self->current = fgetc(file);
if (self->current == EOF)
{
self->processed++;
self->committed++;
}
-
+
if (VALID(intPointer))
{
*intPointer = self->current;
trio_class_t *self,
int *intPointer)
{
- int fd = *((int *)self->location);
+ int fd;
int size;
unsigned char input;
assert(VALID(self));
+ assert(VALID(self->location));
+
+ fd = *((int *)self->location);
size = read(fd, &input, sizeof(char));
if (size == -1)
self->committed++;
self->processed++;
}
-
+
if (VALID(intPointer))
{
*intPointer = self->current;
int *intPointer)
{
trio_custom_t *data;
-
+
assert(VALID(self));
assert(VALID(self->location));
self->current = (data->stream.in == NULL)
? NIL
: (data->stream.in)(data->closure);
-
+
if (self->current == NIL)
{
self->current = EOF;
self->processed++;
self->committed++;
}
-
+
if (VALID(intPointer))
{
*intPointer = self->current;
self->processed++;
self->committed++;
}
-
+
if (VALID(intPointer))
{
*intPointer = self->current;
va_list args;
assert(VALID(format));
-
+
TRIO_VA_START(args, format);
status = TrioScan((trio_pointer_t)stdin, 0,
TrioInStreamFile,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
va_list args)
{
assert(VALID(format));
-
+
return TrioScan((trio_pointer_t)stdin, 0,
TrioInStreamFile,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
}
TRIO_PUBLIC int
trio_pointer_t *args)
{
assert(VALID(format));
-
+
return TrioScan((trio_pointer_t)stdin, 0,
TrioInStreamFile,
format, NULL, args);
assert(VALID(file));
assert(VALID(format));
-
+
TRIO_VA_START(args, format);
status = TrioScan((trio_pointer_t)file, 0,
TrioInStreamFile,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
{
assert(VALID(file));
assert(VALID(format));
-
+
return TrioScan((trio_pointer_t)file, 0,
TrioInStreamFile,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
}
TRIO_PUBLIC int
{
assert(VALID(file));
assert(VALID(format));
-
+
return TrioScan((trio_pointer_t)file, 0,
TrioInStreamFile,
format, NULL, args);
va_list args;
assert(VALID(format));
-
+
TRIO_VA_START(args, format);
status = TrioScan((trio_pointer_t)&fd, 0,
TrioInStreamFileDescriptor,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
va_list args)
{
assert(VALID(format));
-
+
return TrioScan((trio_pointer_t)&fd, 0,
TrioInStreamFileDescriptor,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
}
TRIO_PUBLIC int
trio_pointer_t *args)
{
assert(VALID(format));
-
+
return TrioScan((trio_pointer_t)&fd, 0,
TrioInStreamFileDescriptor,
format, NULL, args);
assert(VALID(stream));
assert(VALID(format));
-
+
TRIO_VA_START(args, format);
data.stream.in = stream;
data.closure = closure;
- status = TrioScan(&data, 0, TrioInStreamCustom, format, &args, NULL);
+ status = TrioScan(&data, 0, TrioInStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
va_list args)
{
trio_custom_t data;
-
+
assert(VALID(stream));
assert(VALID(format));
data.stream.in = stream;
data.closure = closure;
- return TrioScan(&data, 0, TrioInStreamCustom, format, &args, NULL);
+ return TrioScan(&data, 0, TrioInStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
}
TRIO_PUBLIC int
trio_pointer_t *args)
{
trio_custom_t data;
-
+
assert(VALID(stream));
assert(VALID(format));
assert(VALID(buffer));
assert(VALID(format));
-
+
TRIO_VA_START(args, format);
status = TrioScan((trio_pointer_t)&buffer, 0,
TrioInStreamString,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
TRIO_VA_END(args);
return status;
}
{
assert(VALID(buffer));
assert(VALID(format));
-
+
return TrioScan((trio_pointer_t)&buffer, 0,
TrioInStreamString,
- format, &args, NULL);
+ format, TRIO_VA_LIST_ADDR(args), NULL);
}
TRIO_PUBLIC int
{
assert(VALID(buffer));
assert(VALID(format));
-
+
return TrioScan((trio_pointer_t)&buffer, 0,
TrioInStreamString,
format, NULL, args);