<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.