<ctype.h>
and <lctype.h>
, define
several macros that are useful in the analysis of text data. Most of
these macros enable you to determine quickly the type of a
character (whether it is alphabetic, numeric, punctuation, and so on).
These macros refer to an external array that is indexed by the
character itself, so they are generally much faster than functions that
check the character against a range or discrete list of values. Note
that this array is actually indexed by the character value plus 1, so
the standard EOF
value ( - 1) can be tested in a macro without
yielding a nonsense result. EOF
yields a 0 result for all of the
macros because it is not defined as any of the character types. Also,
note that the results produced by most of these functions are affected
by the current locale's LC_CTYPE
category, which may cause a
different character type array to be used than the one supplied for the
default C locale. See Chapter 10, "Localization," in SAS/C Library Reference, Third Edition, Volume 2,& Release 6.00 for
details on locales.
Another advantage of the character type macros is that they prevent problems when programs are moved between machines that use ASCII versus EBCDIC character sets. Programs using these macros are not dependent on a specific character set.
The following are character type macros and functions:
isalnum
isalpha
isascii
iscntrl
iscsym
iscymf
isdigit
isebcdic
isgraph
islower
isprint
ispunct
isspace
isupper
isxdigit
toebcdic
tolower
toupper
Table 2.1 lists the macros defined in the character
type header files <ctype.h>
and <lctype.h>
. The library conforms
to the ISO/ANSI specification in that the macro arguments are evaluated
only once. However, many implementations do not conform to this
specification. For maximum portability, beware of the side
effects of using expressions such as function calls and increment or decrement
operators. You should include <ctype.h>
or <lctype.h>
if you use
any of these macros; otherwise, the compiler generates a reference to a
function of the same name.
Table 2.1 Character Type Macros and Functions and Their Return Values
Function Return Value
isalnum(c) nonzero if c is alphabetic or digit; 0 if not isalpha(c) nonzero if c is alphabetic; 0 if not isascii(c) * nonzero if c is the EBCDIC equivalent of an ASCII character; 0 if not iscntrl(c) nonzero if c is control character; 0 if not iscsym(c) * nonzero if valid character for C identifier; 0 if not iscsymf(c) nonzero if valid first character for C identifier; 0 if not isdigit(c) * nonzero if c is a digit 0 - 9; 0 if not isebcdic(c) * nonzero if a valid EBCDIC character; 0 if not isgraph(c) nonzero if c is graphic (excluding the blank character); 0 if not islower(c) nonzero if c is lowercase; 0 if not isprint(c) nonzero if c is printable (including blank); 0 if not ispunct(c) nonzero if c is punctuation; 0 if not isspace(c) nonzero if c is white space; 0 if not isupper(c) nonzero if c is uppercase; 0 if not isxdigit(c) * nonzero if c is a hexadecimal digit (0 - 9, A - F, a - f); 0 if not toebcdic(c) * truncates integer to valid EBCDIC character tolower(c) converts c to lowercase, if uppercase toupper(c) converts c to uppercase, if lowercase*These functions are not affected by the locale's
LC_TYPE
category.
Note:
The toupper
and tolower
macros generate the value of
c
unchanged if it does not qualify for the conversion.
a
str
mem
mem
routines are always passed an
explicit string length since the string may contain no null characters,
or more than one null character.
Two standard string functions that begin with the letters str
,
strcoll
, and strxfrm
pertain to localization and are discussed in
Chapter 10, "Localization," in SAS/C Library Reference, Volume 2 .
The following are string functions:
atof
atoi
atol
memchr
memcmp
memcmpp
memcpy
memcpyp
memfil
memlwr
memmove
memscan
memscntb
memscan
memset
memupr
memxlt
stcpm
stcpma
strcat
strchr
strcmp
strcpy
strcspn
strlen
strlwr
strncat
strncmp
strncpy
strpbrk
strrchr
strrcspn
strrspn
strsave
strscan
strscntb
strscan
strspn
strstr
strtod
strtok
strtol
strtoul
strupr
strxlt
xltable
int
or unsigned
position of a character in a string compute
the position beginning at 0.
memcmp
, memcpy
,
and memset
by controlling the type of the length
argument. The
compiler inspects the type before the argument is converted to the
type specified in the function prototype. If the type of the
length
argument is one of the types in Table 2.2, the compiler
generates only the code required for the maximum value of the type.
Table 2.2 shows the maximum values of these types. Note that
these values can be obtained from the <limits.h>
header file.
You can use only the types shown in Table 2.2 (in addition to size_t
). If
the length
argument has any other type, the compiler issues a warning
message.
Table 2.2 Types Acceptable as Length Arguments in Built-in Functions
Type Maximum Value
char 255 unsigned char 255 short 32767 signed short 32767 unsigned short 65535
If Table 2.2 lists the type of the length
argument, the
function will not be required to operate on more than 16 megabytes of
data. Therefore, the compiler does not generate a call to the true
(that is, separately linked) function to handle that case.
If the length
argument is one of the char
types, the
compiler generates a MOVE instruction (which can handle up to 256
characters) rather than a MOVE LONG (which can handle up to 16
megabytes of characters). Because the MOVE LONG instruction is one of
the slowest instructions in the IBM 370 instruction set, generating a
MOVE saves execution time.
<string.h>
or <lcstring.h>
, and do not use the function name in an
#undef
preprocessing directive.
length
argument as one of the types in Table 2.2.
length
argument to a wider type. This defeats the
compiler's inspection of the type.
You may want to define one or more macros that cast the length
argument to a shorter type. For example, here is a program that
defines two such macros:
#include <string.h> /* Copy up to 32767 characters. */ #define memcpys(to, from, length) memcpy(to, from, (short)length) /* Copy up to 255 characters. */ #define memcpyc(to, from, length) memcpy(to, from, (char)length) . . . int strsz; /* strsz is known to be less than 32K. */ char *dest, *src; memcpys(dest, src, strsz); /* casts strsz to short */ . . .
Some recent IBM processors include a hardware feature called the
Logical String Assist, which implements the C functions
strlen
, strcpy
,
strcmp
, memchr
, and strchr
in hardware. To make use of this hardware feature, #define
the
symbol _USELSA
before including <string.h>
or
<lcstring.h>
. The resulting code will not
execute on hardware that does not have the Logical String Assist
feature installed.
<math.h>
should be included when
using most of these functions. See the individual function descriptions
to determine whether the header file is required for that function.
The library also provides the standard header file <float.h>
, which
provides additional information about floating-point arithmetic. The
contents of this header file are listed here:
#define FLT_RADIX 16 /* hardware float radix */ #define FLT_ROUNDS 0 /* float addition does not round. */ #define FLT_MANT_DIG 6 /* hex digits in float mantissa */ #define DBL_MANT_DIG 14 /* hex digits in double mantissa */ #define LDBL_MANT_DIG 14 /* hex digits in long double mantissa */ #define FLT_DIG 6 /* float decimal precision */ #define DBL_DIG 16 /* double decimal precision */ #define LDBL_DIG 16 /* long double decimal precision */ #define FLT_MIN_EXP -64 /* minimum exponent of 16 for float */ #define DBL_MIN_EXP -64 /* minimum exponent of 16 for double */ #define LDBL_MIN_EXP -64 /* minimum exponent of 16 for long */ /* double */ #define FLT_MIN_10_EXP -78 /* minimum float power of 10 */ #define DBL_MIN_10_EXP -78 /* minimum double power of 10 */ #define LDBL_MIN_10_EXP -78 /* minimum long double power of 10 */ #define FLT_MAX_EXP 63 /* maximum exponent of 16 for float */ #define DBL_MAX_EXP 63 /* maximum exponent of 16 for double */ #define LDBL_MAX_EXP 63 /* maximum exponent of 16 for long */ /* double */ #define FLT_MAX_10_EXP 75 /* maximum float power of 10 */ #define DBL_MAX_10_EXP 75 /* maximum double power of 10 */ #define LDBL_MAX_10_EXP 75 /* maximum long double power of 10 */ #define FLT_MAX .7237005e76F /* maximum float */ #define DBL_MAX .72370055773322621e76 /* maximum double */ #define LDBL_MAX .72370055773322621e76L /* maximum long double */ /* smallest float x such that 1.0 + x != 1.0 */ #define FLT_EPSILON .9536743e-6F /* smallest double x such that 1.0 + x != 1.0 */ #define DBL_EPSILON .22204460492503131e-15 /* smallest long double x such that 1.0 - x != 1.0 */ #define LDBL_EPSILON .22204460492503131e-15L #define FLT_MIN .5397606e-78F /* minimum float */ #define DBL_MIN .53976053469340279e-78 /* minimum double */ #define LDBL_MIN .53976053469340279e-78L /* minimum long double */Additionally, the header file
<lcmath.h>
declares useful mathematical
constants, as listed in Table 2.3.
Table 2.3 Constant Values Declared in lcmath.h
Constant Representation
M_PI pi M_PI_2 pi/2 M_PI_4 pi/4 M_1_PI 1/pi M_2_PI 2/pi M_E e HUGE* largest possible double TINY double closest to zero LOGHUGE log(HUGE) LOGTINY log(TINY)*
math.h
defines the value HUGE_VAL
, which is an
ANSI-defined symbol with the same value.
abs
acos
asin
atan
atan2
ceil
cos
cosh
div
erf
erfc
exp
fabs
floor
fmax
fmin
fmod
frexp
gamma
hypot
j0
j1
jn
labs
ldexp
_ldexp
ldexp
ldiv
log
log10
_matherr
max
min
modf
pow
rand
sin
sinh
sqrt
srand
tan
tanh
y0
y1
yn
va_arg
va_end
va_start
va_list
are defined in the header file
<stdarg.h>
. For more information on <stdarg.h>
,
see the function description for va_start
.
bsearch
pdset
pdval
qsort
main
function gains control, is system dependent. However, program exit is
not always system dependent, although it does have some implementation
dependencies.
One simple way to terminate execution of a C program is for the
main
function to execute a return
statement; another is for the
main
function to drop through its terminating brace. However, in many
cases, a more flexible program exit capability is needed. This
capability is provided by the exit
function described in this
section. This function offers the advantage of allowing any function
(not just main
) to terminate the program, and it allows information
to be passed to other programs.
For programs using the compiler indep
feature, program execution can also be terminated
by calling the L$UEXIT routine from non-C code, as described in Appendix 5, "Using the indep Option for
Interlanguage Communication," in the SAS/C Compiler and Library User's Guide, Fourth Edition
You can use the atexit
function to define a function to be
called during normal program termination, either due to a call to
exit
or due to return from the main
function.
The abend
and abort
functions can also be used to
terminate execution of a C program. These functions cause abnormal
termination, which causes both library cleanup and user cleanup
(defined by atexit
routines) to be bypassed.
In some cases, it is useful for a program to pass control directly to
another part of the program (within a different function) without
having to go through a long and possibly complicated series of function
returns. The setjmp
and longjmp
functions provide a general
capability for passing control in this way.
You can use the SAS/C extension blkjmp
to intercept calls to
longjmp
that cause the calling routine to be terminated. This
is useful for functions that allocate resources that must be released
before the function is terminated. You can also use blkjmp
to intercept calls to exit
.
Note:
The jump functions use a special type, jmp_buf
, which is defined in the
<setjmp.h>
header file.
Several of the program control functions have a special version for use in the Systems Programming Environment. See Implementation of Functions for more details.
The program control functions are
abend
abort
atexit
blkjmp
exit
longjmp
onjmp
onjmpout
setjmp
malloc
family of functions (calloc
,
malloc
, free
, and realloc
)
conforms to the ISO/ANSI standard and is
therefore the most portable (and usually the most convenient) technique
for memory allocation. The pool
family of functions (pool
,
palloc
, pfree
, and pdel
) is not portable but is more
efficient for many applications. Finally, the sbrk
function
provides compatibility with traditional UNIX low-level memory
management but is inflexible because the maximum amount of memory that
can be allocated is fixed independently of the size of the region or
virtual machine. All of the memory allocation functions return a pointer of type
void *
that is guaranteed to be properly aligned to store any object.
All of these interfaces, except sbrk
, use the operating system's
standard memory allocation technique (GETMAIN under MVS, DMSFREE under
CMS, or CMSSTOR under bimodal CMS) to allocate memory blocks. This
means that blocks allocated by the C language may be interspersed with
blocks allocated by the operating system or by other programs. It also
means that the C program is always able to allocate memory up to the
limits imposed by the region or virtual machine size.
If your application requires more complete control of memory allocation parameters, you can call the GETMAIN, DMSFREE, and CMSSTOR functions yourself, as described in Chapter 14, "Systems Programming with the SAS/C Compiler," of the SAS/C Compiler and Library User's Guide, Fourth Edition . Because the other memory allocation functions do not invoke the operating system every time they are called, they are generally more efficient than direct use of the operating system services.
Under MVS, all SAS/C memory allocation (except when the program invokes
the GETMAIN SVC directly) is task related. Thus, it is not valid to use
malloc
to allocate a block of memory under one TCB and free it
under another. Even if the two tasks share all MVS subpools, this error will
cause memory management chains to become erroneously linked, which will
eventually cause a memory management ABEND in one or more of the involved tasks.
Even the SAS/C pool allocation functions, such as palloc
, do not allow
memory allocation to be managed across task boundaries. palloc
calls
malloc
to extend a pool if necessary; therefore, it may corrupt memory
chains if used under the wrong task. Additionally, the code generated
by palloc
and pfree
does no synchronization, which means that
simultaneous use on the same pool in several tasks could cause the
same element to be allocated twice, or lost from the memory chains.
If an application requires multiple SAS/C subtasks with memory shared between subtasks, we recommend that you assign to a single task the job of performing all shared memory allocation and deallocation for the application. All other tasks should then use POST/WAIT logic to request the allocation task to allocate or free memory. This design ensures that all shared memory is managed as a unit and avoids synchronization issues caused by simultaneous allocation requests.
The memory allocation functions are
calloc
free
malloc
palloc
pdel
pfree
pool
realloc
sbrk
assert
, generate a library traceback with btrace
, and suppress
library diagnostics with quiet
.
The diagnostic control functions are
assert
btrace
perror
quiet
strerror
<time.h>
.
The POSIX standards mandate several changes to the SAS/C timing
functions. As a result, the SAS/C Release 6.00 library assumes a new
default epoch and can process time-zone information defined via
the TZ
environment variable.
In previous releases of SAS/C, time_t
values were measured from
the 370 epoch, starting at January 1, 1900. In accordance with
the POSIX specification , the SAS/C Release 6.00 library measures time
from the UNIX epoch, starting at January 1, 1970.
A program with special requirements can specifically define its own
epoch by declaring the extern variable _epoch
, as in the following
example:
#include <time.h> time_t _epoch = _EPOCH_370;This declaration specifies the 370 epoch. You can also use the value
_EPOCH_UNIX
to specify the standard UNIX epoch. Any legitimate
time_t
value can be used as the epoch, as in this example, which
defines the start of the epoch as January 1, 1971:
#include <time.h> time_t _epoch = _EPOCH_UNIX+365*86400;Also, if the
TZ
environment variable is set, the SAS/C mktime
,
ctime
, localtime
, and strftime
routines will take time-zone
information into account. For TSO or CMS programs, TZ
may be
defined as an external or permanent scope environment variable.
Note:
The TZ
environment variable expresses offset from Greenwich
mean time. The SAS/C library assumes that the hardware time-of-day
clock has been set to accurately reflect Greenwich time, as
recommended by the IBM ESA Principles of Operation. If the hardware
time-of-day clock does not accurately reflect Greenwich time, then
processing of the TZ
information will not be correct, and applications
depending on accurate local time information may fail.
The <time.h>
header file defines two types that describe time values:
time_t
and struct tm
. The type time_t
is a numeric type
used to contain time values expressed in the seconds after some
implementation-defined base point (or era). The type struct tm
is
a structure that is produced by several of the timing routines; it
contains time and date information in a more readily usable form. The
struct tm
structure is defined to contain the following components:
int tm_sec; /* seconds after the minute (0-59) */ int tm_min; /* minutes after the hour (0-59) */ int tm_hour; /* hours since midnight (0-23) */ int tm_mday; /* day of the month (1-31) */ int tm_mon; /* months since January (0-11) */ int tm_year; /* years since 1900 */ int tm_wday; /* days since Sunday (0-6) */ int tm_yday; /* days since January 1 (0-365) */ int tm_isdst; /* Daylight Savings Time flag. */Routines are provided to convert
time_t
values to struct tm
values and to convert either of these types to a formatted string
suitable for printing.
The resolution and accuracy of time values vary from implementation to
implementation. Timing functions under traditional UNIX C compilers return a value
of type long
. The library implements time_t
as a double
to allow more accurate time measurement. Keep this difference in mind for
programs ported among several environments.
The timing functions are
asctime
clock
ctime
difftime
gmtime
localtime
mktime
strftime
time
tzset
The library's I/O implementation is designed to
The library provides several I/O techniques to meet the needs of different applications. To achieve the best results, you must make an informed choice about the techniques to use. Criteria that should influence your choice are
To make these choices, you need to understand general C I/O concepts as well as the native I/O types and file structures supported by the 370 operating systems, MVS and CMS.
Details about C I/O concepts and functions can be found in I/O Functions .
The I/O functions are
afflush
afopen
afread
afread0
afreadh
afreopen
afwrite
afwrite0
afwriteh
aopen
clearerr
close
open
_close
closedir
clrerr
creat
ctermid
dup
dup2
fattr
fclose
fcntl
_fcntl
fdopen
feof
ferror
ffixed
fflush
fgetc
fgetpos
fgets
fileno
fnm
fopen
fprintf
fputc
fputs
fread
freopen
fscanf
fseek
fsetpos
fsync
_fsync
ftell
fterm
ftruncate
fwrite
getc
getchar
gets
isatty
kdelete
kgetpos
kinsert
kreplace
kretrv
ksearch
kseek
ktell
lseek
_lseek
open
_open
opendir
pclose
popen
pipe
popen
printf
putc
putchar
puts
read
_read
readdir
rewind
rewinddir
scanf
setbuf
setvbuf
snprintf
sprintf
sscanf
tmpfile
tmpnam
ttyname
ungetc
vfprintf
vprintf
vsnprintf
vsprintf
write
_write
access
_access
chdir
chmod
cmsdfind
cmsdnext
cmsffind
cmsfnext
cmsfquit
cmsffind
cmsstat
fchmod
fstat
getcwd
link
lstat
mkdir
mkfifo
oeddinfo
osddinfo
osdfind
osdnext
osdquit
osdsinfo
readlink
remove
rename
_rename
rmdir
sfsstat
stat
symlink
unlink
_unlink
utime
The system interface functions are
clearenv
cuserid
getenv
getlogin
iscics
oslink
putenv
setenv
system
The signal-handling functions are
alarm, alarmd
ecbpause
ecbsuspend
kill
oesigsetup
pause
raise
sigaction
sigaddset
sigdelset
sigemptyset
sigfillset
sigismember
sigset_t
objects
sigblock
sigchk
siggen
siginfo
siglongjmp
signal
sigpause
sigpending
sigprocmask
sigsetjmp
sigsetmask
sigsuspend
sleep, sleepd
Copyright (c) 1998 SAS Institute Inc. Cary, NC, USA. All rights reserved.