summaryrefslogtreecommitdiff
path: root/src/lib/libast
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libast')
-rw-r--r--src/lib/libast/Makefile442
-rw-r--r--src/lib/libast/Mamfile7356
-rw-r--r--src/lib/libast/README95
-rw-r--r--src/lib/libast/RELEASE1769
-rw-r--r--src/lib/libast/aso/aso-fcntl.c188
-rw-r--r--src/lib/libast/aso/aso-sem.c193
-rw-r--r--src/lib/libast/aso/aso.c866
-rw-r--r--src/lib/libast/aso/asohdr.h71
-rw-r--r--src/lib/libast/aso/asolock.c55
-rw-r--r--src/lib/libast/aso/asometh.c43
-rw-r--r--src/lib/libast/aso/asorelax.c56
-rw-r--r--src/lib/libast/astsa/README-astsa15
-rw-r--r--src/lib/libast/astsa/aso.c56
-rw-r--r--src/lib/libast/astsa/aso.h32
-rw-r--r--src/lib/libast/astsa/ast.c85
-rw-r--r--src/lib/libast/astsa/ast.h156
-rw-r--r--src/lib/libast/astsa/ast_common.h49
-rw-r--r--src/lib/libast/astsa/astsa.manifest50
-rw-r--r--src/lib/libast/astsa/astsa.mm33
-rw-r--r--src/lib/libast/astsa/astsa.omk82
-rw-r--r--src/lib/libast/astsa/ccode.h34
-rw-r--r--src/lib/libast/astsa/debug.h29
-rw-r--r--src/lib/libast/astsa/error.c103
-rw-r--r--src/lib/libast/astsa/error.h66
-rw-r--r--src/lib/libast/astsa/hashkey.h61
-rwxr-xr-xsrc/lib/libast/astsa/mkast_sa150
-rw-r--r--src/lib/libast/astsa/option.h106
-rw-r--r--src/lib/libast/astsa/optlib.h105
-rw-r--r--src/lib/libast/astsa/sfstr.c246
-rw-r--r--src/lib/libast/astsa/sfstr.h60
-rw-r--r--src/lib/libast/astsa/strdup.c37
-rw-r--r--src/lib/libast/astsa/strmatch.c597
-rw-r--r--src/lib/libast/astsa/times.h27
-rw-r--r--src/lib/libast/astsa/vmalloc.c102
-rw-r--r--src/lib/libast/astsa/vmalloc.h61
-rw-r--r--src/lib/libast/cdt/cdtlib.h183
-rw-r--r--src/lib/libast/cdt/dtclose.c66
-rw-r--r--src/lib/libast/cdt/dtcomp.c60
-rw-r--r--src/lib/libast/cdt/dtdisc.c91
-rw-r--r--src/lib/libast/cdt/dthash.c431
-rw-r--r--src/lib/libast/cdt/dthdr.h37
-rw-r--r--src/lib/libast/cdt/dtlist.c387
-rw-r--r--src/lib/libast/cdt/dtmethod.c107
-rw-r--r--src/lib/libast/cdt/dtnew.c81
-rw-r--r--src/lib/libast/cdt/dtopen.c177
-rw-r--r--src/lib/libast/cdt/dtstrhash.c61
-rw-r--r--src/lib/libast/cdt/dttree.c696
-rw-r--r--src/lib/libast/cdt/dtview.c157
-rw-r--r--src/lib/libast/cdt/dtwalk.c53
-rw-r--r--src/lib/libast/comp/atexit.c115
-rw-r--r--src/lib/libast/comp/basename.c55
-rw-r--r--src/lib/libast/comp/catopen.c182
-rw-r--r--src/lib/libast/comp/closelog.c51
-rw-r--r--src/lib/libast/comp/conf.sh1635
-rw-r--r--src/lib/libast/comp/conf.tab601
-rw-r--r--src/lib/libast/comp/creat64.c38
-rw-r--r--src/lib/libast/comp/dirname.c61
-rw-r--r--src/lib/libast/comp/dup2.c46
-rw-r--r--src/lib/libast/comp/eaccess.c139
-rw-r--r--src/lib/libast/comp/errno.c40
-rw-r--r--src/lib/libast/comp/execlp.c50
-rw-r--r--src/lib/libast/comp/execve.c70
-rw-r--r--src/lib/libast/comp/execvp.c50
-rw-r--r--src/lib/libast/comp/execvpe.c78
-rw-r--r--src/lib/libast/comp/fakelink.h34
-rw-r--r--src/lib/libast/comp/fcntl.c98
-rw-r--r--src/lib/libast/comp/fmtmsg.h141
-rw-r--r--src/lib/libast/comp/fmtmsglib.c335
-rw-r--r--src/lib/libast/comp/fnmatch.c79
-rw-r--r--src/lib/libast/comp/fnmatch.h61
-rw-r--r--src/lib/libast/comp/frexp.c153
-rw-r--r--src/lib/libast/comp/frexpl.c161
-rw-r--r--src/lib/libast/comp/fsync.c46
-rw-r--r--src/lib/libast/comp/ftw.c50
-rw-r--r--src/lib/libast/comp/ftw.h60
-rw-r--r--src/lib/libast/comp/getdate.c83
-rw-r--r--src/lib/libast/comp/getgroups.c78
-rw-r--r--src/lib/libast/comp/getlogin.c42
-rw-r--r--src/lib/libast/comp/getopt.c78
-rw-r--r--src/lib/libast/comp/getopt.h51
-rw-r--r--src/lib/libast/comp/getoptl.c151
-rw-r--r--src/lib/libast/comp/getpgrp.c47
-rw-r--r--src/lib/libast/comp/getsubopt.c84
-rw-r--r--src/lib/libast/comp/getwd.c37
-rw-r--r--src/lib/libast/comp/gross.c99
-rw-r--r--src/lib/libast/comp/gross_sgi.h188
-rw-r--r--src/lib/libast/comp/hsearch.c138
-rw-r--r--src/lib/libast/comp/iconv.c1599
-rw-r--r--src/lib/libast/comp/killpg.c40
-rw-r--r--src/lib/libast/comp/libgen.h52
-rw-r--r--src/lib/libast/comp/link.c47
-rw-r--r--src/lib/libast/comp/localeconv.c100
-rw-r--r--src/lib/libast/comp/lstat.c39
-rw-r--r--src/lib/libast/comp/memccpy.c51
-rw-r--r--src/lib/libast/comp/memchr.c49
-rw-r--r--src/lib/libast/comp/memcmp.c45
-rw-r--r--src/lib/libast/comp/memcpy.c60
-rw-r--r--src/lib/libast/comp/memmove.c53
-rw-r--r--src/lib/libast/comp/memset.c42
-rw-r--r--src/lib/libast/comp/mkdir.c62
-rw-r--r--src/lib/libast/comp/mkfifo.c50
-rw-r--r--src/lib/libast/comp/mknod.c50
-rw-r--r--src/lib/libast/comp/mktemp.c85
-rw-r--r--src/lib/libast/comp/mktime.c77
-rw-r--r--src/lib/libast/comp/mount.c49
-rw-r--r--src/lib/libast/comp/nftw.c61
-rw-r--r--src/lib/libast/comp/omitted.c1152
-rw-r--r--src/lib/libast/comp/open.c119
-rw-r--r--src/lib/libast/comp/openlog.c58
-rw-r--r--src/lib/libast/comp/putenv.c53
-rw-r--r--src/lib/libast/comp/re_comp.c81
-rw-r--r--src/lib/libast/comp/re_comp.h41
-rw-r--r--src/lib/libast/comp/readlink.c61
-rw-r--r--src/lib/libast/comp/realpath.c48
-rw-r--r--src/lib/libast/comp/regcmp.c224
-rw-r--r--src/lib/libast/comp/regexp.c123
-rw-r--r--src/lib/libast/comp/regexp.h129
-rw-r--r--src/lib/libast/comp/remove.c49
-rw-r--r--src/lib/libast/comp/rename.c98
-rw-r--r--src/lib/libast/comp/resolvepath.c72
-rw-r--r--src/lib/libast/comp/rmdir.c66
-rw-r--r--src/lib/libast/comp/setenv.c58
-rw-r--r--src/lib/libast/comp/setlocale.c2865
-rw-r--r--src/lib/libast/comp/setlogmask.c48
-rw-r--r--src/lib/libast/comp/setpgid.c80
-rw-r--r--src/lib/libast/comp/setsid.c90
-rw-r--r--src/lib/libast/comp/sigflag.c52
-rw-r--r--src/lib/libast/comp/sigunblock.c63
-rw-r--r--src/lib/libast/comp/spawnveg.c296
-rw-r--r--src/lib/libast/comp/statvfs.c163
-rw-r--r--src/lib/libast/comp/strcasecmp.c58
-rw-r--r--src/lib/libast/comp/strchr.c57
-rw-r--r--src/lib/libast/comp/strftime.c104
-rw-r--r--src/lib/libast/comp/strncasecmp.c62
-rw-r--r--src/lib/libast/comp/strptime.c82
-rw-r--r--src/lib/libast/comp/strrchr.c60
-rw-r--r--src/lib/libast/comp/strstr.c76
-rw-r--r--src/lib/libast/comp/strtod.c31
-rw-r--r--src/lib/libast/comp/strtol.c34
-rw-r--r--src/lib/libast/comp/strtold.c50
-rw-r--r--src/lib/libast/comp/strtoll.c44
-rw-r--r--src/lib/libast/comp/strtoul.c35
-rw-r--r--src/lib/libast/comp/strtoull.c45
-rw-r--r--src/lib/libast/comp/swab.c60
-rw-r--r--src/lib/libast/comp/symlink.c59
-rw-r--r--src/lib/libast/comp/syslog.c367
-rw-r--r--src/lib/libast/comp/syslog.h132
-rw-r--r--src/lib/libast/comp/sysloglib.h54
-rw-r--r--src/lib/libast/comp/system.c55
-rw-r--r--src/lib/libast/comp/tempnam.c58
-rw-r--r--src/lib/libast/comp/tmpnam.c51
-rw-r--r--src/lib/libast/comp/transition.c86
-rw-r--r--src/lib/libast/comp/tsearch.c240
-rw-r--r--src/lib/libast/comp/unlink.c38
-rw-r--r--src/lib/libast/comp/unsetenv.c50
-rw-r--r--src/lib/libast/comp/vfork.c55
-rw-r--r--src/lib/libast/comp/waitpid.c199
-rw-r--r--src/lib/libast/comp/wc.c139
-rw-r--r--src/lib/libast/comp/wordexp.c217
-rw-r--r--src/lib/libast/comp/wordexp.h63
-rw-r--r--src/lib/libast/dir/dirlib.h174
-rw-r--r--src/lib/libast/dir/dirstd.h63
-rw-r--r--src/lib/libast/dir/getdents.c166
-rw-r--r--src/lib/libast/dir/opendir.c95
-rw-r--r--src/lib/libast/dir/readdir.c61
-rw-r--r--src/lib/libast/dir/rewinddir.c46
-rw-r--r--src/lib/libast/dir/seekdir.c56
-rw-r--r--src/lib/libast/dir/telldir.c43
-rw-r--r--src/lib/libast/disc/memfatal.c82
-rw-r--r--src/lib/libast/disc/sfdcdio.c229
-rw-r--r--src/lib/libast/disc/sfdcdos.c416
-rw-r--r--src/lib/libast/disc/sfdcfilter.c186
-rw-r--r--src/lib/libast/disc/sfdchdr.h28
-rw-r--r--src/lib/libast/disc/sfdcmore.c369
-rw-r--r--src/lib/libast/disc/sfdcprefix.c153
-rw-r--r--src/lib/libast/disc/sfdcseekable.c227
-rw-r--r--src/lib/libast/disc/sfdcslow.c84
-rw-r--r--src/lib/libast/disc/sfdcsubstr.c217
-rw-r--r--src/lib/libast/disc/sfdctee.c102
-rw-r--r--src/lib/libast/disc/sfdcunion.c203
-rw-r--r--src/lib/libast/disc/sfkeyprintf.c392
-rw-r--r--src/lib/libast/disc/sfstrtmp.c62
-rw-r--r--src/lib/libast/features/align.c188
-rw-r--r--src/lib/libast/features/api11
-rw-r--r--src/lib/libast/features/aso671
-rw-r--r--src/lib/libast/features/botch.c72
-rw-r--r--src/lib/libast/features/ccode81
-rw-r--r--src/lib/libast/features/common624
-rw-r--r--src/lib/libast/features/dirent275
-rw-r--r--src/lib/libast/features/eaccess11
-rw-r--r--src/lib/libast/features/errno31
-rw-r--r--src/lib/libast/features/fcntl.c360
-rw-r--r--src/lib/libast/features/float1191
-rw-r--r--src/lib/libast/features/fs251
-rw-r--r--src/lib/libast/features/hack1
-rw-r--r--src/lib/libast/features/iconv116
-rw-r--r--src/lib/libast/features/isoc9913
-rw-r--r--src/lib/libast/features/lib664
-rw-r--r--src/lib/libast/features/libpath.sh73
-rw-r--r--src/lib/libast/features/limits.c339
-rw-r--r--src/lib/libast/features/locale28
-rw-r--r--src/lib/libast/features/map.c565
-rw-r--r--src/lib/libast/features/mmap342
-rw-r--r--src/lib/libast/features/mode.c218
-rw-r--r--src/lib/libast/features/ndbm29
-rw-r--r--src/lib/libast/features/nl_types64
-rw-r--r--src/lib/libast/features/omitted110
-rw-r--r--src/lib/libast/features/options1
-rw-r--r--src/lib/libast/features/param.sh47
-rw-r--r--src/lib/libast/features/preroot.sh46
-rw-r--r--src/lib/libast/features/prog12
-rw-r--r--src/lib/libast/features/sfinit.c94
-rw-r--r--src/lib/libast/features/sfio170
-rw-r--r--src/lib/libast/features/sig.sh132
-rw-r--r--src/lib/libast/features/siglist14
-rw-r--r--src/lib/libast/features/signal.c371
-rw-r--r--src/lib/libast/features/sizeof13
-rw-r--r--src/lib/libast/features/standards153
-rw-r--r--src/lib/libast/features/stdio568
-rw-r--r--src/lib/libast/features/sys272
-rw-r--r--src/lib/libast/features/syscall18
-rw-r--r--src/lib/libast/features/time46
-rw-r--r--src/lib/libast/features/tmlib45
-rw-r--r--src/lib/libast/features/tmx106
-rw-r--r--src/lib/libast/features/tty127
-rw-r--r--src/lib/libast/features/tv81
-rw-r--r--src/lib/libast/features/tvlib80
-rw-r--r--src/lib/libast/features/uwin10
-rw-r--r--src/lib/libast/features/vfork13
-rw-r--r--src/lib/libast/features/vmalloc220
-rw-r--r--src/lib/libast/features/wait9
-rw-r--r--src/lib/libast/features/wchar158
-rw-r--r--src/lib/libast/features/wctype14
-rw-r--r--src/lib/libast/hash/hashalloc.c200
-rw-r--r--src/lib/libast/hash/hashdump.c173
-rw-r--r--src/lib/libast/hash/hashfree.c144
-rw-r--r--src/lib/libast/hash/hashlast.c43
-rw-r--r--src/lib/libast/hash/hashlib.h104
-rw-r--r--src/lib/libast/hash/hashlook.c367
-rw-r--r--src/lib/libast/hash/hashscan.c139
-rw-r--r--src/lib/libast/hash/hashsize.c84
-rw-r--r--src/lib/libast/hash/hashview.c88
-rw-r--r--src/lib/libast/hash/hashwalk.c51
-rw-r--r--src/lib/libast/hash/memhash.c45
-rw-r--r--src/lib/libast/hash/memsum.c53
-rw-r--r--src/lib/libast/hash/strhash.c45
-rw-r--r--src/lib/libast/hash/strkey.c49
-rw-r--r--src/lib/libast/hash/strsum.c53
-rw-r--r--src/lib/libast/include/aso.h183
-rw-r--r--src/lib/libast/include/ast.h405
-rw-r--r--src/lib/libast/include/ast_dir.h77
-rw-r--r--src/lib/libast/include/ast_getopt.h42
-rw-r--r--src/lib/libast/include/ast_std.h362
-rw-r--r--src/lib/libast/include/ast_windows.h39
-rw-r--r--src/lib/libast/include/ccode.h90
-rw-r--r--src/lib/libast/include/cdt.h354
-rw-r--r--src/lib/libast/include/cmdarg.h92
-rw-r--r--src/lib/libast/include/debug.h109
-rw-r--r--src/lib/libast/include/dt.h41
-rw-r--r--src/lib/libast/include/error.h182
-rw-r--r--src/lib/libast/include/find.h86
-rw-r--r--src/lib/libast/include/fnv.h72
-rw-r--r--src/lib/libast/include/fs3d.h117
-rw-r--r--src/lib/libast/include/fts.h162
-rw-r--r--src/lib/libast/include/ftwalk.h124
-rw-r--r--src/lib/libast/include/glob.h146
-rw-r--r--src/lib/libast/include/hash.h202
-rw-r--r--src/lib/libast/include/hashkey.h62
-rw-r--r--src/lib/libast/include/hashpart.h51
-rw-r--r--src/lib/libast/include/ip6.h40
-rw-r--r--src/lib/libast/include/ls.h88
-rw-r--r--src/lib/libast/include/magic.h86
-rw-r--r--src/lib/libast/include/magicid.h46
-rw-r--r--src/lib/libast/include/mc.h96
-rw-r--r--src/lib/libast/include/mime.h91
-rw-r--r--src/lib/libast/include/mnt.h58
-rw-r--r--src/lib/libast/include/modecanon.h65
-rw-r--r--src/lib/libast/include/modex.h51
-rw-r--r--src/lib/libast/include/namval.h42
-rw-r--r--src/lib/libast/include/option.h106
-rw-r--r--src/lib/libast/include/proc.h108
-rw-r--r--src/lib/libast/include/recfmt.h83
-rw-r--r--src/lib/libast/include/regex.h248
-rw-r--r--src/lib/libast/include/sfdisc.h70
-rw-r--r--src/lib/libast/include/sfio.h457
-rw-r--r--src/lib/libast/include/sfio_s.h51
-rw-r--r--src/lib/libast/include/sfio_t.h126
-rw-r--r--src/lib/libast/include/shcmd.h112
-rw-r--r--src/lib/libast/include/stack.h83
-rw-r--r--src/lib/libast/include/stak.h55
-rw-r--r--src/lib/libast/include/stk.h78
-rw-r--r--src/lib/libast/include/swap.h53
-rw-r--r--src/lib/libast/include/tar.h118
-rw-r--r--src/lib/libast/include/times.h54
-rw-r--r--src/lib/libast/include/tm.h192
-rw-r--r--src/lib/libast/include/tok.h47
-rw-r--r--src/lib/libast/include/usage.h37
-rw-r--r--src/lib/libast/include/vdb.h46
-rw-r--r--src/lib/libast/include/vecargs.h45
-rw-r--r--src/lib/libast/include/vmalloc.h335
-rw-r--r--src/lib/libast/include/wait.h98
-rw-r--r--src/lib/libast/man/LIBAST.398
-rw-r--r--src/lib/libast/man/aso.3355
-rw-r--r--src/lib/libast/man/ast.3283
-rw-r--r--src/lib/libast/man/astsa.3161
-rw-r--r--src/lib/libast/man/cdt.3617
-rw-r--r--src/lib/libast/man/chr.3126
-rw-r--r--src/lib/libast/man/compat.3103
-rw-r--r--src/lib/libast/man/error.3283
-rw-r--r--src/lib/libast/man/find.389
-rw-r--r--src/lib/libast/man/fmt.3213
-rw-r--r--src/lib/libast/man/fmtls.3143
-rw-r--r--src/lib/libast/man/fs3d.392
-rw-r--r--src/lib/libast/man/ftwalk.3235
-rw-r--r--src/lib/libast/man/getcwd.367
-rw-r--r--src/lib/libast/man/hash.3644
-rw-r--r--src/lib/libast/man/iblocks.362
-rw-r--r--src/lib/libast/man/int.368
-rw-r--r--src/lib/libast/man/ip6.385
-rw-r--r--src/lib/libast/man/magic.3493
-rw-r--r--src/lib/libast/man/mem.398
-rw-r--r--src/lib/libast/man/mime.3117
-rw-r--r--src/lib/libast/man/modecanon.3104
-rw-r--r--src/lib/libast/man/optget.368
-rw-r--r--src/lib/libast/man/path.3391
-rw-r--r--src/lib/libast/man/preroot.3151
-rw-r--r--src/lib/libast/man/proc.3319
-rw-r--r--src/lib/libast/man/re.3214
-rw-r--r--src/lib/libast/man/regex.3163
-rw-r--r--src/lib/libast/man/setenviron.379
-rw-r--r--src/lib/libast/man/sfdisc.3118
-rw-r--r--src/lib/libast/man/sfio.32373
-rw-r--r--src/lib/libast/man/sig.375
-rw-r--r--src/lib/libast/man/spawnveg.397
-rw-r--r--src/lib/libast/man/stak.3169
-rw-r--r--src/lib/libast/man/stk.3165
-rw-r--r--src/lib/libast/man/strcopy.354
-rw-r--r--src/lib/libast/man/strdup.355
-rw-r--r--src/lib/libast/man/strelapsed.377
-rw-r--r--src/lib/libast/man/strerror.353
-rw-r--r--src/lib/libast/man/stresc.353
-rw-r--r--src/lib/libast/man/streval.383
-rw-r--r--src/lib/libast/man/strgid.353
-rw-r--r--src/lib/libast/man/strmatch.3101
-rw-r--r--src/lib/libast/man/stropt.3130
-rw-r--r--src/lib/libast/man/strperm.3109
-rw-r--r--src/lib/libast/man/strsignal.353
-rw-r--r--src/lib/libast/man/strsort.373
-rw-r--r--src/lib/libast/man/strtape.386
-rw-r--r--src/lib/libast/man/strton.397
-rw-r--r--src/lib/libast/man/struid.353
-rw-r--r--src/lib/libast/man/swap.3138
-rw-r--r--src/lib/libast/man/tab.374
-rw-r--r--src/lib/libast/man/tm.3775
-rw-r--r--src/lib/libast/man/tmx.3576
-rw-r--r--src/lib/libast/man/tok.3217
-rw-r--r--src/lib/libast/man/touch.368
-rw-r--r--src/lib/libast/man/tv.3173
-rw-r--r--src/lib/libast/man/vecargs.3126
-rw-r--r--src/lib/libast/man/vmalloc.3640
-rw-r--r--src/lib/libast/misc/astintercept.c53
-rw-r--r--src/lib/libast/misc/cmdarg.c382
-rw-r--r--src/lib/libast/misc/conformance.c151
-rw-r--r--src/lib/libast/misc/debug.c66
-rw-r--r--src/lib/libast/misc/error.c659
-rw-r--r--src/lib/libast/misc/errorf.c41
-rw-r--r--src/lib/libast/misc/errormsg.c41
-rw-r--r--src/lib/libast/misc/errorx.c50
-rw-r--r--src/lib/libast/misc/fastfind.c1282
-rw-r--r--src/lib/libast/misc/findlib.h123
-rw-r--r--src/lib/libast/misc/fmtrec.c102
-rw-r--r--src/lib/libast/misc/fs3d.c116
-rw-r--r--src/lib/libast/misc/fts.c1605
-rw-r--r--src/lib/libast/misc/ftwalk.c156
-rw-r--r--src/lib/libast/misc/ftwflags.c35
-rw-r--r--src/lib/libast/misc/getcwd.c334
-rw-r--r--src/lib/libast/misc/getenv.c113
-rw-r--r--src/lib/libast/misc/glob.c829
-rw-r--r--src/lib/libast/misc/intercepts.h40
-rw-r--r--src/lib/libast/misc/magic.c2497
-rw-r--r--src/lib/libast/misc/magic.tab1721
-rw-r--r--src/lib/libast/misc/mime.c839
-rw-r--r--src/lib/libast/misc/mimelib.h52
-rw-r--r--src/lib/libast/misc/mimetype.c69
-rw-r--r--src/lib/libast/misc/optctx.c70
-rw-r--r--src/lib/libast/misc/optesc.c93
-rw-r--r--src/lib/libast/misc/optget.c5751
-rw-r--r--src/lib/libast/misc/optjoin.c129
-rw-r--r--src/lib/libast/misc/optlib.h115
-rw-r--r--src/lib/libast/misc/procclose.c98
-rw-r--r--src/lib/libast/misc/procfree.c43
-rw-r--r--src/lib/libast/misc/proclib.h64
-rw-r--r--src/lib/libast/misc/procopen.c941
-rw-r--r--src/lib/libast/misc/procrun.c49
-rw-r--r--src/lib/libast/misc/recfmt.c165
-rw-r--r--src/lib/libast/misc/reclen.c71
-rw-r--r--src/lib/libast/misc/recstr.c206
-rw-r--r--src/lib/libast/misc/setenviron.c147
-rw-r--r--src/lib/libast/misc/sigcrit.c199
-rw-r--r--src/lib/libast/misc/sigdata.c40
-rw-r--r--src/lib/libast/misc/signal.c136
-rw-r--r--src/lib/libast/misc/stack.c172
-rw-r--r--src/lib/libast/misc/state.c42
-rw-r--r--src/lib/libast/misc/stk.c553
-rw-r--r--src/lib/libast/misc/systrace.c68
-rw-r--r--src/lib/libast/misc/translate.c437
-rw-r--r--src/lib/libast/misc/univdata.c58
-rw-r--r--src/lib/libast/misc/univlib.h93
-rw-r--r--src/lib/libast/obsolete/spawn.c152
-rw-r--r--src/lib/libast/path/pathaccess.c69
-rw-r--r--src/lib/libast/path/pathbin.c46
-rw-r--r--src/lib/libast/path/pathcanon.c222
-rw-r--r--src/lib/libast/path/pathcat.c98
-rw-r--r--src/lib/libast/path/pathcd.c142
-rw-r--r--src/lib/libast/path/pathcheck.c91
-rw-r--r--src/lib/libast/path/pathexists.c134
-rw-r--r--src/lib/libast/path/pathfind.c168
-rw-r--r--src/lib/libast/path/pathgetlink.c102
-rw-r--r--src/lib/libast/path/pathkey.c320
-rw-r--r--src/lib/libast/path/pathnative.c126
-rw-r--r--src/lib/libast/path/pathpath.c127
-rw-r--r--src/lib/libast/path/pathposix.c128
-rw-r--r--src/lib/libast/path/pathprobe.c316
-rw-r--r--src/lib/libast/path/pathprog.c128
-rw-r--r--src/lib/libast/path/pathrepl.c93
-rw-r--r--src/lib/libast/path/pathsetlink.c72
-rw-r--r--src/lib/libast/path/pathshell.c112
-rw-r--r--src/lib/libast/path/pathstat.c45
-rw-r--r--src/lib/libast/path/pathtemp.c337
-rw-r--r--src/lib/libast/path/pathtmp.c41
-rw-r--r--src/lib/libast/port/astconf.c1718
-rw-r--r--src/lib/libast/port/astcopy.c90
-rw-r--r--src/lib/libast/port/astdynamic.c132
-rw-r--r--src/lib/libast/port/astlicense.c1292
-rw-r--r--src/lib/libast/port/astmath.c72
-rw-r--r--src/lib/libast/port/astquery.c114
-rw-r--r--src/lib/libast/port/aststatic.c44
-rw-r--r--src/lib/libast/port/astwinsize.c143
-rw-r--r--src/lib/libast/port/atmain.C37
-rw-r--r--src/lib/libast/port/iblocks.c95
-rw-r--r--src/lib/libast/port/lc.c883
-rw-r--r--src/lib/libast/port/lc.tab275
-rw-r--r--src/lib/libast/port/lcgen.c791
-rw-r--r--src/lib/libast/port/lclang.h120
-rw-r--r--src/lib/libast/port/lclib.h71
-rw-r--r--src/lib/libast/port/mc.c675
-rw-r--r--src/lib/libast/port/mnt.c816
-rw-r--r--src/lib/libast/port/touch.c74
-rw-r--r--src/lib/libast/preroot/getpreroot.c165
-rw-r--r--src/lib/libast/preroot/ispreroot.c71
-rw-r--r--src/lib/libast/preroot/realopen.c47
-rw-r--r--src/lib/libast/preroot/setpreroot.c75
-rw-r--r--src/lib/libast/regex/regalloc.c36
-rw-r--r--src/lib/libast/regex/regcache.c198
-rw-r--r--src/lib/libast/regex/regclass.c298
-rw-r--r--src/lib/libast/regex/regcoll.c120
-rw-r--r--src/lib/libast/regex/regcomp.c3544
-rw-r--r--src/lib/libast/regex/regdecomp.c448
-rw-r--r--src/lib/libast/regex/regerror.c95
-rw-r--r--src/lib/libast/regex/regexec.c54
-rw-r--r--src/lib/libast/regex/regfatal.c49
-rw-r--r--src/lib/libast/regex/reginit.c412
-rw-r--r--src/lib/libast/regex/reglib.h582
-rw-r--r--src/lib/libast/regex/regnexec.c2045
-rw-r--r--src/lib/libast/regex/regrecord.c34
-rw-r--r--src/lib/libast/regex/regrexec.c145
-rw-r--r--src/lib/libast/regex/regstat.c53
-rw-r--r--src/lib/libast/regex/regsub.c269
-rw-r--r--src/lib/libast/regex/regsubcomp.c377
-rw-r--r--src/lib/libast/regex/regsubexec.c196
-rw-r--r--src/lib/libast/sfio/_sfclrerr.c34
-rw-r--r--src/lib/libast/sfio/_sfdlen.c34
-rw-r--r--src/lib/libast/sfio/_sfeof.c34
-rw-r--r--src/lib/libast/sfio/_sferror.c34
-rw-r--r--src/lib/libast/sfio/_sffileno.c34
-rw-r--r--src/lib/libast/sfio/_sfgetc.c34
-rw-r--r--src/lib/libast/sfio/_sfgetl.c42
-rw-r--r--src/lib/libast/sfio/_sfgetl2.c50
-rw-r--r--src/lib/libast/sfio/_sfgetu.c42
-rw-r--r--src/lib/libast/sfio/_sfgetu2.c50
-rw-r--r--src/lib/libast/sfio/_sfllen.c34
-rw-r--r--src/lib/libast/sfio/_sfopen.c219
-rw-r--r--src/lib/libast/sfio/_sfputc.c35
-rw-r--r--src/lib/libast/sfio/_sfputd.c96
-rw-r--r--src/lib/libast/sfio/_sfputl.c82
-rw-r--r--src/lib/libast/sfio/_sfputm.c78
-rw-r--r--src/lib/libast/sfio/_sfputu.c75
-rw-r--r--src/lib/libast/sfio/_sfslen.c33
-rw-r--r--src/lib/libast/sfio/_sfstacked.c34
-rw-r--r--src/lib/libast/sfio/_sfulen.c34
-rw-r--r--src/lib/libast/sfio/_sfvalue.c34
-rw-r--r--src/lib/libast/sfio/sfclose.c178
-rw-r--r--src/lib/libast/sfio/sfclrlock.c63
-rw-r--r--src/lib/libast/sfio/sfcvt.c532
-rw-r--r--src/lib/libast/sfio/sfdisc.c271
-rw-r--r--src/lib/libast/sfio/sfdlen.c58
-rw-r--r--src/lib/libast/sfio/sfecvt.c38
-rw-r--r--src/lib/libast/sfio/sfexcept.c133
-rw-r--r--src/lib/libast/sfio/sfextern.c99
-rw-r--r--src/lib/libast/sfio/sffcvt.c38
-rw-r--r--src/lib/libast/sfio/sffilbuf.c116
-rw-r--r--src/lib/libast/sfio/sfflsbuf.c126
-rw-r--r--src/lib/libast/sfio/sfgetd.c79
-rw-r--r--src/lib/libast/sfio/sfgetl.c70
-rw-r--r--src/lib/libast/sfio/sfgetm.c68
-rw-r--r--src/lib/libast/sfio/sfgetr.c169
-rw-r--r--src/lib/libast/sfio/sfgetu.c67
-rw-r--r--src/lib/libast/sfio/sfhdr.h1302
-rw-r--r--src/lib/libast/sfio/sfllen.c39
-rw-r--r--src/lib/libast/sfio/sfmode.c596
-rw-r--r--src/lib/libast/sfio/sfmove.c242
-rw-r--r--src/lib/libast/sfio/sfmutex.c69
-rw-r--r--src/lib/libast/sfio/sfnew.c129
-rw-r--r--src/lib/libast/sfio/sfnotify.c38
-rw-r--r--src/lib/libast/sfio/sfnputc.c81
-rw-r--r--src/lib/libast/sfio/sfopen.c40
-rw-r--r--src/lib/libast/sfio/sfpeek.c89
-rw-r--r--src/lib/libast/sfio/sfpkrd.c325
-rw-r--r--src/lib/libast/sfio/sfpoll.c250
-rw-r--r--src/lib/libast/sfio/sfpool.c369
-rw-r--r--src/lib/libast/sfio/sfpopen.c293
-rw-r--r--src/lib/libast/sfio/sfprintf.c114
-rw-r--r--src/lib/libast/sfio/sfprints.c125
-rw-r--r--src/lib/libast/sfio/sfpurge.c98
-rw-r--r--src/lib/libast/sfio/sfputd.c35
-rw-r--r--src/lib/libast/sfio/sfputl.c35
-rw-r--r--src/lib/libast/sfio/sfputm.c36
-rw-r--r--src/lib/libast/sfio/sfputr.c136
-rw-r--r--src/lib/libast/sfio/sfputu.c35
-rw-r--r--src/lib/libast/sfio/sfraise.c107
-rw-r--r--src/lib/libast/sfio/sfrd.c317
-rw-r--r--src/lib/libast/sfio/sfread.c140
-rw-r--r--src/lib/libast/sfio/sfreserve.c210
-rw-r--r--src/lib/libast/sfio/sfresize.c83
-rw-r--r--src/lib/libast/sfio/sfscanf.c102
-rw-r--r--src/lib/libast/sfio/sfseek.c281
-rw-r--r--src/lib/libast/sfio/sfset.c99
-rw-r--r--src/lib/libast/sfio/sfsetbuf.c426
-rw-r--r--src/lib/libast/sfio/sfsetfd.c136
-rw-r--r--src/lib/libast/sfio/sfsize.c109
-rw-r--r--src/lib/libast/sfio/sfsk.c106
-rw-r--r--src/lib/libast/sfio/sfstack.c115
-rw-r--r--src/lib/libast/sfio/sfstrtod.c157
-rw-r--r--src/lib/libast/sfio/sfstrtof.h568
-rw-r--r--src/lib/libast/sfio/sfswap.c119
-rw-r--r--src/lib/libast/sfio/sfsync.c172
-rw-r--r--src/lib/libast/sfio/sftable.c543
-rw-r--r--src/lib/libast/sfio/sftell.c59
-rw-r--r--src/lib/libast/sfio/sftmp.c402
-rw-r--r--src/lib/libast/sfio/sfungetc.c108
-rw-r--r--src/lib/libast/sfio/sfvprintf.c1445
-rw-r--r--src/lib/libast/sfio/sfvscanf.c1100
-rw-r--r--src/lib/libast/sfio/sfwalk.c67
-rw-r--r--src/lib/libast/sfio/sfwr.c252
-rw-r--r--src/lib/libast/sfio/sfwrite.c171
-rw-r--r--src/lib/libast/sfio/vthread.h219
-rw-r--r--src/lib/libast/std/bytesex.h43
-rw-r--r--src/lib/libast/std/dirent.h22
-rw-r--r--src/lib/libast/std/endian.h54
-rw-r--r--src/lib/libast/std/iconv.h22
-rw-r--r--src/lib/libast/std/nl_types.h22
-rw-r--r--src/lib/libast/std/stdio.h22
-rw-r--r--src/lib/libast/std/wchar.h22
-rw-r--r--src/lib/libast/std/wctype.h22
-rw-r--r--src/lib/libast/stdio/_doprnt.c32
-rw-r--r--src/lib/libast/stdio/_doscan.c32
-rw-r--r--src/lib/libast/stdio/_filbuf.c36
-rw-r--r--src/lib/libast/stdio/_flsbuf.c44
-rw-r--r--src/lib/libast/stdio/_stdfun.c80
-rw-r--r--src/lib/libast/stdio/_stdopen.c32
-rw-r--r--src/lib/libast/stdio/_stdprintf.c38
-rw-r--r--src/lib/libast/stdio/_stdscanf.c38
-rw-r--r--src/lib/libast/stdio/_stdsprnt.c38
-rw-r--r--src/lib/libast/stdio/_stdvbuf.c32
-rw-r--r--src/lib/libast/stdio/_stdvsnprnt.c32
-rw-r--r--src/lib/libast/stdio/_stdvsprnt.c32
-rw-r--r--src/lib/libast/stdio/_stdvsscn.c32
-rw-r--r--src/lib/libast/stdio/asprintf.c36
-rw-r--r--src/lib/libast/stdio/clearerr.c33
-rw-r--r--src/lib/libast/stdio/fclose.c32
-rw-r--r--src/lib/libast/stdio/fcloseall.c57
-rw-r--r--src/lib/libast/stdio/fdopen.c34
-rw-r--r--src/lib/libast/stdio/feof.c42
-rw-r--r--src/lib/libast/stdio/ferror.c42
-rw-r--r--src/lib/libast/stdio/fflush.c41
-rw-r--r--src/lib/libast/stdio/fgetc.c32
-rw-r--r--src/lib/libast/stdio/fgetpos.c48
-rw-r--r--src/lib/libast/stdio/fgets.c110
-rw-r--r--src/lib/libast/stdio/fgetwc.c35
-rw-r--r--src/lib/libast/stdio/fgetws.c52
-rw-r--r--src/lib/libast/stdio/fileno.c42
-rw-r--r--src/lib/libast/stdio/flockfile.c32
-rw-r--r--src/lib/libast/stdio/fmemopen.c32
-rw-r--r--src/lib/libast/stdio/fopen.c30
-rw-r--r--src/lib/libast/stdio/fprintf.c39
-rw-r--r--src/lib/libast/stdio/fpurge.c32
-rw-r--r--src/lib/libast/stdio/fputc.c42
-rw-r--r--src/lib/libast/stdio/fputs.c32
-rw-r--r--src/lib/libast/stdio/fputwc.c33
-rw-r--r--src/lib/libast/stdio/fputws.c36
-rw-r--r--src/lib/libast/stdio/fread.c34
-rw-r--r--src/lib/libast/stdio/freopen.c32
-rw-r--r--src/lib/libast/stdio/fscanf.c39
-rw-r--r--src/lib/libast/stdio/fseek.c48
-rw-r--r--src/lib/libast/stdio/fseeko.c48
-rw-r--r--src/lib/libast/stdio/fsetpos.c48
-rw-r--r--src/lib/libast/stdio/ftell.c48
-rw-r--r--src/lib/libast/stdio/ftello.c48
-rw-r--r--src/lib/libast/stdio/ftrylockfile.c32
-rw-r--r--src/lib/libast/stdio/funlockfile.c32
-rw-r--r--src/lib/libast/stdio/fwide.c51
-rw-r--r--src/lib/libast/stdio/fwprintf.c36
-rw-r--r--src/lib/libast/stdio/fwrite.c34
-rw-r--r--src/lib/libast/stdio/fwscanf.c39
-rw-r--r--src/lib/libast/stdio/getc.c42
-rw-r--r--src/lib/libast/stdio/getchar.c40
-rw-r--r--src/lib/libast/stdio/getdelim.c96
-rw-r--r--src/lib/libast/stdio/getline.c36
-rw-r--r--src/lib/libast/stdio/getw.c34
-rw-r--r--src/lib/libast/stdio/getwc.c31
-rw-r--r--src/lib/libast/stdio/getwchar.c31
-rw-r--r--src/lib/libast/stdio/pclose.c32
-rw-r--r--src/lib/libast/stdio/popen.c30
-rw-r--r--src/lib/libast/stdio/printf.c36
-rw-r--r--src/lib/libast/stdio/putc.c42
-rw-r--r--src/lib/libast/stdio/putchar.c40
-rw-r--r--src/lib/libast/stdio/puts.c30
-rw-r--r--src/lib/libast/stdio/putw.c32
-rw-r--r--src/lib/libast/stdio/putwc.c31
-rw-r--r--src/lib/libast/stdio/putwchar.c31
-rw-r--r--src/lib/libast/stdio/rewind.c33
-rw-r--r--src/lib/libast/stdio/scanf.c36
-rw-r--r--src/lib/libast/stdio/setbuf.c32
-rw-r--r--src/lib/libast/stdio/setbuffer.c32
-rw-r--r--src/lib/libast/stdio/setlinebuf.c33
-rw-r--r--src/lib/libast/stdio/setvbuf.c48
-rw-r--r--src/lib/libast/stdio/snprintf.c36
-rw-r--r--src/lib/libast/stdio/sprintf.c36
-rw-r--r--src/lib/libast/stdio/sscanf.c36
-rw-r--r--src/lib/libast/stdio/stdhdr.h115
-rw-r--r--src/lib/libast/stdio/stdio_c99.c118
-rw-r--r--src/lib/libast/stdio/swprintf.c36
-rw-r--r--src/lib/libast/stdio/swscanf.c36
-rw-r--r--src/lib/libast/stdio/tmpfile.c30
-rw-r--r--src/lib/libast/stdio/ungetc.c32
-rw-r--r--src/lib/libast/stdio/ungetwc.c39
-rw-r--r--src/lib/libast/stdio/vasprintf.c45
-rw-r--r--src/lib/libast/stdio/vfprintf.c32
-rw-r--r--src/lib/libast/stdio/vfscanf.c32
-rw-r--r--src/lib/libast/stdio/vfwprintf.c68
-rw-r--r--src/lib/libast/stdio/vfwscanf.c129
-rw-r--r--src/lib/libast/stdio/vprintf.c30
-rw-r--r--src/lib/libast/stdio/vscanf.c30
-rw-r--r--src/lib/libast/stdio/vsnprintf.c52
-rw-r--r--src/lib/libast/stdio/vsprintf.c30
-rw-r--r--src/lib/libast/stdio/vsscanf.c30
-rw-r--r--src/lib/libast/stdio/vswprintf.c55
-rw-r--r--src/lib/libast/stdio/vswscanf.c51
-rw-r--r--src/lib/libast/stdio/vwprintf.c30
-rw-r--r--src/lib/libast/stdio/vwscanf.c30
-rw-r--r--src/lib/libast/stdio/wprintf.c36
-rw-r--r--src/lib/libast/stdio/wscanf.c36
-rw-r--r--src/lib/libast/string/base64.c312
-rw-r--r--src/lib/libast/string/ccmap.c746
-rw-r--r--src/lib/libast/string/ccmapid.c173
-rw-r--r--src/lib/libast/string/ccnative.c56
-rw-r--r--src/lib/libast/string/chresc.c235
-rw-r--r--src/lib/libast/string/chrtoi.c55
-rw-r--r--src/lib/libast/string/fmtbase.c70
-rw-r--r--src/lib/libast/string/fmtbuf.c69
-rw-r--r--src/lib/libast/string/fmtclock.c63
-rw-r--r--src/lib/libast/string/fmtdev.c60
-rw-r--r--src/lib/libast/string/fmtelapsed.c61
-rw-r--r--src/lib/libast/string/fmterror.c37
-rw-r--r--src/lib/libast/string/fmtesc.c248
-rw-r--r--src/lib/libast/string/fmtfmt.c205
-rw-r--r--src/lib/libast/string/fmtfs.c100
-rw-r--r--src/lib/libast/string/fmtgid.c101
-rw-r--r--src/lib/libast/string/fmtident.c77
-rw-r--r--src/lib/libast/string/fmtint.c122
-rw-r--r--src/lib/libast/string/fmtip4.c43
-rw-r--r--src/lib/libast/string/fmtip6.c175
-rw-r--r--src/lib/libast/string/fmtls.c120
-rw-r--r--src/lib/libast/string/fmtmatch.c286
-rw-r--r--src/lib/libast/string/fmtmode.c47
-rw-r--r--src/lib/libast/string/fmtnum.c92
-rw-r--r--src/lib/libast/string/fmtperm.c91
-rw-r--r--src/lib/libast/string/fmtre.c226
-rw-r--r--src/lib/libast/string/fmtscale.c94
-rw-r--r--src/lib/libast/string/fmtsignal.c62
-rw-r--r--src/lib/libast/string/fmttime.c41
-rw-r--r--src/lib/libast/string/fmttmx.c45
-rw-r--r--src/lib/libast/string/fmttv.c44
-rw-r--r--src/lib/libast/string/fmtuid.c101
-rw-r--r--src/lib/libast/string/fmtversion.c53
-rw-r--r--src/lib/libast/string/memdup.c44
-rw-r--r--src/lib/libast/string/modedata.c69
-rw-r--r--src/lib/libast/string/modei.c55
-rw-r--r--src/lib/libast/string/modelib.h55
-rw-r--r--src/lib/libast/string/modex.c75
-rw-r--r--src/lib/libast/string/stracmp.c62
-rw-r--r--src/lib/libast/string/strcopy.c36
-rw-r--r--src/lib/libast/string/strdup.c60
-rw-r--r--src/lib/libast/string/strelapsed.c154
-rw-r--r--src/lib/libast/string/strerror.c148
-rw-r--r--src/lib/libast/string/stresc.c67
-rw-r--r--src/lib/libast/string/streval.c50
-rw-r--r--src/lib/libast/string/strexpr.c294
-rw-r--r--src/lib/libast/string/strgid.c121
-rw-r--r--src/lib/libast/string/strlcat.c83
-rw-r--r--src/lib/libast/string/strlcpy.c71
-rw-r--r--src/lib/libast/string/strlook.c50
-rw-r--r--src/lib/libast/string/strmatch.c171
-rw-r--r--src/lib/libast/string/strmode.c51
-rw-r--r--src/lib/libast/string/strnacmp.c66
-rw-r--r--src/lib/libast/string/strncopy.c46
-rw-r--r--src/lib/libast/string/strnpcmp.c51
-rw-r--r--src/lib/libast/string/strntod.c32
-rw-r--r--src/lib/libast/string/strntol.c31
-rw-r--r--src/lib/libast/string/strntold.c32
-rw-r--r--src/lib/libast/string/strntoll.c31
-rw-r--r--src/lib/libast/string/strnton.c32
-rw-r--r--src/lib/libast/string/strntonll.c32
-rw-r--r--src/lib/libast/string/strntoul.c32
-rw-r--r--src/lib/libast/string/strntoull.c32
-rw-r--r--src/lib/libast/string/strnvcmp.c86
-rw-r--r--src/lib/libast/string/stropt.c188
-rw-r--r--src/lib/libast/string/strpcmp.c44
-rw-r--r--src/lib/libast/string/strperm.c267
-rw-r--r--src/lib/libast/string/strpsearch.c125
-rw-r--r--src/lib/libast/string/strsearch.c57
-rw-r--r--src/lib/libast/string/strsort.c57
-rw-r--r--src/lib/libast/string/strtape.c148
-rw-r--r--src/lib/libast/string/strtoi.h640
-rw-r--r--src/lib/libast/string/strtoip4.c150
-rw-r--r--src/lib/libast/string/strtoip6.c204
-rw-r--r--src/lib/libast/string/strton.c31
-rw-r--r--src/lib/libast/string/strtonll.c31
-rw-r--r--src/lib/libast/string/struid.c109
-rw-r--r--src/lib/libast/string/struniq.c51
-rw-r--r--src/lib/libast/string/strvcmp.c74
-rw-r--r--src/lib/libast/string/swapget.c57
-rw-r--r--src/lib/libast/string/swapmem.c109
-rw-r--r--src/lib/libast/string/swapop.c59
-rw-r--r--src/lib/libast/string/swapput.c50
-rw-r--r--src/lib/libast/string/tok.c190
-rw-r--r--src/lib/libast/string/tokline.c193
-rw-r--r--src/lib/libast/string/tokscan.c360
-rw-r--r--src/lib/libast/string/wc2utf8.c74
-rw-r--r--src/lib/libast/tm/tmdata.c288
-rw-r--r--src/lib/libast/tm/tmdate.c41
-rw-r--r--src/lib/libast/tm/tmequiv.c57
-rw-r--r--src/lib/libast/tm/tmfix.c173
-rw-r--r--src/lib/libast/tm/tmfmt.c41
-rw-r--r--src/lib/libast/tm/tmform.c44
-rw-r--r--src/lib/libast/tm/tmgoff.c77
-rw-r--r--src/lib/libast/tm/tminit.c460
-rw-r--r--src/lib/libast/tm/tmleap.c41
-rw-r--r--src/lib/libast/tm/tmlex.c67
-rw-r--r--src/lib/libast/tm/tmlocale.c644
-rw-r--r--src/lib/libast/tm/tmmake.c41
-rw-r--r--src/lib/libast/tm/tmpoff.c62
-rw-r--r--src/lib/libast/tm/tmscan.c41
-rw-r--r--src/lib/libast/tm/tmsleep.c42
-rw-r--r--src/lib/libast/tm/tmtime.c41
-rw-r--r--src/lib/libast/tm/tmtype.c57
-rw-r--r--src/lib/libast/tm/tmweek.c87
-rw-r--r--src/lib/libast/tm/tmword.c89
-rw-r--r--src/lib/libast/tm/tmxdate.c1745
-rw-r--r--src/lib/libast/tm/tmxduration.c80
-rw-r--r--src/lib/libast/tm/tmxfmt.c703
-rw-r--r--src/lib/libast/tm/tmxgettime.c44
-rw-r--r--src/lib/libast/tm/tmxleap.c51
-rw-r--r--src/lib/libast/tm/tmxmake.c140
-rw-r--r--src/lib/libast/tm/tmxscan.c533
-rw-r--r--src/lib/libast/tm/tmxsettime.c45
-rw-r--r--src/lib/libast/tm/tmxsleep.c41
-rw-r--r--src/lib/libast/tm/tmxtime.c137
-rw-r--r--src/lib/libast/tm/tmxtouch.c81
-rw-r--r--src/lib/libast/tm/tmzone.c95
-rw-r--r--src/lib/libast/tm/tvcmp.c46
-rw-r--r--src/lib/libast/tm/tvgettime.c70
-rw-r--r--src/lib/libast/tm/tvsettime.c72
-rw-r--r--src/lib/libast/tm/tvsleep.c144
-rw-r--r--src/lib/libast/tm/tvtouch.c295
-rw-r--r--src/lib/libast/uwin/a64l.c76
-rw-r--r--src/lib/libast/uwin/acosh.c108
-rw-r--r--src/lib/libast/uwin/asinh.c107
-rw-r--r--src/lib/libast/uwin/atanh.c89
-rw-r--r--src/lib/libast/uwin/cbrt.c38
-rw-r--r--src/lib/libast/uwin/crypt.c959
-rw-r--r--src/lib/libast/uwin/erf.c403
-rw-r--r--src/lib/libast/uwin/err.c124
-rw-r--r--src/lib/libast/uwin/exp.c213
-rw-r--r--src/lib/libast/uwin/exp__E.c142
-rw-r--r--src/lib/libast/uwin/expm1.c173
-rw-r--r--src/lib/libast/uwin/gamma.c343
-rw-r--r--src/lib/libast/uwin/getpass.c79
-rw-r--r--src/lib/libast/uwin/lgamma.c316
-rw-r--r--src/lib/libast/uwin/log.c496
-rw-r--r--src/lib/libast/uwin/log1p.c176
-rw-r--r--src/lib/libast/uwin/log__L.c116
-rw-r--r--src/lib/libast/uwin/mathimpl.h103
-rw-r--r--src/lib/libast/uwin/mini.sym84
-rw-r--r--src/lib/libast/uwin/rand48.c177
-rw-r--r--src/lib/libast/uwin/random.c381
-rw-r--r--src/lib/libast/uwin/rcmd.c571
-rw-r--r--src/lib/libast/uwin/rint.c41
-rw-r--r--src/lib/libast/uwin/rlib.h80
-rw-r--r--src/lib/libast/uwin/support.c605
-rw-r--r--src/lib/libast/vec/vecargs.c76
-rw-r--r--src/lib/libast/vec/vecfile.c62
-rw-r--r--src/lib/libast/vec/vecfree.c48
-rw-r--r--src/lib/libast/vec/vecload.c96
-rw-r--r--src/lib/libast/vec/vecstring.c46
-rw-r--r--src/lib/libast/vmalloc/malloc.c1438
-rw-r--r--src/lib/libast/vmalloc/vmbest.c1390
-rw-r--r--src/lib/libast/vmalloc/vmclear.c85
-rw-r--r--src/lib/libast/vmalloc/vmclose.c91
-rw-r--r--src/lib/libast/vmalloc/vmdcheap.c63
-rw-r--r--src/lib/libast/vmalloc/vmdebug.c745
-rw-r--r--src/lib/libast/vmalloc/vmdisc.c55
-rw-r--r--src/lib/libast/vmalloc/vmexit.c100
-rw-r--r--src/lib/libast/vmalloc/vmgetmem.c51
-rw-r--r--src/lib/libast/vmalloc/vmhdr.h530
-rw-r--r--src/lib/libast/vmalloc/vmlast.c431
-rw-r--r--src/lib/libast/vmalloc/vmmopen.c518
-rw-r--r--src/lib/libast/vmalloc/vmopen.c180
-rw-r--r--src/lib/libast/vmalloc/vmpool.c316
-rw-r--r--src/lib/libast/vmalloc/vmprivate.c292
-rw-r--r--src/lib/libast/vmalloc/vmprofile.c709
-rw-r--r--src/lib/libast/vmalloc/vmregion.c61
-rw-r--r--src/lib/libast/vmalloc/vmsegment.c58
-rw-r--r--src/lib/libast/vmalloc/vmset.c62
-rw-r--r--src/lib/libast/vmalloc/vmstat.c145
-rw-r--r--src/lib/libast/vmalloc/vmstrdup.c48
-rw-r--r--src/lib/libast/vmalloc/vmtrace.c286
-rw-r--r--src/lib/libast/vmalloc/vmwalk.c69
838 files changed, 157384 insertions, 0 deletions
diff --git a/src/lib/libast/Makefile b/src/lib/libast/Makefile
new file mode 100644
index 0000000..8dd819a
--- /dev/null
+++ b/src/lib/libast/Makefile
@@ -0,0 +1,442 @@
+/*
+ * ast library
+ */
+
+:PACKAGE: ast
+
+LICENSE = since=1985,author=gsf+dgk+kpv
+
+ID = ast
+
+HOSTTYPE == "$(CC.HOSTTYPE)"
+
+CCFLAGS = $(CC.SUFFIX.DEBUG:+$(CC.DEBUG)) $(CC.OPTIMIZE) $(CC.DLL)
+
+IFFEFLAGS = -v -X ast -X std
+
+.SOURCE : aso cdt comp dir disc hash man misc obsolete path port preroot \
+ regex sfio stdio string tm uwin vec vmalloc
+
+.SOURCE.h : include comp std cdt vmalloc
+
+CP = $(STDCP|"cp")
+
+PARANOID ==
+CONF_LIBPREFIX == "$(CC.PREFIX.DYNAMIC|CC.PREFIX.SHARED)"
+CONF_LIBSUFFIX == "$(CC.SUFFIX.DYNAMIC|CC.SUFFIX.SHARED)"
+DEBUG ==
+__OBSOLETE__ == $("6 months ago":@F=%(%Y0101)T)
+
+HEADERSRC = ast.h ast_dir.h ast_getopt.h ast_std.h \
+ ast_namval.h ast_windows.h \
+ ccode.h cdt.h cdtlib.h cmdarg.h debug.h dt.h error.h find.h ftw.h \
+ ftwalk.h fts.h fs3d.h getopt.h glob.h hash.h hashkey.h hashpart.h \
+ ip6.h lc.h ls.h magic.h mc.h mime.h mnt.h modecanon.h modex.h \
+ namval.h option.h proc.h re_comp.h recfmt.h regex.h regexp.h \
+ sfio.h sfio_s.h sfio_t.h sfdisc.h shcmd.h \
+ stack.h stak.h stk.h swap.h tar.h times.h tm.h tok.h \
+ usage.h vdb.h vecargs.h vmalloc.h wait.h wordexp.h \
+ bytesex.h endian.h fnmatch.h magicid.h fnv.h aso.h \
+ $(HEADERSTD)
+
+HEADERGEN = align.h preroot.h sig.h tmx.h tv.h \
+ $(ID)_api.h $(ID)_botch.h $(ID)_ccode.h $(ID)_fcntl.h $(ID)_float.h \
+ $(ID)_fs.h $(ID)_lib.h $(ID)_map.h $(ID)_mmap.h $(ID)_mode.h $(ID)_ndbm.h \
+ $(ID)_param.h $(ID)_sys.h $(ID)_time.h $(ID)_time.h $(ID)_tty.h \
+ $(ID)_vfork.h $(ID)_wait.h $(ID)_limits.h $(ID)_standards.h $(ID)_sizeof.h \
+ $(HEADERSTD:/^/$(ID)_/)
+
+HEADEREXP = $(ID)_common.h
+
+HEADEROPT = fmtmsg.h libgen.h syslog.h
+
+HEADERSTD = dirent.h iconv.h nl_types.h stdio.h wchar.h wctype.h
+
+$(ID) 5.4 :LIBRARY: README RELEASE \
+ LIBAST.3 aso.3 ast.3 astsa.3 cdt.3 chr.3 compat.3 error.3 \
+ find.3 fmt.3 fmtls.3 fs3d.3 ftwalk.3 getcwd.3 hash.3 iblocks.3 \
+ int.3 ip6.3 magic.3 mem.3 mime.3 modecanon.3 optget.3 path.3 \
+ preroot.3 proc.3 re.3 regex.3 setenviron.3 sfdisc.3 sfio.3 \
+ sig.3 spawnveg.3 stak.3 stk.3 strcopy.3 strdup.3 strelapsed.3 \
+ strerror.3 stresc.3 streval.3 strgid.3 strmatch.3 stropt.3 \
+ strperm.3 strsignal.3 strsort.3 strtape.3 strton.3 struid.3 \
+ swap.3 tab.3 tm.3 tmx.3 tok.3 touch.3 tv.3 vecargs.3 vmalloc.3 \
+ $(HEADERSRC) \
+ state.c transition.c \
+ dirlib.h opendir.c readdir.c rewinddir.c seekdir.c telldir.c \
+ getcwd.c fastfind.c \
+ hashlib.h hashalloc.c hashdump.c hashfree.c hashlast.c \
+ hashlook.c hashscan.c hashsize.c hashview.c hashwalk.c \
+ memhash.c memsum.c strhash.c strkey.c strsum.c \
+ stracmp.c strnacmp.c \
+ ccmap.c ccmapid.c ccnative.c \
+ chresc.c chrtoi.c streval.c strexpr.c strmatch.c strcopy.c \
+ modelib.h modei.c modex.c strmode.c \
+ strlcat.c strlcpy.c strlook.c strncopy.c strsearch.c strpsearch.c \
+ stresc.c stropt.c strtape.c strpcmp.c strnpcmp.c strvcmp.c strnvcmp.c \
+ tok.c tokline.c tokscan.c \
+ pathaccess.c pathcat.c pathcanon.c pathcheck.c pathpath.c \
+ pathexists.c pathfind.c pathkey.c pathprobe.c pathrepl.c \
+ pathnative.c pathposix.c pathtemp.c pathtmp.c pathstat.c \
+ pathgetlink.c pathsetlink.c pathbin.c pathshell.c pathcd.c \
+ pathprog.c \
+ fs3d.c ftwalk.c ftwflags.c fts.c \
+ astintercept.c conformance.c getenv.c setenviron.c \
+ optget.c optjoin.c optesc.c optctx.c strsort.c struniq.c \
+ magic.c mime.c mimetype.c signal.c sigflag.c systrace.c \
+ error.c errorf.c errormsg.c errorx.c \
+ localeconv.c setlocale.c translate.c \
+ catopen.c iconv.c lc.c lctab.c mc.c \
+ base64.c recfmt.c recstr.c reclen.c fmtrec.c \
+ fmtbase.c fmtbuf.c fmtclock.c fmtdev.c fmtelapsed.c fmterror.c \
+ fmtesc.c fmtfmt.c fmtfs.c fmtident.c fmtint.c fmtip4.c fmtip6.c fmtls.c \
+ fmtmatch.c fmtmode.c fmtnum.c fmtperm.c fmtre.c fmttime.c fmtuid.c \
+ fmtgid.c fmtsignal.c fmtscale.c fmttmx.c fmttv.c fmtversion.c \
+ strelapsed.c strperm.c struid.c strgid.c \
+ strtoip4.c strtoip6.c stack.c stk.c \
+ swapget.c swapmem.c swapop.c swapput.c \
+ sigdata.c sigcrit.c sigunblock.c \
+ proclib.h procopen.c procclose.c procrun.c procfree.c \
+ tmdate.c tmequiv.c tmfix.c tmfmt.c tmform.c tmgoff.c tminit.c \
+ tmleap.c tmlex.c tmlocale.c tmmake.c tmpoff.c tmscan.c \
+ tmsleep.c tmtime.c tmtype.c tmweek.c tmword.c tmzone.c \
+ tmxdate.c tmxduration.c tmxfmt.c tmxgettime.c tmxleap.c tmxmake.c \
+ tmxscan.c tmxsettime.c tmxsleep.c tmxtime.c tmxtouch.c \
+ tvcmp.c tvgettime.c tvsettime.c tvsleep.c tvtouch.c \
+ cmdarg.c vecargs.c vecfile.c vecfree.c vecload.c vecstring.c \
+ univlib.h univdata.c touch.c mnt.c debug.c \
+ memccpy.c memchr.c memcmp.c memcpy.c memdup.c memmove.c memset.c \
+ mkdir.c mkfifo.c mknod.c rmdir.c remove.c rename.c link.c unlink.c \
+ strdup.c strchr.c strrchr.c strstr.c \
+ strtod.c strtold.c \
+ strtol.c strtoll.c strtoul.c strtoull.c strton.c strtonll.c \
+ strntod.c strntold.c strnton.c strntonll.c \
+ strntol.c strntoll.c strntoul.c strntoull.c \
+ strcasecmp.c strncasecmp.c strerror.c \
+ mktemp.c tmpnam.c fsync.c \
+ execlp.c execve.c execvp.c execvpe.c spawnveg.c \
+ vfork.c killpg.c \
+ hsearch.c tsearch.c \
+ getlogin.c putenv.c setenv.c unsetenv.c \
+ lstat.c statvfs.c \
+ eaccess.c gross.c gross_sgi.h omitted.c \
+ fakelink.h readlink.c symlink.c \
+ getpgrp.c setpgid.c setsid.c waitpid.c \
+ creat64.c fcntl.c open.c \
+ atexit.c getdents.c getwd.c dup2.c errno.c \
+ getpreroot.c ispreroot.c realopen.c setpreroot.c \
+ getgroups.c mount.c system.c iblocks.c \
+ modedata.c tmdata.c \
+ memfatal.c sfkeyprintf.c \
+ sfdcdio.c sfdcdos.c sfdcfilter.c sfdcseekable.c \
+ sfdcslow.c sfdcsubstr.c sfdctee.c sfdcunion.c \
+ sfdcmore.c sfdcprefix.c \
+ wc.c wc2utf8.c \
+ /* standards */ \
+ basename.c closelog.c dirname.c fmtmsglib.c fnmatch.c ftw.c \
+ getdate.c getsubopt.c glob.c nftw.c openlog.c re_comp.c \
+ resolvepath.c realpath.c regcmp.c regexp.c setlogmask.c strftime.c \
+ strptime.c swab.c syslog.c sysloglib.h tempnam.c \
+ wordexp.c mktime.c \
+ /* regex */ \
+ reglib.h regalloc.c regclass.c regcoll.c regcomp.c regcache.c \
+ regdecomp.c regerror.c regexec.c regfatal.c reginit.c regnexec.c \
+ regsubcomp.c regsubexec.c regsub.c regrecord.c regrexec.c regstat.c \
+ /* cdt */ \
+ dthdr.h dtclose.c dtdisc.c dthash.c dtlist.c dtmethod.c \
+ dtopen.c dtstrhash.c dttree.c dtview.c dtwalk.c \
+ dtnew.c dtcomp.c \
+ /* sfio */ \
+ sfhdr.h sfdchdr.h \
+ sfclose.c sfclrlock.c sfdisc.c sfdlen.c sfexcept.c \
+ sfgetl.c sfgetu.c sfcvt.c sfecvt.c sffcvt.c \
+ sfextern.c sffilbuf.c sfflsbuf.c sfprints.c sfgetd.c \
+ sfgetr.c sfllen.c sfmode.c sfmove.c sfnew.c \
+ sfpkrd.c sfnotify.c sfnputc.c sfopen.c sfpeek.c sfpoll.c \
+ sfpool.c sfpopen.c sfprintf.c sfputd.c sfputl.c sfputr.c \
+ sfputu.c sfrd.c sfread.c sfreserve.c sfscanf.c sfseek.c sfset.c \
+ sfsetbuf.c sfsetfd.c sfsize.c sfsk.c sfstack.c sfstrtod.c sfsync.c \
+ sfswap.c sftable.c sftell.c sftmp.c sfungetc.c sfvprintf.c \
+ sfvscanf.c sfwr.c sfwrite.c sfpurge.c sfraise.c sfwalk.c \
+ sfgetm.c sfmutex.c sfputm.c sfresize.c \
+ _sfclrerr.c _sfeof.c _sferror.c _sffileno.c \
+ _sfopen.c _sfstacked.c _sfvalue.c \
+ _sfgetc.c _sfgetl.c _sfgetl2.c _sfgetu.c _sfgetu2.c \
+ _sfdlen.c _sfllen.c _sfslen.c _sfulen.c \
+ _sfputc.c _sfputd.c _sfputl.c _sfputm.c _sfputu.c \
+ /* stdio */ \
+ clearerr.c fclose.c fdopen.c feof.c ferror.c fflush.c \
+ fgetc.c fgetpos.c fgets.c fileno.c fopen.c fprintf.c \
+ fpurge.c fputc.c fputs.c fread.c freopen.c fscanf.c \
+ fseek.c fseeko.c fsetpos.c ftell.c ftello.c fwrite.c \
+ flockfile.c ftrylockfile.c funlockfile.c \
+ getc.c getchar.c getw.c pclose.c popen.c printf.c \
+ putc.c putchar.c puts.c putw.c rewind.c scanf.c \
+ setbuf.c setbuffer.c setlinebuf.c setvbuf.c \
+ snprintf.c sprintf.c sscanf.c \
+ asprintf.c vasprintf.c \
+ stdio/tmpfile.c ungetc.c vfprintf.c vfscanf.c vprintf.c \
+ vscanf.c vsnprintf.c vsprintf.c vsscanf.c \
+ _doprnt.c _doscan.c _filbuf.c _flsbuf.c _stdfun.c \
+ _stdopen.c _stdprintf.c _stdscanf.c _stdsprnt.c \
+ _stdvbuf.c _stdvsnprnt.c _stdvsprnt.c _stdvsscn.c \
+ /* wchar stdio */ \
+ fgetwc.c fwprintf.c putwchar.c vfwscanf.c wprintf.c \
+ fgetws.c fwscanf.c swprintf.c vswprintf.c wscanf.c \
+ fputwc.c getwc.c swscanf.c vswscanf.c \
+ fputws.c getwchar.c ungetwc.c vwprintf.c \
+ fwide.c putwc.c vfwprintf.c vwscanf.c \
+ /* stdio extensions */ \
+ stdio_c99.c fcloseall.c fmemopen.c getdelim.c getline.c \
+ /* math */ \
+ frexp.c frexpl.c \
+ /* ast */ \
+ astcopy.c astconf.c astdynamic.c astlicense.c astquery.c astwinsize.c \
+ conftab.c \
+ $(CC.LD.STATIC) aststatic.c getopt.c getoptl.c $(CC.LD.DYNAMIC) \
+ /* aso */ \
+ aso.c asolock.c asometh.c asorelax.c aso-sem.c aso-fcntl.c \
+ /* vmalloc */ \
+ vmalloc.h vmhdr.h vmbest.c vmclear.c vmclose.c vmdcheap.c vmdebug.c \
+ vmdisc.c vmexit.c vmlast.c vmopen.c vmpool.c vmprivate.c vmprofile.c \
+ vmregion.c vmsegment.c vmset.c vmstat.c vmstrdup.c vmtrace.c vmwalk.c \
+ vmmopen.c malloc.c vmgetmem.c \
+ /* uwin */ \
+ mathimpl.h rlib.h \
+ a64l.c acosh.c asinh.c atanh.c cbrt.c crypt.c erf.c \
+ err.c exp.c exp__E.c expm1.c gamma.c getpass.c lgamma.c log.c log1p.c \
+ log__L.c rand48.c random.c rcmd.c rint.c support.c \
+ /* obsolete */ \
+ sfstrtmp.c spawn.c \
+ -liconv -lw /* these should be pulled in by -lc */
+
+/*
+ * man is stdio.h problematic
+ * the std/stdio.h => ast_stdio.h runaround should
+ * get to a steady state
+ *
+ * also, -D_BLD_ast must be explicit for the uwin bootstrap
+ */
+
+.MAKEINIT : .AST.INIT
+.AST.INIT : .MAKE
+ CCFLAGS += -D_BLD_ast
+
+parameter (_BLD_ast)
+virtual ast/stdio.h
+
+ :NOPROTECT: sfprintf.c sfvprintf.c sfscanf.c sfvscanf.c
+
+ :NOOPTIMIZE: spawnveg.c
+"ibm.risc" :NOOPTIMIZE: regcomp.c
+"linux.i386-64*":NOOPTIMIZE: sfset.c
+"sol?.*" :NOOPTIMIZE: sfrd.c sfvprintf.c tmxfmt.c
+"win32*" :NOOPTIMIZE: fastfind.c mc.c
+
+/*
+ * NOTE: sun4 runtime link botches ro data so advertised sig_info is rw
+ */
+
+:READONLY: conftab.c lctab.c modedata.c /*sftable.c*/ \
+ /*sigdata.c*/ tmdata.c univdata.c
+
+:: atmain.C \
+ stdgets.c stdprintf.c stdscanf.c stdvbuf.c stdsprnt.c \
+ stdvsprnt.c stdvsnprnt.c stdvsscn.c stdopen.c \
+ astsa
+
+if "$(PWD:B)" != "cc-*"
+
+$(INCLUDEDIR) :INSTALLPROTO: $(HEADEREXP) $(HEADERSRC) $(HEADERGEN)
+
+:INSTALLDIR: conf
+
+conf :: conf.sh
+
+conflim.h conftab.h conftab.c :JOINT: conf conf.tab
+ $(*:O=1:P=A) $(IFFEFLAGS:V:N=-v) $(*:O>1) $(CC) $(CCFLAGS:VP:N!=-D_BLD_*|$\(*\)) /* 2007-07-01: $(CCFLAGS:VPX:N!=-D_BLD_*) */
+
+$(HEADERGEN) :COPY: FEATURE/$$(<:B:/$(ID)_//)
+
+ast_namval.h :COPY: namval.h
+
+lcgen : lcgen.c
+ $(CC.NATIVE|CC) -o $(<) $(*)
+
+lc.h lctab.c :JOINT: lcgen lc.tab
+ $(*:O=1:C,^[^/],./&,) $(tmp).1 $(tmp).2 < $(*:O=2) # :P=E: in 2006
+ $(PROTO) -p $(PROTOFLAGS) $(tmp).1 $(PROTOINSTALL) > $(tmp).3
+ $(RM) -f $(tmp).1
+ if $(CMP) -s $(tmp).3 $(<:O=1)
+ then $(RM) $(tmp).3
+ else $(MV) $(tmp).3 $(<:O=1)
+ fi
+ if $(CMP) -s $(tmp).2 $(<:O=2)
+ then $(RM) $(tmp).2
+ else $(MV) $(tmp).2 $(<:O=2)
+ fi
+
+$(LIBDIR)/file/magic :INSTALL: magic.tab
+
+:INSTALL: $(HEADEROPT:D=$(INCLUDEDIR):B:S)
+
+$(HEADEROPT:D=$(INCLUDEDIR):B:S) : $$(<:B:S) ast_lib.h
+ case $(CC.HOSTTYPE) in
+ win32.*)$(PROTO) -p $(PROTOFLAGS) $(*:O=1) $(PROTOINSTALL) > 1.$(tmp).x
+ if $(CMP) -s $(<) 1.$(tmp).x
+ then $(RM) -f 1.$(tmp).x
+ else $(MV) 1.$(tmp).x $(<)
+ fi
+ ;;
+ *) $(SILENT) $(GREP) -l 'define[ ][ ]*_[hl][di][rb]_$(<:B)' $(*:O>1) > /dev/null || {
+ $(PROTO) -p $(PROTOFLAGS) $(*:O=1) $(PROTOINSTALL) > 1.$(tmp).x
+ if $(CMP) -s $(<) 1.$(tmp).x
+ then $(RM) -f 1.$(tmp).x
+ else $(MV) 1.$(tmp).x $(<)
+ fi
+ }
+ ;;
+ esac
+
+/* a few headers are problematic */
+
+$(INCLUDEDIR)/prototyped.h :INSTALL: $(INCLUDEDIR)
+ echo "#include <../prototyped.h>" > 1.$(tmp).x
+ if $(CMP) -s $(<) 1.$(tmp).x
+ then $(RM) -f 1.$(tmp).x
+ else $(MV) 1.$(tmp).x $(<)
+ fi
+
+/*
+ * FEATURE/common for iffe probes, <ast_common.h> for ast source
+ * *but* <ast_common.h> may get pulled in by intercepted headers
+ * so both must be built very early
+ */
+
+$(ID)_common.h : .SCAN.IGNORE FEATURE/common
+ $(SED) '/define _def_map_ast/d' < $(*) > 1.$(tmp).x
+ if $(CMP) -s $(<) 1.$(tmp).x
+ then $(RM) -f 1.$(tmp).x
+ else $(MV) 1.$(tmp).x $(<)
+ fi
+
+FEATURE/common : .SCAN.IGNORE
+
+/*
+ * more stdio.h complications ...
+ * prepare for compilation by generating these headers first;
+ * this helps mam by catching headers that might be indirectly
+ * included on other systems
+ */
+
+.check.hdr : .IGNORE .VIRTUAL \
+ FEATURE/standards - FEATURE/lib - FEATURE/common - \
+ FEATURE/param - FEATURE/aso - \
+ ast_map.h - ast_limits.h - ast_stdio.h ast_nl_types.h - \
+ ast_wchar.h ast_wctype.h
+ : clean up obsolete headers :
+ $(RM) -rf $(HEADERSTD) ast_hdr.h ast_types.h ast_unistd.h iffeio.h \
+ $(INCLUDEDIR)/limits.h $(INCLUDEDIR)/unistd.h \
+ $(PACKAGEROOT)/src/lib/libast/std/limits.h
+
+ast.req : .check.hdr .check.lib
+
+else
+
+ast.req : .check.lib
+
+end
+
+/*
+ * some systems move -lc routines to -lm
+ * see astmath.c for details
+ */
+
+.check.lib : .AFTER astmath.exe FEATURE/aso
+ $(SED) -e '/^#define _REQ_/!d' -e 's/#define _REQ_\([a-z0-9_]*\).*/ -l\1/' $(*:N=FEATURE/*) >> $(<<)
+ if test -f astmath.exe
+ then touch $(<<)
+ else echo ' -lm' >> $(<<)
+ fi
+
+astmath.exe : .DONTCARE astmath.c
+ X=1
+ for N in 1 2 3 4 5 6 8
+ do if $(CC) -DN=$N -DIS $(CCFLAGS) -o $(*:N=*.c:B:S=.exe) $(*) 2>/dev/null
+ then : implicit math function N=$N :
+ elif $(CC) -DN=$N -DIS $(CCFLAGS) -o $(*:N=*.c:B:S=.exe) $(*) -lm 2>/dev/null
+ then : math function N=$N requires -lm :
+ X=0
+ break
+ fi
+ done
+ case $X in
+ 0) $(RM) -f $(*:N=*.c:B:S=.exe) ;;
+ *) touch $(*:N=*.c:B:S=.exe) ;;
+ esac
+ $(RM) -f $(*:N=*.c:B:S=$(CC.SUFFIX.OBJECT))
+
+/*
+ * atmain.C is the only C++ and only for a few systems
+ */
+
+atmain.o : atmain.C
+ ignore $(CC) -c $(CCFLAGS) $(*)
+ if test ! -f $(<)
+ then $(CP) $(*) $(*:B:S=.cpp)
+ ignore $(CC) -c $(CCFLAGS) $(*:B:S=.cpp)
+ if test ! -f $(<)
+ then $(CP) $(*) $(*:B:S=.c)
+ $(CC) -c $(CCFLAGS) $(*:B:S=.c)
+ fi
+ fi
+
+/* astsa is a standalone subset of ast for imbedded applications */
+
+PAXFILTER = ;*.[ch];$(PROTO) $(PROTOFLAGS) -c "" -p
+
+ast_sa.h : .DONTCARE
+
+astsa.tgz : $$("astsa/astsa.manifest":T=F:T=I:/[[:space:]][[:space:]]*/ /G:C,^,astsa/,)
+ $(PAX) $(PAXFLAGS) -wf $(<) -x $(<:/.*\.//) -s ',.*/,,' -A $(PAXFILTER:@Q) $(*)
+
+/* libmini.a is a bootstrap dll for uwin cc -D_BLD_ast that exports part of ast */
+
+MINI = mini
+
+:: $(MINI).sym
+
+if CC.HOSTTYPE == "win32*"
+
+DLL = $(ID)$(VERSION:/[^0-9]//G)
+
+$(MINI) : $(MINI)$$(CC.SUFFIX.SHARED)
+
+$(MINI)$$(CC.SUFFIX.SHARED) : $(MINI).sym $(ID)
+ $(RM) -rf $(MINI).tmp
+ mkdir $(MINI).tmp
+ {
+ echo LIBRARY $(DLL:F=%(upper)s)
+ echo
+ echo SECTIONS
+ echo .data READ WRITE
+ echo
+ echo EXPORTS
+ cat $(*:N=*.sym)
+ } > $(MINI).tmp/$(DLL)$(CC.SUFFIX.LD:O=1)
+ cd $(MINI).tmp
+ $(LD) $(CCFLAGS:N=-[gG]*) $(CC.SHARED) -o $(DLL) $(DLL)$(CC.SUFFIX.LD:O=1) $(*$(ID).so/$(DLL)$(CC.SUFFIX.DYNAMIC):C,^[^-],../&,)
+ cd ..
+ $(MV) $(MINI).tmp/$(DLL)$(CC.SUFFIX.SHARED) $(<)
+ $(RM) -rf $(MINI).tmp
+
+end
+
+:MSGKEY: misc/magic.tab
+ $(SED) \
+ -e '/^#/d' \
+ -e '/[^ ]* *[^ ]* *[^ ]* *./!d' \
+ -e 's,^[^ ]* *[^ ]* *[^ ]* *\(.[^ ]*\).*$,\1,' \
+ -e 's,[\\"],\\&,g' \
+ -e 's,.*,"&",' \
+ $(*)
diff --git a/src/lib/libast/Mamfile b/src/lib/libast/Mamfile
new file mode 100644
index 0000000..0c0290c
--- /dev/null
+++ b/src/lib/libast/Mamfile
@@ -0,0 +1,7356 @@
+info mam static 00000 1994-07-17 make (AT&T Research) 5.7 2012-02-29
+setv INSTALLROOT ../../..
+setv PACKAGEROOT ../../../../..
+setv AR ${mam_cc_AR} ${mam_cc_AR_ARFLAGS}
+setv ARFLAGS rc
+setv AS as
+setv ASFLAGS
+setv CC cc
+setv mam_cc_FLAGS ${mam_cc_DLL} -D_BLD_ast
+setv CCFLAGS ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${mam_cc_OPTIMIZE}?}
+setv CCLDFLAGS ${-strip-symbols?1?${mam_cc_LD_STRIP}??}
+setv COTEMP $$
+setv CPIO cpio
+setv CPIOFLAGS
+setv CPP "${CC} -E"
+setv F77 f77
+setv HOSTCC ${CC}
+setv IGNORE
+setv LD ld
+setv LDFLAGS
+setv LEX lex
+setv LEXFLAGS
+setv LPR lpr
+setv LPRFLAGS
+setv M4FLAGS
+setv NMAKE nmake
+setv NMAKEFLAGS
+setv PR pr
+setv PRFLAGS
+setv SHELL /bin/sh
+setv SILENT
+setv TAR tar
+setv YACC yacc
+setv YACCFLAGS -d
+make ${PACKAGEROOT}/lib/package/ast.lic
+done ${PACKAGEROOT}/lib/package/ast.lic
+make install
+make ast
+make libast.a archive
+make ast.req
+make FEATURE/standards
+meta FEATURE/standards features/%>FEATURE/% features/standards standards
+make features/standards
+done features/standards
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/standards
+done FEATURE/standards generated
+make FEATURE/lib
+meta FEATURE/lib features/%>FEATURE/% features/lib lib
+make features/lib
+done features/lib
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/lib
+done FEATURE/lib generated
+make FEATURE/common
+meta FEATURE/common features/%>FEATURE/% features/common common
+make features/common
+done features/common
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/common
+done FEATURE/common generated
+make FEATURE/param
+meta FEATURE/param features/%.sh>FEATURE/% features/param.sh param
+make features/param.sh
+done features/param.sh
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/param.sh
+make std/endian.h implicit
+make std/bytesex.h implicit
+make ast_common.h implicit
+prev FEATURE/common
+exec - sed '/define _def_map_ast/d' < FEATURE/common > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ast_common.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ast_common.h
+exec - fi
+make ast_map.h implicit
+make FEATURE/map
+meta FEATURE/map features/%.c>FEATURE/% features/map.c map
+make features/map.c
+make FEATURE/api implicit
+meta FEATURE/api features/%>FEATURE/% features/api api
+make features/api
+done features/api
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/api
+done FEATURE/api generated
+make FEATURE/eaccess implicit
+meta FEATURE/eaccess features/%>FEATURE/% features/eaccess eaccess
+make features/eaccess
+done features/eaccess
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/eaccess
+done FEATURE/eaccess generated
+make FEATURE/vmalloc implicit
+meta FEATURE/vmalloc features/%>FEATURE/% features/vmalloc vmalloc
+make features/vmalloc
+done features/vmalloc
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/vmalloc
+make FEATURE/mmap implicit
+meta FEATURE/mmap features/%>FEATURE/% features/mmap mmap
+make features/mmap
+done features/mmap
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/mmap
+done FEATURE/mmap dontcare generated
+done FEATURE/vmalloc generated
+make FEATURE/options implicit
+meta FEATURE/options features/%>FEATURE/% features/options options
+make features/options
+done features/options
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/options
+done FEATURE/options generated
+prev FEATURE/mmap implicit
+prev FEATURE/lib implicit
+done features/map.c
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. ${LDFLAGS} ' run features/map.c
+done FEATURE/map generated
+exec - cmp 2>/dev/null -s FEATURE/map ast_map.h || { rm -f ast_map.h; silent test -d . || mkdir .; ${STDCP} FEATURE/map ast_map.h; }
+done ast_map.h dontcare generated
+done ast_common.h dontcare generated
+done std/bytesex.h dontcare
+done std/endian.h dontcare
+done FEATURE/param generated
+make FEATURE/aso
+meta FEATURE/aso features/%>FEATURE/% features/aso aso
+make features/aso
+done features/aso
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/aso
+done FEATURE/aso generated
+prev ast_map.h
+make ast_limits.h
+make FEATURE/limits
+meta FEATURE/limits features/%.c>FEATURE/% features/limits.c limits
+make features/limits.c
+make conflim.h implicit
+make conf
+make comp/conf.sh
+done comp/conf.sh
+meta conf %.sh>% comp/conf.sh conf
+prev comp/conf.sh
+exec - case static,port:$OPTIND:$RANDOM in
+exec - ?*:*:*|*::*|*:*:$RANDOM)
+exec - ;;
+exec - *) if ENV= LC_ALL=C x= $SHELL -nc '[[ a || b ]] && : ${list[level]} !(pattern)' 2>/dev/null
+exec - then if grep -q '### .*archaic.* ###'
+exec - then : conf contains archaic constructs :
+exec - else ENV= LC_ALL=C $SHELL -n comp/conf.sh
+exec - fi
+exec - fi
+exec - ;;
+exec - esac
+exec - case '${mam_cc_SHELLMAGIC}' in
+exec - "") case 29 in
+exec - 0) ${STDCP} comp/conf.sh conf
+exec - ;;
+exec - *) {
+exec - i=`(read x; echo $x) < comp/conf.sh`
+exec - case $i in
+exec - '#!'*|*'||'*|':'*|'":"'*|"':'"*) echo "$i" ;;
+exec - esac
+exec - cat - comp/conf.sh <<'!'
+exec - HOSTTYPE="${mam_cc_HOSTTYPE}"
+exec - !
+exec - } > conf
+exec - ;;
+exec - esac
+exec - ;;
+exec - *) cat - comp/conf.sh > conf <<'!'
+exec - ${mam_cc_SHELLMAGIC}
+exec - HOSTTYPE="${mam_cc_HOSTTYPE}"
+exec - !
+exec - ;;
+exec - esac
+exec - silent test -w conf -a -x conf || chmod u+w,+x conf
+done conf generated
+make comp/conf.tab
+done comp/conf.tab
+exec - ${INSTALLROOT}/src/lib/libast/conf -v comp/conf.tab ${CC} ${mam_cc_FLAGS} ${CCFLAGS}
+make joint.conflim.h joint
+prev conflim.h
+make conftab.h
+done conftab.h generated
+make conftab.c
+done conftab.c generated
+done joint.conflim.h generated virtual
+done conflim.h generated
+prev FEATURE/param implicit
+make comp/getopt.h implicit
+make include/ast_getopt.h implicit
+done include/ast_getopt.h dontcare
+done comp/getopt.h dontcare
+prev FEATURE/common implicit
+prev FEATURE/lib implicit
+prev FEATURE/standards implicit
+done features/limits.c
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd ${LDFLAGS} ' run features/limits.c
+done FEATURE/limits generated
+exec - cmp 2>/dev/null -s FEATURE/limits ast_limits.h || { rm -f ast_limits.h; silent test -d . || mkdir .; ${STDCP} FEATURE/limits ast_limits.h; }
+done ast_limits.h generated
+make ast_stdio.h
+make FEATURE/stdio
+meta FEATURE/stdio features/%>FEATURE/% features/stdio stdio
+make features/stdio
+done features/stdio
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/stdio
+make include/sfio_s.h implicit
+done include/sfio_s.h dontcare
+make include/ast_std.h implicit
+make include/regex.h implicit
+make ast_wchar.h implicit
+make FEATURE/wchar
+meta FEATURE/wchar features/%>FEATURE/% features/wchar wchar
+make features/wchar
+prev ast_common.h implicit
+done features/wchar
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/wchar
+make std/wctype.h implicit
+make ast_wctype.h implicit
+make FEATURE/wctype
+meta FEATURE/wctype features/%>FEATURE/% features/wctype wctype
+make features/wctype
+done features/wctype
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/wctype
+prev std/endian.h implicit
+done FEATURE/wctype generated
+exec - cmp 2>/dev/null -s FEATURE/wctype ast_wctype.h || { rm -f ast_wctype.h; silent test -d . || mkdir .; ${STDCP} FEATURE/wctype ast_wctype.h; }
+done ast_wctype.h dontcare generated
+done std/wctype.h dontcare
+make std/stdio.h implicit
+prev ast_stdio.h implicit
+done std/stdio.h dontcare
+prev std/stdio.h implicit
+prev ast_common.h implicit
+done FEATURE/wchar generated
+exec - cmp 2>/dev/null -s FEATURE/wchar ast_wchar.h || { rm -f ast_wchar.h; silent test -d . || mkdir .; ${STDCP} FEATURE/wchar ast_wchar.h; }
+prev std/stdio.h implicit
+prev ast_common.h implicit
+done ast_wchar.h dontcare generated
+prev ast_common.h implicit
+done include/regex.h dontcare
+prev comp/getopt.h implicit
+prev ast_map.h implicit
+make ast_botch.h implicit
+make FEATURE/botch
+meta FEATURE/botch features/%.c>FEATURE/% features/botch.c botch
+make features/botch.c
+make FEATURE/sys implicit
+meta FEATURE/sys features/%>FEATURE/% features/sys sys
+make features/sys
+done features/sys
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/sys
+prev std/endian.h implicit
+prev std/endian.h implicit
+done FEATURE/sys generated
+prev FEATURE/lib implicit
+done features/botch.c
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd ${LDFLAGS} ' run features/botch.c
+done FEATURE/botch generated
+exec - cmp 2>/dev/null -s FEATURE/botch ast_botch.h || { rm -f ast_botch.h; silent test -d . || mkdir .; ${STDCP} FEATURE/botch ast_botch.h; }
+done ast_botch.h dontcare generated
+prev ast_limits.h implicit
+make ast_fcntl.h implicit
+make FEATURE/fcntl
+meta FEATURE/fcntl features/%.c>FEATURE/% features/fcntl.c fcntl
+make features/fcntl.c
+make FEATURE/tty implicit
+meta FEATURE/tty features/%>FEATURE/% features/tty tty
+make features/tty
+done features/tty
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/tty
+done FEATURE/tty generated
+make FEATURE/fs implicit
+meta FEATURE/fs features/%>FEATURE/% features/fs fs
+make features/fs
+done features/fs
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/fs
+done FEATURE/fs generated
+prev FEATURE/lib implicit
+done features/fcntl.c
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd ${LDFLAGS} ' run features/fcntl.c
+make ast_fs.h implicit
+prev FEATURE/fs
+exec - cmp 2>/dev/null -s FEATURE/fs ast_fs.h || { rm -f ast_fs.h; silent test -d . || mkdir .; ${STDCP} FEATURE/fs ast_fs.h; }
+done ast_fs.h dontcare generated
+done FEATURE/fcntl generated
+exec - cmp 2>/dev/null -s FEATURE/fcntl ast_fcntl.h || { rm -f ast_fcntl.h; silent test -d . || mkdir .; ${STDCP} FEATURE/fcntl ast_fcntl.h; }
+prev ast_fs.h implicit
+done ast_fcntl.h dontcare generated
+prev include/ast_getopt.h implicit
+make ast_sys.h implicit
+prev FEATURE/sys
+exec - cmp 2>/dev/null -s FEATURE/sys ast_sys.h || { rm -f ast_sys.h; silent test -d . || mkdir .; ${STDCP} FEATURE/sys ast_sys.h; }
+done ast_sys.h dontcare generated
+make ast_lib.h implicit
+prev FEATURE/lib
+exec - cmp 2>/dev/null -s FEATURE/lib ast_lib.h || { rm -f ast_lib.h; silent test -d . || mkdir .; ${STDCP} FEATURE/lib ast_lib.h; }
+done ast_lib.h dontcare generated
+prev ast_common.h implicit
+done include/ast_std.h dontcare
+done FEATURE/stdio generated
+exec - cmp 2>/dev/null -s FEATURE/stdio ast_stdio.h || { rm -f ast_stdio.h; silent test -d . || mkdir .; ${STDCP} FEATURE/stdio ast_stdio.h; }
+prev include/sfio_s.h implicit
+prev include/ast_std.h implicit
+done ast_stdio.h dontcare generated
+make ast_nl_types.h
+make FEATURE/nl_types
+meta FEATURE/nl_types features/%>FEATURE/% features/nl_types nl_types
+make features/nl_types
+done features/nl_types
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/nl_types
+done FEATURE/nl_types generated
+exec - cmp 2>/dev/null -s FEATURE/nl_types ast_nl_types.h || { rm -f ast_nl_types.h; silent test -d . || mkdir .; ${STDCP} FEATURE/nl_types ast_nl_types.h; }
+done ast_nl_types.h generated
+prev ast_wchar.h
+prev ast_wctype.h
+exec - : clean up obsolete headers :
+exec - rm -rf dirent.h iconv.h nl_types.h stdio.h wchar.h wctype.h ast_hdr.h ast_types.h ast_unistd.h iffeio.h \
+exec - ${INSTALLROOT}/include/ast/limits.h ${INSTALLROOT}/include/ast/unistd.h \
+exec - ${PACKAGEROOT}/src/lib/libast/std/limits.h
+exec - set -
+exec - echo 'int main(){return 0;}' > 1.${COTEMP}.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -c 1.${COTEMP}.c &&
+exec - x=`${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l'*' 2>&1 | sed -e 's/[][()+@?]/#/g' || :` &&
+exec - {
+exec - case "" in
+exec - *?) echo " " ;;
+exec - esac
+exec - for i in ast iconv w
+exec - do case $i in
+exec - "ast"|ast)
+exec - ;;
+exec - *) if test -f ${INSTALLROOT}/lib/lib/$i
+exec - then y=`cat ${INSTALLROOT}/lib/lib/$i`
+exec - case $y in
+exec - *-?*) echo "" $y ;;
+exec - esac
+exec - continue
+exec - elif test ! -f ${INSTALLROOT}/lib/lib$i.a
+exec - then case `{ ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l$i 2>&1 || echo '' $x ;} | sed -e 's/[][()+@?]/#/g' || :` in
+exec - *$x*) case `{ ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} -o 1.${COTEMP}.x 1.${COTEMP}.o -l$i 2>&1 || echo '' $x ;} | sed -e 's/[][()+@?]/#/g' || :` in
+exec - *$x*) continue ;;
+exec - esac
+exec - ;;
+exec - esac
+exec - fi
+exec - ;;
+exec - esac
+exec - echo " -l$i"
+exec - done
+exec - } > ast.req
+exec - rm -f 1.${COTEMP}.*
+make astmath.exe
+make port/astmath.c
+prev std/endian.h implicit
+prev std/endian.h implicit
+done port/astmath.c
+exec - X=1
+exec - for N in 1 2 3 4 5 6 8
+exec - do if ${CC} -DN=$N -DIS ${mam_cc_FLAGS} ${CCFLAGS} -I. -Istd -o astmath.exe port/astmath.c 2>/dev/null
+exec - then : implicit math function N=$N :
+exec - elif ${CC} -DN=$N -DIS ${mam_cc_FLAGS} ${CCFLAGS} -I. -Istd -o astmath.exe port/astmath.c -lm 2>/dev/null
+exec - then : math function N=$N requires -lm :
+exec - X=0
+exec - break
+exec - fi
+exec - done
+exec - case $X in
+exec - 0) rm -f astmath.exe ;;
+exec - *) touch astmath.exe ;;
+exec - esac
+exec - rm -f astmath
+done astmath.exe dontcare generated
+prev FEATURE/aso
+exec - sed -e '/^#define _REQ_/!d' -e 's/#define _REQ_\([a-z0-9_]*\).*/ -l\1/' FEATURE/aso >> ast.req
+exec - if test -f astmath.exe
+exec - then touch ast.req
+exec - else echo ' -lm' >> ast.req
+exec - fi
+done ast.req generated
+make state.o
+make misc/state.c
+make include/ast.h implicit
+make ast_api.h implicit
+prev FEATURE/api
+exec - cmp 2>/dev/null -s FEATURE/api ast_api.h || { rm -f ast_api.h; silent test -d . || mkdir .; ${STDCP} FEATURE/api ast_api.h; }
+done ast_api.h dontcare generated
+make include/vmalloc.h implicit
+prev ast_common.h implicit
+prev include/ast_std.h implicit
+done include/vmalloc.h dontcare
+make include/sfio.h implicit
+prev include/sfio_s.h implicit
+prev ast_common.h implicit
+prev include/ast_std.h implicit
+done include/sfio.h dontcare
+prev include/ast_std.h implicit
+done include/ast.h
+done misc/state.c
+meta state.o %.c>%.o misc/state.c state
+prev misc/state.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/state.c
+done state.o generated
+make transition.o
+make comp/transition.c
+prev include/ast.h implicit
+done comp/transition.c
+meta transition.o %.c>%.o comp/transition.c transition
+prev comp/transition.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/transition.c
+done transition.o generated
+make opendir.o
+make dir/opendir.c
+make dir/dirlib.h implicit
+make dir/dirstd.h implicit
+done dir/dirstd.h dontcare
+make direntry.h implicit
+done direntry.h dontcare virtual
+make ast_param.h implicit
+prev FEATURE/param
+exec - cmp 2>/dev/null -s FEATURE/param ast_param.h || { rm -f ast_param.h; silent test -d . || mkdir .; ${STDCP} FEATURE/param ast_param.h; }
+done ast_param.h dontcare generated
+make std/dirent.h implicit
+make ast_dirent.h implicit
+make FEATURE/dirent
+meta FEATURE/dirent features/%>FEATURE/% features/dirent dirent
+make features/dirent
+done features/dirent
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/dirent
+prev include/ast_std.h implicit
+done FEATURE/dirent generated
+exec - cmp 2>/dev/null -s FEATURE/dirent ast_dirent.h || { rm -f ast_dirent.h; silent test -d . || mkdir .; ${STDCP} FEATURE/dirent ast_dirent.h; }
+prev include/ast_std.h implicit
+done ast_dirent.h dontcare generated
+done std/dirent.h dontcare
+make ndir.h implicit
+done ndir.h dontcare virtual
+prev std/dirent.h implicit
+make include/ls.h implicit
+make ast_mode.h implicit
+make FEATURE/mode
+meta FEATURE/mode features/%.c>FEATURE/% features/mode.c mode
+make features/mode.c
+make include/modecanon.h implicit
+done include/modecanon.h
+prev FEATURE/param implicit
+done features/mode.c
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iinclude -Istd ${LDFLAGS} ' run features/mode.c
+done FEATURE/mode generated
+exec - cmp 2>/dev/null -s FEATURE/mode ast_mode.h || { rm -f ast_mode.h; silent test -d . || mkdir .; ${STDCP} FEATURE/mode ast_mode.h; }
+done ast_mode.h dontcare generated
+prev ast_fs.h implicit
+prev include/ast_std.h implicit
+done include/ls.h dontcare
+prev include/ast.h implicit
+done dir/dirlib.h
+done dir/opendir.c
+meta opendir.o %.c>%.o dir/opendir.c opendir
+prev dir/opendir.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idir -Iinclude -Istd -D_PACKAGE_ast -c dir/opendir.c
+done opendir.o generated
+make readdir.o
+make dir/readdir.c
+prev dir/dirlib.h implicit
+done dir/readdir.c
+meta readdir.o %.c>%.o dir/readdir.c readdir
+prev dir/readdir.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idir -Iinclude -Istd -D_PACKAGE_ast -c dir/readdir.c
+done readdir.o generated
+make rewinddir.o
+make dir/rewinddir.c
+prev dir/dirlib.h implicit
+done dir/rewinddir.c
+meta rewinddir.o %.c>%.o dir/rewinddir.c rewinddir
+prev dir/rewinddir.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idir -Iinclude -Istd -D_PACKAGE_ast -c dir/rewinddir.c
+done rewinddir.o generated
+make seekdir.o
+make dir/seekdir.c
+prev dir/dirlib.h implicit
+done dir/seekdir.c
+meta seekdir.o %.c>%.o dir/seekdir.c seekdir
+prev dir/seekdir.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idir -Iinclude -Istd -D_PACKAGE_ast -c dir/seekdir.c
+done seekdir.o generated
+make telldir.o
+make dir/telldir.c
+prev dir/dirlib.h implicit
+done dir/telldir.c
+meta telldir.o %.c>%.o dir/telldir.c telldir
+prev dir/telldir.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idir -Iinclude -Istd -D_PACKAGE_ast -c dir/telldir.c
+done telldir.o generated
+make getcwd.o
+make misc/getcwd.c
+make include/fs3d.h implicit
+prev ast_fs.h implicit
+done include/fs3d.h dontcare
+make include/ast_dir.h implicit
+prev std/dirent.h implicit
+prev dir/dirlib.h implicit
+prev ast_lib.h implicit
+done include/ast_dir.h dontcare
+make include/error.h implicit
+make include/option.h implicit
+prev include/ast.h implicit
+done include/option.h dontcare
+prev include/ast.h implicit
+done include/error.h dontcare
+make FEATURE/syscall implicit
+meta FEATURE/syscall features/%>FEATURE/% features/syscall syscall
+make features/syscall
+done features/syscall
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/syscall
+done FEATURE/syscall dontcare generated
+prev include/ast.h implicit
+done misc/getcwd.c
+meta getcwd.o %.c>%.o misc/getcwd.c getcwd
+prev misc/getcwd.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idir -Iinclude -Istd -D_PACKAGE_ast -c misc/getcwd.c
+done getcwd.o generated
+make fastfind.o
+make misc/fastfind.c
+make misc/findlib.h implicit
+make include/find.h implicit
+done include/find.h dontcare
+prev include/vmalloc.h implicit
+prev include/regex.h implicit
+prev include/ls.h implicit
+prev include/error.h implicit
+prev std/endian.h implicit
+make include/cdt.h implicit
+prev ast_common.h implicit
+prev include/ast_std.h implicit
+done include/cdt.h dontcare
+prev include/ast.h implicit
+done misc/findlib.h
+done misc/fastfind.c
+meta fastfind.o %.c>%.o misc/fastfind.c fastfind
+prev misc/fastfind.c
+exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/fastfind.c
+done fastfind.o generated
+make hashalloc.o
+make hash/hashalloc.c
+make hash/hashlib.h implicit
+make include/hash.h implicit
+make include/hashpart.h implicit
+done include/hashpart.h dontcare
+done include/hash.h dontcare
+prev include/ast.h implicit
+done hash/hashlib.h
+done hash/hashalloc.c
+meta hashalloc.o %.c>%.o hash/hashalloc.c hashalloc
+prev hash/hashalloc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ihash -Iinclude -Istd -D_PACKAGE_ast -c hash/hashalloc.c
+done hashalloc.o generated
+make hashdump.o
+make hash/hashdump.c
+prev hash/hashlib.h implicit
+done hash/hashdump.c
+meta hashdump.o %.c>%.o hash/hashdump.c hashdump
+prev hash/hashdump.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ihash -Iinclude -Istd -D_PACKAGE_ast -c hash/hashdump.c
+done hashdump.o generated
+make hashfree.o
+make hash/hashfree.c
+prev hash/hashlib.h implicit
+done hash/hashfree.c
+meta hashfree.o %.c>%.o hash/hashfree.c hashfree
+prev hash/hashfree.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ihash -Iinclude -Istd -D_PACKAGE_ast -c hash/hashfree.c
+done hashfree.o generated
+make hashlast.o
+make hash/hashlast.c
+prev hash/hashlib.h implicit
+done hash/hashlast.c
+meta hashlast.o %.c>%.o hash/hashlast.c hashlast
+prev hash/hashlast.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ihash -Iinclude -Istd -D_PACKAGE_ast -c hash/hashlast.c
+done hashlast.o generated
+make hashlook.o
+make hash/hashlook.c
+prev hash/hashlib.h implicit
+done hash/hashlook.c
+meta hashlook.o %.c>%.o hash/hashlook.c hashlook
+prev hash/hashlook.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ihash -Iinclude -Istd -D_PACKAGE_ast -c hash/hashlook.c
+done hashlook.o generated
+make hashscan.o
+make hash/hashscan.c
+prev hash/hashlib.h implicit
+done hash/hashscan.c
+meta hashscan.o %.c>%.o hash/hashscan.c hashscan
+prev hash/hashscan.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ihash -Iinclude -Istd -D_PACKAGE_ast -c hash/hashscan.c
+done hashscan.o generated
+make hashsize.o
+make hash/hashsize.c
+prev hash/hashlib.h implicit
+done hash/hashsize.c
+meta hashsize.o %.c>%.o hash/hashsize.c hashsize
+prev hash/hashsize.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ihash -Iinclude -Istd -D_PACKAGE_ast -c hash/hashsize.c
+done hashsize.o generated
+make hashview.o
+make hash/hashview.c
+prev hash/hashlib.h implicit
+done hash/hashview.c
+meta hashview.o %.c>%.o hash/hashview.c hashview
+prev hash/hashview.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ihash -Iinclude -Istd -D_PACKAGE_ast -c hash/hashview.c
+done hashview.o generated
+make hashwalk.o
+make hash/hashwalk.c
+prev hash/hashlib.h implicit
+done hash/hashwalk.c
+meta hashwalk.o %.c>%.o hash/hashwalk.c hashwalk
+prev hash/hashwalk.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ihash -Iinclude -Istd -D_PACKAGE_ast -c hash/hashwalk.c
+done hashwalk.o generated
+make memhash.o
+make hash/memhash.c
+prev hash/hashlib.h implicit
+done hash/memhash.c
+meta memhash.o %.c>%.o hash/memhash.c memhash
+prev hash/memhash.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ihash -Iinclude -Istd -D_PACKAGE_ast -c hash/memhash.c
+done memhash.o generated
+make memsum.o
+make hash/memsum.c
+prev hash/hashlib.h implicit
+done hash/memsum.c
+meta memsum.o %.c>%.o hash/memsum.c memsum
+prev hash/memsum.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ihash -Iinclude -Istd -D_PACKAGE_ast -c hash/memsum.c
+done memsum.o generated
+make strhash.o
+make hash/strhash.c
+prev hash/hashlib.h implicit
+done hash/strhash.c
+meta strhash.o %.c>%.o hash/strhash.c strhash
+prev hash/strhash.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ihash -Iinclude -Istd -D_PACKAGE_ast -c hash/strhash.c
+done strhash.o generated
+make strkey.o
+make hash/strkey.c
+make include/hashkey.h implicit
+done include/hashkey.h
+prev include/ast.h implicit
+done hash/strkey.c
+meta strkey.o %.c>%.o hash/strkey.c strkey
+prev hash/strkey.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c hash/strkey.c
+done strkey.o generated
+make strsum.o
+make hash/strsum.c
+prev hash/hashlib.h implicit
+done hash/strsum.c
+meta strsum.o %.c>%.o hash/strsum.c strsum
+prev hash/strsum.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ihash -Iinclude -Istd -D_PACKAGE_ast -c hash/strsum.c
+done strsum.o generated
+make stracmp.o
+make string/stracmp.c
+make include/ccode.h implicit
+make ast_ccode.h implicit
+make FEATURE/ccode
+meta FEATURE/ccode features/%>FEATURE/% features/ccode ccode
+make features/ccode
+done features/ccode
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/ccode
+done FEATURE/ccode generated
+exec - cmp 2>/dev/null -s FEATURE/ccode ast_ccode.h || { rm -f ast_ccode.h; silent test -d . || mkdir .; ${STDCP} FEATURE/ccode ast_ccode.h; }
+done ast_ccode.h dontcare generated
+prev ast_common.h implicit
+done include/ccode.h
+prev include/ast.h implicit
+done string/stracmp.c
+meta stracmp.o %.c>%.o string/stracmp.c stracmp
+prev string/stracmp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/stracmp.c
+done stracmp.o generated
+make strnacmp.o
+make string/strnacmp.c
+prev include/ccode.h implicit
+prev include/ast.h implicit
+done string/strnacmp.c
+meta strnacmp.o %.c>%.o string/strnacmp.c strnacmp
+prev string/strnacmp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strnacmp.c
+done strnacmp.o generated
+make ccmap.o
+make string/ccmap.c
+prev include/ccode.h implicit
+prev include/ast.h implicit
+done string/ccmap.c
+meta ccmap.o %.c>%.o string/ccmap.c ccmap
+prev string/ccmap.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/ccmap.c
+done ccmap.o generated
+make ccmapid.o
+make string/ccmapid.c
+prev include/ccode.h implicit
+prev include/ast.h implicit
+done string/ccmapid.c
+meta ccmapid.o %.c>%.o string/ccmapid.c ccmapid
+prev string/ccmapid.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/ccmapid.c
+done ccmapid.o generated
+make ccnative.o
+make string/ccnative.c
+prev include/ccode.h implicit
+prev include/ast.h implicit
+done string/ccnative.c
+meta ccnative.o %.c>%.o string/ccnative.c ccnative
+prev string/ccnative.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/ccnative.c
+done ccnative.o generated
+make chresc.o
+make string/chresc.c
+prev include/regex.h implicit
+prev include/ccode.h implicit
+prev include/ast.h implicit
+done string/chresc.c
+meta chresc.o %.c>%.o string/chresc.c chresc
+prev string/chresc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/chresc.c
+done chresc.o generated
+make chrtoi.o
+make string/chrtoi.c
+prev include/ast.h implicit
+done string/chrtoi.c
+meta chrtoi.o %.c>%.o string/chrtoi.c chrtoi
+prev string/chrtoi.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/chrtoi.c
+done chrtoi.o generated
+make streval.o
+make string/streval.c
+prev include/ast.h implicit
+done string/streval.c
+meta streval.o %.c>%.o string/streval.c streval
+prev string/streval.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/streval.c
+done streval.o generated
+make strexpr.o
+make string/strexpr.c
+prev include/ast.h implicit
+done string/strexpr.c
+meta strexpr.o %.c>%.o string/strexpr.c strexpr
+prev string/strexpr.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strexpr.c
+done strexpr.o generated
+make strmatch.o
+make string/strmatch.c
+prev include/regex.h implicit
+prev include/ast.h implicit
+done string/strmatch.c
+meta strmatch.o %.c>%.o string/strmatch.c strmatch
+prev string/strmatch.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strmatch.c
+done strmatch.o generated
+make strcopy.o
+make string/strcopy.c
+prev include/ast.h implicit
+done string/strcopy.c
+meta strcopy.o %.c>%.o string/strcopy.c strcopy
+prev string/strcopy.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strcopy.c
+done strcopy.o generated
+make modei.o
+make string/modei.c
+make string/modelib.h implicit
+make include/modex.h implicit
+prev include/modecanon.h implicit
+prev ast_fs.h implicit
+done include/modex.h dontcare
+prev include/ls.h implicit
+prev include/ast.h implicit
+done string/modelib.h
+done string/modei.c
+meta modei.o %.c>%.o string/modei.c modei
+prev string/modei.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Istring -Iinclude -Istd -D_PACKAGE_ast -c string/modei.c
+done modei.o generated
+make modex.o
+make string/modex.c
+prev string/modelib.h implicit
+done string/modex.c
+meta modex.o %.c>%.o string/modex.c modex
+prev string/modex.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Istring -Iinclude -Istd -D_PACKAGE_ast -c string/modex.c
+done modex.o generated
+make strmode.o
+make string/strmode.c
+prev string/modelib.h implicit
+done string/strmode.c
+meta strmode.o %.c>%.o string/strmode.c strmode
+prev string/strmode.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Istring -Iinclude -Istd -D_PACKAGE_ast -c string/strmode.c
+done strmode.o generated
+make strlcat.o
+make string/strlcat.c
+prev ast_map.h implicit
+prev include/ast.h implicit
+done string/strlcat.c
+meta strlcat.o %.c>%.o string/strlcat.c strlcat
+prev string/strlcat.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strlcat.c
+done strlcat.o generated
+make strlcpy.o
+make string/strlcpy.c
+prev ast_map.h implicit
+prev include/ast.h implicit
+done string/strlcpy.c
+meta strlcpy.o %.c>%.o string/strlcpy.c strlcpy
+prev string/strlcpy.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strlcpy.c
+done strlcpy.o generated
+make strlook.o
+make string/strlook.c
+prev include/ast.h implicit
+done string/strlook.c
+meta strlook.o %.c>%.o string/strlook.c strlook
+prev string/strlook.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strlook.c
+done strlook.o generated
+make strncopy.o
+make string/strncopy.c
+prev include/ast.h implicit
+done string/strncopy.c
+meta strncopy.o %.c>%.o string/strncopy.c strncopy
+prev string/strncopy.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strncopy.c
+done strncopy.o generated
+make strsearch.o
+make string/strsearch.c
+prev include/ast.h implicit
+done string/strsearch.c
+meta strsearch.o %.c>%.o string/strsearch.c strsearch
+prev string/strsearch.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strsearch.c
+done strsearch.o generated
+make strpsearch.o
+make string/strpsearch.c
+prev include/ccode.h implicit
+prev include/ast.h implicit
+done string/strpsearch.c
+meta strpsearch.o %.c>%.o string/strpsearch.c strpsearch
+prev string/strpsearch.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strpsearch.c
+done strpsearch.o generated
+make stresc.o
+make string/stresc.c
+prev include/ast.h implicit
+done string/stresc.c
+meta stresc.o %.c>%.o string/stresc.c stresc
+prev string/stresc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/stresc.c
+done stresc.o generated
+make stropt.o
+make string/stropt.c
+prev include/ast.h implicit
+done string/stropt.c
+meta stropt.o %.c>%.o string/stropt.c stropt
+prev string/stropt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/stropt.c
+done stropt.o generated
+make strtape.o
+make string/strtape.c
+prev include/ast.h implicit
+done string/strtape.c
+meta strtape.o %.c>%.o string/strtape.c strtape
+prev string/strtape.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strtape.c
+done strtape.o generated
+make strpcmp.o
+make string/strpcmp.c
+prev include/ast.h implicit
+done string/strpcmp.c
+meta strpcmp.o %.c>%.o string/strpcmp.c strpcmp
+prev string/strpcmp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strpcmp.c
+done strpcmp.o generated
+make strnpcmp.o
+make string/strnpcmp.c
+prev include/ast.h implicit
+done string/strnpcmp.c
+meta strnpcmp.o %.c>%.o string/strnpcmp.c strnpcmp
+prev string/strnpcmp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strnpcmp.c
+done strnpcmp.o generated
+make strvcmp.o
+make string/strvcmp.c
+prev include/ast.h implicit
+done string/strvcmp.c
+meta strvcmp.o %.c>%.o string/strvcmp.c strvcmp
+prev string/strvcmp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strvcmp.c
+done strvcmp.o generated
+make strnvcmp.o
+make string/strnvcmp.c
+prev include/ast.h implicit
+done string/strnvcmp.c
+meta strnvcmp.o %.c>%.o string/strnvcmp.c strnvcmp
+prev string/strnvcmp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strnvcmp.c
+done strnvcmp.o generated
+make tok.o
+make string/tok.c
+make include/tok.h implicit
+prev include/ast.h implicit
+done include/tok.h
+prev include/ast.h implicit
+done string/tok.c
+meta tok.o %.c>%.o string/tok.c tok
+prev string/tok.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/tok.c
+done tok.o generated
+make tokline.o
+make string/tokline.c
+prev include/tok.h implicit
+prev include/error.h implicit
+prev include/ast.h implicit
+done string/tokline.c
+meta tokline.o %.c>%.o string/tokline.c tokline
+prev string/tokline.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/tokline.c
+done tokline.o generated
+make tokscan.o
+make string/tokscan.c
+prev include/tok.h implicit
+prev include/ast.h implicit
+done string/tokscan.c
+meta tokscan.o %.c>%.o string/tokscan.c tokscan
+prev string/tokscan.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/tokscan.c
+done tokscan.o generated
+make pathaccess.o
+make path/pathaccess.c
+prev ast_api.h implicit
+prev include/ast.h implicit
+done path/pathaccess.c
+meta pathaccess.o %.c>%.o path/pathaccess.c pathaccess
+prev path/pathaccess.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathaccess.c
+done pathaccess.o generated
+make pathcat.o
+make path/pathcat.c
+prev ast_api.h implicit
+prev include/ast.h implicit
+done path/pathcat.c
+meta pathcat.o %.c>%.o path/pathcat.c pathcat
+prev path/pathcat.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathcat.c
+done pathcat.o generated
+make pathcanon.o
+make path/pathcanon.c
+prev ast_api.h implicit
+prev include/error.h implicit
+prev include/fs3d.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done path/pathcanon.c
+meta pathcanon.o %.c>%.o path/pathcanon.c pathcanon
+prev path/pathcanon.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathcanon.c
+done pathcanon.o generated
+make pathcheck.o
+make path/pathcheck.c
+make include/times.h implicit
+make ast_time.h implicit
+make FEATURE/time
+meta FEATURE/time features/%>FEATURE/% features/time time
+make features/time
+done features/time
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/time
+done FEATURE/time generated
+exec - cmp 2>/dev/null -s FEATURE/time ast_time.h || { rm -f ast_time.h; silent test -d . || mkdir .; ${STDCP} FEATURE/time ast_time.h; }
+done ast_time.h dontcare generated
+prev include/ast.h implicit
+done include/times.h
+prev include/error.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done path/pathcheck.c
+meta pathcheck.o %.c>%.o path/pathcheck.c pathcheck
+prev path/pathcheck.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathcheck.c
+done pathcheck.o generated
+make pathpath.o
+make path/pathpath.c
+prev ast_api.h implicit
+prev include/ast.h implicit
+done path/pathpath.c
+meta pathpath.o %.c>%.o path/pathpath.c pathpath
+prev path/pathpath.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathpath.c
+done pathpath.o generated
+make pathexists.o
+make path/pathexists.c
+prev include/error.h implicit
+prev include/ls.h implicit
+make port/lclib.h implicit
+make lc.h implicit
+make lcgen
+make port/lcgen.c
+prev std/stdio.h implicit
+done port/lcgen.c
+exec - ${CC} -o lcgen port/lcgen.c
+done lcgen generated
+make port/lc.tab
+done port/lc.tab
+exec - ./lcgen ${COTEMP}.1 ${COTEMP}.2 < port/lc.tab
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ${COTEMP}.1 > ${COTEMP}.3
+exec - rm -f ${COTEMP}.1
+exec - if cmp 2>/dev/null -s ${COTEMP}.3 lc.h
+exec - then rm ${COTEMP}.3
+exec - else mv ${COTEMP}.3 lc.h
+exec - fi
+exec - if cmp 2>/dev/null -s ${COTEMP}.2 lctab.c
+exec - then rm ${COTEMP}.2
+exec - else mv ${COTEMP}.2 lctab.c
+exec - fi
+prev include/ast.h implicit
+make ${INSTALLROOT}/include/prototyped.h implicit
+done ${INSTALLROOT}/include/prototyped.h dontcare
+make joint.lc.h joint
+prev lc.h
+make lctab.c
+done lctab.c generated
+done joint.lc.h generated virtual
+done lc.h dontcare generated
+prev include/error.h implicit
+prev include/ast.h implicit
+done port/lclib.h
+done path/pathexists.c
+meta pathexists.o %.c>%.o path/pathexists.c pathexists
+prev path/pathexists.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c path/pathexists.c
+done pathexists.o generated
+make pathfind.o
+make path/pathfind.c
+prev include/ls.h implicit
+prev include/error.h implicit
+prev include/ast.h implicit
+done path/pathfind.c
+meta pathfind.o %.c>%.o path/pathfind.c pathfind
+prev path/pathfind.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathfind.c
+done pathfind.o generated
+make pathkey.o
+make path/pathkey.c
+prev ast_api.h implicit
+prev include/ls.h implicit
+make preroot.h implicit
+make FEATURE/preroot
+meta FEATURE/preroot features/%.sh>FEATURE/% features/preroot.sh preroot
+make features/preroot.sh
+done features/preroot.sh
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/preroot.sh
+done FEATURE/preroot generated
+exec - cmp 2>/dev/null -s FEATURE/preroot preroot.h || { rm -f preroot.h; silent test -d . || mkdir .; ${STDCP} FEATURE/preroot preroot.h; }
+done preroot.h generated
+prev include/fs3d.h implicit
+prev include/ast.h implicit
+done path/pathkey.c
+meta pathkey.o %.c>%.o path/pathkey.c pathkey
+prev path/pathkey.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathkey.c
+done pathkey.o generated
+make pathprobe.o
+make path/pathprobe.c
+prev ast_api.h implicit
+make include/proc.h implicit
+prev include/ast.h implicit
+done include/proc.h
+prev include/ls.h implicit
+prev include/error.h implicit
+prev include/ast.h implicit
+done path/pathprobe.c
+meta pathprobe.o %.c>%.o path/pathprobe.c pathprobe
+prev path/pathprobe.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -DHOSTTYPE=\""${mam_cc_HOSTTYPE}"\" -D_PACKAGE_ast -c path/pathprobe.c
+done pathprobe.o generated
+make pathrepl.o
+make path/pathrepl.c
+prev ast_api.h implicit
+prev include/ast.h implicit
+done path/pathrepl.c
+meta pathrepl.o %.c>%.o path/pathrepl.c pathrepl
+prev path/pathrepl.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathrepl.c
+done pathrepl.o generated
+make pathnative.o
+make path/pathnative.c
+prev include/ast.h implicit
+done path/pathnative.c
+meta pathnative.o %.c>%.o path/pathnative.c pathnative
+prev path/pathnative.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathnative.c
+done pathnative.o generated
+make pathposix.o
+make path/pathposix.c
+make uwin.h implicit
+done uwin.h dontcare virtual
+prev include/ast.h implicit
+done path/pathposix.c
+meta pathposix.o %.c>%.o path/pathposix.c pathposix
+prev path/pathposix.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathposix.c
+done pathposix.o generated
+make pathtemp.o
+make path/pathtemp.c
+make include/tm.h implicit
+prev include/times.h implicit
+prev include/ast.h implicit
+done include/tm.h
+make tv.h implicit
+make FEATURE/tv
+meta FEATURE/tv features/%>FEATURE/% features/tv tv
+make features/tv
+done features/tv
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/tv
+prev include/ast.h implicit
+done FEATURE/tv generated
+exec - cmp 2>/dev/null -s FEATURE/tv tv.h || { rm -f tv.h; silent test -d . || mkdir .; ${STDCP} FEATURE/tv tv.h; }
+prev include/ast.h implicit
+done tv.h generated
+prev include/ls.h implicit
+prev include/ast.h implicit
+done path/pathtemp.c
+meta pathtemp.o %.c>%.o path/pathtemp.c pathtemp
+prev path/pathtemp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathtemp.c
+done pathtemp.o generated
+make pathtmp.o
+make path/pathtmp.c
+prev std/stdio.h implicit
+prev include/ast.h implicit
+done path/pathtmp.c
+meta pathtmp.o %.c>%.o path/pathtmp.c pathtmp
+prev path/pathtmp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathtmp.c
+done pathtmp.o generated
+make pathstat.o
+make path/pathstat.c
+prev include/error.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done path/pathstat.c
+meta pathstat.o %.c>%.o path/pathstat.c pathstat
+prev path/pathstat.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathstat.c
+done pathstat.o generated
+make pathgetlink.o
+make path/pathgetlink.c
+make misc/univlib.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done misc/univlib.h
+done path/pathgetlink.c
+meta pathgetlink.o %.c>%.o path/pathgetlink.c pathgetlink
+prev path/pathgetlink.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c path/pathgetlink.c
+done pathgetlink.o generated
+make pathsetlink.o
+make path/pathsetlink.c
+prev misc/univlib.h implicit
+done path/pathsetlink.c
+meta pathsetlink.o %.c>%.o path/pathsetlink.c pathsetlink
+prev path/pathsetlink.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c path/pathsetlink.c
+done pathsetlink.o generated
+make pathbin.o
+make path/pathbin.c
+prev include/ast.h implicit
+done path/pathbin.c
+meta pathbin.o %.c>%.o path/pathbin.c pathbin
+prev path/pathbin.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathbin.c
+done pathbin.o generated
+make pathshell.o
+make path/pathshell.c
+prev include/ast.h implicit
+done path/pathshell.c
+meta pathshell.o %.c>%.o path/pathshell.c pathshell
+prev path/pathshell.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathshell.c
+done pathshell.o generated
+make pathcd.o
+make path/pathcd.c
+make include/stk.h implicit
+prev include/sfio.h implicit
+done include/stk.h
+prev include/error.h implicit
+prev include/ast.h implicit
+done path/pathcd.c
+meta pathcd.o %.c>%.o path/pathcd.c pathcd
+prev path/pathcd.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathcd.c
+done pathcd.o generated
+make pathprog.o
+make path/pathprog.c
+make FEATURE/prog implicit
+meta FEATURE/prog features/%>FEATURE/% features/prog prog
+make features/prog
+done features/prog
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/prog
+done FEATURE/prog generated
+make include/ast_windows.h implicit
+make windows.h implicit
+done windows.h dontcare virtual
+done include/ast_windows.h dontcare
+prev include/ast.h implicit
+done path/pathprog.c
+meta pathprog.o %.c>%.o path/pathprog.c pathprog
+prev path/pathprog.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c path/pathprog.c
+done pathprog.o generated
+make fs3d.o
+make misc/fs3d.c
+prev include/fs3d.h implicit
+prev include/ast.h implicit
+done misc/fs3d.c
+meta fs3d.o %.c>%.o misc/fs3d.c fs3d
+prev misc/fs3d.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/fs3d.c
+done fs3d.o generated
+make ftwalk.o
+make misc/ftwalk.c
+make include/ftwalk.h implicit
+make include/fts.h implicit
+prev ast_mode.h implicit
+prev ast_fs.h implicit
+prev include/ast_std.h implicit
+done include/fts.h dontcare
+done include/ftwalk.h
+prev include/ast.h implicit
+done misc/ftwalk.c
+meta ftwalk.o %.c>%.o misc/ftwalk.c ftwalk
+prev misc/ftwalk.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/ftwalk.c
+done ftwalk.o generated
+make ftwflags.o
+make misc/ftwflags.c
+prev include/ftwalk.h implicit
+prev include/ast.h implicit
+done misc/ftwflags.c
+meta ftwflags.o %.c>%.o misc/ftwflags.c ftwflags
+prev misc/ftwflags.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/ftwflags.c
+done ftwflags.o generated
+make fts.o
+make misc/fts.c
+prev include/fts.h implicit
+prev include/ls.h implicit
+prev include/fs3d.h implicit
+prev include/error.h implicit
+prev include/ast_dir.h implicit
+prev include/ast.h implicit
+done misc/fts.c
+meta fts.o %.c>%.o misc/fts.c fts
+prev misc/fts.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idir -Iinclude -Istd -D__OBSOLETE__=20110101 -D_PACKAGE_ast -c misc/fts.c
+done fts.o generated
+make astintercept.o
+make misc/astintercept.c
+make misc/intercepts.h implicit
+make include/shcmd.h implicit
+done include/shcmd.h dontcare
+prev include/ast.h implicit
+done misc/intercepts.h
+done misc/astintercept.c
+meta astintercept.o %.c>%.o misc/astintercept.c astintercept
+prev misc/astintercept.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/astintercept.c
+done astintercept.o generated
+make conformance.o
+make misc/conformance.c
+prev include/ast.h implicit
+done misc/conformance.c
+meta conformance.o %.c>%.o misc/conformance.c conformance
+prev misc/conformance.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/conformance.c
+done conformance.o generated
+make getenv.o
+make misc/getenv.c
+prev windows.h implicit
+prev misc/intercepts.h implicit
+done misc/getenv.c
+meta getenv.o %.c>%.o misc/getenv.c getenv
+prev misc/getenv.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/getenv.c
+done getenv.o generated
+make setenviron.o
+make misc/setenviron.c
+prev include/fs3d.h implicit
+prev misc/intercepts.h implicit
+done misc/setenviron.c
+meta setenviron.o %.c>%.o misc/setenviron.c setenviron
+prev misc/setenviron.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/setenviron.c
+done setenviron.o generated
+make optget.o
+make misc/optget.c
+prev include/ccode.h implicit
+make include/debug.h implicit
+prev include/error.h implicit
+prev include/ast.h implicit
+done include/debug.h
+make misc/optlib.h implicit
+prev include/error.h implicit
+prev include/cdt.h implicit
+prev include/ast.h implicit
+done misc/optlib.h
+done misc/optget.c
+meta optget.o %.c>%.o misc/optget.c optget
+prev misc/optget.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/optget.c
+done optget.o generated
+make optjoin.o
+make misc/optjoin.c
+prev misc/optlib.h implicit
+done misc/optjoin.c
+meta optjoin.o %.c>%.o misc/optjoin.c optjoin
+prev misc/optjoin.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/optjoin.c
+done optjoin.o generated
+make optesc.o
+make misc/optesc.c
+prev misc/optlib.h implicit
+done misc/optesc.c
+meta optesc.o %.c>%.o misc/optesc.c optesc
+prev misc/optesc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/optesc.c
+done optesc.o generated
+make optctx.o
+make misc/optctx.c
+prev misc/optlib.h implicit
+done misc/optctx.c
+meta optctx.o %.c>%.o misc/optctx.c optctx
+prev misc/optctx.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/optctx.c
+done optctx.o generated
+make strsort.o
+make string/strsort.c
+prev include/ast.h implicit
+done string/strsort.c
+meta strsort.o %.c>%.o string/strsort.c strsort
+prev string/strsort.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strsort.c
+done strsort.o generated
+make struniq.o
+make string/struniq.c
+prev include/ast.h implicit
+done string/struniq.c
+meta struniq.o %.c>%.o string/struniq.c struniq
+prev string/struniq.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/struniq.c
+done struniq.o generated
+make magic.o
+make misc/magic.c
+make include/magic.h implicit
+prev include/ls.h implicit
+prev include/sfio.h implicit
+done include/magic.h
+make include/swap.h implicit
+prev ast_common.h implicit
+done include/swap.h
+prev include/regex.h implicit
+prev include/error.h implicit
+prev include/modex.h implicit
+make include/dt.h implicit
+prev include/vmalloc.h implicit
+prev include/cdt.h implicit
+done include/dt.h
+prev include/ccode.h implicit
+prev include/ast.h implicit
+done misc/magic.c
+meta magic.o %.c>%.o misc/magic.c magic
+prev misc/magic.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/magic.c
+done magic.o generated
+make mime.o
+make misc/mime.c
+make misc/mimelib.h implicit
+make include/mime.h implicit
+prev include/ls.h implicit
+prev include/sfio.h implicit
+done include/mime.h dontcare
+prev include/tok.h implicit
+prev include/magic.h implicit
+prev include/cdt.h implicit
+prev include/ast.h implicit
+done misc/mimelib.h
+done misc/mime.c
+meta mime.o %.c>%.o misc/mime.c mime
+prev misc/mime.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/mime.c
+done mime.o generated
+make mimetype.o
+make misc/mimetype.c
+prev misc/mimelib.h implicit
+done misc/mimetype.c
+meta mimetype.o %.c>%.o misc/mimetype.c mimetype
+prev misc/mimetype.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/mimetype.c
+done mimetype.o generated
+make signal.o
+make misc/signal.c
+prev ast_map.h implicit
+make sig.h implicit
+make FEATURE/sig
+meta FEATURE/sig features/%.sh>FEATURE/% features/sig.sh sig
+make features/sig.sh
+done features/sig.sh
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/sig.sh
+done FEATURE/sig generated
+exec - cmp 2>/dev/null -s FEATURE/sig sig.h || { rm -f sig.h; silent test -d . || mkdir .; ${STDCP} FEATURE/sig sig.h; }
+done sig.h generated
+prev include/ast.h implicit
+done misc/signal.c
+meta signal.o %.c>%.o misc/signal.c signal
+prev misc/signal.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/signal.c
+done signal.o generated
+make sigflag.o
+make comp/sigflag.c
+prev sig.h implicit
+prev include/ast.h implicit
+done comp/sigflag.c
+meta sigflag.o %.c>%.o comp/sigflag.c sigflag
+prev comp/sigflag.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/sigflag.c
+done sigflag.o generated
+make systrace.o
+make misc/systrace.c
+prev include/debug.h implicit
+prev include/proc.h implicit
+prev include/error.h implicit
+prev include/ast.h implicit
+done misc/systrace.c
+meta systrace.o %.c>%.o misc/systrace.c systrace
+prev misc/systrace.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/systrace.c
+done systrace.o generated
+make error.o
+make misc/error.c
+prev include/regex.h implicit
+prev include/times.h implicit
+prev include/stk.h implicit
+prev sig.h implicit
+make include/namval.h implicit
+done include/namval.h
+prev include/ccode.h implicit
+prev port/lclib.h implicit
+done misc/error.c
+meta error.o %.c>%.o misc/error.c error
+prev misc/error.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Iinclude -Istd -I${INSTALLROOT}/include -DERROR_CATALOG=\""libast"\" -D_PACKAGE_ast -c misc/error.c
+done error.o generated
+make errorf.o
+make misc/errorf.c
+prev include/error.h implicit
+done misc/errorf.c
+meta errorf.o %.c>%.o misc/errorf.c errorf
+prev misc/errorf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/errorf.c
+done errorf.o generated
+make errormsg.o
+make misc/errormsg.c
+prev include/error.h implicit
+done misc/errormsg.c
+meta errormsg.o %.c>%.o misc/errormsg.c errormsg
+prev misc/errormsg.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/errormsg.c
+done errormsg.o generated
+make errorx.o
+make misc/errorx.c
+prev port/lclib.h implicit
+done misc/errorx.c
+meta errorx.o %.c>%.o misc/errorx.c errorx
+prev misc/errorx.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c misc/errorx.c
+done errorx.o generated
+make localeconv.o
+make comp/localeconv.c
+prev port/lclib.h implicit
+done comp/localeconv.c
+meta localeconv.o %.c>%.o comp/localeconv.c localeconv
+prev comp/localeconv.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c comp/localeconv.c
+done localeconv.o generated
+make setlocale.o
+make comp/setlocale.c
+prev include/ast_windows.h implicit
+prev std/wctype.h implicit
+prev include/namval.h implicit
+make include/mc.h implicit
+prev include/ast.h implicit
+done include/mc.h
+prev ast_wchar.h implicit
+prev port/lclib.h implicit
+make ast_standards.h implicit
+prev FEATURE/standards
+exec - cmp 2>/dev/null -s FEATURE/standards ast_standards.h || { rm -f ast_standards.h; silent test -d . || mkdir .; ${STDCP} FEATURE/standards ast_standards.h; }
+done ast_standards.h generated
+done comp/setlocale.c
+meta setlocale.o %.c>%.o comp/setlocale.c setlocale
+prev comp/setlocale.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c comp/setlocale.c
+done setlocale.o generated
+make translate.o
+make misc/translate.c
+make std/nl_types.h implicit
+prev ast_nl_types.h implicit
+done std/nl_types.h
+prev include/mc.h implicit
+prev include/error.h implicit
+prev include/cdt.h implicit
+prev port/lclib.h implicit
+done misc/translate.c
+meta translate.o %.c>%.o misc/translate.c translate
+prev misc/translate.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c misc/translate.c
+done translate.o generated
+make catopen.o
+make comp/catopen.c
+make std/iconv.h implicit
+make ast_iconv.h implicit
+make FEATURE/iconv
+meta FEATURE/iconv features/%>FEATURE/% features/iconv iconv
+make features/iconv
+done features/iconv
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/iconv
+prev include/ccode.h implicit
+prev ast_common.h implicit
+done FEATURE/iconv generated
+exec - cmp 2>/dev/null -s FEATURE/iconv ast_iconv.h || { rm -f ast_iconv.h; silent test -d . || mkdir .; ${STDCP} FEATURE/iconv ast_iconv.h; }
+prev include/ccode.h implicit
+prev ast_common.h implicit
+done ast_iconv.h generated
+done std/iconv.h
+prev std/nl_types.h implicit
+prev include/mc.h implicit
+prev include/ast.h implicit
+done comp/catopen.c
+meta catopen.o %.c>%.o comp/catopen.c catopen
+prev comp/catopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/catopen.c
+done catopen.o generated
+make iconv.o
+make comp/iconv.c
+prev include/ast_windows.h implicit
+prev port/lclib.h implicit
+prev std/iconv.h implicit
+prev include/ccode.h implicit
+prev std/dirent.h implicit
+prev include/ast.h implicit
+done comp/iconv.c
+meta iconv.o %.c>%.o comp/iconv.c iconv
+prev comp/iconv.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c comp/iconv.c
+done iconv.o generated
+make lc.o
+make port/lc.c
+make FEATURE/locale implicit
+meta FEATURE/locale features/%>FEATURE/% features/locale locale
+make features/locale
+done features/locale
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/locale
+done FEATURE/locale generated
+make port/lclang.h implicit
+prev include/ast_windows.h implicit
+done port/lclang.h
+prev port/lclib.h implicit
+done port/lc.c
+meta lc.o %.c>%.o port/lc.c lc
+prev port/lc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c port/lc.c
+done lc.o generated
+make lctab.o
+make lctab.c
+prev port/lclang.h implicit
+prev port/lclib.h implicit
+done lctab.c
+meta lctab.o %.c>%.o lctab.c lctab
+prev lctab.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c lctab.c
+done lctab.o generated
+make mc.o
+make port/mc.c
+prev std/nl_types.h implicit
+prev include/mc.h implicit
+prev include/error.h implicit
+prev include/vmalloc.h implicit
+prev std/iconv.h implicit
+prev port/lclib.h implicit
+make sfio/sfhdr.h implicit
+prev port/lclib.h implicit
+make vfork.h implicit
+done vfork.h dontcare virtual
+make std/wchar.h implicit
+prev ast_wchar.h implicit
+done std/wchar.h dontcare
+make FEATURE/float implicit
+meta FEATURE/float features/%>FEATURE/% features/float float
+make features/float
+make FEATURE/isoc99 implicit
+meta FEATURE/isoc99 features/%>FEATURE/% features/isoc99 isoc99
+make features/isoc99
+done features/isoc99
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/isoc99
+done FEATURE/isoc99 generated
+done features/float
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/float
+prev ast_common.h implicit
+done FEATURE/float dontcare generated
+make mman.h implicit
+done mman.h dontcare virtual
+make filio.h implicit
+done filio.h dontcare virtual
+make stat.h implicit
+done stat.h dontcare virtual
+prev include/ls.h implicit
+make ast_tty.h implicit
+prev FEATURE/tty
+exec - cmp 2>/dev/null -s FEATURE/tty ast_tty.h || { rm -f ast_tty.h; silent test -d . || mkdir .; ${STDCP} FEATURE/tty ast_tty.h; }
+done ast_tty.h dontcare generated
+prev ast_time.h implicit
+prev include/ast.h implicit
+make sfio/vthread.h implicit
+prev windows.h implicit
+prev std/endian.h implicit
+prev ast_common.h implicit
+done sfio/vthread.h dontcare
+make include/sfio_t.h implicit
+prev include/sfio.h implicit
+done include/sfio_t.h dontcare
+prev FEATURE/common implicit
+prev FEATURE/mmap implicit
+make FEATURE/sfio implicit
+meta FEATURE/sfio features/%>FEATURE/% features/sfio sfio
+make features/sfio
+done features/sfio
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/sfio
+done FEATURE/sfio dontcare generated
+done sfio/sfhdr.h
+done port/mc.c
+meta mc.o %.c>%.o port/mc.c mc
+prev port/mc.c
+exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${DEBUG+-DDEBUG=${DEBUG}} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c port/mc.c
+done mc.o generated
+make base64.o
+make string/base64.c
+prev include/ast.h implicit
+done string/base64.c
+meta base64.o %.c>%.o string/base64.c base64
+prev string/base64.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/base64.c
+done base64.o generated
+make recfmt.o
+make misc/recfmt.c
+make include/recfmt.h implicit
+prev include/ast.h implicit
+done include/recfmt.h
+done misc/recfmt.c
+meta recfmt.o %.c>%.o misc/recfmt.c recfmt
+prev misc/recfmt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/recfmt.c
+done recfmt.o generated
+make recstr.o
+make misc/recstr.c
+prev include/recfmt.h implicit
+done misc/recstr.c
+meta recstr.o %.c>%.o misc/recstr.c recstr
+prev misc/recstr.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/recstr.c
+done recstr.o generated
+make reclen.o
+make misc/reclen.c
+prev include/recfmt.h implicit
+done misc/reclen.c
+meta reclen.o %.c>%.o misc/reclen.c reclen
+prev misc/reclen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/reclen.c
+done reclen.o generated
+make fmtrec.o
+make misc/fmtrec.c
+prev include/recfmt.h implicit
+done misc/fmtrec.c
+meta fmtrec.o %.c>%.o misc/fmtrec.c fmtrec
+prev misc/fmtrec.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/fmtrec.c
+done fmtrec.o generated
+make fmtbase.o
+make string/fmtbase.c
+prev include/ast.h implicit
+done string/fmtbase.c
+meta fmtbase.o %.c>%.o string/fmtbase.c fmtbase
+prev string/fmtbase.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D__OBSOLETE__=20110101 -D_PACKAGE_ast -c string/fmtbase.c
+done fmtbase.o generated
+make fmtbuf.o
+make string/fmtbuf.c
+prev include/ast.h implicit
+done string/fmtbuf.c
+meta fmtbuf.o %.c>%.o string/fmtbuf.c fmtbuf
+prev string/fmtbuf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtbuf.c
+done fmtbuf.o generated
+make fmtclock.o
+make string/fmtclock.c
+prev include/tm.h implicit
+prev include/ast.h implicit
+done string/fmtclock.c
+meta fmtclock.o %.c>%.o string/fmtclock.c fmtclock
+prev string/fmtclock.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtclock.c
+done fmtclock.o generated
+make fmtdev.o
+make string/fmtdev.c
+prev include/ls.h implicit
+prev include/ast.h implicit
+done string/fmtdev.c
+meta fmtdev.o %.c>%.o string/fmtdev.c fmtdev
+prev string/fmtdev.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtdev.c
+done fmtdev.o generated
+make fmtelapsed.o
+make string/fmtelapsed.c
+prev include/ast.h implicit
+done string/fmtelapsed.c
+meta fmtelapsed.o %.c>%.o string/fmtelapsed.c fmtelapsed
+prev string/fmtelapsed.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtelapsed.c
+done fmtelapsed.o generated
+make fmterror.o
+make string/fmterror.c
+prev include/ast.h implicit
+done string/fmterror.c
+meta fmterror.o %.c>%.o string/fmterror.c fmterror
+prev string/fmterror.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmterror.c
+done fmterror.o generated
+make fmtesc.o
+make string/fmtesc.c
+prev std/wctype.h implicit
+prev std/wchar.h implicit
+prev include/ccode.h implicit
+prev include/ast.h implicit
+done string/fmtesc.c
+meta fmtesc.o %.c>%.o string/fmtesc.c fmtesc
+prev string/fmtesc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtesc.c
+done fmtesc.o generated
+make fmtfmt.o
+make string/fmtfmt.c
+prev include/ast.h implicit
+done string/fmtfmt.c
+meta fmtfmt.o %.c>%.o string/fmtfmt.c fmtfmt
+prev string/fmtfmt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtfmt.c
+done fmtfmt.o generated
+make fmtfs.o
+make string/fmtfs.c
+prev include/cdt.h implicit
+prev FEATURE/fs implicit
+make include/mnt.h implicit
+done include/mnt.h
+prev include/ls.h implicit
+prev include/ast.h implicit
+done string/fmtfs.c
+meta fmtfs.o %.c>%.o string/fmtfs.c fmtfs
+prev string/fmtfs.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtfs.c
+done fmtfs.o generated
+make fmtident.o
+make string/fmtident.c
+prev include/ast.h implicit
+done string/fmtident.c
+meta fmtident.o %.c>%.o string/fmtident.c fmtident
+prev string/fmtident.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtident.c
+done fmtident.o generated
+make fmtint.o
+make string/fmtint.c
+prev include/ast.h implicit
+done string/fmtint.c
+meta fmtint.o %.c>%.o string/fmtint.c fmtint
+prev string/fmtint.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtint.c
+done fmtint.o generated
+make fmtip4.o
+make string/fmtip4.c
+prev include/ast.h implicit
+done string/fmtip4.c
+meta fmtip4.o %.c>%.o string/fmtip4.c fmtip4
+prev string/fmtip4.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtip4.c
+done fmtip4.o generated
+make fmtip6.o
+make string/fmtip6.c
+make include/ip6.h implicit
+done include/ip6.h
+prev include/ast.h implicit
+done string/fmtip6.c
+meta fmtip6.o %.c>%.o string/fmtip6.c fmtip6
+prev string/fmtip6.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtip6.c
+done fmtip6.o generated
+make fmtls.o
+make string/fmtls.c
+prev include/tm.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done string/fmtls.c
+meta fmtls.o %.c>%.o string/fmtls.c fmtls
+prev string/fmtls.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtls.c
+done fmtls.o generated
+make fmtmatch.o
+make string/fmtmatch.c
+prev include/ast.h implicit
+done string/fmtmatch.c
+meta fmtmatch.o %.c>%.o string/fmtmatch.c fmtmatch
+prev string/fmtmatch.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtmatch.c
+done fmtmatch.o generated
+make fmtmode.o
+make string/fmtmode.c
+prev string/modelib.h implicit
+done string/fmtmode.c
+meta fmtmode.o %.c>%.o string/fmtmode.c fmtmode
+prev string/fmtmode.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Istring -Iinclude -Istd -D_PACKAGE_ast -c string/fmtmode.c
+done fmtmode.o generated
+make fmtnum.o
+make string/fmtnum.c
+prev include/ast.h implicit
+done string/fmtnum.c
+meta fmtnum.o %.c>%.o string/fmtnum.c fmtnum
+prev string/fmtnum.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtnum.c
+done fmtnum.o generated
+make fmtperm.o
+make string/fmtperm.c
+prev include/ls.h implicit
+prev include/ast.h implicit
+done string/fmtperm.c
+meta fmtperm.o %.c>%.o string/fmtperm.c fmtperm
+prev string/fmtperm.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtperm.c
+done fmtperm.o generated
+make fmtre.o
+make string/fmtre.c
+prev include/ast.h implicit
+done string/fmtre.c
+meta fmtre.o %.c>%.o string/fmtre.c fmtre
+prev string/fmtre.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtre.c
+done fmtre.o generated
+make fmttime.o
+make string/fmttime.c
+prev include/tm.h implicit
+done string/fmttime.c
+meta fmttime.o %.c>%.o string/fmttime.c fmttime
+prev string/fmttime.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmttime.c
+done fmttime.o generated
+make fmtuid.o
+make string/fmtuid.c
+prev std/stdio.h implicit
+prev include/cdt.h implicit
+prev include/ast.h implicit
+done string/fmtuid.c
+meta fmtuid.o %.c>%.o string/fmtuid.c fmtuid
+prev string/fmtuid.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtuid.c
+done fmtuid.o generated
+make fmtgid.o
+make string/fmtgid.c
+prev std/stdio.h implicit
+prev include/cdt.h implicit
+prev include/ast.h implicit
+done string/fmtgid.c
+meta fmtgid.o %.c>%.o string/fmtgid.c fmtgid
+prev string/fmtgid.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtgid.c
+done fmtgid.o generated
+make fmtsignal.o
+make string/fmtsignal.c
+prev sig.h implicit
+prev include/ast.h implicit
+done string/fmtsignal.c
+meta fmtsignal.o %.c>%.o string/fmtsignal.c fmtsignal
+prev string/fmtsignal.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtsignal.c
+done fmtsignal.o generated
+make fmtscale.o
+make string/fmtscale.c
+prev port/lclib.h implicit
+prev include/ast.h implicit
+done string/fmtscale.c
+meta fmtscale.o %.c>%.o string/fmtscale.c fmtscale
+prev string/fmtscale.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c string/fmtscale.c
+done fmtscale.o generated
+make fmttmx.o
+make string/fmttmx.c
+prev tv.h implicit
+make tmx.h implicit
+make FEATURE/tmx
+meta FEATURE/tmx features/%>FEATURE/% features/tmx tmx
+make features/tmx
+prev FEATURE/common implicit
+done features/tmx
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/tmx
+prev tv.h implicit
+prev include/tm.h implicit
+done FEATURE/tmx generated
+exec - cmp 2>/dev/null -s FEATURE/tmx tmx.h || { rm -f tmx.h; silent test -d . || mkdir .; ${STDCP} FEATURE/tmx tmx.h; }
+prev tv.h implicit
+prev include/tm.h implicit
+done tmx.h generated
+done string/fmttmx.c
+meta fmttmx.o %.c>%.o string/fmttmx.c fmttmx
+prev string/fmttmx.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmttmx.c
+done fmttmx.o generated
+make fmttv.o
+make string/fmttv.c
+prev include/tm.h implicit
+prev tv.h implicit
+done string/fmttv.c
+meta fmttv.o %.c>%.o string/fmttv.c fmttv
+prev string/fmttv.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmttv.c
+done fmttv.o generated
+make fmtversion.o
+make string/fmtversion.c
+prev include/ast.h implicit
+done string/fmtversion.c
+meta fmtversion.o %.c>%.o string/fmtversion.c fmtversion
+prev string/fmtversion.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/fmtversion.c
+done fmtversion.o generated
+make strelapsed.o
+make string/strelapsed.c
+prev include/ast.h implicit
+done string/strelapsed.c
+meta strelapsed.o %.c>%.o string/strelapsed.c strelapsed
+prev string/strelapsed.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strelapsed.c
+done strelapsed.o generated
+make strperm.o
+make string/strperm.c
+prev include/modex.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done string/strperm.c
+meta strperm.o %.c>%.o string/strperm.c strperm
+prev string/strperm.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strperm.c
+done strperm.o generated
+make struid.o
+make string/struid.c
+prev include/cdt.h implicit
+prev include/ast.h implicit
+done string/struid.c
+meta struid.o %.c>%.o string/struid.c struid
+prev string/struid.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/struid.c
+done struid.o generated
+make strgid.o
+make string/strgid.c
+prev include/cdt.h implicit
+prev include/ast.h implicit
+done string/strgid.c
+meta strgid.o %.c>%.o string/strgid.c strgid
+prev string/strgid.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strgid.c
+done strgid.o generated
+make strtoip4.o
+make string/strtoip4.c
+prev include/ast.h implicit
+done string/strtoip4.c
+meta strtoip4.o %.c>%.o string/strtoip4.c strtoip4
+prev string/strtoip4.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strtoip4.c
+done strtoip4.o generated
+make strtoip6.o
+make string/strtoip6.c
+prev include/ip6.h implicit
+prev include/ast.h implicit
+done string/strtoip6.c
+meta strtoip6.o %.c>%.o string/strtoip6.c strtoip6
+prev string/strtoip6.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strtoip6.c
+done strtoip6.o generated
+make stack.o
+make misc/stack.c
+make include/stack.h implicit
+done include/stack.h
+prev include/ast.h implicit
+done misc/stack.c
+meta stack.o %.c>%.o misc/stack.c stack
+prev misc/stack.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/stack.c
+done stack.o generated
+make stk.o
+make misc/stk.c
+prev include/stk.h implicit
+make align.h implicit
+make FEATURE/align
+meta FEATURE/align features/%.c>FEATURE/% features/align.c align
+make features/align.c
+prev FEATURE/common implicit
+done features/align.c
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. ${LDFLAGS} ' run features/align.c
+done FEATURE/align generated
+exec - cmp 2>/dev/null -s FEATURE/align align.h || { rm -f align.h; silent test -d . || mkdir .; ${STDCP} FEATURE/align align.h; }
+done align.h generated
+prev include/ast.h implicit
+prev include/sfio_t.h implicit
+done misc/stk.c
+meta stk.o %.c>%.o misc/stk.c stk
+prev misc/stk.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/stk.c
+done stk.o generated
+make swapget.o
+make string/swapget.c
+prev include/swap.h implicit
+prev include/ast.h implicit
+done string/swapget.c
+meta swapget.o %.c>%.o string/swapget.c swapget
+prev string/swapget.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/swapget.c
+done swapget.o generated
+make swapmem.o
+make string/swapmem.c
+prev include/swap.h implicit
+prev include/ast.h implicit
+done string/swapmem.c
+meta swapmem.o %.c>%.o string/swapmem.c swapmem
+prev string/swapmem.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/swapmem.c
+done swapmem.o generated
+make swapop.o
+make string/swapop.c
+prev include/swap.h implicit
+prev include/ast.h implicit
+done string/swapop.c
+meta swapop.o %.c>%.o string/swapop.c swapop
+prev string/swapop.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/swapop.c
+done swapop.o generated
+make swapput.o
+make string/swapput.c
+prev include/swap.h implicit
+prev include/ast.h implicit
+done string/swapput.c
+meta swapput.o %.c>%.o string/swapput.c swapput
+prev string/swapput.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/swapput.c
+done swapput.o generated
+make sigdata.o
+make misc/sigdata.c
+make FEATURE/signal implicit
+meta FEATURE/signal features/%.c>FEATURE/% features/signal.c signal
+make features/signal.c
+make FEATURE/siglist implicit
+meta FEATURE/siglist features/%>FEATURE/% features/siglist siglist
+make features/siglist
+done features/siglist
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/siglist
+done FEATURE/siglist generated
+prev FEATURE/standards implicit
+done features/signal.c
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. ${LDFLAGS} ' run features/signal.c
+done FEATURE/signal generated
+prev sig.h implicit
+prev include/ast.h implicit
+done misc/sigdata.c
+meta sigdata.o %.c>%.o misc/sigdata.c sigdata
+prev misc/sigdata.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/sigdata.c
+done sigdata.o generated
+make sigcrit.o
+make misc/sigcrit.c
+prev sig.h implicit
+prev include/ast.h implicit
+done misc/sigcrit.c
+meta sigcrit.o %.c>%.o misc/sigcrit.c sigcrit
+prev misc/sigcrit.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/sigcrit.c
+done sigcrit.o generated
+make sigunblock.o
+make comp/sigunblock.c
+prev sig.h implicit
+prev include/ast.h implicit
+done comp/sigunblock.c
+meta sigunblock.o %.c>%.o comp/sigunblock.c sigunblock
+prev comp/sigunblock.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/sigunblock.c
+done sigunblock.o generated
+make procopen.o
+make misc/procopen.c
+prev include/namval.h implicit
+prev ast_tty.h implicit
+prev include/ls.h implicit
+make misc/proclib.h implicit
+prev include/proc.h implicit
+make include/wait.h implicit
+make ast_wait.h implicit
+make FEATURE/wait
+meta FEATURE/wait features/%>FEATURE/% features/wait wait
+make features/wait
+done features/wait
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/wait
+done FEATURE/wait generated
+exec - cmp 2>/dev/null -s FEATURE/wait ast_wait.h || { rm -f ast_wait.h; silent test -d . || mkdir .; ${STDCP} FEATURE/wait ast_wait.h; }
+done ast_wait.h dontcare generated
+prev include/ast.h implicit
+done include/wait.h dontcare
+prev sig.h implicit
+prev include/ast.h implicit
+done misc/proclib.h
+done misc/procopen.c
+meta procopen.o %.c>%.o misc/procopen.c procopen
+prev misc/procopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/procopen.c
+done procopen.o generated
+make procclose.o
+make misc/procclose.c
+prev misc/proclib.h implicit
+done misc/procclose.c
+meta procclose.o %.c>%.o misc/procclose.c procclose
+prev misc/procclose.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/procclose.c
+done procclose.o generated
+make procrun.o
+make misc/procrun.c
+prev misc/proclib.h implicit
+done misc/procrun.c
+meta procrun.o %.c>%.o misc/procrun.c procrun
+prev misc/procrun.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D__OBSOLETE__=20110101 -D_PACKAGE_ast -c misc/procrun.c
+done procrun.o generated
+make procfree.o
+make misc/procfree.c
+prev misc/proclib.h implicit
+done misc/procfree.c
+meta procfree.o %.c>%.o misc/procfree.c procfree
+prev misc/procfree.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/procfree.c
+done procfree.o generated
+make tmdate.o
+make tm/tmdate.c
+prev tmx.h implicit
+done tm/tmdate.c
+meta tmdate.o %.c>%.o tm/tmdate.c tmdate
+prev tm/tmdate.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmdate.c
+done tmdate.o generated
+make tmequiv.o
+make tm/tmequiv.c
+prev include/tm.h implicit
+done tm/tmequiv.c
+meta tmequiv.o %.c>%.o tm/tmequiv.c tmequiv
+prev tm/tmequiv.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmequiv.c
+done tmequiv.o generated
+make tmfix.o
+make tm/tmfix.c
+prev tmx.h implicit
+prev include/ast.h implicit
+done tm/tmfix.c
+meta tmfix.o %.c>%.o tm/tmfix.c tmfix
+prev tm/tmfix.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmfix.c
+done tmfix.o generated
+make tmfmt.o
+make tm/tmfmt.c
+prev tmx.h implicit
+done tm/tmfmt.c
+meta tmfmt.o %.c>%.o tm/tmfmt.c tmfmt
+prev tm/tmfmt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmfmt.c
+done tmfmt.o generated
+make tmform.o
+make tm/tmform.c
+prev include/tm.h implicit
+prev include/ast.h implicit
+done tm/tmform.c
+meta tmform.o %.c>%.o tm/tmform.c tmform
+prev tm/tmform.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmform.c
+done tmform.o generated
+make tmgoff.o
+make tm/tmgoff.c
+prev include/tm.h implicit
+prev include/ast.h implicit
+done tm/tmgoff.c
+meta tmgoff.o %.c>%.o tm/tmgoff.c tmgoff
+prev tm/tmgoff.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmgoff.c
+done tmgoff.o generated
+make tminit.o
+make tm/tminit.c
+make FEATURE/tmlib implicit
+meta FEATURE/tmlib features/%>FEATURE/% features/tmlib tmlib
+make features/tmlib
+done features/tmlib
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/tmlib
+done FEATURE/tmlib generated
+prev include/namval.h implicit
+prev include/tm.h implicit
+done tm/tminit.c
+meta tminit.o %.c>%.o tm/tminit.c tminit
+prev tm/tminit.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tminit.c
+done tminit.o generated
+make tmleap.o
+make tm/tmleap.c
+prev tmx.h implicit
+done tm/tmleap.c
+meta tmleap.o %.c>%.o tm/tmleap.c tmleap
+prev tm/tmleap.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmleap.c
+done tmleap.o generated
+make tmlex.o
+make tm/tmlex.c
+prev include/tm.h implicit
+prev include/ast.h implicit
+done tm/tmlex.c
+meta tmlex.o %.c>%.o tm/tmlex.c tmlex
+prev tm/tmlex.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmlex.c
+done tmlex.o generated
+make tmlocale.o
+make tm/tmlocale.c
+prev std/nl_types.h implicit
+prev std/nl_types.h implicit
+prev include/ast_windows.h implicit
+prev port/lclib.h implicit
+prev ast_nl_types.h implicit
+prev include/tm.h implicit
+prev include/mc.h implicit
+prev std/iconv.h implicit
+prev include/cdt.h implicit
+prev include/ast.h implicit
+done tm/tmlocale.c
+meta tmlocale.o %.c>%.o tm/tmlocale.c tmlocale
+prev tm/tmlocale.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c tm/tmlocale.c
+done tmlocale.o generated
+make tmmake.o
+make tm/tmmake.c
+prev tmx.h implicit
+done tm/tmmake.c
+meta tmmake.o %.c>%.o tm/tmmake.c tmmake
+prev tm/tmmake.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmmake.c
+done tmmake.o generated
+make tmpoff.o
+make tm/tmpoff.c
+prev include/tm.h implicit
+prev include/ast.h implicit
+done tm/tmpoff.c
+meta tmpoff.o %.c>%.o tm/tmpoff.c tmpoff
+prev tm/tmpoff.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmpoff.c
+done tmpoff.o generated
+make tmscan.o
+make tm/tmscan.c
+prev tmx.h implicit
+done tm/tmscan.c
+meta tmscan.o %.c>%.o tm/tmscan.c tmscan
+prev tm/tmscan.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmscan.c
+done tmscan.o generated
+make tmsleep.o
+make tm/tmsleep.c
+prev tv.h implicit
+prev include/tm.h implicit
+prev include/ast.h implicit
+done tm/tmsleep.c
+meta tmsleep.o %.c>%.o tm/tmsleep.c tmsleep
+prev tm/tmsleep.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmsleep.c
+done tmsleep.o generated
+make tmtime.o
+make tm/tmtime.c
+prev tmx.h implicit
+done tm/tmtime.c
+meta tmtime.o %.c>%.o tm/tmtime.c tmtime
+prev tm/tmtime.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmtime.c
+done tmtime.o generated
+make tmtype.o
+make tm/tmtype.c
+prev include/tm.h implicit
+prev include/ast.h implicit
+done tm/tmtype.c
+meta tmtype.o %.c>%.o tm/tmtype.c tmtype
+prev tm/tmtype.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmtype.c
+done tmtype.o generated
+make tmweek.o
+make tm/tmweek.c
+prev tmx.h implicit
+done tm/tmweek.c
+meta tmweek.o %.c>%.o tm/tmweek.c tmweek
+prev tm/tmweek.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmweek.c
+done tmweek.o generated
+make tmword.o
+make tm/tmword.c
+prev include/tm.h implicit
+prev include/ast.h implicit
+done tm/tmword.c
+meta tmword.o %.c>%.o tm/tmword.c tmword
+prev tm/tmword.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmword.c
+done tmword.o generated
+make tmzone.o
+make tm/tmzone.c
+prev include/tm.h implicit
+prev include/ast.h implicit
+done tm/tmzone.c
+meta tmzone.o %.c>%.o tm/tmzone.c tmzone
+prev tm/tmzone.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmzone.c
+done tmzone.o generated
+make tmxdate.o
+make tm/tmxdate.c
+prev include/debug.h implicit
+prev tmx.h implicit
+done tm/tmxdate.c
+meta tmxdate.o %.c>%.o tm/tmxdate.c tmxdate
+prev tm/tmxdate.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmxdate.c
+done tmxdate.o generated
+make tmxduration.o
+make tm/tmxduration.c
+prev tmx.h implicit
+done tm/tmxduration.c
+meta tmxduration.o %.c>%.o tm/tmxduration.c tmxduration
+prev tm/tmxduration.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmxduration.c
+done tmxduration.o generated
+make tmxfmt.o
+make tm/tmxfmt.c
+prev tmx.h implicit
+done tm/tmxfmt.c
+meta tmxfmt.o %.c>%.o tm/tmxfmt.c tmxfmt
+prev tm/tmxfmt.c
+exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmxfmt.c
+done tmxfmt.o generated
+make tmxgettime.o
+make tm/tmxgettime.c
+prev tv.h implicit
+prev tmx.h implicit
+done tm/tmxgettime.c
+meta tmxgettime.o %.c>%.o tm/tmxgettime.c tmxgettime
+prev tm/tmxgettime.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmxgettime.c
+done tmxgettime.o generated
+make tmxleap.o
+make tm/tmxleap.c
+prev tmx.h implicit
+done tm/tmxleap.c
+meta tmxleap.o %.c>%.o tm/tmxleap.c tmxleap
+prev tm/tmxleap.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmxleap.c
+done tmxleap.o generated
+make tmxmake.o
+make tm/tmxmake.c
+prev FEATURE/tmlib implicit
+prev tmx.h implicit
+done tm/tmxmake.c
+meta tmxmake.o %.c>%.o tm/tmxmake.c tmxmake
+prev tm/tmxmake.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmxmake.c
+done tmxmake.o generated
+make tmxscan.o
+make tm/tmxscan.c
+prev tmx.h implicit
+done tm/tmxscan.c
+meta tmxscan.o %.c>%.o tm/tmxscan.c tmxscan
+prev tm/tmxscan.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmxscan.c
+done tmxscan.o generated
+make tmxsettime.o
+make tm/tmxsettime.c
+prev tv.h implicit
+prev tmx.h implicit
+done tm/tmxsettime.c
+meta tmxsettime.o %.c>%.o tm/tmxsettime.c tmxsettime
+prev tm/tmxsettime.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmxsettime.c
+done tmxsettime.o generated
+make tmxsleep.o
+make tm/tmxsleep.c
+prev tv.h implicit
+prev tmx.h implicit
+done tm/tmxsleep.c
+meta tmxsleep.o %.c>%.o tm/tmxsleep.c tmxsleep
+prev tm/tmxsleep.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmxsleep.c
+done tmxsleep.o generated
+make tmxtime.o
+make tm/tmxtime.c
+prev FEATURE/tmlib implicit
+prev tmx.h implicit
+done tm/tmxtime.c
+meta tmxtime.o %.c>%.o tm/tmxtime.c tmxtime
+prev tm/tmxtime.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmxtime.c
+done tmxtime.o generated
+make tmxtouch.o
+make tm/tmxtouch.c
+prev tv.h implicit
+prev tmx.h implicit
+done tm/tmxtouch.c
+meta tmxtouch.o %.c>%.o tm/tmxtouch.c tmxtouch
+prev tm/tmxtouch.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmxtouch.c
+done tmxtouch.o generated
+make tvcmp.o
+make tm/tvcmp.c
+prev tv.h implicit
+done tm/tvcmp.c
+meta tvcmp.o %.c>%.o tm/tvcmp.c tvcmp
+prev tm/tvcmp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tvcmp.c
+done tvcmp.o generated
+make tvgettime.o
+make tm/tvgettime.c
+make FEATURE/tvlib implicit
+meta FEATURE/tvlib features/%>FEATURE/% features/tvlib tvlib
+make features/tvlib
+done features/tvlib
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/tvlib
+done FEATURE/tvlib generated
+prev include/tm.h implicit
+prev tv.h implicit
+done tm/tvgettime.c
+meta tvgettime.o %.c>%.o tm/tvgettime.c tvgettime
+prev tm/tvgettime.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tvgettime.c
+done tvgettime.o generated
+make tvsettime.o
+make tm/tvsettime.c
+prev FEATURE/tvlib implicit
+prev include/tm.h implicit
+prev tv.h implicit
+done tm/tvsettime.c
+meta tvsettime.o %.c>%.o tm/tvsettime.c tvsettime
+prev tm/tvsettime.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tvsettime.c
+done tvsettime.o generated
+make tvsleep.o
+make tm/tvsleep.c
+prev FEATURE/tvlib implicit
+prev include/tm.h implicit
+prev tv.h implicit
+done tm/tvsleep.c
+meta tvsleep.o %.c>%.o tm/tvsleep.c tvsleep
+prev tm/tvsleep.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tvsleep.c
+done tvsleep.o generated
+make tvtouch.o
+make tm/tvtouch.c
+prev FEATURE/tvlib implicit
+prev include/error.h implicit
+prev include/times.h implicit
+prev tv.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done tm/tvtouch.c
+meta tvtouch.o %.c>%.o tm/tvtouch.c tvtouch
+prev tm/tvtouch.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tvtouch.c
+done tvtouch.o generated
+make cmdarg.o
+make misc/cmdarg.c
+prev include/proc.h implicit
+prev ast_api.h implicit
+make include/cmdarg.h implicit
+prev include/error.h implicit
+done include/cmdarg.h
+prev include/ast.h implicit
+done misc/cmdarg.c
+meta cmdarg.o %.c>%.o misc/cmdarg.c cmdarg
+prev misc/cmdarg.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/cmdarg.c
+done cmdarg.o generated
+make vecargs.o
+make vec/vecargs.c
+make include/vecargs.h implicit
+done include/vecargs.h
+prev include/ast.h implicit
+done vec/vecargs.c
+meta vecargs.o %.c>%.o vec/vecargs.c vecargs
+prev vec/vecargs.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c vec/vecargs.c
+done vecargs.o generated
+make vecfile.o
+make vec/vecfile.c
+prev include/vecargs.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done vec/vecfile.c
+meta vecfile.o %.c>%.o vec/vecfile.c vecfile
+prev vec/vecfile.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c vec/vecfile.c
+done vecfile.o generated
+make vecfree.o
+make vec/vecfree.c
+prev include/vecargs.h implicit
+prev include/ast.h implicit
+done vec/vecfree.c
+meta vecfree.o %.c>%.o vec/vecfree.c vecfree
+prev vec/vecfree.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c vec/vecfree.c
+done vecfree.o generated
+make vecload.o
+make vec/vecload.c
+prev include/vecargs.h implicit
+prev include/ast.h implicit
+done vec/vecload.c
+meta vecload.o %.c>%.o vec/vecload.c vecload
+prev vec/vecload.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c vec/vecload.c
+done vecload.o generated
+make vecstring.o
+make vec/vecstring.c
+prev include/vecargs.h implicit
+prev include/ast.h implicit
+done vec/vecstring.c
+meta vecstring.o %.c>%.o vec/vecstring.c vecstring
+prev vec/vecstring.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c vec/vecstring.c
+done vecstring.o generated
+make univdata.o
+make misc/univdata.c
+prev misc/univlib.h implicit
+done misc/univdata.c
+meta univdata.o %.c>%.o misc/univdata.c univdata
+prev misc/univdata.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/univdata.c
+done univdata.o generated
+make touch.o
+make port/touch.c
+prev tv.h implicit
+prev include/times.h implicit
+prev include/ast.h implicit
+done port/touch.c
+meta touch.o %.c>%.o port/touch.c touch
+prev port/touch.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c port/touch.c
+done touch.o generated
+make mnt.o
+make port/mnt.c
+make mnttab.h implicit
+done mnttab.h dontcare virtual
+prev std/stdio.h implicit
+prev std/stdio.h implicit
+prev include/ast_windows.h implicit
+prev include/ls.h implicit
+prev include/mnt.h implicit
+prev include/ast.h implicit
+done port/mnt.c
+meta mnt.o %.c>%.o port/mnt.c mnt
+prev port/mnt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c port/mnt.c
+done mnt.o generated
+make debug.o
+make misc/debug.c
+prev include/times.h implicit
+prev include/debug.h implicit
+prev include/error.h implicit
+prev include/ast.h implicit
+done misc/debug.c
+meta debug.o %.c>%.o misc/debug.c debug
+prev misc/debug.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c misc/debug.c
+done debug.o generated
+make memccpy.o
+make comp/memccpy.c
+prev include/ast.h implicit
+done comp/memccpy.c
+meta memccpy.o %.c>%.o comp/memccpy.c memccpy
+prev comp/memccpy.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/memccpy.c
+done memccpy.o generated
+make memchr.o
+make comp/memchr.c
+prev include/ast.h implicit
+done comp/memchr.c
+meta memchr.o %.c>%.o comp/memchr.c memchr
+prev comp/memchr.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/memchr.c
+done memchr.o generated
+make memcmp.o
+make comp/memcmp.c
+prev include/ast.h implicit
+done comp/memcmp.c
+meta memcmp.o %.c>%.o comp/memcmp.c memcmp
+prev comp/memcmp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/memcmp.c
+done memcmp.o generated
+make memcpy.o
+make comp/memcpy.c
+prev include/ast.h implicit
+done comp/memcpy.c
+meta memcpy.o %.c>%.o comp/memcpy.c memcpy
+prev comp/memcpy.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/memcpy.c
+done memcpy.o generated
+make memdup.o
+make string/memdup.c
+prev include/ast.h implicit
+done string/memdup.c
+meta memdup.o %.c>%.o string/memdup.c memdup
+prev string/memdup.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/memdup.c
+done memdup.o generated
+make memmove.o
+make comp/memmove.c
+prev include/ast.h implicit
+done comp/memmove.c
+meta memmove.o %.c>%.o comp/memmove.c memmove
+prev comp/memmove.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/memmove.c
+done memmove.o generated
+make memset.o
+make comp/memset.c
+prev include/ast.h implicit
+done comp/memset.c
+meta memset.o %.c>%.o comp/memset.c memset
+prev comp/memset.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/memset.c
+done memset.o generated
+make mkdir.o
+make comp/mkdir.c
+prev include/error.h implicit
+prev include/wait.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done comp/mkdir.c
+meta mkdir.o %.c>%.o comp/mkdir.c mkdir
+prev comp/mkdir.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/mkdir.c
+done mkdir.o generated
+make mkfifo.o
+make comp/mkfifo.c
+prev include/error.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done comp/mkfifo.c
+meta mkfifo.o %.c>%.o comp/mkfifo.c mkfifo
+prev comp/mkfifo.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/mkfifo.c
+done mkfifo.o generated
+make mknod.o
+make comp/mknod.c
+prev include/error.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done comp/mknod.c
+meta mknod.o %.c>%.o comp/mknod.c mknod
+prev comp/mknod.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/mknod.c
+done mknod.o generated
+make rmdir.o
+make comp/rmdir.c
+prev include/error.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done comp/rmdir.c
+meta rmdir.o %.c>%.o comp/rmdir.c rmdir
+prev comp/rmdir.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/rmdir.c
+done rmdir.o generated
+make remove.o
+make comp/remove.c
+prev ast_map.h implicit
+prev include/ast.h implicit
+done comp/remove.c
+meta remove.o %.c>%.o comp/remove.c remove
+prev comp/remove.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/remove.c
+done remove.o generated
+make rename.o
+make comp/rename.c
+prev include/proc.h implicit
+prev include/error.h implicit
+prev include/ast.h implicit
+done comp/rename.c
+meta rename.o %.c>%.o comp/rename.c rename
+prev comp/rename.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/rename.c
+done rename.o generated
+make link.o
+make comp/link.c
+prev include/error.h implicit
+prev include/ast.h implicit
+done comp/link.c
+meta link.o %.c>%.o comp/link.c link
+prev comp/link.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/link.c
+done link.o generated
+make unlink.o
+make comp/unlink.c
+prev include/ast.h implicit
+done comp/unlink.c
+meta unlink.o %.c>%.o comp/unlink.c unlink
+prev comp/unlink.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/unlink.c
+done unlink.o generated
+make strdup.o
+make string/strdup.c
+prev include/ast.h implicit
+done string/strdup.c
+meta strdup.o %.c>%.o string/strdup.c strdup
+prev string/strdup.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/strdup.c
+done strdup.o generated
+make strchr.o
+make comp/strchr.c
+prev include/ast.h implicit
+done comp/strchr.c
+meta strchr.o %.c>%.o comp/strchr.c strchr
+prev comp/strchr.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/strchr.c
+done strchr.o generated
+make strrchr.o
+make comp/strrchr.c
+prev include/ast.h implicit
+done comp/strrchr.c
+meta strrchr.o %.c>%.o comp/strrchr.c strrchr
+prev comp/strrchr.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/strrchr.c
+done strrchr.o generated
+make strstr.o
+make comp/strstr.c
+prev include/ast.h implicit
+done comp/strstr.c
+meta strstr.o %.c>%.o comp/strstr.c strstr
+prev comp/strstr.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/strstr.c
+done strstr.o generated
+make strtod.o
+make comp/strtod.c
+make sfio/sfstrtof.h implicit
+prev FEATURE/float implicit
+prev sfio/sfhdr.h implicit
+done sfio/sfstrtof.h
+prev include/ast.h implicit
+done comp/strtod.c
+meta strtod.o %.c>%.o comp/strtod.c strtod
+prev comp/strtod.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c comp/strtod.c
+done strtod.o generated
+make strtold.o
+make comp/strtold.c
+prev sfio/sfstrtof.h implicit
+prev ast_sys.h implicit
+prev ast_lib.h implicit
+prev ast_common.h implicit
+done comp/strtold.c
+meta strtold.o %.c>%.o comp/strtold.c strtold
+prev comp/strtold.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c comp/strtold.c
+done strtold.o generated
+make strtol.o
+make comp/strtol.c
+make string/strtoi.h implicit
+prev sfio/sfhdr.h implicit
+prev include/ast.h implicit
+done string/strtoi.h dontcare
+done comp/strtol.c
+meta strtol.o %.c>%.o comp/strtol.c strtol
+prev comp/strtol.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istring -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c comp/strtol.c
+done strtol.o generated
+make strtoll.o
+make comp/strtoll.c
+prev string/strtoi.h implicit
+prev ast_map.h implicit
+prev include/ast.h implicit
+done comp/strtoll.c
+meta strtoll.o %.c>%.o comp/strtoll.c strtoll
+prev comp/strtoll.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istring -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c comp/strtoll.c
+done strtoll.o generated
+make strtoul.o
+make comp/strtoul.c
+prev string/strtoi.h implicit
+done comp/strtoul.c
+meta strtoul.o %.c>%.o comp/strtoul.c strtoul
+prev comp/strtoul.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istring -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c comp/strtoul.c
+done strtoul.o generated
+make strtoull.o
+make comp/strtoull.c
+prev string/strtoi.h implicit
+prev ast_map.h implicit
+prev include/ast.h implicit
+done comp/strtoull.c
+meta strtoull.o %.c>%.o comp/strtoull.c strtoull
+prev comp/strtoull.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istring -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c comp/strtoull.c
+done strtoull.o generated
+make strton.o
+make string/strton.c
+prev string/strtoi.h implicit
+done string/strton.c
+meta strton.o %.c>%.o string/strton.c strton
+prev string/strton.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istring -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c string/strton.c
+done strton.o generated
+make strtonll.o
+make string/strtonll.c
+prev string/strtoi.h implicit
+done string/strtonll.c
+meta strtonll.o %.c>%.o string/strtonll.c strtonll
+prev string/strtonll.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istring -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c string/strtonll.c
+done strtonll.o generated
+make strntod.o
+make string/strntod.c
+prev sfio/sfstrtof.h implicit
+prev include/ast.h implicit
+done string/strntod.c
+meta strntod.o %.c>%.o string/strntod.c strntod
+prev string/strntod.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c string/strntod.c
+done strntod.o generated
+make strntold.o
+make string/strntold.c
+prev sfio/sfstrtof.h implicit
+prev include/ast.h implicit
+done string/strntold.c
+meta strntold.o %.c>%.o string/strntold.c strntold
+prev string/strntold.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c string/strntold.c
+done strntold.o generated
+make strnton.o
+make string/strnton.c
+prev string/strtoi.h implicit
+done string/strnton.c
+meta strnton.o %.c>%.o string/strnton.c strnton
+prev string/strnton.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istring -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c string/strnton.c
+done strnton.o generated
+make strntonll.o
+make string/strntonll.c
+prev string/strtoi.h implicit
+done string/strntonll.c
+meta strntonll.o %.c>%.o string/strntonll.c strntonll
+prev string/strntonll.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istring -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c string/strntonll.c
+done strntonll.o generated
+make strntol.o
+make string/strntol.c
+prev string/strtoi.h implicit
+done string/strntol.c
+meta strntol.o %.c>%.o string/strntol.c strntol
+prev string/strntol.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istring -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c string/strntol.c
+done strntol.o generated
+make strntoll.o
+make string/strntoll.c
+prev string/strtoi.h implicit
+done string/strntoll.c
+meta strntoll.o %.c>%.o string/strntoll.c strntoll
+prev string/strntoll.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istring -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c string/strntoll.c
+done strntoll.o generated
+make strntoul.o
+make string/strntoul.c
+prev string/strtoi.h implicit
+done string/strntoul.c
+meta strntoul.o %.c>%.o string/strntoul.c strntoul
+prev string/strntoul.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istring -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c string/strntoul.c
+done strntoul.o generated
+make strntoull.o
+make string/strntoull.c
+prev string/strtoi.h implicit
+done string/strntoull.c
+meta strntoull.o %.c>%.o string/strntoull.c strntoull
+prev string/strntoull.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istring -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c string/strntoull.c
+done strntoull.o generated
+make strcasecmp.o
+make comp/strcasecmp.c
+prev include/ast.h implicit
+done comp/strcasecmp.c
+meta strcasecmp.o %.c>%.o comp/strcasecmp.c strcasecmp
+prev comp/strcasecmp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/strcasecmp.c
+done strcasecmp.o generated
+make strncasecmp.o
+make comp/strncasecmp.c
+prev include/ast.h implicit
+done comp/strncasecmp.c
+meta strncasecmp.o %.c>%.o comp/strncasecmp.c strncasecmp
+prev comp/strncasecmp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/strncasecmp.c
+done strncasecmp.o generated
+make strerror.o
+make string/strerror.c
+make FEATURE/errno implicit
+meta FEATURE/errno features/%>FEATURE/% features/errno errno
+make features/errno
+done features/errno
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/errno
+done FEATURE/errno generated
+prev port/lclib.h implicit
+done string/strerror.c
+meta strerror.o %.c>%.o string/strerror.c strerror
+prev string/strerror.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c string/strerror.c
+done strerror.o generated
+make mktemp.o
+make comp/mktemp.c
+prev ast_map.h implicit
+prev std/stdio.h implicit
+prev include/ast.h implicit
+done comp/mktemp.c
+meta mktemp.o %.c>%.o comp/mktemp.c mktemp
+prev comp/mktemp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/mktemp.c
+done mktemp.o generated
+make tmpnam.o
+make comp/tmpnam.c
+prev ast_map.h implicit
+prev std/stdio.h implicit
+prev include/ast.h implicit
+done comp/tmpnam.c
+meta tmpnam.o %.c>%.o comp/tmpnam.c tmpnam
+prev comp/tmpnam.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/tmpnam.c
+done tmpnam.o generated
+make fsync.o
+make comp/fsync.c
+prev include/error.h implicit
+prev include/ast.h implicit
+done comp/fsync.c
+meta fsync.o %.c>%.o comp/fsync.c fsync
+prev comp/fsync.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/fsync.c
+done fsync.o generated
+make execlp.o
+make comp/execlp.c
+prev include/ast.h implicit
+prev ast_lib.h implicit
+done comp/execlp.c
+meta execlp.o %.c>%.o comp/execlp.c execlp
+prev comp/execlp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/execlp.c
+done execlp.o generated
+make execve.o
+make comp/execve.c
+prev include/error.h implicit
+prev include/wait.h implicit
+prev sig.h implicit
+prev include/ast.h implicit
+done comp/execve.c
+meta execve.o %.c>%.o comp/execve.c execve
+prev comp/execve.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/execve.c
+done execve.o generated
+make execvp.o
+make comp/execvp.c
+prev include/ast.h implicit
+prev ast_lib.h implicit
+done comp/execvp.c
+meta execvp.o %.c>%.o comp/execvp.c execvp
+prev comp/execvp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/execvp.c
+done execvp.o generated
+make execvpe.o
+make comp/execvpe.c
+prev include/ast.h implicit
+prev ast_lib.h implicit
+done comp/execvpe.c
+meta execvpe.o %.c>%.o comp/execvpe.c execvpe
+prev comp/execvpe.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/execvpe.c
+done execvpe.o generated
+make spawnveg.o
+make comp/spawnveg.c
+make ast_vfork.h implicit
+make FEATURE/vfork
+meta FEATURE/vfork features/%>FEATURE/% features/vfork vfork
+make features/vfork
+done features/vfork
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/vfork
+done FEATURE/vfork generated
+exec - cmp 2>/dev/null -s FEATURE/vfork ast_vfork.h || { rm -f ast_vfork.h; silent test -d . || mkdir .; ${STDCP} FEATURE/vfork ast_vfork.h; }
+done ast_vfork.h dontcare generated
+prev ast_tty.h implicit
+prev sig.h implicit
+make process.h implicit
+done process.h dontcare virtual
+prev include/wait.h implicit
+prev include/error.h implicit
+prev include/ast.h implicit
+done comp/spawnveg.c
+meta spawnveg.o %.c>%.o comp/spawnveg.c spawnveg
+prev comp/spawnveg.c
+exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/spawnveg.c
+done spawnveg.o generated
+make vfork.o
+make comp/vfork.c
+prev include/error.h implicit
+prev include/ast.h implicit
+done comp/vfork.c
+meta vfork.o %.c>%.o comp/vfork.c vfork
+prev comp/vfork.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/vfork.c
+done vfork.o generated
+make killpg.o
+make comp/killpg.c
+prev sig.h implicit
+prev include/ast.h implicit
+done comp/killpg.c
+meta killpg.o %.c>%.o comp/killpg.c killpg
+prev comp/killpg.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/killpg.c
+done killpg.o generated
+make hsearch.o
+make comp/hsearch.c
+make cdt/dthdr.h implicit
+make cdt/cdtlib.h implicit
+prev include/debug.h implicit
+make include/aso.h implicit
+prev ast_common.h implicit
+done include/aso.h dontcare
+prev include/cdt.h implicit
+make ${INSTALLROOT}/include/ast/dlldefs.h implicit
+done ${INSTALLROOT}/include/ast/dlldefs.h dontcare
+prev include/ast.h implicit
+done cdt/cdtlib.h dontcare
+done cdt/dthdr.h dontcare
+prev include/ast.h implicit
+done comp/hsearch.c
+meta hsearch.o %.c>%.o comp/hsearch.c hsearch
+prev comp/hsearch.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c comp/hsearch.c
+done hsearch.o generated
+make tsearch.o
+make comp/tsearch.c
+prev cdt/dthdr.h implicit
+prev include/ast.h implicit
+done comp/tsearch.c
+meta tsearch.o %.c>%.o comp/tsearch.c tsearch
+prev comp/tsearch.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c comp/tsearch.c
+done tsearch.o generated
+make getlogin.o
+make comp/getlogin.c
+prev include/ast.h implicit
+done comp/getlogin.c
+meta getlogin.o %.c>%.o comp/getlogin.c getlogin
+prev comp/getlogin.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/getlogin.c
+done getlogin.o generated
+make putenv.o
+make comp/putenv.c
+prev ast_map.h implicit
+prev include/ast.h implicit
+done comp/putenv.c
+meta putenv.o %.c>%.o comp/putenv.c putenv
+prev comp/putenv.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/putenv.c
+done putenv.o generated
+make setenv.o
+make comp/setenv.c
+prev ast_map.h implicit
+prev include/ast.h implicit
+done comp/setenv.c
+meta setenv.o %.c>%.o comp/setenv.c setenv
+prev comp/setenv.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/setenv.c
+done setenv.o generated
+make unsetenv.o
+make comp/unsetenv.c
+prev ast_map.h implicit
+prev include/ast.h implicit
+done comp/unsetenv.c
+meta unsetenv.o %.c>%.o comp/unsetenv.c unsetenv
+prev comp/unsetenv.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/unsetenv.c
+done unsetenv.o generated
+make lstat.o
+make comp/lstat.c
+prev include/ls.h implicit
+prev include/ast.h implicit
+done comp/lstat.c
+meta lstat.o %.c>%.o comp/lstat.c lstat
+prev comp/lstat.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/lstat.c
+done lstat.o generated
+make statvfs.o
+make comp/statvfs.c
+prev include/error.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done comp/statvfs.c
+meta statvfs.o %.c>%.o comp/statvfs.c statvfs
+prev comp/statvfs.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/statvfs.c
+done statvfs.o generated
+make eaccess.o
+make comp/eaccess.c
+prev FEATURE/eaccess implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done comp/eaccess.c
+meta eaccess.o %.c>%.o comp/eaccess.c eaccess
+prev comp/eaccess.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/eaccess.c
+done eaccess.o generated
+make gross.o
+make comp/gross.c
+make comp/gross_sgi.h implicit
+make locale_attr.h implicit
+done locale_attr.h dontcare virtual
+done comp/gross_sgi.h dontcare
+make FEATURE/hack implicit
+meta FEATURE/hack features/%>FEATURE/% features/hack hack
+make features/hack
+done features/hack
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/hack
+done FEATURE/hack generated
+prev include/ls.h implicit
+prev include/ast.h implicit
+done comp/gross.c
+meta gross.o %.c>%.o comp/gross.c gross
+prev comp/gross.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/gross.c
+done gross.o generated
+make omitted.o
+make comp/omitted.c
+prev process.h implicit
+prev include/ast_windows.h implicit
+prev include/ls.h implicit
+make FEATURE/omitted implicit
+meta FEATURE/omitted features/%>FEATURE/% features/omitted omitted
+make features/omitted
+done features/omitted
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/omitted
+done FEATURE/omitted generated
+prev include/tm.h implicit
+prev include/error.h implicit
+prev include/ast.h implicit
+done comp/omitted.c
+meta omitted.o %.c>%.o comp/omitted.c omitted
+prev comp/omitted.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/omitted.c
+done omitted.o generated
+make readlink.o
+make comp/readlink.c
+prev include/error.h implicit
+make comp/fakelink.h implicit
+done comp/fakelink.h dontcare
+prev include/ast.h implicit
+done comp/readlink.c
+meta readlink.o %.c>%.o comp/readlink.c readlink
+prev comp/readlink.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/readlink.c
+done readlink.o generated
+make symlink.o
+make comp/symlink.c
+prev include/error.h implicit
+prev comp/fakelink.h implicit
+prev include/ast.h implicit
+done comp/symlink.c
+meta symlink.o %.c>%.o comp/symlink.c symlink
+prev comp/symlink.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/symlink.c
+done symlink.o generated
+make getpgrp.o
+make comp/getpgrp.c
+prev include/ast_std.h implicit
+done comp/getpgrp.c
+meta getpgrp.o %.c>%.o comp/getpgrp.c getpgrp
+prev comp/getpgrp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -c comp/getpgrp.c
+done getpgrp.o generated
+make setpgid.o
+make comp/setpgid.c
+prev include/error.h implicit
+prev include/ast.h implicit
+done comp/setpgid.c
+meta setpgid.o %.c>%.o comp/setpgid.c setpgid
+prev comp/setpgid.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/setpgid.c
+done setpgid.o generated
+make setsid.o
+make comp/setsid.c
+prev include/error.h implicit
+prev ast_tty.h implicit
+prev include/ast.h implicit
+done comp/setsid.c
+meta setsid.o %.c>%.o comp/setsid.c setsid
+prev comp/setsid.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/setsid.c
+done setsid.o generated
+make waitpid.o
+make comp/waitpid.c
+prev include/error.h implicit
+prev sig.h implicit
+prev include/wait.h implicit
+prev include/ast.h implicit
+done comp/waitpid.c
+meta waitpid.o %.c>%.o comp/waitpid.c waitpid
+prev comp/waitpid.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/waitpid.c
+done waitpid.o generated
+make creat64.o
+make comp/creat64.c
+prev include/ast.h implicit
+done comp/creat64.c
+meta creat64.o %.c>%.o comp/creat64.c creat64
+prev comp/creat64.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/creat64.c
+done creat64.o generated
+make fcntl.o
+make comp/fcntl.c
+prev include/error.h implicit
+prev ast_tty.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done comp/fcntl.c
+meta fcntl.o %.c>%.o comp/fcntl.c fcntl
+prev comp/fcntl.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/fcntl.c
+done fcntl.o generated
+make open.o
+make comp/open.c
+prev ast_tty.h implicit
+prev include/error.h implicit
+prev include/ls.h implicit
+prev include/ast.h implicit
+done comp/open.c
+meta open.o %.c>%.o comp/open.c open
+prev comp/open.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/open.c
+done open.o generated
+make atexit.o
+make comp/atexit.c
+prev include/ast.h implicit
+done comp/atexit.c
+meta atexit.o %.c>%.o comp/atexit.c atexit
+prev comp/atexit.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/atexit.c
+done atexit.o generated
+make getdents.o
+make dir/getdents.c
+prev dir/dirlib.h implicit
+done dir/getdents.c
+meta getdents.o %.c>%.o dir/getdents.c getdents
+prev dir/getdents.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idir -Iinclude -Istd -D_PACKAGE_ast -c dir/getdents.c
+done getdents.o generated
+make getwd.o
+make comp/getwd.c
+prev include/ast.h implicit
+done comp/getwd.c
+meta getwd.o %.c>%.o comp/getwd.c getwd
+prev comp/getwd.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/getwd.c
+done getwd.o generated
+make dup2.o
+make comp/dup2.c
+prev include/error.h implicit
+prev include/ast.h implicit
+done comp/dup2.c
+meta dup2.o %.c>%.o comp/dup2.c dup2
+prev comp/dup2.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/dup2.c
+done dup2.o generated
+make errno.o
+make comp/errno.c
+prev include/ast.h implicit
+done comp/errno.c
+meta errno.o %.c>%.o comp/errno.c errno
+prev comp/errno.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/errno.c
+done errno.o generated
+make getpreroot.o
+make preroot/getpreroot.c
+prev std/stdio.h implicit
+prev include/error.h implicit
+prev include/ls.h implicit
+prev include/ast_dir.h implicit
+prev preroot.h implicit
+prev include/ast.h implicit
+done preroot/getpreroot.c
+meta getpreroot.o %.c>%.o preroot/getpreroot.c getpreroot
+prev preroot/getpreroot.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idir -Iinclude -Istd -D_PACKAGE_ast -c preroot/getpreroot.c
+done getpreroot.o generated
+make ispreroot.o
+make preroot/ispreroot.c
+prev include/ls.h implicit
+prev preroot.h implicit
+prev include/ast.h implicit
+done preroot/ispreroot.c
+meta ispreroot.o %.c>%.o preroot/ispreroot.c ispreroot
+prev preroot/ispreroot.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c preroot/ispreroot.c
+done ispreroot.o generated
+make realopen.o
+make preroot/realopen.c
+prev preroot.h implicit
+prev include/ast.h implicit
+done preroot/realopen.c
+meta realopen.o %.c>%.o preroot/realopen.c realopen
+prev preroot/realopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c preroot/realopen.c
+done realopen.o generated
+make setpreroot.o
+make preroot/setpreroot.c
+prev include/option.h implicit
+prev preroot.h implicit
+prev include/ast.h implicit
+done preroot/setpreroot.c
+meta setpreroot.o %.c>%.o preroot/setpreroot.c setpreroot
+prev preroot/setpreroot.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c preroot/setpreroot.c
+done setpreroot.o generated
+make getgroups.o
+make comp/getgroups.c
+prev include/error.h implicit
+prev include/ast.h implicit
+done comp/getgroups.c
+meta getgroups.o %.c>%.o comp/getgroups.c getgroups
+prev comp/getgroups.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/getgroups.c
+done getgroups.o generated
+make mount.o
+make comp/mount.c
+prev include/error.h implicit
+prev include/ast.h implicit
+done comp/mount.c
+meta mount.o %.c>%.o comp/mount.c mount
+prev comp/mount.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/mount.c
+done mount.o generated
+make system.o
+make comp/system.c
+prev ast_map.h implicit
+prev include/proc.h implicit
+prev include/ast.h implicit
+done comp/system.c
+meta system.o %.c>%.o comp/system.c system
+prev comp/system.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/system.c
+done system.o generated
+make iblocks.o
+make port/iblocks.c
+prev include/ls.h implicit
+prev ast_param.h implicit
+prev include/ast.h implicit
+done port/iblocks.c
+meta iblocks.o %.c>%.o port/iblocks.c iblocks
+prev port/iblocks.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c port/iblocks.c
+done iblocks.o generated
+make modedata.o
+make string/modedata.c
+prev string/modelib.h implicit
+done string/modedata.c
+meta modedata.o %.c>%.o string/modedata.c modedata
+prev string/modedata.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Istring -Iinclude -Istd -D_PACKAGE_ast -c string/modedata.c
+done modedata.o generated
+make tmdata.o
+make tm/tmdata.c
+prev include/tm.h implicit
+prev include/ast.h implicit
+done tm/tmdata.c
+meta tmdata.o %.c>%.o tm/tmdata.c tmdata
+prev tm/tmdata.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmdata.c
+done tmdata.o generated
+make memfatal.o
+make disc/memfatal.c
+prev FEATURE/vmalloc implicit
+prev include/vmalloc.h implicit
+prev include/error.h implicit
+prev include/ast.h implicit
+done disc/memfatal.c
+meta memfatal.o %.c>%.o disc/memfatal.c memfatal
+prev disc/memfatal.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c disc/memfatal.c
+done memfatal.o generated
+make sfkeyprintf.o
+make disc/sfkeyprintf.c
+prev ast_api.h implicit
+prev include/regex.h implicit
+make include/sfdisc.h implicit
+prev include/ast.h implicit
+done include/sfdisc.h
+prev include/ccode.h implicit
+prev include/ast.h implicit
+done disc/sfkeyprintf.c
+meta sfkeyprintf.o %.c>%.o disc/sfkeyprintf.c sfkeyprintf
+prev disc/sfkeyprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c disc/sfkeyprintf.c
+done sfkeyprintf.o generated
+make sfdcdio.o
+make disc/sfdcdio.c
+make disc/sfdchdr.h implicit
+prev include/sfdisc.h implicit
+prev sfio/sfhdr.h implicit
+done disc/sfdchdr.h
+done disc/sfdcdio.c
+meta sfdcdio.o %.c>%.o disc/sfdcdio.c sfdcdio
+prev disc/sfdcdio.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idisc -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c disc/sfdcdio.c
+done sfdcdio.o generated
+make sfdcdos.o
+make disc/sfdcdos.c
+prev disc/sfdchdr.h implicit
+done disc/sfdcdos.c
+meta sfdcdos.o %.c>%.o disc/sfdcdos.c sfdcdos
+prev disc/sfdcdos.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idisc -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c disc/sfdcdos.c
+done sfdcdos.o generated
+make sfdcfilter.o
+make disc/sfdcfilter.c
+prev disc/sfdchdr.h implicit
+done disc/sfdcfilter.c
+meta sfdcfilter.o %.c>%.o disc/sfdcfilter.c sfdcfilter
+prev disc/sfdcfilter.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idisc -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c disc/sfdcfilter.c
+done sfdcfilter.o generated
+make sfdcseekable.o
+make disc/sfdcseekable.c
+prev disc/sfdchdr.h implicit
+done disc/sfdcseekable.c
+meta sfdcseekable.o %.c>%.o disc/sfdcseekable.c sfdcseekable
+prev disc/sfdcseekable.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idisc -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c disc/sfdcseekable.c
+done sfdcseekable.o generated
+make sfdcslow.o
+make disc/sfdcslow.c
+prev disc/sfdchdr.h implicit
+done disc/sfdcslow.c
+meta sfdcslow.o %.c>%.o disc/sfdcslow.c sfdcslow
+prev disc/sfdcslow.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idisc -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c disc/sfdcslow.c
+done sfdcslow.o generated
+make sfdcsubstr.o
+make disc/sfdcsubstr.c
+prev disc/sfdchdr.h implicit
+done disc/sfdcsubstr.c
+meta sfdcsubstr.o %.c>%.o disc/sfdcsubstr.c sfdcsubstr
+prev disc/sfdcsubstr.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idisc -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c disc/sfdcsubstr.c
+done sfdcsubstr.o generated
+make sfdctee.o
+make disc/sfdctee.c
+prev disc/sfdchdr.h implicit
+done disc/sfdctee.c
+meta sfdctee.o %.c>%.o disc/sfdctee.c sfdctee
+prev disc/sfdctee.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idisc -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c disc/sfdctee.c
+done sfdctee.o generated
+make sfdcunion.o
+make disc/sfdcunion.c
+prev disc/sfdchdr.h implicit
+done disc/sfdcunion.c
+meta sfdcunion.o %.c>%.o disc/sfdcunion.c sfdcunion
+prev disc/sfdcunion.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idisc -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c disc/sfdcunion.c
+done sfdcunion.o generated
+make sfdcmore.o
+make disc/sfdcmore.c
+prev ast_tty.h implicit
+prev disc/sfdchdr.h implicit
+done disc/sfdcmore.c
+meta sfdcmore.o %.c>%.o disc/sfdcmore.c sfdcmore
+prev disc/sfdcmore.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idisc -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c disc/sfdcmore.c
+done sfdcmore.o generated
+make sfdcprefix.o
+make disc/sfdcprefix.c
+prev disc/sfdchdr.h implicit
+done disc/sfdcprefix.c
+meta sfdcprefix.o %.c>%.o disc/sfdcprefix.c sfdcprefix
+prev disc/sfdcprefix.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idisc -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c disc/sfdcprefix.c
+done sfdcprefix.o generated
+make wc.o
+make comp/wc.c
+prev std/wchar.h implicit
+prev include/ast.h implicit
+done comp/wc.c
+meta wc.o %.c>%.o comp/wc.c wc
+prev comp/wc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/wc.c
+done wc.o generated
+make wc2utf8.o
+make string/wc2utf8.c
+prev include/ast.h implicit
+done string/wc2utf8.c
+meta wc2utf8.o %.c>%.o string/wc2utf8.c wc2utf8
+prev string/wc2utf8.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c string/wc2utf8.c
+done wc2utf8.o generated
+make basename.o
+make comp/basename.c
+prev include/ast_std.h implicit
+done comp/basename.c
+meta basename.o %.c>%.o comp/basename.c basename
+prev comp/basename.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -c comp/basename.c
+done basename.o generated
+make closelog.o
+make comp/closelog.c
+make comp/sysloglib.h implicit
+make comp/syslog.h implicit
+make ast_namval.h implicit
+prev include/namval.h
+exec - cmp 2>/dev/null -s include/namval.h ast_namval.h || { rm -f ast_namval.h; silent test -d . || mkdir .; ${STDCP} include/namval.h ast_namval.h; }
+done ast_namval.h dontcare generated
+done comp/syslog.h dontcare
+done comp/sysloglib.h dontcare
+prev include/ast.h implicit
+done comp/closelog.c
+meta closelog.o %.c>%.o comp/closelog.c closelog
+prev comp/closelog.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/closelog.c
+done closelog.o generated
+make dirname.o
+make comp/dirname.c
+prev include/ast_std.h implicit
+done comp/dirname.c
+meta dirname.o %.c>%.o comp/dirname.c dirname
+prev comp/dirname.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -c comp/dirname.c
+done dirname.o generated
+make fmtmsglib.o
+make comp/fmtmsglib.c
+make comp/fmtmsg.h implicit
+done comp/fmtmsg.h dontcare
+prev include/ast.h implicit
+done comp/fmtmsglib.c
+meta fmtmsglib.o %.c>%.o comp/fmtmsglib.c fmtmsglib
+prev comp/fmtmsglib.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/fmtmsglib.c
+done fmtmsglib.o generated
+make fnmatch.o
+make comp/fnmatch.c
+make comp/fnmatch.h implicit
+prev ast_common.h implicit
+done comp/fnmatch.h
+prev include/regex.h implicit
+prev include/ast.h implicit
+prev ast_lib.h implicit
+done comp/fnmatch.c
+meta fnmatch.o %.c>%.o comp/fnmatch.c fnmatch
+prev comp/fnmatch.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/fnmatch.c
+done fnmatch.o generated
+make ftw.o
+make comp/ftw.c
+make comp/ftw.h implicit
+prev include/ftwalk.h implicit
+done comp/ftw.h
+prev include/ast.h implicit
+done comp/ftw.c
+meta ftw.o %.c>%.o comp/ftw.c ftw
+prev comp/ftw.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/ftw.c
+done ftw.o generated
+make getdate.o
+make comp/getdate.c
+prev ast_map.h implicit
+prev include/tm.h implicit
+prev include/ast.h implicit
+done comp/getdate.c
+meta getdate.o %.c>%.o comp/getdate.c getdate
+prev comp/getdate.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/getdate.c
+done getdate.o generated
+make getsubopt.o
+make comp/getsubopt.c
+prev include/error.h implicit
+prev include/ast.h implicit
+done comp/getsubopt.c
+meta getsubopt.o %.c>%.o comp/getsubopt.c getsubopt
+prev comp/getsubopt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/getsubopt.c
+done getsubopt.o generated
+make glob.o
+make misc/glob.c
+make include/glob.h implicit
+done include/glob.h
+prev include/regex.h implicit
+prev include/error.h implicit
+prev include/ast_dir.h implicit
+make include/stak.h implicit
+prev include/stk.h implicit
+done include/stak.h
+prev include/ls.h implicit
+prev include/ast.h implicit
+done misc/glob.c
+meta glob.o %.c>%.o misc/glob.c glob
+prev misc/glob.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Idir -Iinclude -Istd -D_PACKAGE_ast -c misc/glob.c
+done glob.o generated
+make nftw.o
+make comp/nftw.c
+prev comp/ftw.h implicit
+prev include/ast.h implicit
+done comp/nftw.c
+meta nftw.o %.c>%.o comp/nftw.c nftw
+prev comp/nftw.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/nftw.c
+done nftw.o generated
+make openlog.o
+make comp/openlog.c
+prev comp/sysloglib.h implicit
+prev include/ast.h implicit
+done comp/openlog.c
+meta openlog.o %.c>%.o comp/openlog.c openlog
+prev comp/openlog.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/openlog.c
+done openlog.o generated
+make re_comp.o
+make comp/re_comp.c
+prev include/regex.h implicit
+make comp/re_comp.h implicit
+done comp/re_comp.h
+prev include/ast.h implicit
+done comp/re_comp.c
+meta re_comp.o %.c>%.o comp/re_comp.c re_comp
+prev comp/re_comp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/re_comp.c
+done re_comp.o generated
+make resolvepath.o
+make comp/resolvepath.c
+prev ast_api.h implicit
+prev ast_map.h implicit
+prev include/error.h implicit
+prev include/ast.h implicit
+done comp/resolvepath.c
+meta resolvepath.o %.c>%.o comp/resolvepath.c resolvepath
+prev comp/resolvepath.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/resolvepath.c
+done resolvepath.o generated
+make realpath.o
+make comp/realpath.c
+prev ast_map.h implicit
+prev include/ast.h implicit
+done comp/realpath.c
+meta realpath.o %.c>%.o comp/realpath.c realpath
+prev comp/realpath.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/realpath.c
+done realpath.o generated
+make regcmp.o
+make comp/regcmp.c
+prev align.h implicit
+prev include/regex.h implicit
+make comp/libgen.h implicit
+done comp/libgen.h
+prev include/ast.h implicit
+done comp/regcmp.c
+meta regcmp.o %.c>%.o comp/regcmp.c regcmp
+prev comp/regcmp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/regcmp.c
+done regcmp.o generated
+make regexp.o
+make comp/regexp.c
+prev align.h implicit
+prev include/regex.h implicit
+make comp/regexp.h implicit
+done comp/regexp.h
+prev include/ast.h implicit
+done comp/regexp.c
+meta regexp.o %.c>%.o comp/regexp.c regexp
+prev comp/regexp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/regexp.c
+done regexp.o generated
+make setlogmask.o
+make comp/setlogmask.c
+prev comp/sysloglib.h implicit
+prev include/ast.h implicit
+done comp/setlogmask.c
+meta setlogmask.o %.c>%.o comp/setlogmask.c setlogmask
+prev comp/setlogmask.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/setlogmask.c
+done setlogmask.o generated
+make strftime.o
+make comp/strftime.c
+prev ast_map.h implicit
+prev include/tm.h implicit
+prev include/ast.h implicit
+done comp/strftime.c
+meta strftime.o %.c>%.o comp/strftime.c strftime
+prev comp/strftime.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/strftime.c
+done strftime.o generated
+make strptime.o
+make comp/strptime.c
+prev ast_map.h implicit
+prev tmx.h implicit
+prev include/ast.h implicit
+done comp/strptime.c
+meta strptime.o %.c>%.o comp/strptime.c strptime
+prev comp/strptime.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/strptime.c
+done strptime.o generated
+make swab.o
+make comp/swab.c
+prev include/swap.h implicit
+prev include/ast.h implicit
+done comp/swab.c
+meta swab.o %.c>%.o comp/swab.c swab
+prev comp/swab.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/swab.c
+done swab.o generated
+make syslog.o
+make comp/syslog.c
+prev std/endian.h implicit
+prev include/ls.h implicit
+prev include/tm.h implicit
+prev include/error.h implicit
+prev comp/sysloglib.h implicit
+prev include/ast.h implicit
+done comp/syslog.c
+meta syslog.o %.c>%.o comp/syslog.c syslog
+prev comp/syslog.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/syslog.c
+done syslog.o generated
+make tempnam.o
+make comp/tempnam.c
+prev std/stdio.h implicit
+prev include/ast.h implicit
+prev include/ast_std.h implicit
+done comp/tempnam.c
+meta tempnam.o %.c>%.o comp/tempnam.c tempnam
+prev comp/tempnam.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/tempnam.c
+done tempnam.o generated
+make wordexp.o
+make comp/wordexp.c
+prev include/stak.h implicit
+make comp/wordexp.h implicit
+prev ast_common.h implicit
+done comp/wordexp.h
+prev include/ast.h implicit
+done comp/wordexp.c
+meta wordexp.o %.c>%.o comp/wordexp.c wordexp
+prev comp/wordexp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/wordexp.c
+done wordexp.o generated
+make mktime.o
+make comp/mktime.c
+prev ast_map.h implicit
+prev include/tm.h implicit
+prev include/ast.h implicit
+done comp/mktime.c
+meta mktime.o %.c>%.o comp/mktime.c mktime
+prev comp/mktime.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/mktime.c
+done mktime.o generated
+make regalloc.o
+make regex/regalloc.c
+make regex/reglib.h implicit
+prev std/wctype.h implicit
+prev std/wchar.h implicit
+prev std/stdio.h implicit
+prev include/regex.h implicit
+prev include/stk.h implicit
+prev include/cdt.h implicit
+prev include/ast.h implicit
+done regex/reglib.h
+done regex/regalloc.c
+meta regalloc.o %.c>%.o regex/regalloc.c regalloc
+prev regex/regalloc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/regalloc.c
+done regalloc.o generated
+make regclass.o
+make regex/regclass.c
+prev regex/reglib.h implicit
+done regex/regclass.c
+meta regclass.o %.c>%.o regex/regclass.c regclass
+prev regex/regclass.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/regclass.c
+done regclass.o generated
+make regcoll.o
+make regex/regcoll.c
+prev regex/reglib.h implicit
+done regex/regcoll.c
+meta regcoll.o %.c>%.o regex/regcoll.c regcoll
+prev regex/regcoll.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/regcoll.c
+done regcoll.o generated
+make regcomp.o
+make regex/regcomp.c
+prev port/lclib.h implicit
+prev regex/reglib.h implicit
+done regex/regcomp.c
+meta regcomp.o %.c>%.o regex/regcomp.c regcomp
+prev regex/regcomp.c
+exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -Icomp -Iport -Iregex -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c regex/regcomp.c
+done regcomp.o generated
+make regcache.o
+make regex/regcache.c
+prev include/regex.h implicit
+prev include/ast.h implicit
+done regex/regcache.c
+meta regcache.o %.c>%.o regex/regcache.c regcache
+prev regex/regcache.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c regex/regcache.c
+done regcache.o generated
+make regdecomp.o
+make regex/regdecomp.c
+prev regex/reglib.h implicit
+done regex/regdecomp.c
+meta regdecomp.o %.c>%.o regex/regdecomp.c regdecomp
+prev regex/regdecomp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/regdecomp.c
+done regdecomp.o generated
+make regerror.o
+make regex/regerror.c
+prev regex/reglib.h implicit
+done regex/regerror.c
+meta regerror.o %.c>%.o regex/regerror.c regerror
+prev regex/regerror.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/regerror.c
+done regerror.o generated
+make regexec.o
+make regex/regexec.c
+prev regex/reglib.h implicit
+done regex/regexec.c
+meta regexec.o %.c>%.o regex/regexec.c regexec
+prev regex/regexec.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/regexec.c
+done regexec.o generated
+make regfatal.o
+make regex/regfatal.c
+prev include/error.h implicit
+prev regex/reglib.h implicit
+done regex/regfatal.c
+meta regfatal.o %.c>%.o regex/regfatal.c regfatal
+prev regex/regfatal.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/regfatal.c
+done regfatal.o generated
+make reginit.o
+make regex/reginit.c
+prev include/ccode.h implicit
+prev regex/reglib.h implicit
+done regex/reginit.c
+meta reginit.o %.c>%.o regex/reginit.c reginit
+prev regex/reginit.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/reginit.c
+done reginit.o generated
+make regnexec.o
+make regex/regnexec.c
+prev regex/reglib.h implicit
+done regex/regnexec.c
+meta regnexec.o %.c>%.o regex/regnexec.c regnexec
+prev regex/regnexec.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/regnexec.c
+done regnexec.o generated
+make regsubcomp.o
+make regex/regsubcomp.c
+prev regex/reglib.h implicit
+done regex/regsubcomp.c
+meta regsubcomp.o %.c>%.o regex/regsubcomp.c regsubcomp
+prev regex/regsubcomp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/regsubcomp.c
+done regsubcomp.o generated
+make regsubexec.o
+make regex/regsubexec.c
+prev regex/reglib.h implicit
+done regex/regsubexec.c
+meta regsubexec.o %.c>%.o regex/regsubexec.c regsubexec
+prev regex/regsubexec.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/regsubexec.c
+done regsubexec.o generated
+make regsub.o
+make regex/regsub.c
+prev regex/reglib.h implicit
+done regex/regsub.c
+meta regsub.o %.c>%.o regex/regsub.c regsub
+prev regex/regsub.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/regsub.c
+done regsub.o generated
+make regrecord.o
+make regex/regrecord.c
+prev regex/reglib.h implicit
+done regex/regrecord.c
+meta regrecord.o %.c>%.o regex/regrecord.c regrecord
+prev regex/regrecord.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/regrecord.c
+done regrecord.o generated
+make regrexec.o
+make regex/regrexec.c
+prev regex/reglib.h implicit
+done regex/regrexec.c
+meta regrexec.o %.c>%.o regex/regrexec.c regrexec
+prev regex/regrexec.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/regrexec.c
+done regrexec.o generated
+make regstat.o
+make regex/regstat.c
+prev regex/reglib.h implicit
+done regex/regstat.c
+meta regstat.o %.c>%.o regex/regstat.c regstat
+prev regex/regstat.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iregex -Iinclude -Istd -D_PACKAGE_ast -c regex/regstat.c
+done regstat.o generated
+make dtclose.o
+make cdt/dtclose.c
+prev cdt/dthdr.h implicit
+done cdt/dtclose.c
+meta dtclose.o %.c>%.o cdt/dtclose.c dtclose
+prev cdt/dtclose.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c cdt/dtclose.c
+done dtclose.o generated
+make dtdisc.o
+make cdt/dtdisc.c
+prev cdt/dthdr.h implicit
+done cdt/dtdisc.c
+meta dtdisc.o %.c>%.o cdt/dtdisc.c dtdisc
+prev cdt/dtdisc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c cdt/dtdisc.c
+done dtdisc.o generated
+make dthash.o
+make cdt/dthash.c
+prev cdt/dthdr.h implicit
+done cdt/dthash.c
+meta dthash.o %.c>%.o cdt/dthash.c dthash
+prev cdt/dthash.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c cdt/dthash.c
+done dthash.o generated
+make dtlist.o
+make cdt/dtlist.c
+prev cdt/dthdr.h implicit
+done cdt/dtlist.c
+meta dtlist.o %.c>%.o cdt/dtlist.c dtlist
+prev cdt/dtlist.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c cdt/dtlist.c
+done dtlist.o generated
+make dtmethod.o
+make cdt/dtmethod.c
+prev cdt/dthdr.h implicit
+done cdt/dtmethod.c
+meta dtmethod.o %.c>%.o cdt/dtmethod.c dtmethod
+prev cdt/dtmethod.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c cdt/dtmethod.c
+done dtmethod.o generated
+make dtopen.o
+make cdt/dtopen.c
+prev cdt/dthdr.h implicit
+done cdt/dtopen.c
+meta dtopen.o %.c>%.o cdt/dtopen.c dtopen
+prev cdt/dtopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c cdt/dtopen.c
+done dtopen.o generated
+make dtstrhash.o
+make cdt/dtstrhash.c
+prev cdt/dthdr.h implicit
+done cdt/dtstrhash.c
+meta dtstrhash.o %.c>%.o cdt/dtstrhash.c dtstrhash
+prev cdt/dtstrhash.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c cdt/dtstrhash.c
+done dtstrhash.o generated
+make dttree.o
+make cdt/dttree.c
+prev cdt/dthdr.h implicit
+done cdt/dttree.c
+meta dttree.o %.c>%.o cdt/dttree.c dttree
+prev cdt/dttree.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c cdt/dttree.c
+done dttree.o generated
+make dtview.o
+make cdt/dtview.c
+prev cdt/dthdr.h implicit
+done cdt/dtview.c
+meta dtview.o %.c>%.o cdt/dtview.c dtview
+prev cdt/dtview.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c cdt/dtview.c
+done dtview.o generated
+make dtwalk.o
+make cdt/dtwalk.c
+prev cdt/dthdr.h implicit
+done cdt/dtwalk.c
+meta dtwalk.o %.c>%.o cdt/dtwalk.c dtwalk
+prev cdt/dtwalk.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icdt -Icomp -Iinclude -Istd -I${INSTALLROOT}/include/ast -D_PACKAGE_ast -c cdt/dtwalk.c
+done dtwalk.o generated
+make dtnew.o
+make cdt/dtnew.c
+prev include/dt.h implicit
+done cdt/dtnew.c
+meta dtnew.o %.c>%.o cdt/dtnew.c dtnew
+prev cdt/dtnew.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c cdt/dtnew.c
+done dtnew.o generated
+make dtcomp.o
+make cdt/dtcomp.c
+prev include/cdt.h implicit
+done cdt/dtcomp.c
+meta dtcomp.o %.c>%.o cdt/dtcomp.c dtcomp
+prev cdt/dtcomp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c cdt/dtcomp.c
+done dtcomp.o generated
+make sfclose.o
+make sfio/sfclose.c
+prev sfio/sfhdr.h implicit
+done sfio/sfclose.c
+meta sfclose.o %.c>%.o sfio/sfclose.c sfclose
+prev sfio/sfclose.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfclose.c
+done sfclose.o generated
+make sfclrlock.o
+make sfio/sfclrlock.c
+prev sfio/sfhdr.h implicit
+done sfio/sfclrlock.c
+meta sfclrlock.o %.c>%.o sfio/sfclrlock.c sfclrlock
+prev sfio/sfclrlock.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfclrlock.c
+done sfclrlock.o generated
+make sfdisc.o
+make sfio/sfdisc.c
+prev sfio/sfhdr.h implicit
+done sfio/sfdisc.c
+meta sfdisc.o %.c>%.o sfio/sfdisc.c sfdisc
+prev sfio/sfdisc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfdisc.c
+done sfdisc.o generated
+make sfdlen.o
+make sfio/sfdlen.c
+prev sfio/sfhdr.h implicit
+done sfio/sfdlen.c
+meta sfdlen.o %.c>%.o sfio/sfdlen.c sfdlen
+prev sfio/sfdlen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfdlen.c
+done sfdlen.o generated
+make sfexcept.o
+make sfio/sfexcept.c
+prev sfio/sfhdr.h implicit
+done sfio/sfexcept.c
+meta sfexcept.o %.c>%.o sfio/sfexcept.c sfexcept
+prev sfio/sfexcept.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfexcept.c
+done sfexcept.o generated
+make sfgetl.o
+make sfio/sfgetl.c
+prev sfio/sfhdr.h implicit
+done sfio/sfgetl.c
+meta sfgetl.o %.c>%.o sfio/sfgetl.c sfgetl
+prev sfio/sfgetl.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfgetl.c
+done sfgetl.o generated
+make sfgetu.o
+make sfio/sfgetu.c
+prev sfio/sfhdr.h implicit
+done sfio/sfgetu.c
+meta sfgetu.o %.c>%.o sfio/sfgetu.c sfgetu
+prev sfio/sfgetu.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfgetu.c
+done sfgetu.o generated
+make sfcvt.o
+make sfio/sfcvt.c
+prev sfio/sfhdr.h implicit
+prev FEATURE/isoc99 implicit
+done sfio/sfcvt.c
+meta sfcvt.o %.c>%.o sfio/sfcvt.c sfcvt
+prev sfio/sfcvt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfcvt.c
+done sfcvt.o generated
+make sfecvt.o
+make sfio/sfecvt.c
+prev sfio/sfhdr.h implicit
+done sfio/sfecvt.c
+meta sfecvt.o %.c>%.o sfio/sfecvt.c sfecvt
+prev sfio/sfecvt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfecvt.c
+done sfecvt.o generated
+make sffcvt.o
+make sfio/sffcvt.c
+prev sfio/sfhdr.h implicit
+done sfio/sffcvt.c
+meta sffcvt.o %.c>%.o sfio/sffcvt.c sffcvt
+prev sfio/sffcvt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sffcvt.c
+done sffcvt.o generated
+make sfextern.o
+make sfio/sfextern.c
+prev sfio/sfhdr.h implicit
+done sfio/sfextern.c
+meta sfextern.o %.c>%.o sfio/sfextern.c sfextern
+prev sfio/sfextern.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfextern.c
+done sfextern.o generated
+make sffilbuf.o
+make sfio/sffilbuf.c
+prev sfio/sfhdr.h implicit
+done sfio/sffilbuf.c
+meta sffilbuf.o %.c>%.o sfio/sffilbuf.c sffilbuf
+prev sfio/sffilbuf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sffilbuf.c
+done sffilbuf.o generated
+make sfflsbuf.o
+make sfio/sfflsbuf.c
+prev sfio/sfhdr.h implicit
+done sfio/sfflsbuf.c
+meta sfflsbuf.o %.c>%.o sfio/sfflsbuf.c sfflsbuf
+prev sfio/sfflsbuf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfflsbuf.c
+done sfflsbuf.o generated
+make sfprints.o
+make sfio/sfprints.c
+prev sfio/sfhdr.h implicit
+done sfio/sfprints.c
+meta sfprints.o %.c>%.o sfio/sfprints.c sfprints
+prev sfio/sfprints.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfprints.c
+done sfprints.o generated
+make sfgetd.o
+make sfio/sfgetd.c
+prev sfio/sfhdr.h implicit
+done sfio/sfgetd.c
+meta sfgetd.o %.c>%.o sfio/sfgetd.c sfgetd
+prev sfio/sfgetd.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfgetd.c
+done sfgetd.o generated
+make sfgetr.o
+make sfio/sfgetr.c
+prev sfio/sfhdr.h implicit
+done sfio/sfgetr.c
+meta sfgetr.o %.c>%.o sfio/sfgetr.c sfgetr
+prev sfio/sfgetr.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfgetr.c
+done sfgetr.o generated
+make sfllen.o
+make sfio/sfllen.c
+prev sfio/sfhdr.h implicit
+done sfio/sfllen.c
+meta sfllen.o %.c>%.o sfio/sfllen.c sfllen
+prev sfio/sfllen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfllen.c
+done sfllen.o generated
+make sfmode.o
+make sfio/sfmode.c
+prev include/wait.h implicit
+prev sig.h implicit
+prev sfio/sfhdr.h implicit
+done sfio/sfmode.c
+meta sfmode.o %.c>%.o sfio/sfmode.c sfmode
+prev sfio/sfmode.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfmode.c
+done sfmode.o generated
+make sfmove.o
+make sfio/sfmove.c
+prev sfio/sfhdr.h implicit
+done sfio/sfmove.c
+meta sfmove.o %.c>%.o sfio/sfmove.c sfmove
+prev sfio/sfmove.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfmove.c
+done sfmove.o generated
+make sfnew.o
+make sfio/sfnew.c
+prev sfio/sfhdr.h implicit
+done sfio/sfnew.c
+meta sfnew.o %.c>%.o sfio/sfnew.c sfnew
+prev sfio/sfnew.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfnew.c
+done sfnew.o generated
+make sfpkrd.o
+make sfio/sfpkrd.c
+prev sfio/sfhdr.h implicit
+done sfio/sfpkrd.c
+meta sfpkrd.o %.c>%.o sfio/sfpkrd.c sfpkrd
+prev sfio/sfpkrd.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfpkrd.c
+done sfpkrd.o generated
+make sfnotify.o
+make sfio/sfnotify.c
+prev sfio/sfhdr.h implicit
+done sfio/sfnotify.c
+meta sfnotify.o %.c>%.o sfio/sfnotify.c sfnotify
+prev sfio/sfnotify.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfnotify.c
+done sfnotify.o generated
+make sfnputc.o
+make sfio/sfnputc.c
+prev sfio/sfhdr.h implicit
+done sfio/sfnputc.c
+meta sfnputc.o %.c>%.o sfio/sfnputc.c sfnputc
+prev sfio/sfnputc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfnputc.c
+done sfnputc.o generated
+make sfopen.o
+make sfio/sfopen.c
+prev sfio/sfhdr.h implicit
+done sfio/sfopen.c
+meta sfopen.o %.c>%.o sfio/sfopen.c sfopen
+prev sfio/sfopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfopen.c
+done sfopen.o generated
+make sfpeek.o
+make sfio/sfpeek.c
+prev sfio/sfhdr.h implicit
+done sfio/sfpeek.c
+meta sfpeek.o %.c>%.o sfio/sfpeek.c sfpeek
+prev sfio/sfpeek.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfpeek.c
+done sfpeek.o generated
+make sfpoll.o
+make sfio/sfpoll.c
+prev sfio/sfhdr.h implicit
+done sfio/sfpoll.c
+meta sfpoll.o %.c>%.o sfio/sfpoll.c sfpoll
+prev sfio/sfpoll.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfpoll.c
+done sfpoll.o generated
+make sfpool.o
+make sfio/sfpool.c
+prev sfio/sfhdr.h implicit
+done sfio/sfpool.c
+meta sfpool.o %.c>%.o sfio/sfpool.c sfpool
+prev sfio/sfpool.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfpool.c
+done sfpool.o generated
+make sfpopen.o
+make sfio/sfpopen.c
+prev include/proc.h implicit
+prev sfio/sfhdr.h implicit
+done sfio/sfpopen.c
+meta sfpopen.o %.c>%.o sfio/sfpopen.c sfpopen
+prev sfio/sfpopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfpopen.c
+done sfpopen.o generated
+make sfprintf.o
+make sfio/sfprintf.c
+prev sfio/sfhdr.h implicit
+done sfio/sfprintf.c
+meta sfprintf.o %.c>%.o sfio/sfprintf.c sfprintf
+prev sfio/sfprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS.FORCE} ${mam_cc_NOPROTECT} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfprintf.c
+done sfprintf.o generated
+make sfputd.o
+make sfio/sfputd.c
+prev sfio/sfhdr.h implicit
+done sfio/sfputd.c
+meta sfputd.o %.c>%.o sfio/sfputd.c sfputd
+prev sfio/sfputd.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfputd.c
+done sfputd.o generated
+make sfputl.o
+make sfio/sfputl.c
+prev sfio/sfhdr.h implicit
+done sfio/sfputl.c
+meta sfputl.o %.c>%.o sfio/sfputl.c sfputl
+prev sfio/sfputl.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfputl.c
+done sfputl.o generated
+make sfputr.o
+make sfio/sfputr.c
+prev sfio/sfhdr.h implicit
+done sfio/sfputr.c
+meta sfputr.o %.c>%.o sfio/sfputr.c sfputr
+prev sfio/sfputr.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfputr.c
+done sfputr.o generated
+make sfputu.o
+make sfio/sfputu.c
+prev sfio/sfhdr.h implicit
+done sfio/sfputu.c
+meta sfputu.o %.c>%.o sfio/sfputu.c sfputu
+prev sfio/sfputu.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfputu.c
+done sfputu.o generated
+make sfrd.o
+make sfio/sfrd.c
+prev sfio/sfhdr.h implicit
+done sfio/sfrd.c
+meta sfrd.o %.c>%.o sfio/sfrd.c sfrd
+prev sfio/sfrd.c
+exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${DEBUG+-DDEBUG=${DEBUG}} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfrd.c
+done sfrd.o generated
+make sfread.o
+make sfio/sfread.c
+prev sfio/sfhdr.h implicit
+done sfio/sfread.c
+meta sfread.o %.c>%.o sfio/sfread.c sfread
+prev sfio/sfread.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfread.c
+done sfread.o generated
+make sfreserve.o
+make sfio/sfreserve.c
+prev sfio/sfhdr.h implicit
+done sfio/sfreserve.c
+meta sfreserve.o %.c>%.o sfio/sfreserve.c sfreserve
+prev sfio/sfreserve.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfreserve.c
+done sfreserve.o generated
+make sfscanf.o
+make sfio/sfscanf.c
+prev sfio/sfhdr.h implicit
+done sfio/sfscanf.c
+meta sfscanf.o %.c>%.o sfio/sfscanf.c sfscanf
+prev sfio/sfscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS.FORCE} ${mam_cc_NOPROTECT} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfscanf.c
+done sfscanf.o generated
+make sfseek.o
+make sfio/sfseek.c
+prev sfio/sfhdr.h implicit
+done sfio/sfseek.c
+meta sfseek.o %.c>%.o sfio/sfseek.c sfseek
+prev sfio/sfseek.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfseek.c
+done sfseek.o generated
+make sfset.o
+make sfio/sfset.c
+prev sfio/sfhdr.h implicit
+done sfio/sfset.c
+meta sfset.o %.c>%.o sfio/sfset.c sfset
+prev sfio/sfset.c
+exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${DEBUG+-DDEBUG=${DEBUG}} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfset.c
+done sfset.o generated
+make sfsetbuf.o
+make sfio/sfsetbuf.c
+prev sfio/sfhdr.h implicit
+done sfio/sfsetbuf.c
+meta sfsetbuf.o %.c>%.o sfio/sfsetbuf.c sfsetbuf
+prev sfio/sfsetbuf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfsetbuf.c
+done sfsetbuf.o generated
+make sfsetfd.o
+make sfio/sfsetfd.c
+prev sfio/sfhdr.h implicit
+done sfio/sfsetfd.c
+meta sfsetfd.o %.c>%.o sfio/sfsetfd.c sfsetfd
+prev sfio/sfsetfd.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfsetfd.c
+done sfsetfd.o generated
+make sfsize.o
+make sfio/sfsize.c
+prev sfio/sfhdr.h implicit
+done sfio/sfsize.c
+meta sfsize.o %.c>%.o sfio/sfsize.c sfsize
+prev sfio/sfsize.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfsize.c
+done sfsize.o generated
+make sfsk.o
+make sfio/sfsk.c
+prev sfio/sfhdr.h implicit
+done sfio/sfsk.c
+meta sfsk.o %.c>%.o sfio/sfsk.c sfsk
+prev sfio/sfsk.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfsk.c
+done sfsk.o generated
+make sfstack.o
+make sfio/sfstack.c
+prev sfio/sfhdr.h implicit
+done sfio/sfstack.c
+meta sfstack.o %.c>%.o sfio/sfstack.c sfstack
+prev sfio/sfstack.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfstack.c
+done sfstack.o generated
+make sfstrtod.o
+make sfio/sfstrtod.c
+prev sfio/sfhdr.h implicit
+done sfio/sfstrtod.c
+meta sfstrtod.o %.c>%.o sfio/sfstrtod.c sfstrtod
+prev sfio/sfstrtod.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfstrtod.c
+done sfstrtod.o generated
+make sfsync.o
+make sfio/sfsync.c
+prev sfio/sfhdr.h implicit
+done sfio/sfsync.c
+meta sfsync.o %.c>%.o sfio/sfsync.c sfsync
+prev sfio/sfsync.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfsync.c
+done sfsync.o generated
+make sfswap.o
+make sfio/sfswap.c
+prev sfio/sfhdr.h implicit
+done sfio/sfswap.c
+meta sfswap.o %.c>%.o sfio/sfswap.c sfswap
+prev sfio/sfswap.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfswap.c
+done sfswap.o generated
+make sftable.o
+make sfio/sftable.c
+make FEATURE/sfinit implicit
+meta FEATURE/sfinit features/%.c>FEATURE/% features/sfinit.c sfinit
+make features/sfinit.c
+prev FEATURE/float implicit
+prev FEATURE/common implicit
+done features/sfinit.c
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Istd ${LDFLAGS} ' run features/sfinit.c
+done FEATURE/sfinit generated
+prev FEATURE/float implicit
+prev sfio/sfhdr.h implicit
+done sfio/sftable.c
+meta sftable.o %.c>%.o sfio/sftable.c sftable
+prev sfio/sftable.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sftable.c
+done sftable.o generated
+make sftell.o
+make sfio/sftell.c
+prev sfio/sfhdr.h implicit
+done sfio/sftell.c
+meta sftell.o %.c>%.o sfio/sftell.c sftell
+prev sfio/sftell.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sftell.c
+done sftell.o generated
+make sftmp.o
+make sfio/sftmp.c
+prev sfio/sfhdr.h implicit
+done sfio/sftmp.c
+meta sftmp.o %.c>%.o sfio/sftmp.c sftmp
+prev sfio/sftmp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sftmp.c
+done sftmp.o generated
+make sfungetc.o
+make sfio/sfungetc.c
+prev sfio/sfhdr.h implicit
+done sfio/sfungetc.c
+meta sfungetc.o %.c>%.o sfio/sfungetc.c sfungetc
+prev sfio/sfungetc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfungetc.c
+done sfungetc.o generated
+make sfvprintf.o
+make sfio/sfvprintf.c
+prev include/ccode.h implicit
+prev sfio/sfhdr.h implicit
+done sfio/sfvprintf.c
+meta sfvprintf.o %.c>%.o sfio/sfvprintf.c sfvprintf
+prev sfio/sfvprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${mam_cc_NOPROTECT} ${DEBUG+-DDEBUG=${DEBUG}} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfvprintf.c
+done sfvprintf.o generated
+make sfvscanf.o
+make sfio/sfvscanf.c
+prev sfio/sfstrtof.h implicit
+prev sfio/sfhdr.h implicit
+done sfio/sfvscanf.c
+meta sfvscanf.o %.c>%.o sfio/sfvscanf.c sfvscanf
+prev sfio/sfvscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS.FORCE} ${mam_cc_NOPROTECT} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfvscanf.c
+done sfvscanf.o generated
+make sfwr.o
+make sfio/sfwr.c
+prev sfio/sfhdr.h implicit
+done sfio/sfwr.c
+meta sfwr.o %.c>%.o sfio/sfwr.c sfwr
+prev sfio/sfwr.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfwr.c
+done sfwr.o generated
+make sfwrite.o
+make sfio/sfwrite.c
+prev sfio/sfhdr.h implicit
+done sfio/sfwrite.c
+meta sfwrite.o %.c>%.o sfio/sfwrite.c sfwrite
+prev sfio/sfwrite.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfwrite.c
+done sfwrite.o generated
+make sfpurge.o
+make sfio/sfpurge.c
+prev sfio/sfhdr.h implicit
+done sfio/sfpurge.c
+meta sfpurge.o %.c>%.o sfio/sfpurge.c sfpurge
+prev sfio/sfpurge.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfpurge.c
+done sfpurge.o generated
+make sfraise.o
+make sfio/sfraise.c
+prev sfio/sfhdr.h implicit
+done sfio/sfraise.c
+meta sfraise.o %.c>%.o sfio/sfraise.c sfraise
+prev sfio/sfraise.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfraise.c
+done sfraise.o generated
+make sfwalk.o
+make sfio/sfwalk.c
+prev sfio/sfhdr.h implicit
+done sfio/sfwalk.c
+meta sfwalk.o %.c>%.o sfio/sfwalk.c sfwalk
+prev sfio/sfwalk.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfwalk.c
+done sfwalk.o generated
+make sfgetm.o
+make sfio/sfgetm.c
+prev sfio/sfhdr.h implicit
+done sfio/sfgetm.c
+meta sfgetm.o %.c>%.o sfio/sfgetm.c sfgetm
+prev sfio/sfgetm.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfgetm.c
+done sfgetm.o generated
+make sfmutex.o
+make sfio/sfmutex.c
+prev sfio/sfhdr.h implicit
+done sfio/sfmutex.c
+meta sfmutex.o %.c>%.o sfio/sfmutex.c sfmutex
+prev sfio/sfmutex.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfmutex.c
+done sfmutex.o generated
+make sfputm.o
+make sfio/sfputm.c
+prev sfio/sfhdr.h implicit
+done sfio/sfputm.c
+meta sfputm.o %.c>%.o sfio/sfputm.c sfputm
+prev sfio/sfputm.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfputm.c
+done sfputm.o generated
+make sfresize.o
+make sfio/sfresize.c
+prev sfio/sfhdr.h implicit
+done sfio/sfresize.c
+meta sfresize.o %.c>%.o sfio/sfresize.c sfresize
+prev sfio/sfresize.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfresize.c
+done sfresize.o generated
+make _sfclrerr.o
+make sfio/_sfclrerr.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfclrerr.c
+meta _sfclrerr.o %.c>%.o sfio/_sfclrerr.c _sfclrerr
+prev sfio/_sfclrerr.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfclrerr.c
+done _sfclrerr.o generated
+make _sfeof.o
+make sfio/_sfeof.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfeof.c
+meta _sfeof.o %.c>%.o sfio/_sfeof.c _sfeof
+prev sfio/_sfeof.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfeof.c
+done _sfeof.o generated
+make _sferror.o
+make sfio/_sferror.c
+prev sfio/sfhdr.h implicit
+done sfio/_sferror.c
+meta _sferror.o %.c>%.o sfio/_sferror.c _sferror
+prev sfio/_sferror.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sferror.c
+done _sferror.o generated
+make _sffileno.o
+make sfio/_sffileno.c
+prev sfio/sfhdr.h implicit
+done sfio/_sffileno.c
+meta _sffileno.o %.c>%.o sfio/_sffileno.c _sffileno
+prev sfio/_sffileno.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sffileno.c
+done _sffileno.o generated
+make _sfopen.o
+make sfio/_sfopen.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfopen.c
+meta _sfopen.o %.c>%.o sfio/_sfopen.c _sfopen
+prev sfio/_sfopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfopen.c
+done _sfopen.o generated
+make _sfstacked.o
+make sfio/_sfstacked.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfstacked.c
+meta _sfstacked.o %.c>%.o sfio/_sfstacked.c _sfstacked
+prev sfio/_sfstacked.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfstacked.c
+done _sfstacked.o generated
+make _sfvalue.o
+make sfio/_sfvalue.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfvalue.c
+meta _sfvalue.o %.c>%.o sfio/_sfvalue.c _sfvalue
+prev sfio/_sfvalue.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfvalue.c
+done _sfvalue.o generated
+make _sfgetc.o
+make sfio/_sfgetc.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfgetc.c
+meta _sfgetc.o %.c>%.o sfio/_sfgetc.c _sfgetc
+prev sfio/_sfgetc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfgetc.c
+done _sfgetc.o generated
+make _sfgetl.o
+make sfio/_sfgetl.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfgetl.c
+meta _sfgetl.o %.c>%.o sfio/_sfgetl.c _sfgetl
+prev sfio/_sfgetl.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfgetl.c
+done _sfgetl.o generated
+make _sfgetl2.o
+make sfio/_sfgetl2.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfgetl2.c
+meta _sfgetl2.o %.c>%.o sfio/_sfgetl2.c _sfgetl2
+prev sfio/_sfgetl2.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfgetl2.c
+done _sfgetl2.o generated
+make _sfgetu.o
+make sfio/_sfgetu.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfgetu.c
+meta _sfgetu.o %.c>%.o sfio/_sfgetu.c _sfgetu
+prev sfio/_sfgetu.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfgetu.c
+done _sfgetu.o generated
+make _sfgetu2.o
+make sfio/_sfgetu2.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfgetu2.c
+meta _sfgetu2.o %.c>%.o sfio/_sfgetu2.c _sfgetu2
+prev sfio/_sfgetu2.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfgetu2.c
+done _sfgetu2.o generated
+make _sfdlen.o
+make sfio/_sfdlen.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfdlen.c
+meta _sfdlen.o %.c>%.o sfio/_sfdlen.c _sfdlen
+prev sfio/_sfdlen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfdlen.c
+done _sfdlen.o generated
+make _sfllen.o
+make sfio/_sfllen.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfllen.c
+meta _sfllen.o %.c>%.o sfio/_sfllen.c _sfllen
+prev sfio/_sfllen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfllen.c
+done _sfllen.o generated
+make _sfslen.o
+make sfio/_sfslen.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfslen.c
+meta _sfslen.o %.c>%.o sfio/_sfslen.c _sfslen
+prev sfio/_sfslen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfslen.c
+done _sfslen.o generated
+make _sfulen.o
+make sfio/_sfulen.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfulen.c
+meta _sfulen.o %.c>%.o sfio/_sfulen.c _sfulen
+prev sfio/_sfulen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfulen.c
+done _sfulen.o generated
+make _sfputc.o
+make sfio/_sfputc.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfputc.c
+meta _sfputc.o %.c>%.o sfio/_sfputc.c _sfputc
+prev sfio/_sfputc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfputc.c
+done _sfputc.o generated
+make _sfputd.o
+make sfio/_sfputd.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfputd.c
+meta _sfputd.o %.c>%.o sfio/_sfputd.c _sfputd
+prev sfio/_sfputd.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfputd.c
+done _sfputd.o generated
+make _sfputl.o
+make sfio/_sfputl.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfputl.c
+meta _sfputl.o %.c>%.o sfio/_sfputl.c _sfputl
+prev sfio/_sfputl.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfputl.c
+done _sfputl.o generated
+make _sfputm.o
+make sfio/_sfputm.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfputm.c
+meta _sfputm.o %.c>%.o sfio/_sfputm.c _sfputm
+prev sfio/_sfputm.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfputm.c
+done _sfputm.o generated
+make _sfputu.o
+make sfio/_sfputu.c
+prev sfio/sfhdr.h implicit
+done sfio/_sfputu.c
+meta _sfputu.o %.c>%.o sfio/_sfputu.c _sfputu
+prev sfio/_sfputu.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/_sfputu.c
+done _sfputu.o generated
+make clearerr.o
+make stdio/clearerr.c
+make stdio/stdhdr.h implicit
+prev std/stdio.h implicit
+prev sfio/sfhdr.h implicit
+done stdio/stdhdr.h
+done stdio/clearerr.c
+meta clearerr.o %.c>%.o stdio/clearerr.c clearerr
+prev stdio/clearerr.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/clearerr.c
+done clearerr.o generated
+make fclose.o
+make stdio/fclose.c
+prev stdio/stdhdr.h implicit
+done stdio/fclose.c
+meta fclose.o %.c>%.o stdio/fclose.c fclose
+prev stdio/fclose.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fclose.c
+done fclose.o generated
+make fdopen.o
+make stdio/fdopen.c
+prev stdio/stdhdr.h implicit
+done stdio/fdopen.c
+meta fdopen.o %.c>%.o stdio/fdopen.c fdopen
+prev stdio/fdopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fdopen.c
+done fdopen.o generated
+make feof.o
+make stdio/feof.c
+prev stdio/stdhdr.h implicit
+done stdio/feof.c
+meta feof.o %.c>%.o stdio/feof.c feof
+prev stdio/feof.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/feof.c
+done feof.o generated
+make ferror.o
+make stdio/ferror.c
+prev stdio/stdhdr.h implicit
+done stdio/ferror.c
+meta ferror.o %.c>%.o stdio/ferror.c ferror
+prev stdio/ferror.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/ferror.c
+done ferror.o generated
+make fflush.o
+make stdio/fflush.c
+prev stdio/stdhdr.h implicit
+done stdio/fflush.c
+meta fflush.o %.c>%.o stdio/fflush.c fflush
+prev stdio/fflush.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fflush.c
+done fflush.o generated
+make fgetc.o
+make stdio/fgetc.c
+prev stdio/stdhdr.h implicit
+done stdio/fgetc.c
+meta fgetc.o %.c>%.o stdio/fgetc.c fgetc
+prev stdio/fgetc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fgetc.c
+done fgetc.o generated
+make fgetpos.o
+make stdio/fgetpos.c
+prev stdio/stdhdr.h implicit
+done stdio/fgetpos.c
+meta fgetpos.o %.c>%.o stdio/fgetpos.c fgetpos
+prev stdio/fgetpos.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fgetpos.c
+done fgetpos.o generated
+make fgets.o
+make stdio/fgets.c
+prev stdio/stdhdr.h implicit
+done stdio/fgets.c
+meta fgets.o %.c>%.o stdio/fgets.c fgets
+prev stdio/fgets.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fgets.c
+done fgets.o generated
+make fileno.o
+make stdio/fileno.c
+prev stdio/stdhdr.h implicit
+done stdio/fileno.c
+meta fileno.o %.c>%.o stdio/fileno.c fileno
+prev stdio/fileno.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fileno.c
+done fileno.o generated
+make fopen.o
+make stdio/fopen.c
+prev stdio/stdhdr.h implicit
+done stdio/fopen.c
+meta fopen.o %.c>%.o stdio/fopen.c fopen
+prev stdio/fopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fopen.c
+done fopen.o generated
+make fprintf.o
+make stdio/fprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/fprintf.c
+meta fprintf.o %.c>%.o stdio/fprintf.c fprintf
+prev stdio/fprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fprintf.c
+done fprintf.o generated
+make fpurge.o
+make stdio/fpurge.c
+prev stdio/stdhdr.h implicit
+done stdio/fpurge.c
+meta fpurge.o %.c>%.o stdio/fpurge.c fpurge
+prev stdio/fpurge.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fpurge.c
+done fpurge.o generated
+make fputc.o
+make stdio/fputc.c
+prev stdio/stdhdr.h implicit
+done stdio/fputc.c
+meta fputc.o %.c>%.o stdio/fputc.c fputc
+prev stdio/fputc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fputc.c
+done fputc.o generated
+make fputs.o
+make stdio/fputs.c
+prev stdio/stdhdr.h implicit
+done stdio/fputs.c
+meta fputs.o %.c>%.o stdio/fputs.c fputs
+prev stdio/fputs.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fputs.c
+done fputs.o generated
+make fread.o
+make stdio/fread.c
+prev stdio/stdhdr.h implicit
+done stdio/fread.c
+meta fread.o %.c>%.o stdio/fread.c fread
+prev stdio/fread.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fread.c
+done fread.o generated
+make freopen.o
+make stdio/freopen.c
+prev stdio/stdhdr.h implicit
+done stdio/freopen.c
+meta freopen.o %.c>%.o stdio/freopen.c freopen
+prev stdio/freopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/freopen.c
+done freopen.o generated
+make fscanf.o
+make stdio/fscanf.c
+prev stdio/stdhdr.h implicit
+done stdio/fscanf.c
+meta fscanf.o %.c>%.o stdio/fscanf.c fscanf
+prev stdio/fscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fscanf.c
+done fscanf.o generated
+make fseek.o
+make stdio/fseek.c
+prev stdio/stdhdr.h implicit
+done stdio/fseek.c
+meta fseek.o %.c>%.o stdio/fseek.c fseek
+prev stdio/fseek.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fseek.c
+done fseek.o generated
+make fseeko.o
+make stdio/fseeko.c
+prev stdio/stdhdr.h implicit
+done stdio/fseeko.c
+meta fseeko.o %.c>%.o stdio/fseeko.c fseeko
+prev stdio/fseeko.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fseeko.c
+done fseeko.o generated
+make fsetpos.o
+make stdio/fsetpos.c
+prev stdio/stdhdr.h implicit
+done stdio/fsetpos.c
+meta fsetpos.o %.c>%.o stdio/fsetpos.c fsetpos
+prev stdio/fsetpos.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fsetpos.c
+done fsetpos.o generated
+make ftell.o
+make stdio/ftell.c
+prev stdio/stdhdr.h implicit
+done stdio/ftell.c
+meta ftell.o %.c>%.o stdio/ftell.c ftell
+prev stdio/ftell.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/ftell.c
+done ftell.o generated
+make ftello.o
+make stdio/ftello.c
+prev stdio/stdhdr.h implicit
+done stdio/ftello.c
+meta ftello.o %.c>%.o stdio/ftello.c ftello
+prev stdio/ftello.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/ftello.c
+done ftello.o generated
+make fwrite.o
+make stdio/fwrite.c
+prev stdio/stdhdr.h implicit
+done stdio/fwrite.c
+meta fwrite.o %.c>%.o stdio/fwrite.c fwrite
+prev stdio/fwrite.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fwrite.c
+done fwrite.o generated
+make flockfile.o
+make stdio/flockfile.c
+prev stdio/stdhdr.h implicit
+done stdio/flockfile.c
+meta flockfile.o %.c>%.o stdio/flockfile.c flockfile
+prev stdio/flockfile.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/flockfile.c
+done flockfile.o generated
+make ftrylockfile.o
+make stdio/ftrylockfile.c
+prev stdio/stdhdr.h implicit
+done stdio/ftrylockfile.c
+meta ftrylockfile.o %.c>%.o stdio/ftrylockfile.c ftrylockfile
+prev stdio/ftrylockfile.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/ftrylockfile.c
+done ftrylockfile.o generated
+make funlockfile.o
+make stdio/funlockfile.c
+prev stdio/stdhdr.h implicit
+done stdio/funlockfile.c
+meta funlockfile.o %.c>%.o stdio/funlockfile.c funlockfile
+prev stdio/funlockfile.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/funlockfile.c
+done funlockfile.o generated
+make getc.o
+make stdio/getc.c
+prev stdio/stdhdr.h implicit
+done stdio/getc.c
+meta getc.o %.c>%.o stdio/getc.c getc
+prev stdio/getc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/getc.c
+done getc.o generated
+make getchar.o
+make stdio/getchar.c
+prev stdio/stdhdr.h implicit
+done stdio/getchar.c
+meta getchar.o %.c>%.o stdio/getchar.c getchar
+prev stdio/getchar.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/getchar.c
+done getchar.o generated
+make getw.o
+make stdio/getw.c
+prev stdio/stdhdr.h implicit
+done stdio/getw.c
+meta getw.o %.c>%.o stdio/getw.c getw
+prev stdio/getw.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/getw.c
+done getw.o generated
+make pclose.o
+make stdio/pclose.c
+prev stdio/stdhdr.h implicit
+done stdio/pclose.c
+meta pclose.o %.c>%.o stdio/pclose.c pclose
+prev stdio/pclose.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/pclose.c
+done pclose.o generated
+make popen.o
+make stdio/popen.c
+prev stdio/stdhdr.h implicit
+done stdio/popen.c
+meta popen.o %.c>%.o stdio/popen.c popen
+prev stdio/popen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/popen.c
+done popen.o generated
+make printf.o
+make stdio/printf.c
+prev stdio/stdhdr.h implicit
+done stdio/printf.c
+meta printf.o %.c>%.o stdio/printf.c printf
+prev stdio/printf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/printf.c
+done printf.o generated
+make putc.o
+make stdio/putc.c
+prev stdio/stdhdr.h implicit
+done stdio/putc.c
+meta putc.o %.c>%.o stdio/putc.c putc
+prev stdio/putc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/putc.c
+done putc.o generated
+make putchar.o
+make stdio/putchar.c
+prev stdio/stdhdr.h implicit
+done stdio/putchar.c
+meta putchar.o %.c>%.o stdio/putchar.c putchar
+prev stdio/putchar.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/putchar.c
+done putchar.o generated
+make puts.o
+make stdio/puts.c
+prev stdio/stdhdr.h implicit
+done stdio/puts.c
+meta puts.o %.c>%.o stdio/puts.c puts
+prev stdio/puts.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/puts.c
+done puts.o generated
+make putw.o
+make stdio/putw.c
+prev stdio/stdhdr.h implicit
+done stdio/putw.c
+meta putw.o %.c>%.o stdio/putw.c putw
+prev stdio/putw.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/putw.c
+done putw.o generated
+make rewind.o
+make stdio/rewind.c
+prev stdio/stdhdr.h implicit
+done stdio/rewind.c
+meta rewind.o %.c>%.o stdio/rewind.c rewind
+prev stdio/rewind.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/rewind.c
+done rewind.o generated
+make scanf.o
+make stdio/scanf.c
+prev stdio/stdhdr.h implicit
+done stdio/scanf.c
+meta scanf.o %.c>%.o stdio/scanf.c scanf
+prev stdio/scanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/scanf.c
+done scanf.o generated
+make setbuf.o
+make stdio/setbuf.c
+prev stdio/stdhdr.h implicit
+done stdio/setbuf.c
+meta setbuf.o %.c>%.o stdio/setbuf.c setbuf
+prev stdio/setbuf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/setbuf.c
+done setbuf.o generated
+make setbuffer.o
+make stdio/setbuffer.c
+prev stdio/stdhdr.h implicit
+done stdio/setbuffer.c
+meta setbuffer.o %.c>%.o stdio/setbuffer.c setbuffer
+prev stdio/setbuffer.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/setbuffer.c
+done setbuffer.o generated
+make setlinebuf.o
+make stdio/setlinebuf.c
+prev stdio/stdhdr.h implicit
+done stdio/setlinebuf.c
+meta setlinebuf.o %.c>%.o stdio/setlinebuf.c setlinebuf
+prev stdio/setlinebuf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/setlinebuf.c
+done setlinebuf.o generated
+make setvbuf.o
+make stdio/setvbuf.c
+prev stdio/stdhdr.h implicit
+done stdio/setvbuf.c
+meta setvbuf.o %.c>%.o stdio/setvbuf.c setvbuf
+prev stdio/setvbuf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/setvbuf.c
+done setvbuf.o generated
+make snprintf.o
+make stdio/snprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/snprintf.c
+meta snprintf.o %.c>%.o stdio/snprintf.c snprintf
+prev stdio/snprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/snprintf.c
+done snprintf.o generated
+make sprintf.o
+make stdio/sprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/sprintf.c
+meta sprintf.o %.c>%.o stdio/sprintf.c sprintf
+prev stdio/sprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/sprintf.c
+done sprintf.o generated
+make sscanf.o
+make stdio/sscanf.c
+prev stdio/stdhdr.h implicit
+done stdio/sscanf.c
+meta sscanf.o %.c>%.o stdio/sscanf.c sscanf
+prev stdio/sscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/sscanf.c
+done sscanf.o generated
+make asprintf.o
+make stdio/asprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/asprintf.c
+meta asprintf.o %.c>%.o stdio/asprintf.c asprintf
+prev stdio/asprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/asprintf.c
+done asprintf.o generated
+make vasprintf.o
+make stdio/vasprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/vasprintf.c
+meta vasprintf.o %.c>%.o stdio/vasprintf.c vasprintf
+prev stdio/vasprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/vasprintf.c
+done vasprintf.o generated
+make tmpfile.o
+make stdio/tmpfile.c
+prev stdio/stdhdr.h implicit
+done stdio/tmpfile.c
+meta tmpfile.o %.c>%.o stdio/tmpfile.c tmpfile
+prev stdio/tmpfile.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/tmpfile.c
+done tmpfile.o generated
+make ungetc.o
+make stdio/ungetc.c
+prev stdio/stdhdr.h implicit
+done stdio/ungetc.c
+meta ungetc.o %.c>%.o stdio/ungetc.c ungetc
+prev stdio/ungetc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/ungetc.c
+done ungetc.o generated
+make vfprintf.o
+make stdio/vfprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/vfprintf.c
+meta vfprintf.o %.c>%.o stdio/vfprintf.c vfprintf
+prev stdio/vfprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/vfprintf.c
+done vfprintf.o generated
+make vfscanf.o
+make stdio/vfscanf.c
+prev stdio/stdhdr.h implicit
+done stdio/vfscanf.c
+meta vfscanf.o %.c>%.o stdio/vfscanf.c vfscanf
+prev stdio/vfscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/vfscanf.c
+done vfscanf.o generated
+make vprintf.o
+make stdio/vprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/vprintf.c
+meta vprintf.o %.c>%.o stdio/vprintf.c vprintf
+prev stdio/vprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/vprintf.c
+done vprintf.o generated
+make vscanf.o
+make stdio/vscanf.c
+prev stdio/stdhdr.h implicit
+done stdio/vscanf.c
+meta vscanf.o %.c>%.o stdio/vscanf.c vscanf
+prev stdio/vscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/vscanf.c
+done vscanf.o generated
+make vsnprintf.o
+make stdio/vsnprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/vsnprintf.c
+meta vsnprintf.o %.c>%.o stdio/vsnprintf.c vsnprintf
+prev stdio/vsnprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/vsnprintf.c
+done vsnprintf.o generated
+make vsprintf.o
+make stdio/vsprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/vsprintf.c
+meta vsprintf.o %.c>%.o stdio/vsprintf.c vsprintf
+prev stdio/vsprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/vsprintf.c
+done vsprintf.o generated
+make vsscanf.o
+make stdio/vsscanf.c
+prev stdio/stdhdr.h implicit
+done stdio/vsscanf.c
+meta vsscanf.o %.c>%.o stdio/vsscanf.c vsscanf
+prev stdio/vsscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/vsscanf.c
+done vsscanf.o generated
+make _doprnt.o
+make stdio/_doprnt.c
+prev stdio/stdhdr.h implicit
+done stdio/_doprnt.c
+meta _doprnt.o %.c>%.o stdio/_doprnt.c _doprnt
+prev stdio/_doprnt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/_doprnt.c
+done _doprnt.o generated
+make _doscan.o
+make stdio/_doscan.c
+prev stdio/stdhdr.h implicit
+done stdio/_doscan.c
+meta _doscan.o %.c>%.o stdio/_doscan.c _doscan
+prev stdio/_doscan.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/_doscan.c
+done _doscan.o generated
+make _filbuf.o
+make stdio/_filbuf.c
+prev stdio/stdhdr.h implicit
+done stdio/_filbuf.c
+meta _filbuf.o %.c>%.o stdio/_filbuf.c _filbuf
+prev stdio/_filbuf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/_filbuf.c
+done _filbuf.o generated
+make _flsbuf.o
+make stdio/_flsbuf.c
+prev stdio/stdhdr.h implicit
+done stdio/_flsbuf.c
+meta _flsbuf.o %.c>%.o stdio/_flsbuf.c _flsbuf
+prev stdio/_flsbuf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/_flsbuf.c
+done _flsbuf.o generated
+make _stdfun.o
+make stdio/_stdfun.c
+prev stdio/stdhdr.h implicit
+make FEATURE/uwin implicit
+meta FEATURE/uwin features/%>FEATURE/% features/uwin uwin
+make features/uwin
+done features/uwin
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/uwin
+done FEATURE/uwin dontcare generated
+prev uwin.h implicit
+prev include/ast_windows.h implicit
+prev include/ast.h implicit
+done stdio/_stdfun.c
+meta _stdfun.o %.c>%.o stdio/_stdfun.c _stdfun
+prev stdio/_stdfun.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/_stdfun.c
+done _stdfun.o generated
+make _stdopen.o
+make stdio/_stdopen.c
+prev stdio/stdhdr.h implicit
+done stdio/_stdopen.c
+meta _stdopen.o %.c>%.o stdio/_stdopen.c _stdopen
+prev stdio/_stdopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/_stdopen.c
+done _stdopen.o generated
+make _stdprintf.o
+make stdio/_stdprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/_stdprintf.c
+meta _stdprintf.o %.c>%.o stdio/_stdprintf.c _stdprintf
+prev stdio/_stdprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/_stdprintf.c
+done _stdprintf.o generated
+make _stdscanf.o
+make stdio/_stdscanf.c
+prev stdio/stdhdr.h implicit
+done stdio/_stdscanf.c
+meta _stdscanf.o %.c>%.o stdio/_stdscanf.c _stdscanf
+prev stdio/_stdscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/_stdscanf.c
+done _stdscanf.o generated
+make _stdsprnt.o
+make stdio/_stdsprnt.c
+prev stdio/stdhdr.h implicit
+done stdio/_stdsprnt.c
+meta _stdsprnt.o %.c>%.o stdio/_stdsprnt.c _stdsprnt
+prev stdio/_stdsprnt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/_stdsprnt.c
+done _stdsprnt.o generated
+make _stdvbuf.o
+make stdio/_stdvbuf.c
+prev stdio/stdhdr.h implicit
+done stdio/_stdvbuf.c
+meta _stdvbuf.o %.c>%.o stdio/_stdvbuf.c _stdvbuf
+prev stdio/_stdvbuf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/_stdvbuf.c
+done _stdvbuf.o generated
+make _stdvsnprnt.o
+make stdio/_stdvsnprnt.c
+prev stdio/stdhdr.h implicit
+done stdio/_stdvsnprnt.c
+meta _stdvsnprnt.o %.c>%.o stdio/_stdvsnprnt.c _stdvsnprnt
+prev stdio/_stdvsnprnt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/_stdvsnprnt.c
+done _stdvsnprnt.o generated
+make _stdvsprnt.o
+make stdio/_stdvsprnt.c
+prev stdio/stdhdr.h implicit
+done stdio/_stdvsprnt.c
+meta _stdvsprnt.o %.c>%.o stdio/_stdvsprnt.c _stdvsprnt
+prev stdio/_stdvsprnt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/_stdvsprnt.c
+done _stdvsprnt.o generated
+make _stdvsscn.o
+make stdio/_stdvsscn.c
+prev stdio/stdhdr.h implicit
+done stdio/_stdvsscn.c
+meta _stdvsscn.o %.c>%.o stdio/_stdvsscn.c _stdvsscn
+prev stdio/_stdvsscn.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/_stdvsscn.c
+done _stdvsscn.o generated
+make fgetwc.o
+make stdio/fgetwc.c
+prev stdio/stdhdr.h implicit
+done stdio/fgetwc.c
+meta fgetwc.o %.c>%.o stdio/fgetwc.c fgetwc
+prev stdio/fgetwc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fgetwc.c
+done fgetwc.o generated
+make fwprintf.o
+make stdio/fwprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/fwprintf.c
+meta fwprintf.o %.c>%.o stdio/fwprintf.c fwprintf
+prev stdio/fwprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fwprintf.c
+done fwprintf.o generated
+make putwchar.o
+make stdio/putwchar.c
+prev ast_wchar.h implicit
+prev stdio/stdhdr.h implicit
+done stdio/putwchar.c
+meta putwchar.o %.c>%.o stdio/putwchar.c putwchar
+prev stdio/putwchar.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/putwchar.c
+done putwchar.o generated
+make vfwscanf.o
+make stdio/vfwscanf.c
+prev stdio/stdhdr.h implicit
+done stdio/vfwscanf.c
+meta vfwscanf.o %.c>%.o stdio/vfwscanf.c vfwscanf
+prev stdio/vfwscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/vfwscanf.c
+done vfwscanf.o generated
+make wprintf.o
+make stdio/wprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/wprintf.c
+meta wprintf.o %.c>%.o stdio/wprintf.c wprintf
+prev stdio/wprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/wprintf.c
+done wprintf.o generated
+make fgetws.o
+make stdio/fgetws.c
+prev stdio/stdhdr.h implicit
+done stdio/fgetws.c
+meta fgetws.o %.c>%.o stdio/fgetws.c fgetws
+prev stdio/fgetws.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fgetws.c
+done fgetws.o generated
+make fwscanf.o
+make stdio/fwscanf.c
+prev stdio/stdhdr.h implicit
+done stdio/fwscanf.c
+meta fwscanf.o %.c>%.o stdio/fwscanf.c fwscanf
+prev stdio/fwscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fwscanf.c
+done fwscanf.o generated
+make swprintf.o
+make stdio/swprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/swprintf.c
+meta swprintf.o %.c>%.o stdio/swprintf.c swprintf
+prev stdio/swprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/swprintf.c
+done swprintf.o generated
+make vswprintf.o
+make stdio/vswprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/vswprintf.c
+meta vswprintf.o %.c>%.o stdio/vswprintf.c vswprintf
+prev stdio/vswprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/vswprintf.c
+done vswprintf.o generated
+make wscanf.o
+make stdio/wscanf.c
+prev stdio/stdhdr.h implicit
+done stdio/wscanf.c
+meta wscanf.o %.c>%.o stdio/wscanf.c wscanf
+prev stdio/wscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/wscanf.c
+done wscanf.o generated
+make fputwc.o
+make stdio/fputwc.c
+prev stdio/stdhdr.h implicit
+done stdio/fputwc.c
+meta fputwc.o %.c>%.o stdio/fputwc.c fputwc
+prev stdio/fputwc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fputwc.c
+done fputwc.o generated
+make getwc.o
+make stdio/getwc.c
+prev ast_wchar.h implicit
+prev stdio/stdhdr.h implicit
+done stdio/getwc.c
+meta getwc.o %.c>%.o stdio/getwc.c getwc
+prev stdio/getwc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/getwc.c
+done getwc.o generated
+make swscanf.o
+make stdio/swscanf.c
+prev stdio/stdhdr.h implicit
+done stdio/swscanf.c
+meta swscanf.o %.c>%.o stdio/swscanf.c swscanf
+prev stdio/swscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/swscanf.c
+done swscanf.o generated
+make vswscanf.o
+make stdio/vswscanf.c
+prev stdio/stdhdr.h implicit
+done stdio/vswscanf.c
+meta vswscanf.o %.c>%.o stdio/vswscanf.c vswscanf
+prev stdio/vswscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/vswscanf.c
+done vswscanf.o generated
+make fputws.o
+make stdio/fputws.c
+prev stdio/stdhdr.h implicit
+done stdio/fputws.c
+meta fputws.o %.c>%.o stdio/fputws.c fputws
+prev stdio/fputws.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fputws.c
+done fputws.o generated
+make getwchar.o
+make stdio/getwchar.c
+prev ast_wchar.h implicit
+prev stdio/stdhdr.h implicit
+done stdio/getwchar.c
+meta getwchar.o %.c>%.o stdio/getwchar.c getwchar
+prev stdio/getwchar.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/getwchar.c
+done getwchar.o generated
+make ungetwc.o
+make stdio/ungetwc.c
+prev stdio/stdhdr.h implicit
+done stdio/ungetwc.c
+meta ungetwc.o %.c>%.o stdio/ungetwc.c ungetwc
+prev stdio/ungetwc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/ungetwc.c
+done ungetwc.o generated
+make vwprintf.o
+make stdio/vwprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/vwprintf.c
+meta vwprintf.o %.c>%.o stdio/vwprintf.c vwprintf
+prev stdio/vwprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/vwprintf.c
+done vwprintf.o generated
+make fwide.o
+make stdio/fwide.c
+prev stdio/stdhdr.h implicit
+done stdio/fwide.c
+meta fwide.o %.c>%.o stdio/fwide.c fwide
+prev stdio/fwide.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fwide.c
+done fwide.o generated
+make putwc.o
+make stdio/putwc.c
+prev ast_wchar.h implicit
+prev stdio/stdhdr.h implicit
+done stdio/putwc.c
+meta putwc.o %.c>%.o stdio/putwc.c putwc
+prev stdio/putwc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/putwc.c
+done putwc.o generated
+make vfwprintf.o
+make stdio/vfwprintf.c
+prev stdio/stdhdr.h implicit
+done stdio/vfwprintf.c
+meta vfwprintf.o %.c>%.o stdio/vfwprintf.c vfwprintf
+prev stdio/vfwprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/vfwprintf.c
+done vfwprintf.o generated
+make vwscanf.o
+make stdio/vwscanf.c
+prev stdio/stdhdr.h implicit
+done stdio/vwscanf.c
+meta vwscanf.o %.c>%.o stdio/vwscanf.c vwscanf
+prev stdio/vwscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/vwscanf.c
+done vwscanf.o generated
+make stdio_c99.o
+make stdio/stdio_c99.c
+prev stdio/stdhdr.h implicit
+done stdio/stdio_c99.c
+meta stdio_c99.o %.c>%.o stdio/stdio_c99.c stdio_c99
+prev stdio/stdio_c99.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/stdio_c99.c
+done stdio_c99.o generated
+make fcloseall.o
+make stdio/fcloseall.c
+prev stdio/stdhdr.h implicit
+done stdio/fcloseall.c
+meta fcloseall.o %.c>%.o stdio/fcloseall.c fcloseall
+prev stdio/fcloseall.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fcloseall.c
+done fcloseall.o generated
+make fmemopen.o
+make stdio/fmemopen.c
+prev stdio/stdhdr.h implicit
+done stdio/fmemopen.c
+meta fmemopen.o %.c>%.o stdio/fmemopen.c fmemopen
+prev stdio/fmemopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/fmemopen.c
+done fmemopen.o generated
+make getdelim.o
+make stdio/getdelim.c
+prev stdio/stdhdr.h implicit
+done stdio/getdelim.c
+meta getdelim.o %.c>%.o stdio/getdelim.c getdelim
+prev stdio/getdelim.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/getdelim.c
+done getdelim.o generated
+make getline.o
+make stdio/getline.c
+prev stdio/stdhdr.h implicit
+done stdio/getline.c
+meta getline.o %.c>%.o stdio/getline.c getline
+prev stdio/getline.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Istdio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c stdio/getline.c
+done getline.o generated
+make frexp.o
+make comp/frexp.c
+prev FEATURE/float implicit
+prev include/ast.h implicit
+done comp/frexp.c
+meta frexp.o %.c>%.o comp/frexp.c frexp
+prev comp/frexp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/frexp.c
+done frexp.o generated
+make frexpl.o
+make comp/frexpl.c
+prev FEATURE/float implicit
+prev include/ast.h implicit
+done comp/frexpl.c
+meta frexpl.o %.c>%.o comp/frexpl.c frexpl
+prev comp/frexpl.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/frexpl.c
+done frexpl.o generated
+make astcopy.o
+make port/astcopy.c
+prev include/ls.h implicit
+make ast_mmap.h implicit
+prev FEATURE/mmap
+exec - cmp 2>/dev/null -s FEATURE/mmap ast_mmap.h || { rm -f ast_mmap.h; silent test -d . || mkdir .; ${STDCP} FEATURE/mmap ast_mmap.h; }
+done ast_mmap.h generated
+prev include/ast.h implicit
+done port/astcopy.c
+meta astcopy.o %.c>%.o port/astcopy.c astcopy
+prev port/astcopy.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c port/astcopy.c
+done astcopy.o generated
+make astconf.o
+make port/astconf.c
+make FEATURE/libpath implicit
+meta FEATURE/libpath features/%.sh>FEATURE/% features/libpath.sh libpath
+make features/libpath.sh
+done features/libpath.sh
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/libpath.sh
+done FEATURE/libpath generated
+make conftab.h implicit
+done conftab.h
+prev include/ls.h implicit
+prev include/proc.h implicit
+prev include/regex.h implicit
+prev include/fs3d.h implicit
+prev include/error.h implicit
+prev include/ast.h implicit
+prev misc/univlib.h implicit
+done port/astconf.c
+meta astconf.o %.c>%.o port/astconf.c astconf
+prev port/astconf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Imisc -Iinclude -Istd -D__OBSOLETE__=20110101 -DCONF_LIBSUFFIX=\""${mam_cc_SUFFIX_DYNAMIC-${mam_cc_SUFFIX_SHARED}}"\" -DCONF_LIBPREFIX=\""${mam_cc_PREFIX_DYNAMIC-${mam_cc_PREFIX_SHARED}}"\" -DHOSTTYPE=\""${mam_cc_HOSTTYPE}"\" -D_PACKAGE_ast -c port/astconf.c
+done astconf.o generated
+make astdynamic.o
+make port/astdynamic.c
+prev sfio/sfhdr.h implicit
+prev include/ast_windows.h implicit
+prev include/ast.h implicit
+prev include/sfio_t.h implicit
+done port/astdynamic.c
+meta astdynamic.o %.c>%.o port/astdynamic.c astdynamic
+prev port/astdynamic.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c port/astdynamic.c
+done astdynamic.o generated
+make astlicense.o
+make port/astlicense.c
+prev include/ast.h implicit
+done port/astlicense.c
+meta astlicense.o %.c>%.o port/astlicense.c astlicense
+prev port/astlicense.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c port/astlicense.c
+done astlicense.o generated
+make astquery.o
+make port/astquery.c
+prev include/error.h implicit
+prev include/ast.h implicit
+done port/astquery.c
+meta astquery.o %.c>%.o port/astquery.c astquery
+prev port/astquery.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c port/astquery.c
+done astquery.o generated
+make astwinsize.o
+make port/astwinsize.c
+make jioctl.h implicit
+done jioctl.h dontcare virtual
+prev ast_tty.h implicit
+prev include/ast.h implicit
+done port/astwinsize.c
+meta astwinsize.o %.c>%.o port/astwinsize.c astwinsize
+prev port/astwinsize.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c port/astwinsize.c
+done astwinsize.o generated
+make conftab.o
+make conftab.c
+prev conftab.h implicit
+prev FEATURE/param implicit
+prev FEATURE/common implicit
+prev FEATURE/standards implicit
+done conftab.c
+meta conftab.o %.c>%.o conftab.c conftab
+prev conftab.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -c conftab.c
+done conftab.o generated
+make aststatic.o
+make port/aststatic.c
+prev include/ast.h implicit
+done port/aststatic.c
+meta aststatic.o %.c>%.o port/aststatic.c aststatic
+prev port/aststatic.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c port/aststatic.c
+done aststatic.o generated
+make getopt.o
+make comp/getopt.c
+prev include/option.h implicit
+prev include/error.h implicit
+prev include/ast.h implicit
+done comp/getopt.c
+meta getopt.o %.c>%.o comp/getopt.c getopt
+prev comp/getopt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/getopt.c
+done getopt.o generated
+make getoptl.o
+make comp/getoptl.c
+prev comp/getopt.h implicit
+prev include/option.h implicit
+prev include/error.h implicit
+prev include/ast_getopt.h implicit
+prev include/ast.h implicit
+done comp/getoptl.c
+meta getoptl.o %.c>%.o comp/getoptl.c getoptl
+prev comp/getoptl.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/getoptl.c
+done getoptl.o generated
+make aso.o
+make aso/aso.c
+prev std/stdio.h implicit
+make aso/asohdr.h implicit
+prev include/aso.h implicit
+prev FEATURE/aso implicit
+make include/fnv.h implicit
+prev ast_common.h implicit
+done include/fnv.h dontcare
+prev include/error.h implicit
+prev include/ast.h implicit
+done aso/asohdr.h
+done aso/aso.c
+meta aso.o %.c>%.o aso/aso.c aso
+prev aso/aso.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iaso -Icomp -Iinclude -Istd -D_PACKAGE_ast -c aso/aso.c
+done aso.o generated
+make asolock.o
+make aso/asolock.c
+prev aso/asohdr.h implicit
+done aso/asolock.c
+meta asolock.o %.c>%.o aso/asolock.c asolock
+prev aso/asolock.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iaso -Icomp -Iinclude -Istd -D_PACKAGE_ast -c aso/asolock.c
+done asolock.o generated
+make asometh.o
+make aso/asometh.c
+prev aso/asohdr.h implicit
+done aso/asometh.c
+meta asometh.o %.c>%.o aso/asometh.c asometh
+prev aso/asometh.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iaso -Icomp -Iinclude -Istd -D_PACKAGE_ast -c aso/asometh.c
+done asometh.o generated
+make asorelax.o
+make aso/asorelax.c
+prev tv.h implicit
+prev aso/asohdr.h implicit
+done aso/asorelax.c
+meta asorelax.o %.c>%.o aso/asorelax.c asorelax
+prev aso/asorelax.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iaso -Icomp -Iinclude -Istd -D_PACKAGE_ast -c aso/asorelax.c
+done asorelax.o generated
+make aso-sem.o
+make aso/aso-sem.c
+prev aso/asohdr.h implicit
+done aso/aso-sem.c
+meta aso-sem.o %.c>%.o aso/aso-sem.c aso-sem
+prev aso/aso-sem.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iaso -Icomp -Iinclude -Istd -D_PACKAGE_ast -c aso/aso-sem.c
+done aso-sem.o generated
+make aso-fcntl.o
+make aso/aso-fcntl.c
+prev aso/asohdr.h implicit
+done aso/aso-fcntl.c
+meta aso-fcntl.o %.c>%.o aso/aso-fcntl.c aso-fcntl
+prev aso/aso-fcntl.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iaso -Icomp -Iinclude -Istd -D_PACKAGE_ast -c aso/aso-fcntl.c
+done aso-fcntl.o generated
+make vmbest.o
+make vmalloc/vmbest.c
+prev windows.h implicit
+prev include/ast_windows.h implicit
+make vmalloc/vmhdr.h implicit
+prev include/vmalloc.h implicit
+prev include/ast_windows.h implicit
+prev include/aso.h implicit
+prev FEATURE/vmalloc implicit
+prev ast_common.h implicit
+prev include/ast.h implicit
+done vmalloc/vmhdr.h dontcare
+done vmalloc/vmbest.c
+meta vmbest.o %.c>%.o vmalloc/vmbest.c vmbest
+prev vmalloc/vmbest.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmbest.c
+done vmbest.o generated
+make vmclear.o
+make vmalloc/vmclear.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmclear.c
+meta vmclear.o %.c>%.o vmalloc/vmclear.c vmclear
+prev vmalloc/vmclear.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmclear.c
+done vmclear.o generated
+make vmclose.o
+make vmalloc/vmclose.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmclose.c
+meta vmclose.o %.c>%.o vmalloc/vmclose.c vmclose
+prev vmalloc/vmclose.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmclose.c
+done vmclose.o generated
+make vmdcheap.o
+make vmalloc/vmdcheap.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmdcheap.c
+meta vmdcheap.o %.c>%.o vmalloc/vmdcheap.c vmdcheap
+prev vmalloc/vmdcheap.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmdcheap.c
+done vmdcheap.o generated
+make vmdebug.o
+make vmalloc/vmdebug.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmdebug.c
+meta vmdebug.o %.c>%.o vmalloc/vmdebug.c vmdebug
+prev vmalloc/vmdebug.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmdebug.c
+done vmdebug.o generated
+make vmdisc.o
+make vmalloc/vmdisc.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmdisc.c
+meta vmdisc.o %.c>%.o vmalloc/vmdisc.c vmdisc
+prev vmalloc/vmdisc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmdisc.c
+done vmdisc.o generated
+make vmexit.o
+make vmalloc/vmexit.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmexit.c
+meta vmexit.o %.c>%.o vmalloc/vmexit.c vmexit
+prev vmalloc/vmexit.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmexit.c
+done vmexit.o generated
+make vmlast.o
+make vmalloc/vmlast.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmlast.c
+meta vmlast.o %.c>%.o vmalloc/vmlast.c vmlast
+prev vmalloc/vmlast.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmlast.c
+done vmlast.o generated
+make vmopen.o
+make vmalloc/vmopen.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmopen.c
+meta vmopen.o %.c>%.o vmalloc/vmopen.c vmopen
+prev vmalloc/vmopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmopen.c
+done vmopen.o generated
+make vmpool.o
+make vmalloc/vmpool.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmpool.c
+meta vmpool.o %.c>%.o vmalloc/vmpool.c vmpool
+prev vmalloc/vmpool.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmpool.c
+done vmpool.o generated
+make vmprivate.o
+make vmalloc/vmprivate.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmprivate.c
+meta vmprivate.o %.c>%.o vmalloc/vmprivate.c vmprivate
+prev vmalloc/vmprivate.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmprivate.c
+done vmprivate.o generated
+make vmprofile.o
+make vmalloc/vmprofile.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmprofile.c
+meta vmprofile.o %.c>%.o vmalloc/vmprofile.c vmprofile
+prev vmalloc/vmprofile.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmprofile.c
+done vmprofile.o generated
+make vmregion.o
+make vmalloc/vmregion.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmregion.c
+meta vmregion.o %.c>%.o vmalloc/vmregion.c vmregion
+prev vmalloc/vmregion.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmregion.c
+done vmregion.o generated
+make vmsegment.o
+make vmalloc/vmsegment.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmsegment.c
+meta vmsegment.o %.c>%.o vmalloc/vmsegment.c vmsegment
+prev vmalloc/vmsegment.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmsegment.c
+done vmsegment.o generated
+make vmset.o
+make vmalloc/vmset.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmset.c
+meta vmset.o %.c>%.o vmalloc/vmset.c vmset
+prev vmalloc/vmset.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmset.c
+done vmset.o generated
+make vmstat.o
+make vmalloc/vmstat.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmstat.c
+meta vmstat.o %.c>%.o vmalloc/vmstat.c vmstat
+prev vmalloc/vmstat.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmstat.c
+done vmstat.o generated
+make vmstrdup.o
+make vmalloc/vmstrdup.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmstrdup.c
+meta vmstrdup.o %.c>%.o vmalloc/vmstrdup.c vmstrdup
+prev vmalloc/vmstrdup.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmstrdup.c
+done vmstrdup.o generated
+make vmtrace.o
+make vmalloc/vmtrace.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmtrace.c
+meta vmtrace.o %.c>%.o vmalloc/vmtrace.c vmtrace
+prev vmalloc/vmtrace.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmtrace.c
+done vmtrace.o generated
+make vmwalk.o
+make vmalloc/vmwalk.c
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmwalk.c
+meta vmwalk.o %.c>%.o vmalloc/vmwalk.c vmwalk
+prev vmalloc/vmwalk.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmwalk.c
+done vmwalk.o generated
+make vmmopen.o
+make vmalloc/vmmopen.c
+prev std/stdio.h implicit
+prev vmalloc/vmhdr.h implicit
+done vmalloc/vmmopen.c
+meta vmmopen.o %.c>%.o vmalloc/vmmopen.c vmmopen
+prev vmalloc/vmmopen.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmmopen.c
+done vmmopen.o generated
+make malloc.o
+make vmalloc/malloc.c
+prev include/ast_windows.h implicit
+prev vmalloc/vmhdr.h implicit
+done vmalloc/malloc.c
+meta malloc.o %.c>%.o vmalloc/malloc.c malloc
+prev vmalloc/malloc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Ivmalloc -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/malloc.c
+done malloc.o generated
+make vmgetmem.o
+make vmalloc/vmgetmem.c
+prev include/vmalloc.h implicit
+done vmalloc/vmgetmem.c
+meta vmgetmem.o %.c>%.o vmalloc/vmgetmem.c vmgetmem
+prev vmalloc/vmgetmem.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c vmalloc/vmgetmem.c
+done vmgetmem.o generated
+make a64l.o
+make uwin/a64l.c
+prev FEATURE/uwin implicit
+done uwin/a64l.c
+meta a64l.o %.c>%.o uwin/a64l.c a64l
+prev uwin/a64l.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Istd -c uwin/a64l.c
+done a64l.o generated
+make acosh.o
+make uwin/acosh.c
+make uwin/mathimpl.h implicit
+done uwin/mathimpl.h dontcare
+prev FEATURE/uwin implicit
+done uwin/acosh.c
+meta acosh.o %.c>%.o uwin/acosh.c acosh
+prev uwin/acosh.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iuwin -Istd -c uwin/acosh.c
+done acosh.o generated
+make asinh.o
+make uwin/asinh.c
+prev uwin/mathimpl.h implicit
+prev FEATURE/uwin implicit
+done uwin/asinh.c
+meta asinh.o %.c>%.o uwin/asinh.c asinh
+prev uwin/asinh.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iuwin -Istd -c uwin/asinh.c
+done asinh.o generated
+make atanh.o
+make uwin/atanh.c
+prev uwin/mathimpl.h implicit
+prev FEATURE/uwin implicit
+done uwin/atanh.c
+meta atanh.o %.c>%.o uwin/atanh.c atanh
+prev uwin/atanh.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iuwin -Istd -c uwin/atanh.c
+done atanh.o generated
+make cbrt.o
+make uwin/cbrt.c
+prev uwin/mathimpl.h implicit
+prev FEATURE/uwin implicit
+done uwin/cbrt.c
+meta cbrt.o %.c>%.o uwin/cbrt.c cbrt
+prev uwin/cbrt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iuwin -Istd -c uwin/cbrt.c
+done cbrt.o generated
+make crypt.o
+make uwin/crypt.c
+prev std/stdio.h implicit
+prev FEATURE/uwin implicit
+done uwin/crypt.c
+meta crypt.o %.c>%.o uwin/crypt.c crypt
+prev uwin/crypt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -c uwin/crypt.c
+done crypt.o generated
+make erf.o
+make uwin/erf.c
+prev uwin/mathimpl.h implicit
+make ieee_libm.h implicit
+done ieee_libm.h dontcare virtual
+prev FEATURE/uwin implicit
+done uwin/erf.c
+meta erf.o %.c>%.o uwin/erf.c erf
+prev uwin/erf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iuwin -Istd -c uwin/erf.c
+done erf.o generated
+make err.o
+make uwin/err.c
+prev windows.h implicit
+prev include/error.h implicit
+prev include/ast.h implicit
+prev FEATURE/uwin implicit
+done uwin/err.c
+meta err.o %.c>%.o uwin/err.c err
+prev uwin/err.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c uwin/err.c
+done err.o generated
+make exp.o
+make uwin/exp.c
+prev uwin/mathimpl.h implicit
+prev FEATURE/uwin implicit
+done uwin/exp.c
+meta exp.o %.c>%.o uwin/exp.c exp
+prev uwin/exp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iuwin -Istd -c uwin/exp.c
+done exp.o generated
+make exp__E.o
+make uwin/exp__E.c
+prev uwin/mathimpl.h implicit
+prev FEATURE/uwin implicit
+done uwin/exp__E.c
+meta exp__E.o %.c>%.o uwin/exp__E.c exp__E
+prev uwin/exp__E.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iuwin -Istd -c uwin/exp__E.c
+done exp__E.o generated
+make expm1.o
+make uwin/expm1.c
+prev uwin/mathimpl.h implicit
+prev FEATURE/uwin implicit
+done uwin/expm1.c
+meta expm1.o %.c>%.o uwin/expm1.c expm1
+prev uwin/expm1.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iuwin -Istd -c uwin/expm1.c
+done expm1.o generated
+make gamma.o
+make uwin/gamma.c
+prev uwin/mathimpl.h implicit
+prev FEATURE/uwin implicit
+done uwin/gamma.c
+meta gamma.o %.c>%.o uwin/gamma.c gamma
+prev uwin/gamma.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iuwin -Istd -c uwin/gamma.c
+done gamma.o generated
+make getpass.o
+make uwin/getpass.c
+prev include/ast.h implicit
+prev FEATURE/uwin implicit
+done uwin/getpass.c
+meta getpass.o %.c>%.o uwin/getpass.c getpass
+prev uwin/getpass.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c uwin/getpass.c
+done getpass.o generated
+make lgamma.o
+make uwin/lgamma.c
+prev uwin/mathimpl.h implicit
+prev FEATURE/uwin implicit
+done uwin/lgamma.c
+meta lgamma.o %.c>%.o uwin/lgamma.c lgamma
+prev uwin/lgamma.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iuwin -Istd -c uwin/lgamma.c
+done lgamma.o generated
+make log.o
+make uwin/log.c
+prev uwin/mathimpl.h implicit
+prev FEATURE/uwin implicit
+done uwin/log.c
+meta log.o %.c>%.o uwin/log.c log
+prev uwin/log.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iuwin -Istd -c uwin/log.c
+done log.o generated
+make log1p.o
+make uwin/log1p.c
+prev uwin/mathimpl.h implicit
+prev FEATURE/uwin implicit
+done uwin/log1p.c
+meta log1p.o %.c>%.o uwin/log1p.c log1p
+prev uwin/log1p.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iuwin -Istd -c uwin/log1p.c
+done log1p.o generated
+make log__L.o
+make uwin/log__L.c
+prev uwin/mathimpl.h implicit
+prev FEATURE/uwin implicit
+done uwin/log__L.c
+meta log__L.o %.c>%.o uwin/log__L.c log__L
+prev uwin/log__L.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iuwin -Istd -c uwin/log__L.c
+done log__L.o generated
+make rand48.o
+make uwin/rand48.c
+prev FEATURE/uwin implicit
+done uwin/rand48.c
+meta rand48.o %.c>%.o uwin/rand48.c rand48
+prev uwin/rand48.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Istd -c uwin/rand48.c
+done rand48.o generated
+make random.o
+make uwin/random.c
+prev FEATURE/uwin implicit
+done uwin/random.c
+meta random.o %.c>%.o uwin/random.c random
+prev uwin/random.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Istd -c uwin/random.c
+done random.o generated
+make rcmd.o
+make uwin/rcmd.c
+prev std/nl_types.h implicit
+make uwin/rlib.h implicit
+prev std/endian.h implicit
+prev std/stdio.h implicit
+prev std/stdio.h implicit
+prev include/ast_std.h implicit
+done uwin/rlib.h dontcare
+prev FEATURE/uwin implicit
+done uwin/rcmd.c
+meta rcmd.o %.c>%.o uwin/rcmd.c rcmd
+prev uwin/rcmd.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iuwin -Iinclude -Istd -c uwin/rcmd.c
+done rcmd.o generated
+make rint.o
+make uwin/rint.c
+prev FEATURE/uwin implicit
+done uwin/rint.c
+meta rint.o %.c>%.o uwin/rint.c rint
+prev uwin/rint.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Istd -c uwin/rint.c
+done rint.o generated
+make support.o
+make uwin/support.c
+prev uwin/mathimpl.h implicit
+prev FEATURE/uwin implicit
+done uwin/support.c
+meta support.o %.c>%.o uwin/support.c support
+prev uwin/support.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iuwin -Istd -c uwin/support.c
+done support.o generated
+make sfstrtmp.o
+make disc/sfstrtmp.c
+prev include/ast.h implicit
+prev include/sfio_t.h implicit
+done disc/sfstrtmp.c
+meta sfstrtmp.o %.c>%.o disc/sfstrtmp.c sfstrtmp
+prev disc/sfstrtmp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D__OBSOLETE__=20110101 -D_PACKAGE_ast -c disc/sfstrtmp.c
+done sfstrtmp.o generated
+make spawn.o
+make obsolete/spawn.c
+prev include/error.h implicit
+prev include/ast.h implicit
+prev ast_lib.h implicit
+done obsolete/spawn.c
+meta spawn.o %.c>%.o obsolete/spawn.c spawn
+prev obsolete/spawn.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c obsolete/spawn.c
+done spawn.o generated
+exec - ${AR} rc libast.a state.o transition.o opendir.o readdir.o rewinddir.o seekdir.o telldir.o getcwd.o fastfind.o hashalloc.o hashdump.o hashfree.o hashlast.o hashlook.o hashscan.o hashsize.o hashview.o hashwalk.o memhash.o memsum.o strhash.o strkey.o strsum.o stracmp.o strnacmp.o ccmap.o ccmapid.o ccnative.o chresc.o chrtoi.o
+exec - ${AR} rc libast.a streval.o strexpr.o strmatch.o strcopy.o modei.o modex.o strmode.o strlcat.o strlcpy.o strlook.o strncopy.o strsearch.o strpsearch.o stresc.o stropt.o strtape.o strpcmp.o strnpcmp.o strvcmp.o strnvcmp.o tok.o tokline.o tokscan.o pathaccess.o pathcat.o pathcanon.o pathcheck.o pathpath.o pathexists.o pathfind.o pathkey.o pathprobe.o pathrepl.o pathnative.o pathposix.o pathtemp.o pathtmp.o pathstat.o pathgetlink.o pathsetlink.o pathbin.o pathshell.o pathcd.o pathprog.o fs3d.o ftwalk.o ftwflags.o fts.o astintercept.o conformance.o getenv.o setenviron.o optget.o optjoin.o optesc.o optctx.o strsort.o struniq.o magic.o mime.o mimetype.o signal.o sigflag.o systrace.o error.o errorf.o errormsg.o errorx.o localeconv.o setlocale.o translate.o catopen.o iconv.o lc.o lctab.o mc.o base64.o recfmt.o recstr.o reclen.o fmtrec.o fmtbase.o fmtbuf.o fmtclock.o fmtdev.o fmtelapsed.o fmterror.o fmtesc.o fmtfmt.o fmtfs.o fmtident.o fmtint.o fmtip4.o fmtip6.o fmtls.o fmtmatch.o fmtmode.o fmtnum.o fmtperm.o fmtre.o fmttime.o
+exec - ${AR} rc libast.a fmtuid.o fmtgid.o fmtsignal.o fmtscale.o fmttmx.o fmttv.o fmtversion.o strelapsed.o strperm.o struid.o strgid.o strtoip4.o strtoip6.o stack.o stk.o swapget.o swapmem.o swapop.o swapput.o sigdata.o sigcrit.o sigunblock.o procopen.o procclose.o procrun.o procfree.o tmdate.o tmequiv.o tmfix.o tmfmt.o tmform.o tmgoff.o tminit.o tmleap.o tmlex.o tmlocale.o tmmake.o tmpoff.o tmscan.o tmsleep.o tmtime.o tmtype.o tmweek.o tmword.o tmzone.o tmxdate.o tmxduration.o tmxfmt.o tmxgettime.o tmxleap.o tmxmake.o tmxscan.o tmxsettime.o tmxsleep.o tmxtime.o tmxtouch.o tvcmp.o tvgettime.o tvsettime.o tvsleep.o tvtouch.o cmdarg.o vecargs.o vecfile.o vecfree.o vecload.o vecstring.o univdata.o touch.o mnt.o debug.o memccpy.o memchr.o memcmp.o memcpy.o memdup.o memmove.o memset.o mkdir.o mkfifo.o mknod.o rmdir.o remove.o rename.o link.o unlink.o strdup.o strchr.o strrchr.o strstr.o strtod.o strtold.o strtol.o strtoll.o strtoul.o strtoull.o strton.o strtonll.o strntod.o strntold.o strnton.o
+exec - ${AR} rc libast.a strntonll.o strntol.o strntoll.o strntoul.o strntoull.o strcasecmp.o strncasecmp.o strerror.o mktemp.o tmpnam.o fsync.o execlp.o execve.o execvp.o execvpe.o spawnveg.o vfork.o killpg.o hsearch.o tsearch.o getlogin.o putenv.o setenv.o unsetenv.o lstat.o statvfs.o eaccess.o gross.o omitted.o readlink.o symlink.o getpgrp.o setpgid.o setsid.o waitpid.o creat64.o fcntl.o open.o atexit.o getdents.o getwd.o dup2.o errno.o getpreroot.o ispreroot.o realopen.o setpreroot.o getgroups.o mount.o system.o iblocks.o modedata.o tmdata.o memfatal.o sfkeyprintf.o sfdcdio.o sfdcdos.o sfdcfilter.o sfdcseekable.o sfdcslow.o sfdcsubstr.o sfdctee.o sfdcunion.o sfdcmore.o sfdcprefix.o wc.o wc2utf8.o basename.o closelog.o dirname.o fmtmsglib.o fnmatch.o ftw.o getdate.o getsubopt.o glob.o nftw.o openlog.o re_comp.o resolvepath.o realpath.o regcmp.o regexp.o setlogmask.o strftime.o strptime.o swab.o syslog.o tempnam.o wordexp.o mktime.o regalloc.o regclass.o regcoll.o regcomp.o regcache.o regdecomp.o regerror.o regexec.o regfatal.o reginit.o
+exec - ${AR} rc libast.a regnexec.o regsubcomp.o regsubexec.o regsub.o regrecord.o regrexec.o regstat.o dtclose.o dtdisc.o dthash.o dtlist.o dtmethod.o dtopen.o dtstrhash.o dttree.o dtview.o dtwalk.o dtnew.o dtcomp.o sfclose.o sfclrlock.o sfdisc.o sfdlen.o sfexcept.o sfgetl.o sfgetu.o sfcvt.o sfecvt.o sffcvt.o sfextern.o sffilbuf.o sfflsbuf.o sfprints.o sfgetd.o sfgetr.o sfllen.o sfmode.o sfmove.o sfnew.o sfpkrd.o sfnotify.o sfnputc.o sfopen.o sfpeek.o sfpoll.o sfpool.o sfpopen.o sfprintf.o sfputd.o sfputl.o sfputr.o sfputu.o sfrd.o sfread.o sfreserve.o sfscanf.o sfseek.o sfset.o sfsetbuf.o sfsetfd.o sfsize.o sfsk.o sfstack.o sfstrtod.o sfsync.o sfswap.o sftable.o sftell.o sftmp.o sfungetc.o sfvprintf.o sfvscanf.o sfwr.o sfwrite.o sfpurge.o sfraise.o sfwalk.o sfgetm.o sfmutex.o sfputm.o sfresize.o _sfclrerr.o _sfeof.o _sferror.o _sffileno.o _sfopen.o _sfstacked.o _sfvalue.o _sfgetc.o _sfgetl.o _sfgetl2.o _sfgetu.o _sfgetu2.o _sfdlen.o _sfllen.o _sfslen.o _sfulen.o _sfputc.o _sfputd.o _sfputl.o _sfputm.o
+exec - ${AR} rc libast.a _sfputu.o clearerr.o fclose.o fdopen.o feof.o ferror.o fflush.o fgetc.o fgetpos.o fgets.o fileno.o fopen.o fprintf.o fpurge.o fputc.o fputs.o fread.o freopen.o fscanf.o fseek.o fseeko.o fsetpos.o ftell.o ftello.o fwrite.o flockfile.o ftrylockfile.o funlockfile.o getc.o getchar.o getw.o pclose.o popen.o printf.o putc.o putchar.o puts.o putw.o rewind.o scanf.o setbuf.o setbuffer.o setlinebuf.o setvbuf.o snprintf.o sprintf.o sscanf.o asprintf.o vasprintf.o tmpfile.o ungetc.o vfprintf.o vfscanf.o vprintf.o vscanf.o vsnprintf.o vsprintf.o vsscanf.o _doprnt.o _doscan.o _filbuf.o _flsbuf.o _stdfun.o _stdopen.o _stdprintf.o _stdscanf.o _stdsprnt.o _stdvbuf.o _stdvsnprnt.o _stdvsprnt.o _stdvsscn.o fgetwc.o fwprintf.o putwchar.o vfwscanf.o wprintf.o fgetws.o fwscanf.o swprintf.o vswprintf.o wscanf.o fputwc.o getwc.o swscanf.o vswscanf.o fputws.o getwchar.o ungetwc.o vwprintf.o fwide.o putwc.o vfwprintf.o vwscanf.o stdio_c99.o fcloseall.o fmemopen.o getdelim.o getline.o frexp.o frexpl.o astcopy.o
+exec - ${AR} rc libast.a astconf.o astdynamic.o astlicense.o astquery.o astwinsize.o conftab.o aststatic.o getopt.o getoptl.o aso.o asolock.o asometh.o asorelax.o aso-sem.o aso-fcntl.o vmbest.o vmclear.o vmclose.o vmdcheap.o vmdebug.o vmdisc.o vmexit.o vmlast.o vmopen.o vmpool.o vmprivate.o vmprofile.o vmregion.o vmsegment.o vmset.o vmstat.o vmstrdup.o vmtrace.o vmwalk.o vmmopen.o malloc.o vmgetmem.o a64l.o acosh.o asinh.o atanh.o cbrt.o crypt.o erf.o err.o exp.o exp__E.o expm1.o gamma.o getpass.o lgamma.o log.o log1p.o log__L.o rand48.o random.o rcmd.o rint.o support.o sfstrtmp.o spawn.o
+exec - (ranlib libast.a) >/dev/null 2>&1 || true
+done libast.a generated
+done ast virtual
+prev libast.a archive
+make ${INSTALLROOT}/lib
+exec - if silent test ! -d ${INSTALLROOT}/lib
+exec - then mkdir -p ${INSTALLROOT}/lib
+exec - fi
+done ${INSTALLROOT}/lib generated
+make ${INSTALLROOT}/lib/libast.a archive
+prev ${INSTALLROOT}/lib
+prev libast.a archive
+exec - test '' = 'libast.a' || ${STDCMP} 2>/dev/null -s libast.a ${INSTALLROOT}/lib/libast.a || { ${STDMV} ${INSTALLROOT}/lib/libast.a ${INSTALLROOT}/lib/libast.a.old 2>/dev/null || true; ${STDCP} libast.a ${INSTALLROOT}/lib/libast.a ;}
+exec - (ranlib ${INSTALLROOT}/lib/libast.a) >/dev/null 2>&1 || true
+done ${INSTALLROOT}/lib/libast.a generated
+make ${INSTALLROOT}/man/man3
+exec - if silent test ! -d ${INSTALLROOT}/man/man3
+exec - then mkdir -p ${INSTALLROOT}/man/man3
+exec - fi
+done ${INSTALLROOT}/man/man3 generated
+make ${INSTALLROOT}/man/man3/LIBAST.3
+prev ${INSTALLROOT}/man/man3
+make man/LIBAST.3
+done man/LIBAST.3
+exec - test '' = 'man/LIBAST.3' || ${STDCMP} 2>/dev/null -s man/LIBAST.3 ${INSTALLROOT}/man/man3/LIBAST.3 || { ${STDMV} ${INSTALLROOT}/man/man3/LIBAST.3 ${INSTALLROOT}/man/man3/LIBAST.3.old 2>/dev/null || true; ${STDCP} man/LIBAST.3 ${INSTALLROOT}/man/man3/LIBAST.3 ;}
+done ${INSTALLROOT}/man/man3/LIBAST.3 generated
+make ${INSTALLROOT}/man/man3/aso.3
+make man/aso.3
+done man/aso.3
+exec - test '' = 'man/aso.3' || ${STDCMP} 2>/dev/null -s man/aso.3 ${INSTALLROOT}/man/man3/aso.3 || { ${STDMV} ${INSTALLROOT}/man/man3/aso.3 ${INSTALLROOT}/man/man3/aso.3.old 2>/dev/null || true; ${STDCP} man/aso.3 ${INSTALLROOT}/man/man3/aso.3 ;}
+done ${INSTALLROOT}/man/man3/aso.3 generated
+make ${INSTALLROOT}/man/man3/ast.3
+make man/ast.3
+done man/ast.3
+exec - test '' = 'man/ast.3' || ${STDCMP} 2>/dev/null -s man/ast.3 ${INSTALLROOT}/man/man3/ast.3 || { ${STDMV} ${INSTALLROOT}/man/man3/ast.3 ${INSTALLROOT}/man/man3/ast.3.old 2>/dev/null || true; ${STDCP} man/ast.3 ${INSTALLROOT}/man/man3/ast.3 ;}
+done ${INSTALLROOT}/man/man3/ast.3 generated
+make ${INSTALLROOT}/man/man3/astsa.3
+make man/astsa.3
+done man/astsa.3
+exec - test '' = 'man/astsa.3' || ${STDCMP} 2>/dev/null -s man/astsa.3 ${INSTALLROOT}/man/man3/astsa.3 || { ${STDMV} ${INSTALLROOT}/man/man3/astsa.3 ${INSTALLROOT}/man/man3/astsa.3.old 2>/dev/null || true; ${STDCP} man/astsa.3 ${INSTALLROOT}/man/man3/astsa.3 ;}
+done ${INSTALLROOT}/man/man3/astsa.3 generated
+make ${INSTALLROOT}/man/man3/cdt.3
+make man/cdt.3
+done man/cdt.3
+exec - test '' = 'man/cdt.3' || ${STDCMP} 2>/dev/null -s man/cdt.3 ${INSTALLROOT}/man/man3/cdt.3 || { ${STDMV} ${INSTALLROOT}/man/man3/cdt.3 ${INSTALLROOT}/man/man3/cdt.3.old 2>/dev/null || true; ${STDCP} man/cdt.3 ${INSTALLROOT}/man/man3/cdt.3 ;}
+done ${INSTALLROOT}/man/man3/cdt.3 generated
+make ${INSTALLROOT}/man/man3/chr.3
+make man/chr.3
+done man/chr.3
+exec - test '' = 'man/chr.3' || ${STDCMP} 2>/dev/null -s man/chr.3 ${INSTALLROOT}/man/man3/chr.3 || { ${STDMV} ${INSTALLROOT}/man/man3/chr.3 ${INSTALLROOT}/man/man3/chr.3.old 2>/dev/null || true; ${STDCP} man/chr.3 ${INSTALLROOT}/man/man3/chr.3 ;}
+done ${INSTALLROOT}/man/man3/chr.3 generated
+make ${INSTALLROOT}/man/man3/compat.3
+make man/compat.3
+done man/compat.3
+exec - test '' = 'man/compat.3' || ${STDCMP} 2>/dev/null -s man/compat.3 ${INSTALLROOT}/man/man3/compat.3 || { ${STDMV} ${INSTALLROOT}/man/man3/compat.3 ${INSTALLROOT}/man/man3/compat.3.old 2>/dev/null || true; ${STDCP} man/compat.3 ${INSTALLROOT}/man/man3/compat.3 ;}
+done ${INSTALLROOT}/man/man3/compat.3 generated
+make ${INSTALLROOT}/man/man3/error.3
+make man/error.3
+done man/error.3
+exec - test '' = 'man/error.3' || ${STDCMP} 2>/dev/null -s man/error.3 ${INSTALLROOT}/man/man3/error.3 || { ${STDMV} ${INSTALLROOT}/man/man3/error.3 ${INSTALLROOT}/man/man3/error.3.old 2>/dev/null || true; ${STDCP} man/error.3 ${INSTALLROOT}/man/man3/error.3 ;}
+done ${INSTALLROOT}/man/man3/error.3 generated
+make ${INSTALLROOT}/man/man3/find.3
+make man/find.3
+done man/find.3
+exec - test '' = 'man/find.3' || ${STDCMP} 2>/dev/null -s man/find.3 ${INSTALLROOT}/man/man3/find.3 || { ${STDMV} ${INSTALLROOT}/man/man3/find.3 ${INSTALLROOT}/man/man3/find.3.old 2>/dev/null || true; ${STDCP} man/find.3 ${INSTALLROOT}/man/man3/find.3 ;}
+done ${INSTALLROOT}/man/man3/find.3 generated
+make ${INSTALLROOT}/man/man3/fmt.3
+make man/fmt.3
+done man/fmt.3
+exec - test '' = 'man/fmt.3' || ${STDCMP} 2>/dev/null -s man/fmt.3 ${INSTALLROOT}/man/man3/fmt.3 || { ${STDMV} ${INSTALLROOT}/man/man3/fmt.3 ${INSTALLROOT}/man/man3/fmt.3.old 2>/dev/null || true; ${STDCP} man/fmt.3 ${INSTALLROOT}/man/man3/fmt.3 ;}
+done ${INSTALLROOT}/man/man3/fmt.3 generated
+make ${INSTALLROOT}/man/man3/fmtls.3
+make man/fmtls.3
+done man/fmtls.3
+exec - test '' = 'man/fmtls.3' || ${STDCMP} 2>/dev/null -s man/fmtls.3 ${INSTALLROOT}/man/man3/fmtls.3 || { ${STDMV} ${INSTALLROOT}/man/man3/fmtls.3 ${INSTALLROOT}/man/man3/fmtls.3.old 2>/dev/null || true; ${STDCP} man/fmtls.3 ${INSTALLROOT}/man/man3/fmtls.3 ;}
+done ${INSTALLROOT}/man/man3/fmtls.3 generated
+make ${INSTALLROOT}/man/man3/fs3d.3
+make man/fs3d.3
+done man/fs3d.3
+exec - test '' = 'man/fs3d.3' || ${STDCMP} 2>/dev/null -s man/fs3d.3 ${INSTALLROOT}/man/man3/fs3d.3 || { ${STDMV} ${INSTALLROOT}/man/man3/fs3d.3 ${INSTALLROOT}/man/man3/fs3d.3.old 2>/dev/null || true; ${STDCP} man/fs3d.3 ${INSTALLROOT}/man/man3/fs3d.3 ;}
+done ${INSTALLROOT}/man/man3/fs3d.3 generated
+make ${INSTALLROOT}/man/man3/ftwalk.3
+make man/ftwalk.3
+done man/ftwalk.3
+exec - test '' = 'man/ftwalk.3' || ${STDCMP} 2>/dev/null -s man/ftwalk.3 ${INSTALLROOT}/man/man3/ftwalk.3 || { ${STDMV} ${INSTALLROOT}/man/man3/ftwalk.3 ${INSTALLROOT}/man/man3/ftwalk.3.old 2>/dev/null || true; ${STDCP} man/ftwalk.3 ${INSTALLROOT}/man/man3/ftwalk.3 ;}
+done ${INSTALLROOT}/man/man3/ftwalk.3 generated
+make ${INSTALLROOT}/man/man3/getcwd.3
+make man/getcwd.3
+done man/getcwd.3
+exec - test '' = 'man/getcwd.3' || ${STDCMP} 2>/dev/null -s man/getcwd.3 ${INSTALLROOT}/man/man3/getcwd.3 || { ${STDMV} ${INSTALLROOT}/man/man3/getcwd.3 ${INSTALLROOT}/man/man3/getcwd.3.old 2>/dev/null || true; ${STDCP} man/getcwd.3 ${INSTALLROOT}/man/man3/getcwd.3 ;}
+done ${INSTALLROOT}/man/man3/getcwd.3 generated
+make ${INSTALLROOT}/man/man3/hash.3
+make man/hash.3
+done man/hash.3
+exec - test '' = 'man/hash.3' || ${STDCMP} 2>/dev/null -s man/hash.3 ${INSTALLROOT}/man/man3/hash.3 || { ${STDMV} ${INSTALLROOT}/man/man3/hash.3 ${INSTALLROOT}/man/man3/hash.3.old 2>/dev/null || true; ${STDCP} man/hash.3 ${INSTALLROOT}/man/man3/hash.3 ;}
+done ${INSTALLROOT}/man/man3/hash.3 generated
+make ${INSTALLROOT}/man/man3/iblocks.3
+make man/iblocks.3
+done man/iblocks.3
+exec - test '' = 'man/iblocks.3' || ${STDCMP} 2>/dev/null -s man/iblocks.3 ${INSTALLROOT}/man/man3/iblocks.3 || { ${STDMV} ${INSTALLROOT}/man/man3/iblocks.3 ${INSTALLROOT}/man/man3/iblocks.3.old 2>/dev/null || true; ${STDCP} man/iblocks.3 ${INSTALLROOT}/man/man3/iblocks.3 ;}
+done ${INSTALLROOT}/man/man3/iblocks.3 generated
+make ${INSTALLROOT}/man/man3/int.3
+make man/int.3
+done man/int.3
+exec - test '' = 'man/int.3' || ${STDCMP} 2>/dev/null -s man/int.3 ${INSTALLROOT}/man/man3/int.3 || { ${STDMV} ${INSTALLROOT}/man/man3/int.3 ${INSTALLROOT}/man/man3/int.3.old 2>/dev/null || true; ${STDCP} man/int.3 ${INSTALLROOT}/man/man3/int.3 ;}
+done ${INSTALLROOT}/man/man3/int.3 generated
+make ${INSTALLROOT}/man/man3/ip6.3
+make man/ip6.3
+done man/ip6.3
+exec - test '' = 'man/ip6.3' || ${STDCMP} 2>/dev/null -s man/ip6.3 ${INSTALLROOT}/man/man3/ip6.3 || { ${STDMV} ${INSTALLROOT}/man/man3/ip6.3 ${INSTALLROOT}/man/man3/ip6.3.old 2>/dev/null || true; ${STDCP} man/ip6.3 ${INSTALLROOT}/man/man3/ip6.3 ;}
+done ${INSTALLROOT}/man/man3/ip6.3 generated
+make ${INSTALLROOT}/man/man3/magic.3
+make man/magic.3
+done man/magic.3
+exec - test '' = 'man/magic.3' || ${STDCMP} 2>/dev/null -s man/magic.3 ${INSTALLROOT}/man/man3/magic.3 || { ${STDMV} ${INSTALLROOT}/man/man3/magic.3 ${INSTALLROOT}/man/man3/magic.3.old 2>/dev/null || true; ${STDCP} man/magic.3 ${INSTALLROOT}/man/man3/magic.3 ;}
+done ${INSTALLROOT}/man/man3/magic.3 generated
+make ${INSTALLROOT}/man/man3/mem.3
+make man/mem.3
+done man/mem.3
+exec - test '' = 'man/mem.3' || ${STDCMP} 2>/dev/null -s man/mem.3 ${INSTALLROOT}/man/man3/mem.3 || { ${STDMV} ${INSTALLROOT}/man/man3/mem.3 ${INSTALLROOT}/man/man3/mem.3.old 2>/dev/null || true; ${STDCP} man/mem.3 ${INSTALLROOT}/man/man3/mem.3 ;}
+done ${INSTALLROOT}/man/man3/mem.3 generated
+make ${INSTALLROOT}/man/man3/mime.3
+make man/mime.3
+done man/mime.3
+exec - test '' = 'man/mime.3' || ${STDCMP} 2>/dev/null -s man/mime.3 ${INSTALLROOT}/man/man3/mime.3 || { ${STDMV} ${INSTALLROOT}/man/man3/mime.3 ${INSTALLROOT}/man/man3/mime.3.old 2>/dev/null || true; ${STDCP} man/mime.3 ${INSTALLROOT}/man/man3/mime.3 ;}
+done ${INSTALLROOT}/man/man3/mime.3 generated
+make ${INSTALLROOT}/man/man3/modecanon.3
+make man/modecanon.3
+done man/modecanon.3
+exec - test '' = 'man/modecanon.3' || ${STDCMP} 2>/dev/null -s man/modecanon.3 ${INSTALLROOT}/man/man3/modecanon.3 || { ${STDMV} ${INSTALLROOT}/man/man3/modecanon.3 ${INSTALLROOT}/man/man3/modecanon.3.old 2>/dev/null || true; ${STDCP} man/modecanon.3 ${INSTALLROOT}/man/man3/modecanon.3 ;}
+done ${INSTALLROOT}/man/man3/modecanon.3 generated
+make ${INSTALLROOT}/man/man3/optget.3
+make man/optget.3
+done man/optget.3
+exec - test '' = 'man/optget.3' || ${STDCMP} 2>/dev/null -s man/optget.3 ${INSTALLROOT}/man/man3/optget.3 || { ${STDMV} ${INSTALLROOT}/man/man3/optget.3 ${INSTALLROOT}/man/man3/optget.3.old 2>/dev/null || true; ${STDCP} man/optget.3 ${INSTALLROOT}/man/man3/optget.3 ;}
+done ${INSTALLROOT}/man/man3/optget.3 generated
+make ${INSTALLROOT}/man/man3/path.3
+make man/path.3
+done man/path.3
+exec - test '' = 'man/path.3' || ${STDCMP} 2>/dev/null -s man/path.3 ${INSTALLROOT}/man/man3/path.3 || { ${STDMV} ${INSTALLROOT}/man/man3/path.3 ${INSTALLROOT}/man/man3/path.3.old 2>/dev/null || true; ${STDCP} man/path.3 ${INSTALLROOT}/man/man3/path.3 ;}
+done ${INSTALLROOT}/man/man3/path.3 generated
+make ${INSTALLROOT}/man/man3/preroot.3
+make man/preroot.3
+done man/preroot.3
+exec - test '' = 'man/preroot.3' || ${STDCMP} 2>/dev/null -s man/preroot.3 ${INSTALLROOT}/man/man3/preroot.3 || { ${STDMV} ${INSTALLROOT}/man/man3/preroot.3 ${INSTALLROOT}/man/man3/preroot.3.old 2>/dev/null || true; ${STDCP} man/preroot.3 ${INSTALLROOT}/man/man3/preroot.3 ;}
+done ${INSTALLROOT}/man/man3/preroot.3 generated
+make ${INSTALLROOT}/man/man3/proc.3
+make man/proc.3
+done man/proc.3
+exec - test '' = 'man/proc.3' || ${STDCMP} 2>/dev/null -s man/proc.3 ${INSTALLROOT}/man/man3/proc.3 || { ${STDMV} ${INSTALLROOT}/man/man3/proc.3 ${INSTALLROOT}/man/man3/proc.3.old 2>/dev/null || true; ${STDCP} man/proc.3 ${INSTALLROOT}/man/man3/proc.3 ;}
+done ${INSTALLROOT}/man/man3/proc.3 generated
+make ${INSTALLROOT}/man/man3/re.3
+make man/re.3
+done man/re.3
+exec - test '' = 'man/re.3' || ${STDCMP} 2>/dev/null -s man/re.3 ${INSTALLROOT}/man/man3/re.3 || { ${STDMV} ${INSTALLROOT}/man/man3/re.3 ${INSTALLROOT}/man/man3/re.3.old 2>/dev/null || true; ${STDCP} man/re.3 ${INSTALLROOT}/man/man3/re.3 ;}
+done ${INSTALLROOT}/man/man3/re.3 generated
+make ${INSTALLROOT}/man/man3/regex.3
+make man/regex.3
+done man/regex.3
+exec - test '' = 'man/regex.3' || ${STDCMP} 2>/dev/null -s man/regex.3 ${INSTALLROOT}/man/man3/regex.3 || { ${STDMV} ${INSTALLROOT}/man/man3/regex.3 ${INSTALLROOT}/man/man3/regex.3.old 2>/dev/null || true; ${STDCP} man/regex.3 ${INSTALLROOT}/man/man3/regex.3 ;}
+done ${INSTALLROOT}/man/man3/regex.3 generated
+make ${INSTALLROOT}/man/man3/setenviron.3
+make man/setenviron.3
+done man/setenviron.3
+exec - test '' = 'man/setenviron.3' || ${STDCMP} 2>/dev/null -s man/setenviron.3 ${INSTALLROOT}/man/man3/setenviron.3 || { ${STDMV} ${INSTALLROOT}/man/man3/setenviron.3 ${INSTALLROOT}/man/man3/setenviron.3.old 2>/dev/null || true; ${STDCP} man/setenviron.3 ${INSTALLROOT}/man/man3/setenviron.3 ;}
+done ${INSTALLROOT}/man/man3/setenviron.3 generated
+make ${INSTALLROOT}/man/man3/sfdisc.3
+make man/sfdisc.3
+done man/sfdisc.3
+exec - test '' = 'man/sfdisc.3' || ${STDCMP} 2>/dev/null -s man/sfdisc.3 ${INSTALLROOT}/man/man3/sfdisc.3 || { ${STDMV} ${INSTALLROOT}/man/man3/sfdisc.3 ${INSTALLROOT}/man/man3/sfdisc.3.old 2>/dev/null || true; ${STDCP} man/sfdisc.3 ${INSTALLROOT}/man/man3/sfdisc.3 ;}
+done ${INSTALLROOT}/man/man3/sfdisc.3 generated
+make ${INSTALLROOT}/man/man3/sfio.3
+make man/sfio.3
+done man/sfio.3
+exec - test '' = 'man/sfio.3' || ${STDCMP} 2>/dev/null -s man/sfio.3 ${INSTALLROOT}/man/man3/sfio.3 || { ${STDMV} ${INSTALLROOT}/man/man3/sfio.3 ${INSTALLROOT}/man/man3/sfio.3.old 2>/dev/null || true; ${STDCP} man/sfio.3 ${INSTALLROOT}/man/man3/sfio.3 ;}
+done ${INSTALLROOT}/man/man3/sfio.3 generated
+make ${INSTALLROOT}/man/man3/sig.3
+make man/sig.3
+done man/sig.3
+exec - test '' = 'man/sig.3' || ${STDCMP} 2>/dev/null -s man/sig.3 ${INSTALLROOT}/man/man3/sig.3 || { ${STDMV} ${INSTALLROOT}/man/man3/sig.3 ${INSTALLROOT}/man/man3/sig.3.old 2>/dev/null || true; ${STDCP} man/sig.3 ${INSTALLROOT}/man/man3/sig.3 ;}
+done ${INSTALLROOT}/man/man3/sig.3 generated
+make ${INSTALLROOT}/man/man3/spawnveg.3
+make man/spawnveg.3
+done man/spawnveg.3
+exec - test '' = 'man/spawnveg.3' || ${STDCMP} 2>/dev/null -s man/spawnveg.3 ${INSTALLROOT}/man/man3/spawnveg.3 || { ${STDMV} ${INSTALLROOT}/man/man3/spawnveg.3 ${INSTALLROOT}/man/man3/spawnveg.3.old 2>/dev/null || true; ${STDCP} man/spawnveg.3 ${INSTALLROOT}/man/man3/spawnveg.3 ;}
+done ${INSTALLROOT}/man/man3/spawnveg.3 generated
+make ${INSTALLROOT}/man/man3/stak.3
+make man/stak.3
+done man/stak.3
+exec - test '' = 'man/stak.3' || ${STDCMP} 2>/dev/null -s man/stak.3 ${INSTALLROOT}/man/man3/stak.3 || { ${STDMV} ${INSTALLROOT}/man/man3/stak.3 ${INSTALLROOT}/man/man3/stak.3.old 2>/dev/null || true; ${STDCP} man/stak.3 ${INSTALLROOT}/man/man3/stak.3 ;}
+done ${INSTALLROOT}/man/man3/stak.3 generated
+make ${INSTALLROOT}/man/man3/stk.3
+make man/stk.3
+done man/stk.3
+exec - test '' = 'man/stk.3' || ${STDCMP} 2>/dev/null -s man/stk.3 ${INSTALLROOT}/man/man3/stk.3 || { ${STDMV} ${INSTALLROOT}/man/man3/stk.3 ${INSTALLROOT}/man/man3/stk.3.old 2>/dev/null || true; ${STDCP} man/stk.3 ${INSTALLROOT}/man/man3/stk.3 ;}
+done ${INSTALLROOT}/man/man3/stk.3 generated
+make ${INSTALLROOT}/man/man3/strcopy.3
+make man/strcopy.3
+done man/strcopy.3
+exec - test '' = 'man/strcopy.3' || ${STDCMP} 2>/dev/null -s man/strcopy.3 ${INSTALLROOT}/man/man3/strcopy.3 || { ${STDMV} ${INSTALLROOT}/man/man3/strcopy.3 ${INSTALLROOT}/man/man3/strcopy.3.old 2>/dev/null || true; ${STDCP} man/strcopy.3 ${INSTALLROOT}/man/man3/strcopy.3 ;}
+done ${INSTALLROOT}/man/man3/strcopy.3 generated
+make ${INSTALLROOT}/man/man3/strdup.3
+make man/strdup.3
+done man/strdup.3
+exec - test '' = 'man/strdup.3' || ${STDCMP} 2>/dev/null -s man/strdup.3 ${INSTALLROOT}/man/man3/strdup.3 || { ${STDMV} ${INSTALLROOT}/man/man3/strdup.3 ${INSTALLROOT}/man/man3/strdup.3.old 2>/dev/null || true; ${STDCP} man/strdup.3 ${INSTALLROOT}/man/man3/strdup.3 ;}
+done ${INSTALLROOT}/man/man3/strdup.3 generated
+make ${INSTALLROOT}/man/man3/strelapsed.3
+make man/strelapsed.3
+done man/strelapsed.3
+exec - test '' = 'man/strelapsed.3' || ${STDCMP} 2>/dev/null -s man/strelapsed.3 ${INSTALLROOT}/man/man3/strelapsed.3 || { ${STDMV} ${INSTALLROOT}/man/man3/strelapsed.3 ${INSTALLROOT}/man/man3/strelapsed.3.old 2>/dev/null || true; ${STDCP} man/strelapsed.3 ${INSTALLROOT}/man/man3/strelapsed.3 ;}
+done ${INSTALLROOT}/man/man3/strelapsed.3 generated
+make ${INSTALLROOT}/man/man3/strerror.3
+make man/strerror.3
+done man/strerror.3
+exec - test '' = 'man/strerror.3' || ${STDCMP} 2>/dev/null -s man/strerror.3 ${INSTALLROOT}/man/man3/strerror.3 || { ${STDMV} ${INSTALLROOT}/man/man3/strerror.3 ${INSTALLROOT}/man/man3/strerror.3.old 2>/dev/null || true; ${STDCP} man/strerror.3 ${INSTALLROOT}/man/man3/strerror.3 ;}
+done ${INSTALLROOT}/man/man3/strerror.3 generated
+make ${INSTALLROOT}/man/man3/stresc.3
+make man/stresc.3
+done man/stresc.3
+exec - test '' = 'man/stresc.3' || ${STDCMP} 2>/dev/null -s man/stresc.3 ${INSTALLROOT}/man/man3/stresc.3 || { ${STDMV} ${INSTALLROOT}/man/man3/stresc.3 ${INSTALLROOT}/man/man3/stresc.3.old 2>/dev/null || true; ${STDCP} man/stresc.3 ${INSTALLROOT}/man/man3/stresc.3 ;}
+done ${INSTALLROOT}/man/man3/stresc.3 generated
+make ${INSTALLROOT}/man/man3/streval.3
+make man/streval.3
+done man/streval.3
+exec - test '' = 'man/streval.3' || ${STDCMP} 2>/dev/null -s man/streval.3 ${INSTALLROOT}/man/man3/streval.3 || { ${STDMV} ${INSTALLROOT}/man/man3/streval.3 ${INSTALLROOT}/man/man3/streval.3.old 2>/dev/null || true; ${STDCP} man/streval.3 ${INSTALLROOT}/man/man3/streval.3 ;}
+done ${INSTALLROOT}/man/man3/streval.3 generated
+make ${INSTALLROOT}/man/man3/strgid.3
+make man/strgid.3
+done man/strgid.3
+exec - test '' = 'man/strgid.3' || ${STDCMP} 2>/dev/null -s man/strgid.3 ${INSTALLROOT}/man/man3/strgid.3 || { ${STDMV} ${INSTALLROOT}/man/man3/strgid.3 ${INSTALLROOT}/man/man3/strgid.3.old 2>/dev/null || true; ${STDCP} man/strgid.3 ${INSTALLROOT}/man/man3/strgid.3 ;}
+done ${INSTALLROOT}/man/man3/strgid.3 generated
+make ${INSTALLROOT}/man/man3/strmatch.3
+make man/strmatch.3
+done man/strmatch.3
+exec - test '' = 'man/strmatch.3' || ${STDCMP} 2>/dev/null -s man/strmatch.3 ${INSTALLROOT}/man/man3/strmatch.3 || { ${STDMV} ${INSTALLROOT}/man/man3/strmatch.3 ${INSTALLROOT}/man/man3/strmatch.3.old 2>/dev/null || true; ${STDCP} man/strmatch.3 ${INSTALLROOT}/man/man3/strmatch.3 ;}
+done ${INSTALLROOT}/man/man3/strmatch.3 generated
+make ${INSTALLROOT}/man/man3/stropt.3
+make man/stropt.3
+done man/stropt.3
+exec - test '' = 'man/stropt.3' || ${STDCMP} 2>/dev/null -s man/stropt.3 ${INSTALLROOT}/man/man3/stropt.3 || { ${STDMV} ${INSTALLROOT}/man/man3/stropt.3 ${INSTALLROOT}/man/man3/stropt.3.old 2>/dev/null || true; ${STDCP} man/stropt.3 ${INSTALLROOT}/man/man3/stropt.3 ;}
+done ${INSTALLROOT}/man/man3/stropt.3 generated
+make ${INSTALLROOT}/man/man3/strperm.3
+make man/strperm.3
+done man/strperm.3
+exec - test '' = 'man/strperm.3' || ${STDCMP} 2>/dev/null -s man/strperm.3 ${INSTALLROOT}/man/man3/strperm.3 || { ${STDMV} ${INSTALLROOT}/man/man3/strperm.3 ${INSTALLROOT}/man/man3/strperm.3.old 2>/dev/null || true; ${STDCP} man/strperm.3 ${INSTALLROOT}/man/man3/strperm.3 ;}
+done ${INSTALLROOT}/man/man3/strperm.3 generated
+make ${INSTALLROOT}/man/man3/strsignal.3
+make man/strsignal.3
+done man/strsignal.3
+exec - test '' = 'man/strsignal.3' || ${STDCMP} 2>/dev/null -s man/strsignal.3 ${INSTALLROOT}/man/man3/strsignal.3 || { ${STDMV} ${INSTALLROOT}/man/man3/strsignal.3 ${INSTALLROOT}/man/man3/strsignal.3.old 2>/dev/null || true; ${STDCP} man/strsignal.3 ${INSTALLROOT}/man/man3/strsignal.3 ;}
+done ${INSTALLROOT}/man/man3/strsignal.3 generated
+make ${INSTALLROOT}/man/man3/strsort.3
+make man/strsort.3
+done man/strsort.3
+exec - test '' = 'man/strsort.3' || ${STDCMP} 2>/dev/null -s man/strsort.3 ${INSTALLROOT}/man/man3/strsort.3 || { ${STDMV} ${INSTALLROOT}/man/man3/strsort.3 ${INSTALLROOT}/man/man3/strsort.3.old 2>/dev/null || true; ${STDCP} man/strsort.3 ${INSTALLROOT}/man/man3/strsort.3 ;}
+done ${INSTALLROOT}/man/man3/strsort.3 generated
+make ${INSTALLROOT}/man/man3/strtape.3
+make man/strtape.3
+done man/strtape.3
+exec - test '' = 'man/strtape.3' || ${STDCMP} 2>/dev/null -s man/strtape.3 ${INSTALLROOT}/man/man3/strtape.3 || { ${STDMV} ${INSTALLROOT}/man/man3/strtape.3 ${INSTALLROOT}/man/man3/strtape.3.old 2>/dev/null || true; ${STDCP} man/strtape.3 ${INSTALLROOT}/man/man3/strtape.3 ;}
+done ${INSTALLROOT}/man/man3/strtape.3 generated
+make ${INSTALLROOT}/man/man3/strton.3
+make man/strton.3
+done man/strton.3
+exec - test '' = 'man/strton.3' || ${STDCMP} 2>/dev/null -s man/strton.3 ${INSTALLROOT}/man/man3/strton.3 || { ${STDMV} ${INSTALLROOT}/man/man3/strton.3 ${INSTALLROOT}/man/man3/strton.3.old 2>/dev/null || true; ${STDCP} man/strton.3 ${INSTALLROOT}/man/man3/strton.3 ;}
+done ${INSTALLROOT}/man/man3/strton.3 generated
+make ${INSTALLROOT}/man/man3/struid.3
+make man/struid.3
+done man/struid.3
+exec - test '' = 'man/struid.3' || ${STDCMP} 2>/dev/null -s man/struid.3 ${INSTALLROOT}/man/man3/struid.3 || { ${STDMV} ${INSTALLROOT}/man/man3/struid.3 ${INSTALLROOT}/man/man3/struid.3.old 2>/dev/null || true; ${STDCP} man/struid.3 ${INSTALLROOT}/man/man3/struid.3 ;}
+done ${INSTALLROOT}/man/man3/struid.3 generated
+make ${INSTALLROOT}/man/man3/swap.3
+make man/swap.3
+done man/swap.3
+exec - test '' = 'man/swap.3' || ${STDCMP} 2>/dev/null -s man/swap.3 ${INSTALLROOT}/man/man3/swap.3 || { ${STDMV} ${INSTALLROOT}/man/man3/swap.3 ${INSTALLROOT}/man/man3/swap.3.old 2>/dev/null || true; ${STDCP} man/swap.3 ${INSTALLROOT}/man/man3/swap.3 ;}
+done ${INSTALLROOT}/man/man3/swap.3 generated
+make ${INSTALLROOT}/man/man3/tab.3
+make man/tab.3
+done man/tab.3
+exec - test '' = 'man/tab.3' || ${STDCMP} 2>/dev/null -s man/tab.3 ${INSTALLROOT}/man/man3/tab.3 || { ${STDMV} ${INSTALLROOT}/man/man3/tab.3 ${INSTALLROOT}/man/man3/tab.3.old 2>/dev/null || true; ${STDCP} man/tab.3 ${INSTALLROOT}/man/man3/tab.3 ;}
+done ${INSTALLROOT}/man/man3/tab.3 generated
+make ${INSTALLROOT}/man/man3/tm.3
+make man/tm.3
+done man/tm.3
+exec - test '' = 'man/tm.3' || ${STDCMP} 2>/dev/null -s man/tm.3 ${INSTALLROOT}/man/man3/tm.3 || { ${STDMV} ${INSTALLROOT}/man/man3/tm.3 ${INSTALLROOT}/man/man3/tm.3.old 2>/dev/null || true; ${STDCP} man/tm.3 ${INSTALLROOT}/man/man3/tm.3 ;}
+done ${INSTALLROOT}/man/man3/tm.3 generated
+make ${INSTALLROOT}/man/man3/tmx.3
+make man/tmx.3
+done man/tmx.3
+exec - test '' = 'man/tmx.3' || ${STDCMP} 2>/dev/null -s man/tmx.3 ${INSTALLROOT}/man/man3/tmx.3 || { ${STDMV} ${INSTALLROOT}/man/man3/tmx.3 ${INSTALLROOT}/man/man3/tmx.3.old 2>/dev/null || true; ${STDCP} man/tmx.3 ${INSTALLROOT}/man/man3/tmx.3 ;}
+done ${INSTALLROOT}/man/man3/tmx.3 generated
+make ${INSTALLROOT}/man/man3/tok.3
+make man/tok.3
+done man/tok.3
+exec - test '' = 'man/tok.3' || ${STDCMP} 2>/dev/null -s man/tok.3 ${INSTALLROOT}/man/man3/tok.3 || { ${STDMV} ${INSTALLROOT}/man/man3/tok.3 ${INSTALLROOT}/man/man3/tok.3.old 2>/dev/null || true; ${STDCP} man/tok.3 ${INSTALLROOT}/man/man3/tok.3 ;}
+done ${INSTALLROOT}/man/man3/tok.3 generated
+make ${INSTALLROOT}/man/man3/touch.3
+make man/touch.3
+done man/touch.3
+exec - test '' = 'man/touch.3' || ${STDCMP} 2>/dev/null -s man/touch.3 ${INSTALLROOT}/man/man3/touch.3 || { ${STDMV} ${INSTALLROOT}/man/man3/touch.3 ${INSTALLROOT}/man/man3/touch.3.old 2>/dev/null || true; ${STDCP} man/touch.3 ${INSTALLROOT}/man/man3/touch.3 ;}
+done ${INSTALLROOT}/man/man3/touch.3 generated
+make ${INSTALLROOT}/man/man3/tv.3
+make man/tv.3
+done man/tv.3
+exec - test '' = 'man/tv.3' || ${STDCMP} 2>/dev/null -s man/tv.3 ${INSTALLROOT}/man/man3/tv.3 || { ${STDMV} ${INSTALLROOT}/man/man3/tv.3 ${INSTALLROOT}/man/man3/tv.3.old 2>/dev/null || true; ${STDCP} man/tv.3 ${INSTALLROOT}/man/man3/tv.3 ;}
+done ${INSTALLROOT}/man/man3/tv.3 generated
+make ${INSTALLROOT}/man/man3/vecargs.3
+make man/vecargs.3
+done man/vecargs.3
+exec - test '' = 'man/vecargs.3' || ${STDCMP} 2>/dev/null -s man/vecargs.3 ${INSTALLROOT}/man/man3/vecargs.3 || { ${STDMV} ${INSTALLROOT}/man/man3/vecargs.3 ${INSTALLROOT}/man/man3/vecargs.3.old 2>/dev/null || true; ${STDCP} man/vecargs.3 ${INSTALLROOT}/man/man3/vecargs.3 ;}
+done ${INSTALLROOT}/man/man3/vecargs.3 generated
+make ${INSTALLROOT}/man/man3/vmalloc.3
+make man/vmalloc.3
+done man/vmalloc.3
+exec - test '' = 'man/vmalloc.3' || ${STDCMP} 2>/dev/null -s man/vmalloc.3 ${INSTALLROOT}/man/man3/vmalloc.3 || { ${STDMV} ${INSTALLROOT}/man/man3/vmalloc.3 ${INSTALLROOT}/man/man3/vmalloc.3.old 2>/dev/null || true; ${STDCP} man/vmalloc.3 ${INSTALLROOT}/man/man3/vmalloc.3 ;}
+done ${INSTALLROOT}/man/man3/vmalloc.3 generated
+make ${INSTALLROOT}/lib/lib
+exec - if silent test ! -d ${INSTALLROOT}/lib/lib
+exec - then mkdir -p ${INSTALLROOT}/lib/lib
+exec - fi
+done ${INSTALLROOT}/lib/lib generated
+make ${INSTALLROOT}/lib/lib/ast
+prev ${INSTALLROOT}/lib/lib
+prev ast.req
+exec - test '' = 'ast.req' || ${STDCMP} 2>/dev/null -s ast.req ${INSTALLROOT}/lib/lib/ast || { ${STDMV} ${INSTALLROOT}/lib/lib/ast ${INSTALLROOT}/lib/lib/ast.old 2>/dev/null || true; ${STDCP} ast.req ${INSTALLROOT}/lib/lib/ast ;}
+done ${INSTALLROOT}/lib/lib/ast generated
+make ${INSTALLROOT}/include/ast
+exec - if silent test ! -d ${INSTALLROOT}/include/ast
+exec - then mkdir -p ${INSTALLROOT}/include/ast
+exec - fi
+done ${INSTALLROOT}/include/ast generated
+make ${INSTALLROOT}/include/ast/ast_common.h
+prev ${INSTALLROOT}/include/ast
+prev ast_common.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_common.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_common.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_common.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_common.h generated
+make ${INSTALLROOT}/include/ast/ast.h
+prev include/ast.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/ast.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast.h generated
+make ${INSTALLROOT}/include/ast/ast_dir.h
+prev include/ast_dir.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/ast_dir.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_dir.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_dir.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_dir.h generated
+make ${INSTALLROOT}/include/ast/ast_getopt.h
+prev include/ast_getopt.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/ast_getopt.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_getopt.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_getopt.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_getopt.h generated
+make ${INSTALLROOT}/include/ast/ast_std.h
+prev include/ast_std.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/ast_std.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_std.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_std.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_std.h generated
+make ${INSTALLROOT}/include/ast/ast_namval.h
+prev ast_namval.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_namval.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_namval.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_namval.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_namval.h generated
+make ${INSTALLROOT}/include/ast/ast_windows.h
+prev include/ast_windows.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/ast_windows.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_windows.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_windows.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_windows.h generated
+make ${INSTALLROOT}/include/ast/ccode.h
+prev include/ccode.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/ccode.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ccode.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ccode.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ccode.h generated
+make ${INSTALLROOT}/include/ast/cdt.h
+prev include/cdt.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/cdt.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/cdt.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/cdt.h
+exec - fi
+done ${INSTALLROOT}/include/ast/cdt.h generated
+make ${INSTALLROOT}/include/ast/cdtlib.h
+prev cdt/cdtlib.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' cdt/cdtlib.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/cdtlib.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/cdtlib.h
+exec - fi
+done ${INSTALLROOT}/include/ast/cdtlib.h generated
+make ${INSTALLROOT}/include/ast/cmdarg.h
+prev include/cmdarg.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/cmdarg.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/cmdarg.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/cmdarg.h
+exec - fi
+done ${INSTALLROOT}/include/ast/cmdarg.h generated
+make ${INSTALLROOT}/include/ast/debug.h
+prev include/debug.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/debug.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/debug.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/debug.h
+exec - fi
+done ${INSTALLROOT}/include/ast/debug.h generated
+make ${INSTALLROOT}/include/ast/dt.h
+prev include/dt.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/dt.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/dt.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/dt.h
+exec - fi
+done ${INSTALLROOT}/include/ast/dt.h generated
+make ${INSTALLROOT}/include/ast/error.h
+prev include/error.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/error.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/error.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/error.h
+exec - fi
+done ${INSTALLROOT}/include/ast/error.h generated
+make ${INSTALLROOT}/include/ast/find.h
+prev include/find.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/find.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/find.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/find.h
+exec - fi
+done ${INSTALLROOT}/include/ast/find.h generated
+make ${INSTALLROOT}/include/ast/ftw.h
+prev comp/ftw.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/ftw.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ftw.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ftw.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ftw.h generated
+make ${INSTALLROOT}/include/ast/ftwalk.h
+prev include/ftwalk.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/ftwalk.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ftwalk.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ftwalk.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ftwalk.h generated
+make ${INSTALLROOT}/include/ast/fts.h
+prev include/fts.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/fts.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/fts.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/fts.h
+exec - fi
+done ${INSTALLROOT}/include/ast/fts.h generated
+make ${INSTALLROOT}/include/ast/fs3d.h
+prev include/fs3d.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/fs3d.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/fs3d.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/fs3d.h
+exec - fi
+done ${INSTALLROOT}/include/ast/fs3d.h generated
+make ${INSTALLROOT}/include/ast/getopt.h
+prev comp/getopt.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/getopt.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/getopt.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/getopt.h
+exec - fi
+done ${INSTALLROOT}/include/ast/getopt.h generated
+make ${INSTALLROOT}/include/ast/glob.h
+prev include/glob.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/glob.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/glob.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/glob.h
+exec - fi
+done ${INSTALLROOT}/include/ast/glob.h generated
+make ${INSTALLROOT}/include/ast/hash.h
+prev include/hash.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/hash.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/hash.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/hash.h
+exec - fi
+done ${INSTALLROOT}/include/ast/hash.h generated
+make ${INSTALLROOT}/include/ast/hashkey.h
+prev include/hashkey.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/hashkey.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/hashkey.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/hashkey.h
+exec - fi
+done ${INSTALLROOT}/include/ast/hashkey.h generated
+make ${INSTALLROOT}/include/ast/hashpart.h
+prev include/hashpart.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/hashpart.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/hashpart.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/hashpart.h
+exec - fi
+done ${INSTALLROOT}/include/ast/hashpart.h generated
+make ${INSTALLROOT}/include/ast/ip6.h
+prev include/ip6.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/ip6.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ip6.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ip6.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ip6.h generated
+make ${INSTALLROOT}/include/ast/lc.h
+prev lc.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' lc.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/lc.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/lc.h
+exec - fi
+done ${INSTALLROOT}/include/ast/lc.h generated
+make ${INSTALLROOT}/include/ast/ls.h
+prev include/ls.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/ls.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ls.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ls.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ls.h generated
+make ${INSTALLROOT}/include/ast/magic.h
+prev include/magic.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/magic.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/magic.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/magic.h
+exec - fi
+done ${INSTALLROOT}/include/ast/magic.h generated
+make ${INSTALLROOT}/include/ast/mc.h
+prev include/mc.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/mc.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/mc.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/mc.h
+exec - fi
+done ${INSTALLROOT}/include/ast/mc.h generated
+make ${INSTALLROOT}/include/ast/mime.h
+prev include/mime.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/mime.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/mime.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/mime.h
+exec - fi
+done ${INSTALLROOT}/include/ast/mime.h generated
+make ${INSTALLROOT}/include/ast/mnt.h
+prev include/mnt.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/mnt.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/mnt.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/mnt.h
+exec - fi
+done ${INSTALLROOT}/include/ast/mnt.h generated
+make ${INSTALLROOT}/include/ast/modecanon.h
+prev include/modecanon.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/modecanon.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/modecanon.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/modecanon.h
+exec - fi
+done ${INSTALLROOT}/include/ast/modecanon.h generated
+make ${INSTALLROOT}/include/ast/modex.h
+prev include/modex.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/modex.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/modex.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/modex.h
+exec - fi
+done ${INSTALLROOT}/include/ast/modex.h generated
+make ${INSTALLROOT}/include/ast/namval.h
+prev include/namval.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/namval.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/namval.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/namval.h
+exec - fi
+done ${INSTALLROOT}/include/ast/namval.h generated
+make ${INSTALLROOT}/include/ast/option.h
+prev include/option.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/option.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/option.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/option.h
+exec - fi
+done ${INSTALLROOT}/include/ast/option.h generated
+make ${INSTALLROOT}/include/ast/proc.h
+prev include/proc.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/proc.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/proc.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/proc.h
+exec - fi
+done ${INSTALLROOT}/include/ast/proc.h generated
+make ${INSTALLROOT}/include/ast/re_comp.h
+prev comp/re_comp.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/re_comp.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/re_comp.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/re_comp.h
+exec - fi
+done ${INSTALLROOT}/include/ast/re_comp.h generated
+make ${INSTALLROOT}/include/ast/recfmt.h
+prev include/recfmt.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/recfmt.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/recfmt.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/recfmt.h
+exec - fi
+done ${INSTALLROOT}/include/ast/recfmt.h generated
+make ${INSTALLROOT}/include/ast/regex.h
+prev include/regex.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/regex.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/regex.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/regex.h
+exec - fi
+done ${INSTALLROOT}/include/ast/regex.h generated
+make ${INSTALLROOT}/include/ast/regexp.h
+prev comp/regexp.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/regexp.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/regexp.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/regexp.h
+exec - fi
+done ${INSTALLROOT}/include/ast/regexp.h generated
+make ${INSTALLROOT}/include/ast/sfio.h
+prev include/sfio.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/sfio.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/sfio.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/sfio.h
+exec - fi
+done ${INSTALLROOT}/include/ast/sfio.h generated
+make ${INSTALLROOT}/include/ast/sfio_s.h
+prev include/sfio_s.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/sfio_s.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/sfio_s.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/sfio_s.h
+exec - fi
+done ${INSTALLROOT}/include/ast/sfio_s.h generated
+make ${INSTALLROOT}/include/ast/sfio_t.h
+prev include/sfio_t.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/sfio_t.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/sfio_t.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/sfio_t.h
+exec - fi
+done ${INSTALLROOT}/include/ast/sfio_t.h generated
+make ${INSTALLROOT}/include/ast/sfdisc.h
+prev include/sfdisc.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/sfdisc.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/sfdisc.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/sfdisc.h
+exec - fi
+done ${INSTALLROOT}/include/ast/sfdisc.h generated
+make ${INSTALLROOT}/include/ast/shcmd.h
+prev include/shcmd.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/shcmd.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/shcmd.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/shcmd.h
+exec - fi
+done ${INSTALLROOT}/include/ast/shcmd.h generated
+make ${INSTALLROOT}/include/ast/stack.h
+prev include/stack.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/stack.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/stack.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/stack.h
+exec - fi
+done ${INSTALLROOT}/include/ast/stack.h generated
+make ${INSTALLROOT}/include/ast/stak.h
+prev include/stak.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/stak.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/stak.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/stak.h
+exec - fi
+done ${INSTALLROOT}/include/ast/stak.h generated
+make ${INSTALLROOT}/include/ast/stk.h
+prev include/stk.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/stk.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/stk.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/stk.h
+exec - fi
+done ${INSTALLROOT}/include/ast/stk.h generated
+make ${INSTALLROOT}/include/ast/swap.h
+prev include/swap.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/swap.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/swap.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/swap.h
+exec - fi
+done ${INSTALLROOT}/include/ast/swap.h generated
+make ${INSTALLROOT}/include/ast/tar.h
+make include/tar.h
+done include/tar.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/tar.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/tar.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/tar.h
+exec - fi
+done ${INSTALLROOT}/include/ast/tar.h generated
+make ${INSTALLROOT}/include/ast/times.h
+prev include/times.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/times.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/times.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/times.h
+exec - fi
+done ${INSTALLROOT}/include/ast/times.h generated
+make ${INSTALLROOT}/include/ast/tm.h
+prev include/tm.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/tm.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/tm.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/tm.h
+exec - fi
+done ${INSTALLROOT}/include/ast/tm.h generated
+make ${INSTALLROOT}/include/ast/tok.h
+prev include/tok.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/tok.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/tok.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/tok.h
+exec - fi
+done ${INSTALLROOT}/include/ast/tok.h generated
+make ${INSTALLROOT}/include/ast/usage.h
+make include/usage.h
+done include/usage.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/usage.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/usage.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/usage.h
+exec - fi
+done ${INSTALLROOT}/include/ast/usage.h generated
+make ${INSTALLROOT}/include/ast/vdb.h
+make include/vdb.h
+done include/vdb.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/vdb.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/vdb.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/vdb.h
+exec - fi
+done ${INSTALLROOT}/include/ast/vdb.h generated
+make ${INSTALLROOT}/include/ast/vecargs.h
+prev include/vecargs.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/vecargs.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/vecargs.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/vecargs.h
+exec - fi
+done ${INSTALLROOT}/include/ast/vecargs.h generated
+make ${INSTALLROOT}/include/ast/vmalloc.h
+prev include/vmalloc.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/vmalloc.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/vmalloc.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/vmalloc.h
+exec - fi
+done ${INSTALLROOT}/include/ast/vmalloc.h generated
+make ${INSTALLROOT}/include/ast/wait.h
+prev include/wait.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/wait.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/wait.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/wait.h
+exec - fi
+done ${INSTALLROOT}/include/ast/wait.h generated
+make ${INSTALLROOT}/include/ast/wordexp.h
+prev comp/wordexp.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/wordexp.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/wordexp.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/wordexp.h
+exec - fi
+done ${INSTALLROOT}/include/ast/wordexp.h generated
+make ${INSTALLROOT}/include/ast/bytesex.h
+prev std/bytesex.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' std/bytesex.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/bytesex.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/bytesex.h
+exec - fi
+done ${INSTALLROOT}/include/ast/bytesex.h generated
+make ${INSTALLROOT}/include/ast/endian.h
+prev std/endian.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' std/endian.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/endian.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/endian.h
+exec - fi
+done ${INSTALLROOT}/include/ast/endian.h generated
+make ${INSTALLROOT}/include/ast/fnmatch.h
+prev comp/fnmatch.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/fnmatch.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/fnmatch.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/fnmatch.h
+exec - fi
+done ${INSTALLROOT}/include/ast/fnmatch.h generated
+make ${INSTALLROOT}/include/ast/magicid.h
+make include/magicid.h
+prev ast_common.h implicit
+done include/magicid.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/magicid.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/magicid.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/magicid.h
+exec - fi
+done ${INSTALLROOT}/include/ast/magicid.h generated
+make ${INSTALLROOT}/include/ast/fnv.h
+prev include/fnv.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/fnv.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/fnv.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/fnv.h
+exec - fi
+done ${INSTALLROOT}/include/ast/fnv.h generated
+make ${INSTALLROOT}/include/ast/aso.h
+prev include/aso.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' include/aso.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/aso.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/aso.h
+exec - fi
+done ${INSTALLROOT}/include/ast/aso.h generated
+make ${INSTALLROOT}/include/ast/dirent.h
+prev std/dirent.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' std/dirent.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/dirent.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/dirent.h
+exec - fi
+done ${INSTALLROOT}/include/ast/dirent.h generated
+make ${INSTALLROOT}/include/ast/iconv.h
+prev std/iconv.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' std/iconv.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/iconv.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/iconv.h
+exec - fi
+done ${INSTALLROOT}/include/ast/iconv.h generated
+make ${INSTALLROOT}/include/ast/nl_types.h
+prev std/nl_types.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' std/nl_types.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/nl_types.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/nl_types.h
+exec - fi
+done ${INSTALLROOT}/include/ast/nl_types.h generated
+make ${INSTALLROOT}/include/ast/stdio.h
+prev std/stdio.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' std/stdio.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/stdio.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/stdio.h
+exec - fi
+done ${INSTALLROOT}/include/ast/stdio.h generated
+make ${INSTALLROOT}/include/ast/wchar.h
+prev std/wchar.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' std/wchar.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/wchar.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/wchar.h
+exec - fi
+done ${INSTALLROOT}/include/ast/wchar.h generated
+make ${INSTALLROOT}/include/ast/wctype.h
+prev std/wctype.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' std/wctype.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/wctype.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/wctype.h
+exec - fi
+done ${INSTALLROOT}/include/ast/wctype.h generated
+make ${INSTALLROOT}/include/ast/align.h
+prev align.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' align.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/align.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/align.h
+exec - fi
+done ${INSTALLROOT}/include/ast/align.h generated
+make ${INSTALLROOT}/include/ast/preroot.h
+prev preroot.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' preroot.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/preroot.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/preroot.h
+exec - fi
+done ${INSTALLROOT}/include/ast/preroot.h generated
+make ${INSTALLROOT}/include/ast/sig.h
+prev sig.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' sig.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/sig.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/sig.h
+exec - fi
+done ${INSTALLROOT}/include/ast/sig.h generated
+make ${INSTALLROOT}/include/ast/tmx.h
+prev tmx.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' tmx.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/tmx.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/tmx.h
+exec - fi
+done ${INSTALLROOT}/include/ast/tmx.h generated
+make ${INSTALLROOT}/include/ast/tv.h
+prev tv.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' tv.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/tv.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/tv.h
+exec - fi
+done ${INSTALLROOT}/include/ast/tv.h generated
+make ${INSTALLROOT}/include/ast/ast_api.h
+prev ast_api.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_api.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_api.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_api.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_api.h generated
+make ${INSTALLROOT}/include/ast/ast_botch.h
+prev ast_botch.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_botch.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_botch.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_botch.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_botch.h generated
+make ${INSTALLROOT}/include/ast/ast_ccode.h
+prev ast_ccode.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_ccode.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_ccode.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_ccode.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_ccode.h generated
+make ${INSTALLROOT}/include/ast/ast_fcntl.h
+prev ast_fcntl.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_fcntl.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_fcntl.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_fcntl.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_fcntl.h generated
+make ${INSTALLROOT}/include/ast/ast_float.h
+make ast_float.h
+prev FEATURE/float
+exec - cmp 2>/dev/null -s FEATURE/float ast_float.h || { rm -f ast_float.h; silent test -d . || mkdir .; ${STDCP} FEATURE/float ast_float.h; }
+prev ast_common.h implicit
+done ast_float.h generated
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_float.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_float.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_float.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_float.h generated
+make ${INSTALLROOT}/include/ast/ast_fs.h
+prev ast_fs.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_fs.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_fs.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_fs.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_fs.h generated
+make ${INSTALLROOT}/include/ast/ast_lib.h
+prev ast_lib.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_lib.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_lib.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_lib.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_lib.h generated
+make ${INSTALLROOT}/include/ast/ast_map.h
+prev ast_map.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_map.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_map.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_map.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_map.h generated
+make ${INSTALLROOT}/include/ast/ast_mmap.h
+prev ast_mmap.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_mmap.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_mmap.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_mmap.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_mmap.h generated
+make ${INSTALLROOT}/include/ast/ast_mode.h
+prev ast_mode.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_mode.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_mode.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_mode.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_mode.h generated
+make ${INSTALLROOT}/include/ast/ast_ndbm.h
+make ast_ndbm.h
+make FEATURE/ndbm
+meta FEATURE/ndbm features/%>FEATURE/% features/ndbm ndbm
+make features/ndbm
+done features/ndbm
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/ndbm
+prev std/stdio.h implicit
+done FEATURE/ndbm generated
+exec - cmp 2>/dev/null -s FEATURE/ndbm ast_ndbm.h || { rm -f ast_ndbm.h; silent test -d . || mkdir .; ${STDCP} FEATURE/ndbm ast_ndbm.h; }
+done ast_ndbm.h generated
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_ndbm.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_ndbm.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_ndbm.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_ndbm.h generated
+make ${INSTALLROOT}/include/ast/ast_param.h
+prev ast_param.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_param.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_param.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_param.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_param.h generated
+make ${INSTALLROOT}/include/ast/ast_sys.h
+prev ast_sys.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_sys.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_sys.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_sys.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_sys.h generated
+make ${INSTALLROOT}/include/ast/ast_time.h
+prev ast_time.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_time.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_time.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_time.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_time.h generated
+make ${INSTALLROOT}/include/ast/ast_tty.h
+prev ast_tty.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_tty.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_tty.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_tty.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_tty.h generated
+make ${INSTALLROOT}/include/ast/ast_vfork.h
+prev ast_vfork.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_vfork.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_vfork.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_vfork.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_vfork.h generated
+make ${INSTALLROOT}/include/ast/ast_wait.h
+prev ast_wait.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_wait.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_wait.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_wait.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_wait.h generated
+make ${INSTALLROOT}/include/ast/ast_limits.h
+prev ast_limits.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_limits.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_limits.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_limits.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_limits.h generated
+make ${INSTALLROOT}/include/ast/ast_standards.h
+prev ast_standards.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_standards.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_standards.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_standards.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_standards.h generated
+make ${INSTALLROOT}/include/ast/ast_sizeof.h
+make ast_sizeof.h
+make FEATURE/sizeof
+meta FEATURE/sizeof features/%>FEATURE/% features/sizeof sizeof
+make features/sizeof
+done features/sizeof
+exec - iffe -v -X ast -X std -c '${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS} ' run features/sizeof
+done FEATURE/sizeof generated
+exec - cmp 2>/dev/null -s FEATURE/sizeof ast_sizeof.h || { rm -f ast_sizeof.h; silent test -d . || mkdir .; ${STDCP} FEATURE/sizeof ast_sizeof.h; }
+done ast_sizeof.h generated
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_sizeof.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_sizeof.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_sizeof.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_sizeof.h generated
+make ${INSTALLROOT}/include/ast/ast_dirent.h
+prev ast_dirent.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_dirent.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_dirent.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_dirent.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_dirent.h generated
+make ${INSTALLROOT}/include/ast/ast_iconv.h
+prev ast_iconv.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_iconv.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_iconv.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_iconv.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_iconv.h generated
+make ${INSTALLROOT}/include/ast/ast_nl_types.h
+prev ast_nl_types.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_nl_types.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_nl_types.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_nl_types.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_nl_types.h generated
+make ${INSTALLROOT}/include/ast/ast_stdio.h
+prev ast_stdio.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_stdio.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_stdio.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_stdio.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_stdio.h generated
+make ${INSTALLROOT}/include/ast/ast_wchar.h
+prev ast_wchar.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_wchar.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_wchar.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_wchar.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_wchar.h generated
+make ${INSTALLROOT}/include/ast/ast_wctype.h
+prev ast_wctype.h
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' ast_wctype.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/ast_wctype.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/ast_wctype.h
+exec - fi
+done ${INSTALLROOT}/include/ast/ast_wctype.h generated
+make ${INSTALLROOT}/lib/file
+exec - if silent test ! -d ${INSTALLROOT}/lib/file
+exec - then mkdir -p ${INSTALLROOT}/lib/file
+exec - fi
+done ${INSTALLROOT}/lib/file generated
+make ${INSTALLROOT}/lib/file/magic
+prev ${INSTALLROOT}/lib/file
+make misc/magic.tab
+done misc/magic.tab
+exec - test '' = 'misc/magic.tab' || ${STDCMP} 2>/dev/null -s misc/magic.tab ${INSTALLROOT}/lib/file/magic || { ${STDMV} ${INSTALLROOT}/lib/file/magic ${INSTALLROOT}/lib/file/magic.old 2>/dev/null || true; ${STDCP} misc/magic.tab ${INSTALLROOT}/lib/file/magic ;}
+done ${INSTALLROOT}/lib/file/magic generated
+make ${INSTALLROOT}/include/ast/fmtmsg.h
+prev comp/fmtmsg.h
+prev ast_lib.h
+exec - case ${mam_cc_HOSTTYPE} in
+exec - win32.*)proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/fmtmsg.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/fmtmsg.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/fmtmsg.h
+exec - fi
+exec - ;;
+exec - *) silent grep -l 'define[ ][ ]*_[hl][di][rb]_fmtmsg' ast_lib.h > /dev/null || {
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/fmtmsg.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/fmtmsg.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/fmtmsg.h
+exec - fi
+exec - }
+exec - ;;
+exec - esac
+prev ${INSTALLROOT}/include/prototyped.h implicit
+done ${INSTALLROOT}/include/ast/fmtmsg.h generated
+make ${INSTALLROOT}/include/ast/libgen.h
+prev comp/libgen.h
+prev ast_lib.h
+exec - case ${mam_cc_HOSTTYPE} in
+exec - win32.*)proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/libgen.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/libgen.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/libgen.h
+exec - fi
+exec - ;;
+exec - *) silent grep -l 'define[ ][ ]*_[hl][di][rb]_libgen' ast_lib.h > /dev/null || {
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/libgen.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/libgen.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/libgen.h
+exec - fi
+exec - }
+exec - ;;
+exec - esac
+prev ${INSTALLROOT}/include/prototyped.h implicit
+done ${INSTALLROOT}/include/ast/libgen.h generated
+make ${INSTALLROOT}/include/ast/syslog.h
+prev comp/syslog.h
+prev ast_lib.h
+exec - case ${mam_cc_HOSTTYPE} in
+exec - win32.*)proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/syslog.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/syslog.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/syslog.h
+exec - fi
+exec - ;;
+exec - *) silent grep -l 'define[ ][ ]*_[hl][di][rb]_syslog' ast_lib.h > /dev/null || {
+exec - proto -p -s -l ${PACKAGEROOT}/lib/package/ast.lic '-o since=1985,author=gsf+dgk+kpv' comp/syslog.h > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/syslog.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/syslog.h
+exec - fi
+exec - }
+exec - ;;
+exec - esac
+prev ast_namval.h implicit
+prev ${INSTALLROOT}/include/prototyped.h implicit
+done ${INSTALLROOT}/include/ast/syslog.h generated
+make ${INSTALLROOT}/include/ast/prototyped.h
+prev ${INSTALLROOT}/include/ast
+exec - echo "#include <../prototyped.h>" > 1.${COTEMP}.x
+exec - if cmp 2>/dev/null -s ${INSTALLROOT}/include/ast/prototyped.h 1.${COTEMP}.x
+exec - then rm -f 1.${COTEMP}.x
+exec - else mv 1.${COTEMP}.x ${INSTALLROOT}/include/ast/prototyped.h
+exec - fi
+done ${INSTALLROOT}/include/ast/prototyped.h generated
+done install virtual
+make test
+done test dontcare virtual
diff --git a/src/lib/libast/README b/src/lib/libast/README
new file mode 100644
index 0000000..cc0cf82
--- /dev/null
+++ b/src/lib/libast/README
@@ -0,0 +1,95 @@
+The advanced software technology department has been collecting useful C
+routines in a single library called libast. libast is used by nmake, the
+nmake cpp (which is mainly based on another library (libpp)), CIA
+(C information abstractor from Robin Chen), and a collection of other
+/bin and /usr/bin commands that benefit from concentrating functionality
+in libast.
+
+More detail is available in the man pages. libast contains:
+
+ (1) routines to support a generic environment for
+ a variety of UNIX operating system variants
+
+ (2) routines that update standard libc routines
+
+ (3) routines shared between several commands
+
+If you already have nmake 2.0 or newer installed then use
+`nmake install' from this directory, otherwise use
+ship/shipin from the root of the distribution directory tree.
+
+Some of the routines not found in section 3:
+
+hash: generic, scoped hash table support
+
+ hashalloc create a hash table or push new scope
+ hashdump debug dump of one or all hash tables
+ hashfree free a hashalloc()'d table
+ hashlook low level name lookup
+ hashscan entry generator for scoped table scan
+ hashsize explicitly change table size (usually automatic)
+ hashwalk apply function to each table entry
+ memhash return hash code for n-char chunk of memory
+ strhash return hash code for null terminated string
+
+include/ast: libast support headers
+
+ align.h compile time type alignmnent support
+ dirent.h POSIX directory(3) interface definitions
+ error.h error() interface definitions
+ ftw.h ftwalk() interface definitions
+ hash.h hash*() interface definitions
+ ls.h strls() interface definitions
+ re.h re*() interface definitions
+ tar.h POSIX ustar format interface definitions
+ tm.h tm*() interface definitions
+
+misc:
+
+ cmdargs apply a sequence of cmd line option parsers
+ cmdopen like popen() but stdin and stdout are specified
+ cvtatoe convert ASCII to EBCDIC
+ cvtetoa convert EBCDIC to ASCII
+ error output generic error and trace messages
+ ftwalk an ftw(3) that works -- used in new tw(1)
+ getcwd uses $PWD if ok, doesn't use /bin/pwd
+ getshell return full path of shell for cmdopen()
+ ooptget optget() for obsolete ar(1) and tar(1) options
+ optget YA getopt(3) but no argc or error message output
+ pathaccess find file with specific acces on list of dirs
+ pathcanon canonicalize path name in place
+ pathcmd return full path name of executable using $PATH
+ pathroot determine `related root' directory for command
+ perror uses strerror()
+ readargs append each line of file to argv[0]
+
+re: egrep(1) and ed(1) style re's from V9
+ (not the good awk(1) algorithm)
+
+ recomp compile re pattern
+ reerror report re*() errors
+ reexec match string using compiled re
+ resub ed(1) style substitute using last reexec()
+
+string:
+
+ chresc return next char in string converting \ sequences
+ ctoi convert char constant string to int
+ strcopy like strcpy(3) but returns end of destination
+ strdup malloc(3) and strcpy(3) smashed together
+ strerror return error message string given errno
+ stresc convert \ sequences in string in place
+ streval evaluate C expression in string
+ strls ls -l format support
+ strmatch Korn shell file pattern match
+ strmode return ls -l style output given st.st_mode
+ strsignal return signal id string given SIG* number
+ strtape convert generic tape unit to /dev/* file
+ token generate space separated tokens in string
+
+tm: time conversion support
+
+ tmdate convert date string to time_t
+ tmform format time_t to date string
+ tmmake return current time_t
+ tmtime convert struct tm to time_t
diff --git a/src/lib/libast/RELEASE b/src/lib/libast/RELEASE
new file mode 100644
index 0000000..cb9fb68
--- /dev/null
+++ b/src/lib/libast/RELEASE
@@ -0,0 +1,1769 @@
+12-03-10 misc/optget.c: HELP_index for "PLUGIN" too
+12-02-29 include/shcmd.h: PLUGIN_VERSION 20111111 for cdt disc/meth change
+12-02-29 comp/spawnveg.c: fix sigcritical() to include waitpid() for internal child
+12-02-29 malloc.c: make __malloc_hook initialization thread safe
+12-02-24 comp/iconv.c: fix winix UTF-8 vs UCS-2 over-conversion
+12-02-24 astsa/*.h: clean up header guards
+12-02-24 astsa/astsa.omk: clean up standalone old make makefile interactions
+12-02-21 misc/cmdarg.c: fix bug that set argv[0]
+12-02-10 sfvprintf.c: fix 1 byte too long buffer access
+12-02-07 malloc.c/features/vmalloc: add gnu __malloc_hook tests
+12-02-06 vmmopen.c: fix ALIGN vs sys/param.h macro conflict
+12-02-02 astlicense.c: add license.component for component-specific licenses
+12-01-31 spawnveg.c: fix transient bug that made invalid setpgid() call
+12-01-27 pathpath.c: fix buffer size math when internal allocation requested
+12-01-24 malloc.c: fix _vmkeep() bug that did not return previous state
+12-01-23 malloc.c: add VMALLOC_OPTIONS=break to try sbrk() block allocator first
+12-01-21 astlicense.c: option style only overrides default license.type
+12-01-18 malloc.c: disable multiple regions for tracing or !vmbest or ASO_SIGNAL
+12-01-12 sfpkrd.c: add __sun I_PEEK+rsh runtime workaround
+12-01-10 shcmd.h: void* => Shbltin_t*
+12-01-10 tmxdate.c: handle { n>=1000 } TM_PARTS
+11-12-21 plug up some meory links -- thanks mhlavink
+11-12-21 vmprivate.c: enclose VM_NONMEM exception in CLRLOCK(vm,0) ... SETLOCK(vm,0)
+11-12-13 aso: in -lposix for uwin, not -last -- just like vmalloc
+11-12-13 sfpoll.c: all streams SF_IOINTR => don't ignore EINTR
+11-12-13 sfdcslow.c: set SF_IOINTR
+11-12-09 malloc.c: add _vmkeep() for setlocale() intercept _SYS_setlocale_free_OK
+11-12-04 sfio: _Sfmaxr=0 (unlimited) by default; use ulimit -M|-d or SFIO_OPTIONS
+11-12-01 aso: sync to new api
+11-11-11 optget.c: move .TH to the top for --nroff to get our macros first
+11-11-11 aso,cdt,vmalloc: resync with kpv
+11-11-11 cdt: preserve bits and Dt_link_t for CDT_VERSION < 20111111
+11-10-24 sfvprintf.c: %.-ns truncate from left to n chars
+11-10-21 sfvprintf.c: fix %0s (no width) core dump
+11-10-10 aso: add _WIN32 support
+11-09-26 vmalloc: sync with kpv
+11-08-29 features/{dirent,wchar,wctype}: eliminate #include with no header
+11-08-25 #pragma prototyped tweaks -- sun4 is dead, long live sun4
+11-08-25 ftwalk.c: FTS_SLNONE => FTW_SL
+11-08-11 features/wchar: fix #include _nxt_wchar for K&R C
+11-08-04 optget.c: tweak --html rendering
+11-07-24 mime.c: add %(default)[st] default if arg == ""
+11-07-21 setlocale.c: fix debug locale to treat "<<" as two single byte chars
+11-06-14 spawnveg.c: pgid -1: new session -2: setpgrp()&&tcsetpgid()
+11-06-14 pathprog.c: add darwin _NSGetExecutablePath
+11-05-14 features/common,features/align.c: { _X86_ _X64_ } conditionals for generic uwin
+11-05-13 tm/tminit.c: tweak tzname[] prototype
+11-05-09 astlicense.c: add ". file" parent-relative include and depth 4 input stack
+11-05-05 cmdarg: update to cmdopen_20110505 api
+11-05-03 sfio/sfclose.c: make sure close() errors propagate to sfclose() return value
+11-04-20 port/astlicense.c: add { id name } keys
+11-04-15 fmtdev.c: fix to work for non-{blk,chr} special
+11-04-12 stk: change size args to size_t and stseek() offset to ssize_t
+11-04-12 sfio: sync with kpv to optimize large SF_STRING sfputr() buffer allocation
+11-03-28 misc/fts.c: fix FTS_SLNONE logic to set it when it should!
+11-03-17 misc/stk.c: fixed bug that could delete an active stack frame
+11-03-10 sfio/sfvprintf.c: add %0<width>s to preserve <width> trailing chars in string arg
+11-03-09 misc/magic.c: add %d...%s where if %d==1 then %s=="" else %s=="s"
+11-03-09 misc/magic.tab: add windows ico
+11-02-08 misc/stk.c: change STK_FSIZE to (1024*sizeof(char*)) for 64 bit normalization
+11-02-02 sfio/sfmode.c: don't call sfsetbuf() on unbuffered stream to make it unbuffered
+11-02-02 features/wchar: handle hp.ia64 va_list interactions
+11-02-02 comp/omitted.c: fix mismatch between stat() vs _stat()
+11-01-31 std/wctype,features/wctype: add to handle <wchar.h> interactions
+11-01-28 add -lw for ancient sunos
+11-01-28 include/magic.h,misc/magic.c: add MAGIC_ALL
+11-01-27 tm/tmxfmt.c,tmpoff.c: %_z for SHH:MM
+11-01-25 features/wchar: change <wctype.h> <wchar.h> ordering
+10-12-24 sfstrtof.h: fix thousand grouping bug that did not check last group
+10-12-21 pathkey.c: add win32 { /32 /64 } preroot to hash
+10-12-09 pathprog.c: handle intermediate path != '* and fix invalid pathpath() call
+10-12-01 astconf.c: fix look.standard undefined variable reference
+10-12-01 sfset.c: SF_LINE|SF_WCWIDTH => no need for sfsetbuf() to call isatty()
+10-12-01 sfsetbuf.c: cache /dev/null <dev,ino> to cut down /dev/null stat()'s
+10-12-01 optget.c: delay dictionary initialization until needed
+10-11-30 malloc.c: drop { VMDEBUG VMETHOD VMPROFILE VMTRACE } env checks
+10-11-30 port/astconf.c: eliminate esaccess() calls for OP_universe checks
+10-11-24 regcomp.c: [[=]=]] must at least match itself in non-C locales
+10-11-23 glob.h,glob.c: add GLOB_GROUP => REG_SHELL_GROUP
+10-11-20 glob.c: handle mode switches across /
+10-11-19 regcomp.c: REG_SHELL => REG_CLASS_ESCAPE
+10-11-16 vmalloc.h: add VMFL tracing to vmstrdup()
+10-11-16 ast.h: simplify VMDEBUG _BLD_DEBUG and VMFL logic
+10-11-12 tm/tmlocale.c: ast TM_* extensions default to C locale
+10-11-10 regex/regnexec.c,vmalloc/vmstat.c: eliminate strict-aliasing puns
+10-10-20 misc/translate.c: change debug translation to drop " in (a,b,c,"d")
+10-10-10 misc/glob.c: drop ancient D_FILENO(d)!=0 test and trust readdir()
+10-10-06 misc/translate.c: fix "debug" locale logic
+10-10-04 misc/magic.c: fix magic() skip check to honor the continuation
+10-10-04 regex/regcoll.c: add wchar_t* args to regcollate(), drop ucs name lookup
+10-09-28 comp/setlocale.c: add utf8_wctomb()
+10-09-28 string/chresc.c,regex/regcoll.c: fix \S[.X.] (\C[.X.] never worked!)
+10-09-24 string/chresc.c: \Cc for control c, \S[.X.] for collating symbol X
+10-09-24 string/chresc.c: { \cc \e } deprecated
+10-09-22 regex/regcomp.c: fix off-by-one collation class allocation bug
+10-09-20 regex/regclass.c: fix CTYPES off-by-one bug
+10-09-14 comp/conf.sh: const int conf_elements, prefix_elements;
+10-09-08 add features/sizeof => ast_sizeof.h
+10-08-31 comp/getopt[l].c: export functions for dlls
+10-08-25 port/lc.c: add features/locale check for canonical UTF-8 spelling
+10-08-20 include/ast.h: add export plugin_version() prototype
+10-08-20 comp/conf.tab: add SF_BUFSIZE
+10-08-11 misc/conformance.c: conformance(0,0) => "standard"
+10-08-11 misc/conformance.c: check ast_env_serial for dynamic astconf() changes
+10-08-11 port/lcgen.c: remember to fudge Table_t.count for synthesized entries
+10-08-04 include/ast.h,comp/setlocale.c: add { debug C.UTF-8 } mbalpha() mbwidth()
+10-08-02 misc/translate.c: add NLSPATH message cache check
+10-07-29 string/fmtint.c: fix nasty bug that rendered "1000" as "1"
+10-07-27 setlocale,lsgen,localeconv: handle C vs C_EU decimal thousands sep
+10-07-26 misc/optget.c: fix interaction with nested plugin/builtin calls
+10-06-29 string/strtoi.h: strton() multiplier 1 => power of two suffix
+10-06-28 features/wchar: handle systems that require __va_list => va_list
+10-06-28 comp/conf.tab: another PID_MAX tweak -- default to 99999 for most
+10-06-28 port/astconf.c: lone "CONFORMANCE = standard" => all defaults standard
+10-06-25 misc/optget.c: avoid sfprints() call during initialization
+10-06-01 features/api, ast_api.h: formalized forwards/backwards api compatibility
+10-06-01 _AST_API=20100601: add size_t args for all path*() output buffers
+10-06-01 comp/setlocale.c: handle C.UTF-8 test locale
+10-06-01 include/mc.h: add size_t to mcfind() for result buffer (internal api)
+10-06-01 use strlcpy() instead of strncpy()
+10-05-28 include/ast_version.h: add AST_PLUGIN_VERSION for dllplugin()
+10-05-28 include/shcmd.h: add SH_PLUGIN_VERSION for dllplugin()
+10-05-28 misc/conformance.c: add conformance(3)
+10-05-28 misc/optget.c: add [(id1|id2)...] conformance("id1|id2",0) conditionals
+10-05-25 include/sfhdr.h: adjust SF_NMAP according to _ptr_bits
+10-05-25 include/shcmd.h: add sh_builtin() macro for lib_init() table initialization
+10-05-21 misc/optget.c: --html \bfoo::bar([[:digit:]][[:upper:]]*) => foo-bar.html
+10-05-15 include/proc.h,misc/procopen.c: add PROC_ORPHAN
+10-05-09 misc/optget.c: add --???MAN[section] --???SECTION
+10-05-07 sfio,stdio: fix all snprintf() variants to handle buf==0 and/or n==0
+10-05-04 string/fmtesc.c: add mb iswsoace() and iswcntrl() quoting checks
+10-05-03 fix LC_MESSAGES catalog lookup bugs, check for $set==3, accept $set==1
+10-04-30 string/chresc.c: add chrexp() for FMT_EXP_*
+10-04-30 string/stresc.c: add strexp() for FMT_EXP_*
+10-04-30 string/chresc.c: fix \uXXXXY bug that consumed Y
+10-04-22 misc/optget.c: check for html entities in <A name="...">
+10-04-22 misc/getcwd.c: add features/syscall check for SYSGETCWD() { linux solaris }
+10-04-22 string/stresc.c: wide chars absent locale guidance default to UTF-8
+10-04-12 port/mnt.c: favor bsd getfsstat() over getmntinfo()
+10-04-11 string/strtoi.h: k (1000) and ki (1024) now differentiated
+10-04-10 misc/recstr.c: fix 'd[delimiter]' parse
+10-04-08 include/vmalloc.h,vmalloc/vmstat.c: add Vmstat_t.mode region mode bits
+10-04-05 misc/fts.c: drop 1997-01-07 fts_open()=0 is one file and stat() fails
+10-04-05 misc/optget.c,optlib.h: add Optpass_t.release for --nroff .TH
+10-04-02 misc/optget.c: fix $'[-n?\n...]' --version bug
+10-04-02 regex/regcomp.c: ~(X) => REG_EXTENDED|REG_AUGMENTED, ~(PU) instead of ~(U)
+10-03-24 misc/procopen.c: add PROC_FD_CTTY(fd)
+10-03-24 path/pathtemp.c: fix pointer => int casts
+10-03-15 regex/regcache.c: fix 1 byte buffer overflow (didn't count trailing \0)
+10-03-08 features/tvlib: fix utimensat probe to include all macros/structs
+10-03-07 features/lib: change stream_peek to test pipes only
+10-03-07 string/strelapsed.c: fix next char return overrun
+10-03-06 tm/tvtouch.c: use runtime fallback if utimensat() fails with ENOSYS
+10-03-05 path/pathtemp.c: add pfx /seed for regression testing
+10-03-04 vmalloc/vmwalk.c: add user supplied handle arg
+10-03-04 path/pathtemp.c: properly handle mktemp()-style *+(X) templates
+10-03-03 include/ast_getopt.h: remove NULL guard - _AST_GETOPT_H now handles it
+10-02-24 comp/getopt.h: fix ast_std.h interactions
+10-02-24 vmalloc/malloc.c: empty { VMALLOC_OPTION VMDEBUG ... } => no debug!
+10-02-02 string/base64.c: fix corner case output buffer overflow
+10-02-02 features/fs: sys/mnttab.h requires stdio.h on some systems!!
+10-02-01 misc/optget.c: uppercase --html heading -- doh
+10-01-29 misc/optget.c: [+NAME?...] overrides error_info.id for >= STYLE_man
+10-01-25 vmalloc/vmprivate.c: fix seg ptr initialization bug (24 years old!!)
+10-01-20 misc/optget.c: handle nested {...} rendering
+10-01-20 misc/state.c: add ast.version for runtime api version
+10-01-20 port/astconf.c: "_AST_VERSION" now returns ast.version
+10-01-20 include/ast_std.h: add ast.version for runtime api version
+10-01-19 astlicense.c: add epl
+10-01-01 vmalloc: VMALLOC_OPTIONS env var for all runtime options
+10-01-01 include: change some <ast.h> refs to less intrusive <ast_*.h>
+10-01-01 setlocale.c,translate.c,fmterror.c: AST_LC_internal retains prev state
+10-01-01 comp/setlocale.c: AST_LC_setenv defers to LC_ALL (for sh)
+10-01-01 ast_std.h: add { AST_LC_internal AST_LC_setenv }
+09-12-24 comp/setlocale.c: fix setlocale(LC_ALL,"") when already initialized
+09-12-17 misc/optget.c: handle mixed solaris usage="x:f:(in)yo:(out)"
+09-12-11 regex/regcomp.c: posix semantics for [z-a]
+09-12-11 regex/regcomp.c: fix BRE/ERE ^^ logic
+09-12-11 regex/regcomp.c: fix regcomb() for REG_LEFT|REG_RIGHT
+09-12-11 regex/regcomp.c: bm complete=0 if REX_END
+09-12-11 comp/sigflag.c: add with npt check in features/sig.sh
+09-12-11 tm/tminit.c: fix _tzset_environ logic
+09-12-09 tm/tmlocale.c: include "ast_nl_types.h" to pull nl_langinfo in!
+09-12-04 features/options: add "opt map-libc" check
+09-12-03 tm/tmxdate.c: fix 'next month final day' for dec -> jan
+09-11-21 misc/magic.tab: add gimp XCF
+09-11-20 vmalloc/vmtrace.c: add pid to assertion disgnostics
+09-11-11 regex.h,regcomp.c: add REG_CLASS_ESCAPE, \ inside [...] literal by default
+09-11-03 regex/regcache.c: change to variable length pattern strings
+09-10-28 include/error.h: fix ERROR_translate() arg parens
+09-10-26 port/lcgen.c,comp/setlocale.c: handle LANG init after LC_* already defined
+09-10-05 _sfopen.c: add but ignore 'F' flags for stdio compatibility
+09-09-28 fts.h,ftwalk.h,fts.c: promote { namelen pathlen level } to (s)size_t
+09-09-28 locales: add AST_LC_LANG for $LANG
+09-09-28 setlocale.c: fix logic for dynamic { LANG LC_ALL LC_* } changes
+09-09-17 include/sfio.h,sfio/sfwalk.c: add sfwalk()
+09-09-09 sfio/sfputr.c: add SIGPIPE hang fix
+09-08-24 sfio/sfreserve.c: fix SF_UNBOUND logic with pushed streams
+09-08-18 include/ast_std.h,ast.h: add ast.mb_sync to sync mbchar() after error
+09-08-17 comp/setlocale.c: add AST_LC_utf8 and { utf8_mbtowc() utf8_mblen() }
+09-08-11 comp/setlocale.c: treat "en"/"en_US" AST_LC_MESSAGES as "C"/"POSIX"
+09-08-10 vmalloc/vmhdr.h: add user-defined _AST_PAGESIZE and computed VMHEAPINCR
+09-08-09 comp/conf.tab: add NPROCESSORS_MAX
+09-07-29 astlicense.c: fix first name=value logic error
+09-07-22 string/fmtip6.c: don't drop trailing 0 in 44::1:0:0
+09-06-30 port/astconf.c: standard PATH_RESOLVE is "physical" (not "metaphysical")
+09-06-19 vmalloc: sync with kpv
+09-06-19 include/shcmd.h: add sh_context(p) cast
+09-06-11 misc/magic.tab: differentiate pc 386 32/64 bit dll/exe/obj
+09-06-06 port/astconf.c: fix look->name null pointer reference
+09-06-05 port/astconf.c: fix 'UNIVERSE = value' synthesize logic
+09-05-25 tm/tmxduration.c: add
+09-05-08 comp/syslog.c: add _UWIN /var/log/syslog preference
+09-05-01 comp/setlocale.c: fix _UWIN intercepts to return NiL on unknown locales
+09-04-27 sfio/sfpool.c: fix bug that did not return pool on delete
+09-04-22 include/regex.h,regex/regcomp.c: add REG_REGEXP <regexp.h> compatibility
+09-04-15 tm/tmxdate.c: handle "4th thursday in november"
+09-03-31 string/strvcmp.c,string/strnvcmp.c: add version strcmp(3)
+09-03-31 string/strpcmp.c,string/strnpcmp.c: add path prefix strcmp(3)
+09-03-29 misc/optget.c: clean up num = number casts
+09-03-04 tm/tmxmake.c: add tmxtm() with zone override
+09-03-03 tm/tmxfmt.c: add %(...)<c>, specifically %(...)z for output zone
+09-02-22 tm/tmxdate.c: add iso P... durations
+09-02-02 path/pathprog.c: add
+09-02-02 misc/opthdr.h,optget.c: fix flags mixup, handle old '-' as option
+09-02-02 sfio/sfprints.c: fix sfvaprints() return value to not count trailing '\0'
+09-02-02 misc/cmdarg.c: handle !defined(ARG_MAX)
+09-02-02 port/astconf.c: fix UNIVERSE overwrite of null[] value!
+09-01-31 features/sys: drop header sys/localedef.h
+09-01-28 include/fs3d.h,misc/fs3d.c: mount() => fs3d_mount() for diff std prototypes
+09-01-14 misc/fts_open.c: delay top list reorder until first fts_read()
+09-01-14 include/ls.h: LS_W_INUMBER => 9 to accomodate large st_ino
+09-01-14 misc/optget.c: expand STYLE_usage input text
+09-01-09 features/uwin,stdio/_stdfun.c: iffe for _p__iob and __p__iob
+09-01-09 misc/magic.tab: add ISO filesystem image entries
+09-01-07 string/strtoi.c: strtol() etc. do not consume [lLuU] suffix -- thanks jkf
+09-01-07 sfio/sfstrtof.h: strtod() etc. do not consume [fFlL] suffix -- thanks jkf
+09-01-05 string/strlcat.c: fix logic to match docs (not that easy)
+08-12-30 tm/tmxdate.c,include/tm.h: add TM_WORK { "workday" "working" "work" }
+08-12-28 sfio/sfcvt.c: fix 'a' format rounding
+08-12-21 tm/tmdata.c: add 2008-12-31+23:59:60-0000 leap second event
+08-12-19 tm/tmxdate.c: check for dates near the epoch rolling back to the future
+08-12-19 tm/tmxfmt.c: change %s for now==0 to be the epoch
+08-12-07 include/ast_std.h,misc/getenv.c: no _ast_getenv for uwin ast54 compatibility
+08-12-07 tm/tmxfmt.c: add %[_][EO]K for [space pad] [full|long] iso
+08-12-07 sfio/sfvscanf.c: fix ok[] short by one allocation
+08-12-07 comp/setlocale.c: fix off by one composite initialition loop test
+08-12-07 path/pathkey.c: fix off by one loop test
+08-12-04 vmalloc/vmbest.c: catch sbrk() wraparound
+08-12-04 comp/spawnveg.c: clean up attrs on failure too
+08-11-04 regex/regcomp.c: fix locale [!-...] and [^-...] re-initialization
+08-11-04 stdio: add flockfile.c ftrylockfile.c funlockfile.c
+08-10-24 port/astconf.c: handle multiple/trailing '/' in universe initialization
+08-09-10 misc/magic.c: handle old vcodex() indices
+08-09-10 sfio/sfvprintf.c: drop SF_WCWIDTH, use %Lc or %Ls instead
+08-09-05 Makefile: ibm.risc joins the :NOOPTIMIZE: crowd
+08-09-04 regex/regnexec.c: fix nested delimiter match beyond end of subject
+08-08-20 misc/fts.c: fix st_nlink stat() optimization logic
+08-08-19 sfio/sfpkrd.c: workaround macosx recv(PEEK) data consumption on non-socket
+08-08-19 strn?tol?d: handle long double with smaller exponent range than double
+08-08-18 sfio/sfcvt.c: eliminate excessive multiplies and integral overprecision
+08-08-11 tm/tmxfmt.c: handle %10N and %010N
+08-08-06 include/shcmd.h: add 'int invariant;' for builtin invariant arg count
+08-08-05 features/ndbm: favor sleepycat ndbm compatibility
+08-07-21 include/glob.h,misc/glob.c: GLOB_STARSTAR only forces lstat on chdir
+08-07-17 sfio: sync with kpv
+08-07-17 misc/optget.c: call astwinsize() each time terminal width required
+08-07-16 sfio/sfvscanf.c: fix %% to skip leading space per posix
+08-07-16 vmalloc/vmbest.c: add VMCHECK=m, VM_mmap to favor mmap() alloc
+08-07-16 features/stdio,stdio/f(read|write).c: size_t return value!! ouch
+08-06-24 tm/tmxfmt.c: fix %z to handle tm_isdst -- doh
+08-06-24 misc/astintercept.c,misc/getenv.c: split from misc/setenviron.c
+08-06-17 misc/setenviron.c: add { astintercept() getenv() }
+08-06-09 tm/tmlocale.c: use _DATE_FMT if defined for TM_DEFAULT
+08-06-06 misc/optget.c: handle sub-component about details
+08-06-04 misc/optget.c: fix [-n?\n...\n] version parse
+08-06-04 include/debug.h,misc/debug.c: merge with kpvdebug.h
+08-06-02 features/ndbm: add to tame dbmlib.iffe replication
+08-06-01 comp/resolvepath.c,realpath.c: fix resolvepath() return value type
+08-05-22 tm/tmxdate.c: fix a few ordinal/last/this/next bugs
+08-05-18 string/fmtre.c: fix omitted stack var initialization bug
+08-05-14 regex/regcomp.c,regcoll.c: fix UTF-8 collation sequence logic
+08-05-11 tm/tmxfmt.c: :NOOPTIMIZE:, otherwise %Q/../../ fails
+08-05-01 tm/tmxdate.c: mon 1..12 => mon[13] -- doh
+08-04-30 misc/glob.c,reegex/regcomp.c: ~(R) => ~(O) to avoid pcre clash
+08-04-24 port/astconf.c: 'name = value' does assignment without system init
+08-04-15 port/astconf.c: SC#N treated like 'SC(N)'
+08-04-14 misc/optget.c: clean up nroff output
+08-04-01 port/astconf.c: add RELEASE => /proc/version fallback
+08-03-30 misc/optget.c: [-n]... to enable -number & +number options
+08-03-06 misc/optget.c: ---* and +++* are now operands
+08-03-06 misc/errorx.c: fix old error_info.translate workaround
+08-02-05 regex/regcomp.c: allow REG_SHELL {,n}... => {0,n}...
+08-02-27 misc/stk.c: top element during allocation relocated to top
+08-02-18 include/ip6.h,string/strtoip6.c,fmtip6.c: add ipv6 addr support
+08-02-14 regex/regsubexec.c: fix null match (tricky)
+08-02-14 regex/regsubcomp.c: fix SRE to match ksh
+08-02-11 comp/spawnveg.c: return proper errno on [v]fork() failure
+08-02-11 tm/tmxdate.c,tmdata.c: handle more ISO 8601:2000 forms
+08-02-02 regex/reglib.h: add REGMULTIREF to REG_COMP
+08-02-02 string/strmatch.c: fix str="" pat="" sub values
+08-01-31 comp/conf.sh,conf.tab: handle /bin/sh \ in read data, redir subshell
+08-01-18 misc/magic.tab: amd-x68, 64-bit => x86-64
+08-01-18 string/strnton.c,strntonll.c: add
+07-12-10 string/strelapsed.c: "0" is a valid elapsed time!
+07-12-02 sfio/sfreserve.c: preserve SF_SHARE sfrd() via sfreserve(f,0,0)
+07-11-21 comp/setlocale.c: add sjis_mbtowc() to work around [\~] translation
+07-11-15 features/signal.c: RT(1) .. RT(MAX-1) => RTMIN+1 .. RTMAX-1
+07-11-14 features/float: favor sscanf() due to gnu strto[l]d() nan bugs
+07-10-31 regex/regcomp.c: fix REX_COLL_CLASS node allocation size
+07-10-31 sfio/sfcvt.c: use signbit() if available
+07-10-31 features/isoc99: _ISOC99_SOURCE tests
+07-10-31 port/astmath.c: add -DN=8 for signbit()
+07-10-31 sfio/sfstrtod.h: don't forget about -0.0
+07-10-26 features/map.c: add { optopt optarg optind opterr }
+07-10-26 features/stdio: add _filbuf => _ast__filbuf
+07-10-26 comp/getsubopt.c: fix #undef that interfered with <ast_map.h>
+07-10-26 regex/regcomp.c: fix bug that missed ')' in ~(F)...
+07-10-12 port/astconf.c: fix CONF_ALLOC 16 bit overflow
+07-10-12 misc/fts.c: fix fts_close() to free the handle -- doh
+07-10-11 comp/setlocale.c: second and subsequent setlocale(*,"") reverts to previous
+07-10-11 path/pathprobe.c: add vfs ST_NOSUID check
+07-10-10 comp/conf.tab: add a few more xpg6 deferrals
+07-09-28 astsa: update to share with mainline src via _PACKAGE_astsa
+07-09-25 sfio/sfgetr.c: no limit on string stream line size
+07-09-25 sfio/sfextern.c: increase _Sfmaxr to 256*1024
+07-09-18 misc/procopen.c: tighten up SIGCHLD logic between parent/child
+07-09-18 misc/signal.c: unblock SIG_DFL after setting handler, sig<0 => don't unblock
+07-09-13 misc/fs3d.c: no $LD_PRELOAD => no 3d and avoids invalid mount(2) call
+07-09-11 vmalloc: vmstat(0,0)==1 => region in use, drop VM_primary|VM_secondary
+07-09-05 misc/recstr.c: handle [lL] gobbled by strtol() -- ouch
+07-08-17 path/pathprobe.c: handle '\r' in VERSION string
+07-07-17 regex/regcache.c: regcache(0,n,0) extends cache to size n (no shrinking)
+07-07-16 tm/tmdata.c: add 2005-12-31, drop 1999-12-31 (where did that come from?)
+07-05-21 tm/tmxfmt.c,tmxscan.c: %F => %L (TM_DEFAULT); %F => %Y-%m-%d
+07-05-15 sfio/sfvprintf.c: %h? and SFFMT_SHORT => raw bytes
+07-05-09 features/signal.c,features/siglist: use kill -l & strsignal()
+07-04-25 misc/optctx.c: add for opt_info switching
+07-04-24 misc/cmdarg.c,include/cmdarg.h: add CMD_CHECKED, CMD_SILENT
+07-04-24 misc/procopen.c,include/proc.h: add PROC_CHECK
+07-04-24 misc/procrun.c: add flags arg (current use PROC_ARGMOD)
+07-04-24 misc/cmdarg.c,include/cmdarg.h: move from src/cmd/tw
+07-04-20 port/(lclang.h|lc.c|mc.c|lclib.h|lcgen.c): separate lctab.c
+07-04-20 comp/conf.sh: defer to systems without 'grep -q' -- sigh
+07-04-20 comp/conf.sh: probe for LL integer constant initializer suffix
+07-04-20 include/syslog.h: <namval.h> => <ast_namval.h> for win32
+07-04-20 ast_namval.h: add as copy of include/namval.h for win32
+07-04-19 comp/conf.tab: fix SVID SI entries to probe SI_* (not _SI_*)
+07-04-13 tm/tmxdate.c,tm/tmzone.c: handle [-+]0000 UTC zone offset
+07-04-11 sfio/sfvprintf.c: add %F, propagate SFFMT_UPPER
+07-04-11 sfio/sfcvt.c: handle SFFMT_UPPER => nan/inf vs. NAN/INF
+07-04-02 comp/conf.tab,comp/conf.sh: add C/POSIX <stdint.h> symbols
+07-03-28 misc/optget.c: fix l10n --?-
+07-03-25 features/common: fix { ast_std.h ast_map.h stdint.h } logic
+07-03-21 error.h: move from error_info to (*_error_data_)
+07-03-21 misc/error.c: add errorctx() for error_info switching
+07-03-21 option.h: move from opt_info to (*_opt_data_)
+07-03-19 regex/regdecomp.c: fix REX_ONECHAR escapes and add REX_KMP
+07-03-11 tm/tmxscan.c,regex/regnexec.c: fix strict-alias transgressions
+07-02-27 comp/conf.sh: handle native getconf invalid numeric values
+07-02-21 comp/conf.sh,comp/conf.tab: handle SSIZE_MAX vs _POSIX_SSIZE_MAX
+07-02-20 sfio/sfvprintf.c: handle SF_WCWIDTH justification
+07-02-14 features/common: cover <stdint.h>, move to int_(bits)_t
+07-02-14 include/int.h: drop
+07-02-14 include/sfio.h: add SF_WCWIDTH
+07-02-12 comp/conf.sh: fix CONF_LIMIT bug that missed ULONG_MAX etc.
+07-02-12 comp/conf.tab: *LONGLONG* => *LLONG* to match posix
+07-02-12 features/float: *LONGLONG* => *LLONG* to match posix
+07-02-12 port/astconf.c: handle CONF_LIMITS_DEF with no deferral
+07-02-12 stdio/vasprintf.c: add trailing '\0' -- doh
+07-02-04 string/fmtelapsed.c: fix naive multi month/year logic
+07-02-02 misc/optget.c: add --??posix for getopts(1)/getopt(3)
+07-01-26 string/chresc.c: use mbchar()
+07-01-26 misc/optget.c: handle "o:-:" usage for old-style long options
+07-01-22 sfio/sfdisc.c,sfpool.c: handle push on streams with pending peek
+07-01-22 include/sfio.h: mv Sfieee_t to sfio/sfhdr.h
+07-01-17 tm/tmxfmt.c: fix terminating nil logic which clobbered size-1
+07-01-11 misc/stk.c: a 2 day marathon bug fix (can we release now dr ek?)
+07-01-05 comp/spawnveg.c: posix_spawnattr_setflags(POSIX_SPAWN_SETPGROUP)
+07-01-05 misc/error.c: fix multibyte vs. printable logic
+07-01-01 comp/conf.sh: LC_ALL=C
+06-12-26 tm/tmxdate.c: handle nn*.nnnn* == sec.ns
+06-12-20 features/libpath.sh: generalize sol.* LIBPATH patterns
+06-12-18 comp/setlocale.c: include ast_standards.h and ast_wchar.h !
+06-12-12 string/strperm.c: octal modes are absolute!
+06-12-11 comp/conf.tab: always defer ARG_MAX
+06-12-07 Makefile: fix conftab.c generation CCFLAGS to match build - doh
+06-12-04 sfio/sfcvt.c: fix (int) vs. (long) cast mismatches
+06-12-01 comp/conf.tab: add changes to cover solaris { bin xpg4 xpg6 }
+06-12-01 regex/reginit.c: adjust { SRE KRE } escaped (){}*? inside [...]
+06-12-01 sfio/sfcvt.c: add signbit/copysign tests
+06-11-22 comp/spawnveg.c: fix _real_vfork logic to work with 3d
+06-11-20 features/common: bias _ast_int8_t "long long" before "__int64"
+06-11-20 string/strperm.c: fix X to work with all ops (not just +)
+06-11-15 astconf.c,conf.tab: add CONF_DEFER_* for variable constants
+06-11-11 port/astconf.c: validate path arg w.r.t. underlying calls
+06-11-11 comp/conf.sh: fix S CONF_STANDARD bug, add D to defer to native
+06-11-11 comp/conf.tab: add D to defer to native
+06-11-01 include/vmalloc.h: avoid VM_FLAGS sys/v*.h clash
+06-11-01 include/ast.h: add FMT_PARAM for fmtquote()
+06-10-31 disc/sfdcseekable.c: add SFSK_DISCARD for seekable window control
+06-10-31 comp/spawnveg.c,features/lib: handle posix_spawn exit status 127
+06-10-30 features/lib: fix posix_spawn() fork() prototype conflicts
+06-10-30 string/fmtscale.c: fix 1024 rounding bugs
+06-10-27 disc/sfkeyprintf.c: handle 'i' (=='d') -- oops
+06-10-26 sfio/sfvprintf.c: %#d => fmtscale(1000), %#i => fmtscale(1024)
+06-10-26 features/map.c: _map_libc cleanup
+06-10-26 features/fcntl: add to the circle of trust
+06-10-26 features/sys: add <sys/socket.h> socklen_t
+06-10-26 include/regex.h: handle include before <ast_map.h>
+06-10-25 astconf "SHELL" => "SH" to avoid _POSIX_SHELL conflict
+06-10-25 comp/conf.*: drop no-op duplicate conftab.c entries
+06-10-18 string/fmtscale.c: 1000: n[.]n[n](kMGTPE), 1024: n[.]n[n](KMGTPE)i
+06-10-11 ast_std.h: now implies <sys/stat.h> (did on most before anyway)
+06-10-11 strtoi.h: ignore sign for 0, validate scale shift
+06-10-11 strdup.c,vmstrdup.c: handle 0 arg
+06-10-11 add sfstruse()/sfstropen() error checks
+06-10-10 misc/procopen.c: envv==environ => don't modify environ
+06-10-10 misc/procclose.c: return valid exit(1) status
+06-10-06 port/astconf.c,comp/conf.sh,comp/conf.tab: play nice with getconf(1)
+06-10-01 comp/conf.tab: SHELL default checks { _CS_PATH } X { ksh ksh93 sh }
+06-10-01 comp/conf.sh: export CONF_getconf to shell actions
+06-10-01 comp/putenv.c: always enable setenv() for procopen()
+06-10-01 misc/procopen.c: use pathshell() or astconf("SHELL",0,0) if PARANOID
+06-10-01 path/pathshell.c: localize the shell path patterns and accept ksh93
+06-09-28 Makefile: avoid ast <stdio.h> vix iffe -X ast -- doh
+06-09-27 regex/regdecomp.c: add
+06-09-26 regex/regcomp.c: handle KRE ~(...)<invalid-kre>
+06-09-25 reorganize to avoid native header intercepts
+06-09-15 uwin/crypt.c: _UWIN only!
+06-09-14 Makefile: tweak the ast_common.h bootstrap again (finally?)
+06-09-14 misc/optget.c: noncommercial => OPT_proprietary
+06-09-12 string/strelapsed.c: fix multi-char qualifier parse
+06-09-12 string/strtoi.h: drop [cClLqQwW] multipliers
+06-09-11 misc/optget.c: add numeric arg validity check
+06-09-07 misc/optget.c,tm/tmfix.c: fix uninitialzed var refs
+06-09-05 path/pathprobe.c: add version header verification
+06-08-01 Makefile: handle iffe vs FEATURE/common vs ast_common.h
+06-08-31 Makefile: add ast_map.h to the bootstrap list
+06-08-30 misc/glob.c: fix ~(E)re bug that stripped ~(E) before regcomp
+06-08-30 include/ast.h: add { integralof(x) pointerof(x) }
+06-08-27 string/strelapsed.c: fix off-by-one (too little) parse bug
+06-08-25 misc/optget.c: 0*<n>.* numeric option args => <n>.*
+06-08-22 misc/glob.c: handle ~(...) pattern options
+06-08-16 string/strelapsed.c: fix off-by-one (too far) parse bug
+06-08-16 regex/regcomp.c: accept but ignore ~(N)
+06-08-14 features/libpath.sh: add solaris LD_LIBRARY_PATH_64 check
+06-08-05 sfio/sfpool.c: pool SF_READ|SF_WRITE loop fix
+06-08-02 misc/fts.c: fix FTS_NOSTAT optimization to check for ..
+06-07-28 include/glob.h: add gl_extra for user globlist_t expansion
+06-07-27 features/common: #include "ast_map.h"
+06-07-26 comp/fnmatch.[ch]: allow <ast_map.h> to map fnmatch()
+06-07-22 cdt: snarf from kpv
+06-07-17 string/strperm.c: perm==-1 skips umask(1)
+06-07-17 sfio/sfvprintf.c: handle format invalid mb seq
+06-07-17 regex/regcomp.c: inline REG_SHELL => anchored, otherwise not
+06-07-17 regex/regcomp.c: inline B|G:basic E:REG_EXTENDED F|L:REG_LITERAL
+06-07-17 regex/regcomp.c: inline l:REG_LEFT r:REG_RIGHT
+06-07-17 regex/regcomp.c: inline a:REG_LEFT|REG_RIGHT p:~REG_LENIENT
+06-07-17 string/chresc.c: add \Uxxxxxxxx
+06-07-17 sfio/sfstrtof.h: ignore thousands sep after decimal
+06-07-17 string/tokline.c: splice() => spliceline() for bsd
+06-06-27 features/float,sfio/sfcvt.c: fix Nan logic
+06-06-27 port/astmath.c: fix long double isnan() test
+06-06-27 features/map.c: _map_libc for std => _ast_std
+06-06-25 string/strperm.c: handle posix = w.r.t. umask
+06-06-19 port/mnt.c,features/fs: handle netbsd getmntent api change
+06-06-18 regex/regstat.c: add REG_LITERAL check
+06-06-11 cdt/dtview.c: update from kpv
+06-05-31 sfio/sfhdr.h: fix _SFOPEN() typo
+06-05-09 comp/conf.sh: add native getconf -a names to the mix
+06-04-28 misc/optget.c: add solaris long option name compatibility
+06-03-09 string/strmatch.c: add REG_ADVANCE => REG_* flags
+06-02-14 comp/iconv.c: fix uwin iconv_list() /reg/ generator
+06-02-10 port/astconf.c: relax standard prefix filter
+06-02-08 sfrd.c,sfsync.c: lock logic bug fix
+06-02-01 port/astlicense.c: add { parent incorporation }
+06-01-26 port/astconf.c: fix { LIBPREFIX LIBSUFFIX } length
+06-01-06 features/lib: change _UNIV_DEFAULT probe to use cross{...}
+06-01-04 misc/stk.c: fix n**2 realloc behavior
+06-01-01 include/sfio.h: export { _Sfi _Sfmaxr }
+05-12-13 string/chresc.c: handle \C-X => control-X, \M- => ESC
+05-11-22 regex/regcache.c: add, convert string/strmatch.c to regcache()
+05-10-06 string/ccmap.c: update ebcdic-u to be idempotent
+05-09-28 vmalloc: snarf from kpv; fixes large block brk() thrashing
+05-09-26 misc/magic.c,misc/magic.tab: handle latest vcodex header
+05-09-12 misc/optget.c: reset opt_info.offset on error
+ string/strtoi.h: strton() '.' multiplier only if m>1
+ string/fmtesc.c: add unadvertized FMT_PARM for FMT_SHELL
+05-09-09 string/fmtesc.c: fix FMT_SHELL logic w.r.t. [$`]
+05-08-11 string/strerror.c: fix { sys_errlist sys_nerr } prototypes
+05-08-03 sfio: snarf sfvaprints sfaprints
+05-07-21 port/astconf.c: retain most recent synthesized lookup
+05-07-20 sfio/sfsetbuf.c: default file io size now 64K on all systems
+05-07-17 ccmap*: add microfocus cobol EBCDIC_U
+05-06-29 regex/regcomp.c: fix the A & B inline flag logic
+05-06-15 include/recfmt.h: add fs format flag to fmtrec()
+05-06-14 error.c: add ERROR_OPTIONS { break count match }
+05-06-07 features/stdio: drop FEATURE/limits to fix bootstrap circular dep
+05-06-02 features/*,Makefile: drop vestigel iffeio.h bootstrap workaround
+05-05-31 string/fmtbuf.c: unlock (spin) before each return -- doh
+05-05-30 sfio/sfpkrd.c: work around macos 10.4 recv(MSG_PEEK) bug
+05-05-27 regex: add REX_NEST (?%[S.][T.][OT])
+ magic.tab: ammend bsd db magic
+05-05-23 regex: REX_NEST (?%[D.][E.][L.][Q.][oc]...)
+05-05-21 regex: state.fold[] is now locale specific -- doh
+05-05-19 regex: add REX_NEST (?%\\()<>[]""...) %(...) nested match
+05-05-15 recfmt.h: add recstr() reclen() fmtrec()
+05-05-13 optget.c: allow boolean options to take numeric values
+05-05-12 recfmt.c: add to recfmt.h, adjust Recfmt_t encodings
+05-04-30 sfio: add sfmaxr(), default 64K
+05-04-22 comp/omitted.c: fix magic() logic for files < 512 bytes
+05-04-20 cdt: snarf update from kpv; void* Dt_t.user added
+ misc/error.c: library => ERROR_LIBRARY
+05-04-19 regex/regcomp.c: handle REG_SHELL [^...] == [!...]
+05-04-11 tm/tmxscan.c: handle yyy.mm.dd[-+.]hh.mm.ss.nnnnnn
+05-04-07 regex/regnexec.c: fix out of bounds boundary check -- ouch
+ features/align.c: add jmp_buf to the alignment mix (ia64)
+ vmalloc/vmhdr.h: add jmp_buf to the alignment mix (ia64)
+05-03-31 misc/optget.c: fix option { - _ } separator matching
+05-03-30 misc/glob.c: eliminate superfluous GLOB_NOMATCH stat() calls
+05-03-24 port/astwinsize.c: include <sys/ioctl.h> if possible
+05-03-23 string/ccmap.c: add ebcdic-m mvs cobol table
+05-03-11 comp/omitted.c: handle utime[s](const,const)
+ comp/conf.tab: fix linux PID_MAX probe
+05-03-10 comp/setlocale.c: LC_* value "" => unset -- doh
+ misc/optget.c: reorder _PACKAGE_astsa code for msgcc
+05-03-08 misc/optget.c: delete leading space in STYLE_nroff output
+05-03-07 sfio/sfhdr.h: drop extern _sfdscan -- clashes with sfvscanf.c static
+05-03-01 tm/tminit.c: add tmlocaltime() for tzset() getenv() override workaround
+05-02-20 features/tvlib: tmsettimeofday only for systems that have settimeofday
+ features/float: fix mvs.s390 NaN tests
+05-02-18 tm/tmxmake.c: fix <0 west of GMT bug that warped to 1800's -- wow
+05-02-11 port/mnt.c: handle lynxos MOUNTED=/etc/fstab
+05-02-08 features/float,sfio.h,sfcvt.c,sftable.c: add INF and fix NAN
+05-02-04 features/lib: add _std_strtol (for lynxos)
+ include/ast_std.h: add _std_strtol tests
+ comp/strtod.c: #define S2F_function strtod
+ misc/signal.c: fix ancient bsd SV_INTERRUPT vs. SV_ABORT clash
+05-01-11 sfio/sfmove.c: try to seek(fr) when fw==0
+ comp/omitted.c: intercept utimes() too
+ comp/omitted.c: add DOSPATHVARS env var path value conversions
+ features/tvlib,tm/tvtouch.c: check for utimets()
+ misc/optget.c: handle '-' or '_' option word separators
+ sfio/_sfopen.c: allow stream mode changes after initialization
+ sfio: sync with kpv: SF_SYNCED fix for ksh input loss bug
+05-01-09 tm/tmxfmt.c: fix %6N for n<100000000
+05-01-08 regex/regcomp.c: conj() => con() to avoid C99 clash
+05-01-05 tm/*: fix { %U %V %W } logic -- my head hurts
+04-12-30 tm/tmxtime.c: fix tm_isdst<0 loop
+04-12-23 vmalloc/vmbest.c: fix vmresize bug that didn't 0 new data
+04-12-19 misc/optget.c: broaden - long option match
+04-12-09 string/strtoi.h: fix terabyte 't' suffix math
+ string/strmatch.c: flush cache on locale change
+04-12-01 tm/tmsleep.c: add
+ tv.h,tv*.c,tv.3: move from pax
+ tmx.h,tmx*.c,tmx.3: add high resolution tm(3) counterparts
+ features/lib: add *another* sgi linux.ia64 memccpy bug check
+04-10-31 Makefile: __OBSOLETE__ now computed <6 months ago year>0101
+ ccode.h,ccmapid.c: add ccmaplist(Ccmap_t*) iterator
+ option.h,optesc.c: add 3rd arg, 1 => quote '?' too
+ misc/magic.c: fix bug that terminated `string \0a' at \0
+ misc/magic.c: handle vcodex() via decompose()
+ misc/magic.tab: add vcodex magic
+ features/stdio: handle _LARGEFILE64_SOURCE -- oops
+ stdio/(fseek|ftell|fseeko|fsetpos|fgetpos|ftello).c: oops^2
+04-10-28 string/swapop.c: size==-4 => size=4 and extend op=3 to op=7
+ tm/tmfix.c: fix tm_mon<0 logic
+04-10-22 tm/tmdate.c: handle 'final day feb 2004'
+ port/astlicense.c: add query=all|id|${...}${...}
+ port/astlicense.c: "free" => "mit"
+ comp/omitted.c: revert to the open source license
+ string/stropt.c: drop siz==0 => tab is hash table
+ include/sfio.h: incorporate <sfstr.h>
+ include/sfstr.h: drop
+ disc/sfstrtmp.c: drop -- use sfstrbuf()
+04-10-20 misc/magic.tab: update tar magic
+04-10-18 ufc-crypt.h,crypt_util.c: drop GPL code
+ crypt.c: add BSD code
+ pathpath.c: disable { $0 $_ $PWD } related root search
+04-10-01 normalize ident stamps
+ port/astlicense.c: add type=cpl -- yeah
+04-09-25 string/swapop.c: return op < size -- duh
+04-09-23 comp/spawnveg.c: :NOOPTIMIZE: -- volatile sometimes ignored
+04-09-21 comp/spawnveg.c: exec_errno_ptr is volatile -- duh
+04-09-14 tm/tmscan.c: add %| alternation and %& => tmdate()
+04-09-08 misc/optget.c: add :!value: omitted optional arg value
+ misc/optget.c: fix --noNAME ambiguous option logic
+04-08-26 string/strperm.c: add who^mode to propagate least restrictive up
+ astmath.c: add { frexpl ldexpl } checks for ast.req
+ port/astlicense.c: ignore first option if non-assignment
+ include/ast_dir.h: move d_fileno map before struct defs -- duh
+04-08-24 vmalloc/vmbest.c: add {VM_region} VMCHECK=+r for region segment checks
+ misc/recfmt.c,include/recfmt.h: add
+04-08-23 vmalloc/vmbest.c: add {VM_primary VM_secondary} VMCHECK=-s for primary
+ features/common: punt to <stdarg.h> for unknown va_list
+04-08-11 vmalloc: sync _UWIN libposix hooks
+04-07-27 features/common,features/limits.c: ULL suffix for unsigned _ast_int8_t
+04-07-22 include/ast.h,comp/eaccess.c: add eaccess() for effective access()
+04-07-19 comp/open.c,sfio/_sfopen.c: { O_RDONLY O_WRONLY O_RDWR } are values
+04-06-28 misc/error.c: check level after error_info.auxilliary
+04-06-24 string/strmatch.c: strgrpmatch() match[] now variable size array
+04-06-17 features/common: change _DLL null define to (the standard ast) 1
+04-06-11 misc/optget.c: allow optional [-|+|--|++] optstr() option prefix
+ misc/optget.c: reset optstr() state on 0 return
+ misc/optget.c: text()=>textout() linux.ppc symbol hijack workaround
+04-05-31 sfio/sfreserve.c: no side buffer if user buffer is large enough
+04-05-27 string/fmtbuf.c: handle one concurrent buf > sizeof(buf)
+04-05-24 regcomp.c: fix no-advance initialization
+04-05-05 conf.tab,conf.sh: update to align with standards
+ magic.tab: ms suffix update
+04-05-04 port/lcgen.c: fix territory initialization
+04-04-15 tm/tmdate.c,include/tm.h: fix specific and ordinal days
+04-04-08 astconf: retain { HOSTTYPE LIBPATH LIBPREFIX LIBSUFFIX } strict vals
+04-04-07 vmalloc/vmbest.c: fix alpha tiny block bug
+ vmalloc/malloc.c: re-enable on alpha
+04-03-30 tm/tminit.c: GMT => UCT only if tz.daylight not defined
+04-03-25 vmalloc/malloc.c: _AST_std_malloc=1 for __alpha
+ path/pathprobe.c: per-user probe dir => $HOME/.probe/$HOSTTYPE
+04-03-23 regex/reglib.h: fix isw*() redefines
+04-03-17 features/stdio: no __FILE override for __CYGWIN_ (sys/reent.h clash)
+ sfio/sfhdr.h,sfio/sfsetbuf.c: lower sfmove() default buf size 4x
+04-02-29 comp/omitted.c: move env trace after PATH fixup
+ comp/omitted.c: cygwin spawn _P_DETACH => _P_NOWAIT+setpgid(pid,0)
+ misc/optget.c: fix html mailto: match
+ port/astlicense.c: add type=test for fixed 2001 date
+ features/float: check local NaNQ first
+ vmalloc/vmhdr.h: fix _vmextern_ vm_truncate return type
+ misc/magic.tab: add elf s390 index=22
+04-02-26 vmalloc: VMCHECK a:assertions c:arena-check w:warn-instead-of-abort
+ sfio/sfvscanf.c: fix extf arg selection
+04-02-24 features/dirent: set nodefine to avoid ast_std.h _typ_off64_t undef
+ disc/sfkeyprintf.c: only case pattern must be ()[] balanced
+04-02-14 include/sfio_t.h: add SF_DCDOWN, SFDCNEXT(), SFDCPREV()
+04-02-13 string/strmatch.c: fix bug that didn't save one-time sub[] size
+ vmalloc: -g: export VMCHECK=1 enable malloc/free checks
+ vmalloc: -g: free(0) to check and disable malloc/free checks
+ vmalloc: -g: free(1) to check and enable malloc/free checks
+04-02-11 Makefile: add :P=A: to conf and lcgen exec for cross-compile
+ regex: use MBSIZE() instead of mbsize() to grab 1 char on err
+ vmalloc/vmbest.c: updated to do more comprehensive DEBUG tests
+04-02-04 sfio/sfraise.c: add sfraise(0,a,b) to iterate over all streams
+04-02-01 vmalloc/vmbest.c: _BLD_DEBUG free(0) checks the arena
+04-01-31 features/vmalloc: fix typo that missed _mmap_zero
+04-01-23 string/strerror.c: handle real strerror() return value overwrite
+04-01-11 path/pathpath.c: fix size vs. sizeof(buf) typo
+03-12-22 misc/magic.tab: dos EXE tweaks
+03-12-05 vmalloc: sync with kpv, adding exceptf announcements
+03-12-04 port/astlicense.c: fix expand() loop sentinel bug
+03-12-02 include/ast.h: mbchar() advances by 1 on mbtowc() error
+ misc/fts.c: increase MINNAME to 32
+03-11-21 vmalloc/vmbest.c: export VMCHECK=1 to enable $(CC.DEBUG) vmcheck()
+ vmalloc/vmbest.c: export VMCHECK=2 to disable KPVCOMPACT
+ misc/magic.c: add { cobol copybook pl1 } and suffix preference
+03-11-12 features/stdio: drop cuserid,getopt for SUSV3
+03-11-11 vmalloc/*: merge kpv update -- this should stomp the compaction bug
+03-10-23 comp/iconv.c: fix sfreserve lock fallback
+03-10-20 sfio/_sfopen.c: add to allow user sfopen() intercept
+03-10-17 regnexec.c: fix exec time REG_LEFT, \x.... => wctomb()
+03-10-12 string/strtoi.h: fix strton '.' overconsumption
+03-10-12 comp/iconv.c: identity is always (iconv_t)0
+03-10-09 string/fmtesc.c: fix FMT_SHELL to check for all shell magic chars
+03-10-01 port/astlicense.c: unknown authors copied verbatim (instead of ignored)
+03-09-30 string/chresc.c: handle \u..., \x... consumes all trailing hex digits
+ string/stresc.c: \u... and \x... > UCHAR_MAX => wctomb()
+03-09-29 fnv.h: add
+03-09-23 modedata.c: table is for external modes, so no arch specific hacks
+ optget.c: fix option prefix match translation bug
+ optget.c: add `<length> <name>=<value>\n' to optstr()
+ features/lib: add memcmp() test for sgi optimzation bug
+03-09-22 regex.h,regcomp.c: add regncomp()
+ regclass.c: fix for loop dangling ; in regaddclass()
+03-09-20 sftable.c,sfvprintf.c: fix SFFMT_CHAR handling to match extf api
+03-09-19 sfmode.c: update release to kpv's
+03-09-17 regcomp.c: add pedantic backref error checks
+03-09-16 regnexec.c: exec time REG_LEFT => don't advance past initial position
+ regclass.c: add regaddclass() for user defined [:class:]
+ regexec.h: REG_VERSION_N2X, add redisc_t {re_map} ccode map
+ regstat.c: add regstat_t
+03-09-11 optget.c: --n:=v sets opt_info.assign=':', opt_info.number enabled
+03-09-09 disc/sfkeyprintf.c: *pn on lookup is arg separator; lookup "" arg too
+03-09-05 optget.c: [f:l*?] preserves user long name past '*' in opt_info.name[]
+03-09-03 sfstr.h: add sfstrpend() for #pending bytes in read buffer
+03-08-25 regex: add REG_FIRST, optimize bm
+ features/lib: _AST_no_spawnveg==1 falls back to fork/exec
+03-08-22 features/stdio,stdio/asprintf.c,stdio/vasprintf.c: add
+03-08-21 path/pathnative.c,path/pathposix.c: interix updates
+ features/botched: add cygwin _stat => _stat64
+03-08-15 include/ast.h: map out bsd strmode()
+ features/common: add interix _ast_intmax_t workarounds
+ misc/fs3d.c: 3d mount test now uses "" instead of NiL (or cygwin dumps)
+03-08-11 string/fmtesc.c: fix optional quoting checks
+ tm/tmdate.c: fix > 1 year of seconds arithmetic
+ tm/tmfix.c: fix leap year adjustments
+03-08-01 features/lib: beef up sock_peek test for interix
+03-07-29 features/float: add -lm to frexp... test
+ Makefile: fix -lm astmath test sense
+03-07-26 features/mem.c: favor _mem_sbrk over _mem_mmap_*
+03-07-22 vmalloc/vmbest.c: fall back to sbrk() if mmap() fails
+ features/mem.c: _mem_sbrk means sbrk() and brk() work
+03-07-17 regex/regcomp.c: fix bug that treated KRE X{n,m} like {n,m}(X)
+ misc/magic.c: check MAGIC_VERBOSE for all load() messages
+03-07-14 misc/optget.c: handle [...]{[...]\f...\f...}
+03-06-21 misc/sigcrit.c: block SIGCHLD if _lib_sigprocmask || _lib_sigsetmask
+ comp/spawnveg.c,sfio/sfmode.c: use sigcritical() SIG_REG_* macros
+ comp/spawnveg.c: drop ENOEXEC logic
+ vmalloc/*: snarf kpv KPVCOMPACT() fix
+ vmalloc/vmbest.c: export VMCHECK=2 to disable KPVCOMPACT (just in case)
+ string/strdup.c: drop __strdup() etc. intercepts -- malloc gets it
+ features/mem: define _mem_method and _mem_* possible values
+ vmalloc/malloc.c: _AST_mem_method==_mem_* to force mem get method
+ sfio/sfputr.c: __ia64 memccpy is bogus -- how many tries do they get?
+ path/pathshell.c: verify abs path and access(path,X_OK) -- duh
+ vmalloc/vmhdr.h: add private _Vmessage() for non-sfio ASSERT()
+ port/astconf.c: fix bug that always returned the minmax value
+03-06-11 comp/*.c: reorder macro hding for mvs.390 and <ast_map.h>
+ features/vmalloc: add _lib_brk and _lib_sbrk verification
+ include/ast_std.h,etc.: add _map_malloc for malloc => _ast_malloc
+ comp/conf.sh: fix SI_* and *_SI_* macro redefs
+ ast.h: VMDEBUG or _BLD_DEBUG enable <vmalloc.h> and VMFL tracing
+ vmalloc/vmtrace.c: _PACKAGE_ast __FUNCTION__ is a string
+ vmalloc/vmtrace.c: set trace file fd FD_CLOEXEC
+ vmalloc/vmbest.c: set /dev/zero mmap fd FD_CLOEXEC
+ features/mmap: fix ancient read() vs. mmap() time arithmetic typo
+ vmalloc/malloc.c: _AST_std_malloc==1 to force standard malloc
+03-06-09 comp/omitted.c: add _imp__FUNCTION sybols for __CYGWIN__ static link
+ vmalloc/vmbest.c: handle systems with sbrk() but no brk()
+03-06-04 port/astconf.c: drop non-standard diagnostics
+03-06-03 comp/conf.sh: rework symbol collision logic
+03-05-30 conf.tab,conf.sh,astconf.c: add <sys/systeminfo.h> sysinfo() SI_*
+03-05-29 ccode.h: rework for extensibility, drop obsolete mematoe(), memetoa()
+03-05-28 regex/*: recode to use isw*() directly when needed, is*() otherwise
+03-05-27 features/vmalloc: fix _std_malloc test
+03-05-25 misc/optget.c: fix optstr() ???* internal options
+03-05-24 misc/optget.c: fix (ancient) argv null dereference
+03-05-23 comp/getcwd.c: don't intercept on _WINIX -- unreliable st_ino
+03-05-22 sfio/sfsprintf.c: n<0 => don't append '\0'
+03-05-18 misc/fts.c: re-stat FTS_DP to update nlink/times
+ misc/fts.c: add FTSENT.stack to eliminate getlist() recursion
+ regex/ucs_names.h: use "..." catenation to placate some cc's
+03-05-11 string/strtoi.h: handle "-" "+" "0x" "11#"
+03-05-09 vmalloc/vmbest.c: large memory allocation tweaks
+03-05-06 misc/optget.c: fix getopt_long() prefix==1 bug that missed short flags
+03-04-27 comp/system.c: handle <ast_map.h>
+03-04-24 vmalloc/vmmopen.c: drop dup <unistd.h>
+03-04-21 tm/tmdate.c: fix next hour/min logic
+03-04-15 vmalloc/malloc.c: intercept __malloc() along with __libc_malloc()
+ string/strdup.c: intercept __strdup() along with __libc_strdup()
+ features/mmap: consolidate from features/(lib|sfio|vmalloc)
+ add _NO_MMAP==1 to disable all mmap()/munmap() calls
+ path/pathposix.c: add
+03-04-14 comp/setlocale.c: fix debug_mbtowc() return value for *s==0 || n < 1
+ comp/iconv.c: fix error return errno values
+03-04-11 misc/stk.c: fix stkgrow() realloc bug
+03-04-05 string/tok.c: support readonly single token input strings
+ disc/sfdcdio.c: fix F_DIOINFO and FDIRECT #ifdef's
+ include/ast_std.h: allow _LARGEFILE64_SOURCE on __hppa
+ features/common: fix `tst _foo_' => `tst foo_' typo
+ features/float: fix `tst _foo_' => `tst foo_' typo
+ features/float: add FLTMAX_(UINTMAX_MAX,INTMAX_MAX,INTMAX_MIN)
+ comp/omitted.c: fix pathconf => _pathconf => _ast_pathconf loop
+03-04-03 features/float: add _ast_no_um2fm: no usinged intmax => floatmax cast
+ vmalloc/vmbest.c: add getenv("VMCHECK") to initialize Vmcheck
+03-03-28 include/ast_dir.h: add D_TYPE; { D_FILENO D_TYPE } must be #ifdef'd
+ misc/fts.c|getcwd.c|glob.c,preroot/getpreroot.c: add D_FILENO #ifdef's
+ Makefile: make sure _BLD_ast is defined for all compiles
+03-03-27 ast_vfork.h: generate from features/vfork to pick up headers/pragmas
+03-03-25 comp/omitted.c: drop free() of live environ
+ path/pathshell.c: allow trailing .exe -- pox on that
+ string/strtoi.h: fix bug leading 3 digits before thousands sep bug
+ string/(fmt|str)[gu]id.c: we know root when we see it
+03-03-24 misc/optget.c: handle : and ? in := default value
+03-03-21 ast_std.h: drop all spawn*() but spawnveg()
+ obsolete/spawn.c: add for dropped spawn*()
+ features/lib: _use_spawnveg if spawnveg() is a win over fork()/exec()
+ features/lib: drop NutForkExecve() and _map_spawnve
+ features/lib: fix memccpy test to clean up /tmp droppings
+ comp/spawnveg.c: call posix_spawn() if implemented
+ comp/omitted.c: add spawnve() intercept
+ comp/getoptl.c: set getopt_long() optind even if no options
+ tm/tmfmt.c: add %Q<delim>recent<delim>distant<delim>
+ misc/optget.c: fix trailing '*' for option and option args
+ sfio/sfmode.c: getenv("_AST_SFIO_OPTIONS") [,]SF_LINE[,] for fd {0,1,2}
+ vmalloc/*: kpv sync for uwin build independent of libast
+03-03-18 port/astconf.c: switch to dynamic string values (saves 7K data/bss)
+ string/strmatch.c: switch to dynamic regex cache (saves 3K data/bss)
+ regex/regcoll.c,ucs_names.h: initialize rw tables from smaller ro data
+ features/lib: add vfork test for passing SIG_IGN across exec
+ features/lib: add spawn test for passing SIG_IGN across spawn
+03-03-17 comp/omitted.c: unlink() renames to .deleted dir in case file open
+ sfio/sfpopen.c: handle mode "" for spawn with no pipe
+ features/float,comp/frexp.c,comp/frexpl.c: add pow2() table alternative
+03-03-12 features/lib: fix linux.ia64 memccpy() tests -- now its their turn
+ features/vmalloc: fix /dev/zero test
+ features/align: _ast_intmax_t and _ast_fltmax_t join the union
+ misc/stk.c: fix struct frame size to align data
+ disc/sfdcdos.c: change sfslen() => sfvalue(f)
+03-03-10 misc/optget.c: handle [f\f:x:lll\f?ddd]
+03-03-07 port/astconf.c: uninitialized CONFORMANCE + POSIXLY_CORRECT => standard
+03-03-05 comp/omitted.c: make sure at least /bin is in PATH to find cygwin dlls
+03-03-02 path/pathshell.c: write access to /bin is effectively root
+03-02-28 features/float: add (FLT|DBL|LDBL)_U?(LONG|LONGLONG|INTMAX)_(MIN|MAX)
+03-02-25 features/lib: change vfork() test to use _exit() instead of exit()
+03-02-23 include/error.h: update ERROR_VERSION for error_info.number space
+03-02-22 comp/conf.sh: wrap ksh check in eval to avoid premature exit
+03-02-21 misc/fts.c: verify chdir(..) to avoid malicious dir rename()
+03-02-19 string/strtoip4.c: isspace() instead of ' '||'\t'
+03-02-17 regex/regcomp.c: fix stats.l REX_REP logic that botched REX_BM
+03-02-13 string/base64.c: handle catenated encodings
+03-02-11 features/libpath.sh: change LIBPATH to <dir>[:<env>[:<pat>]][,...]
+03-02-07 path/pathfind.c: allow "/dev/null" to be PATH_REGULAR
+03-02-06 include/ast.h,fmtquote.c: add FMT_ALWAYS|FMT_ESCAPED|FMT_SHELL|FMT_WIDE
+03-02-05 tm/tmdate.c,tm/tmword.c,string/strelapsed.c: '_' treated like ' '
+03-02-01 string/strelapsed.c: handle ps style [day-][hour:]min:sec
+03-01-31 port/astlicense.c: fix author=* match
+03-01-30 include/tm.h: add tmisleapyear() macro
+03-01-29 comp/getopt.h,comp/getoptl.c: add gnu getopt_long(), getopt_long_only()
+ include/ast_getopt.h: for non-gnu part of comp/getopt.h
+ include/ast_std.h: include <ast_getopt.h> instead of <getopt.h>
+03-01-28 ast.h,string/base64.c: add base64encode() and base64decode()
+ path/pathfind.c: verify S_ISREG()
+03-01-24 path/pathexists.c: fix abs dir bug and deal with case ignorance
+03-01-23 path/pathpath.c: honor PATH_ABSOLUTE for the easy case too
+03-01-22 path/pathprobe.c: fix search to find both the probe script and command
+03-01-17 misc/magic.tab: application/zip => appplication/(gzip|pzip|zip)
+03-01-14 misc/optget.c: change href="" to href="."
+03-01-10 include/ast_std.h: strtold() import hackery for static __CYGWIN__
+03-01-03 include/regex.h,regex/regcomp.h: add REG_SHELL_GROUP
+ include/ast.h,string/strmatch.c: add STR_GROUP for REG_SHELL_GROUP
+02-12-15 include/error.h: errorcontext => Error_context_s (compatible til 2004)
+02-12-06 misc/sigdata.c: add NoF(sigdadata) -- why nmake was uninterruptable!
+02-12-03 comp/omitted.c,features/omitted: handle cygwin alarm() return botch
+02-11-27 misc/swapop.c: op=3,size=4 => op=7
+ string/strlcat.c,strlcpy.c: fix uwin decl clash
+02-11-26 sfio/sfvprintf.c: fix sfsprintf() '\0' termination bug
+02-11-22 misc/glob.c: move static struniq() to libast extern
+ string/fmtversion.c,include/ast.h: add fmtversion
+02-11-18 string/strncopy.c: add
+ misc/magic.tab: list size for magicid.h magic
+02-11-14 sfio/sfvprintf.c: add %#c for C escapes
+ include/error.h: add ERROR_NOTIFY context flag for builtin commands
+02-11-11 string/strtoi.h: add S2I_size for strnto*() size_t 2nd arg
+ sfio/sfstrtof.h: add S2I_size for strnto*() size_t 2nd arg
+ comp/putenv.c: add setenv() and unsetenv() wrappers for setenviron()
+02-10-31 path/pathfind.c: add dir of including file to the pathinclude() list
+ misc/optesc.c: add
+02-10-30 string/strtoip4.c: set next char pointer even on error
+02-10-29 comp/resolvepath.c: add (size_t version of realpath())
+ misc/mime.c: fix mimehead() to ignore null content values
+02-10-28 misc/glob.c: add GLOB_STARSTAR for /**/ and GLOB_NOTDIR optimization
+02-10-27 string/struniq.c: add
+02-10-23 features/common: fix off-by-one loop check
+02-10-18 include/ast_std.h: avoid off_t,ftruncate,lseek,truncate redefinitions
+02-10-17 misc/mime.c: handle type/* match, fix bogus header parse
+02-10-04 sfio/sfstrtof.h: S2F_static <0:export =0:private >0:static
+02-10-02 features/common: don't define _WIN32; define _WINIX => unix on windows
+ features/tty: finally stomp the bsd _POSIX_VDISABLE redefinition
+ misc/fastfind.c: add more specific findwrite() error messages
+ comp/omitted.c: fix cygwin utime() to update st_ctime
+ comp/strtol.c,strtoul.c: __CYGWIN__ static link workaround XXX
+ string/fmtls.c,fmttime.c: tmform() => tmfmt()
+02-09-22 port/astconf.c: return values in fmtbuf() buffer instead of stack
+ port/mnt.c: don't set MNT_REMOTE for win32 ?:\* paths
+ sfio/sfvscanf.c: _sfdscan() is library global (not static)
+02-09-21 path/pathkey.c: add tool arg for mamake compatible hash
+ features/fcntl.c: handle iffe _hdr_lcl_* => _lcl_* change
+02-09-15 comp/conf.sh: fix enum vs. macro test
+ cdt: kpv sync
+02-09-11 ast.h,features/common: move _WIN32 macro init to features/common
+ features/common: enable __EXTERN__ and __DEFINE__ for _WIN32&!_UWIN
+ features/float: add -lm to _ast_*_nan_init tests
+ vmalloc: kpv sync with vmresizef => vmgetmem
+ features/iconv: must have both <iconv.h> and iconv_open()!
+ features/vmalloc: alloca test must compile *and* link
+ sfio/sfvscanf.c,sfstrtof.h: add flag arg to char get, fix NaN loop
+02-09-10 vmalloc/vmhdr.h: enable getpagesize() and sbrk() prototypes
+ features/fcntl.c: enable mmap64() prototype
+ include/ast_windows.h: windows.h wrapper with ast namespace workarounds
+02-09-07 misc/mime.c: fix quoted value parse bug that ate the whole line
+02-09-05 features/vmalloc: add free() to _std_malloc test
+ include/ast.h: NoF(x) now defines _DATA_x for !_BLD_DLL too
+ tm/tmlocale.c: { C POSIX en } == unix dadgummit
+02-08-29 path/pathfind.c: initialize Dir_t.next=0
+02-08-28 uwin/rint.c: update
+ features/libpath.sh: "bin" is now the default value
+02-08-22 vmtrace.h: add for debugging
+02-08-20 misc/magic.c: convert to use <cdt.h>
+ vmalloc/vmresizef.c: add for generic discipline resizef default
+ string/strelapsed.c: allow long time component names
+02-08-19 misc/optget.c: add `.fp 5 CW' to --nroff output
+ string/(fmtfs|fmtuid|fmtgid|strgid|struid).c: convert to use <cdt.h>
+ include/dt.h,cdt/dtnew.c: add for dtopen() in specific vm region
+02-08-13 comp/omitted.c: fix bzero logic for e.g. unixware.i386
+ include/ast.h: add fmtbase->fmtbasell; swap in 2003-09-01
+02-08-12 regex/regnexec.c: fix REG_MINIMAL REX_DOT mb bug
+02-08-08 features/iconv: <ast_common.h> instead of <sys/types.h> <ast_common.h>
+02-08-07 regex/regcomp.c: recognize anchors in BRE subexpressions
+02-08-06 comp/iconv.c: handle win32 cpNNNN == windows-NNNN aliases
+02-08-05 cdt/*: sync with kpv src
+02-08-02 features/iconv: include sys/types.h for ast_types.h
+02-08-01 misc/magic.c: magic file "." names the default
+ misc/magic.c: handle addr type (from irix string)
+ features/lib: move malloc tests to features/vmalloc
+ features/vmalloc: snarf tests from features/lib
+ vmalloc/*: sync with kpv src
+ comp/libc.c: dropped -- __libc_* intercepts moved to vmalloc/malloc.c
+02-07-30 features/lib: handle __libc_malloc() in _std_malloc test
+ vmalloc/malloc.c: add gnu pvalloc()
+ features/vmalloc: fix alloca check
+02-07-29 features/limits.c: handle netbsd guards
+02-07-27 sfio/sfpoll.c: handle rw pipes
+02-07-25 features/iconv: include ast_types.h for size_t in ast_iconv.h
+02-07-18 apply LARGEFILE64 header prototype clash patches
+ misc/optget.c: __EXTERN__ _opt_info_ instead of opt_info
+02-07-17 ast_std.h: memzero() now defaults to memset() instead of bzero()
+02-07-16 ast_std.h: add ast.env_serial
+ misc/setenviron.c: increment ast.env_serial
+ include/tm.h: tmset() now calls tminit() directly
+ tm/tminit.c: check ast.env_serial for env change
+ tm/tmfix.c: speed up for large values of tm_mday
+02-07-15 comp/fnmatch.c: fix memory leak caused by missing regfree()
+ comp/strstr.c: fix broken interpretation and implementation
+ comp/iconv.c: intercept (but no-op) null to and from buffer pointers
+02-06-27 ast_std.h: map _sysconf => _ast_sysconf for sun
+02-06-26 cdt,sfio,vmalloc: kpv sync -- is this ever easy?
+02-06-24 sfio: kpv sync, vfwscanf(),fputw() fix (wcslen(x)*sizeof(wchar_t)!!)
+ misc/fts.c: fix symlink chdir() optimzation bug
+02-06-11 sfio/sfwrite.c: string to file fix
+ Makefile: __OBSOLETE__==20020101
+02-06-01 regex/regcomp.c: REG_DELIMITED now consumes the delimiter
+02-05-31 regex/reglib.h,regcomp.c,regnexec.c: null subexpression fixes
+02-05-24 misc/fts.c: disable dir link counts in 3d
+ misc/magic.c: fix "*(mkfile)" sh pattern to "*@(mkfile)"
+02-05-20 regex.h,regex/regsubcomp.c,regex/regsubexec.c: add
+ regex/regsub.c: deprecate
+02-05-16 tm/tmfix.c: fix '60+n min/sec ago' bug for n min/sec after the hour
+02-05-14 regex/regsub.c: fix (^|x) null match early termination bug
+02-05-13 dir/dirlib.h: drop errant extern==__EXPORT__
+ features/uwin: add uwin lib tests
+ uwin/*.c: check features/uwin for stubs
+ features/float: add nan representation generation
+ sfio/sftable.h: used _ast_*_nan_init for huge values
+02-05-09 misc/fts.c: fix virtual top to force ``child'' stat()
+ features/common: define va_copy() only if not in <stdarg.h>
+02-05-01 string/strtoip4.c: cisco inverted quad mask must have 4 parts
+02-04-30 misc/magic.tab: fix pzip version check
+02-04-19 string/strtoip4.c: handle cisco inverted quad mask n.n.n.n/i.i.i.i
+02-04-18 misc/fts.c: add chdir() verification stat() optimizations
+ path/pathkey.c: check PROBE_ATTRIBUTES for list of vars
+02-04-12 port/astlicense.c: type=open tweak, fix author list spacing
+02-04-11 regex/regcomp.c: check for pattern number overflow
+02-04-05 tm/tmfmt.c: add %u
+02-04-04 sfkeyprintf.c: fix %c numeric value
+ path/pathpath.c: check plain path first -- duh
+02-04-03 misc/fts.c: fix (FTS_PHYSICAL|FTS_NOSTAT) stat optimizations
+ ftwalk.c: only clear FTW_DELAY if FTW_CHILDREN
+ ftwalk.h: add FTW_NSOK for FTW_DELAY
+02-03-29 ast.h: drop strerror() prototype -- already in <ast_std.h>
+ features/stdio: check for _SFIO_H redundant _Sfstd* declarations
+02-03-26 misc/glob.c: fix GLOB_LIST gl_flags values
+02-03-24 port/mnt.c: update bsd fstype name and mount option logic
+02-03-23 Makefile: add ast_wchar.h to the .check.hdr list (for mamake)
+02-03-17 features/stdio: hack around g++ 3.* clashes
+ Makefile: add ast_nl_types.h to the .check.hdr list (for mamake)
+ string/strtoip4.c: fix validity check bug that only checked last part
+02-03-14 misc/optget.c: fix --keys to not expand inline \f...\f
+02-03-12 port/astlicense.c: add type=free
+ path/pathaccess.c: sibling ".." search ignores relative dirs
+ sfio/sfvscanf.c: sfstrtof get() must return 0 on eof
+02-03-11 path/pathexists.c: check path by pairs checking {ENOTDIR,ENOENT}
+02-02-14 features/float: copy local min/max macros to avoid printf roundoff
+ features/wchar: include <ast_common.h>, not <ast_std.h>
+ misc/magic.c: match[]=>matches[] to fix K&R match() macro conflict
+ include/vmalloc.h: include <stdlib.h> for !_PACKAGE_ast
+ uwin/mini.sym: add sprintf (now required by features/common)
+ regex/regnexec.c: truncate wide chars for <ctype.h> functions
+ Makefile: fix MAM ast_common.h sequencing bug by making it first
+ cdt/dthash.c: fix DT_DELETE memory leak (DT_DETACH typo)
+ cdt/dthash.c: fix DT_DELETE double free (dt->data->here typo)
+ regex/regcomp.c: fix recomb() to reject RE with backref
+ features/iffeio: explicitly generate stdio.lcl
+ stdio: add {fcloseall,f(get|put)s_unlocked,fmemopen,getdelim,getline}
+ tmmake,tmtime: allow negative time_t if native localtime/gmtime do
+ tmdate: allow years before 1969
+ fmtfmt: add
+ include/ast.h: add { PATH_TOUCH_CREATE PATH_TOUCH_VERBATIM }
+ Makefile: add std/*.h for std header iffe overrides
+ comp/iconv.c: fix non-C win32 sfreserve() loop
+02-02-11 features/common: separate long long / long double tests
+ features/common: verify printf handles long long / long double
+02-02-02 include/ast_std.h,sfio/sfhdr.h: drop _hdr_locale tests -- always on now
+ include/ast_std.h: trust _UWIN <unistd.h>
+02-01-31 port/mnt.c: add aix options field
+02-01-30 comp/strstr.c: add for ancient s5
+ stdio/_flsbuf.c: only on systems that transfer to native (e.g., uwin)
+ string/strtoi.h: cat min/max error return values
+02-01-28 features/tty: add cf[gs]et[io]speed macros for <termio.h>
+ comp/rename.c: punt to (ancient) /usr/lib/mv_dir on EISDIR
+02-01-24 sigcrit.c: fix SIGCLD!=SIGCHLD interrupt loop
+ sfvprintf.c: convert fast io macros to functions for uts.390 cc
+ string/strtoi.h: drop #pragma prototyped for standalone sfio
+ sfdcsubstr.c: rename from sfdcsubstream.c for 14 char fs
+02-01-22 execlp,execvp,execvpe,spawnlp,spawnvp,spawnvpe: fix __EXPORT__
+ spawnlp,spawnve,spawnvp,spawnvpe: handle ms mode arg -- barf
+ sftable.c: ifdef hacks for _WIN32&_ALPHA_ fp exception
+ _stdfun.c: add _UWIN&_ALPHA_ iob map
+02-01-18 sfio/sfstrtof.h: drop #pragma prototyped for standalone sfio
+02-01-17 features/hdr: don't include <stddef.h> after it doesn't check out!
+02-01-16 misc/magic.c: add version type for YYYYMMDD or [a.][b.]c.d
+ misc/magic.c: recode mime %s parse -- sensible and no buffer overflow
+02-01-15 misc/magic.tab,magicid.h: add generic binary magic number and header
+02-01-12 tm/tmlocale.c: override win32 default date for {C,POSIX,en} locales
+ comp/omitted.c: fix cygwin workaround logic bugs
+02-01-09 stdio/fseeko.c,ftello.c: add from UNIX98
+02-01-08 comp/conf.sh: use $cc instead of cc
+02-01-07 string/strlcat.c,string/strlcpy.c: add bsd api
+01-12-18 comp/conf.tab: fix LFS_CFLAGS default for sun _CS_LFS_CFLAGS botch
+ features/common: add hdr stdarg test
+ tm/tmdate.c: handle YYYY/MM/DD
+01-12-10 misc/magic.tab: add generic 0x00010203 binary magic
+01-12-03 path/pathprobe.c: return HOME relative path if readonly/non-suid fs
+01-11-30 misc/optget.c: add simple cache for repeat offenders (like ksh read)
+ sfio/sfhdr.h: preserve errno across SFMMSEQON-SFMMSEQOFF
+01-11-29 magic.tab: fix GIF version number listing
+01-11-28 string/fmtbase.c: p!=0 => base always included in output
+01-11-26 misc/fts.c: empty path is an error
+01-11-14 misc/optget.c: fix --?+SECTION queries to include paragraphs
+01-11-20 regex/regnexec.c: fix REG_MINIMAL character class match bug
+01-11-19 features/lib: retain _lib_confstr for all solaris releases
+01-11-16 comp/setlocale.c: fix !_lib_setlocale typo
+01-10-31 regex/ucs_names.h: add string catenation to keep line length low
+ misc/fastfind.c: handle gnu slocate db read
+ misc/optget.c: add --?+SECTION queries
+ comp/fnmatch.h: add FNM_NOSYS
+01-10-30 tm/tmdate.c: fix cron specs when both wday and mday are specified
+01-10-20 misc/glob.c: fix bug that called \ trim() twice on same path
+ misc/glob.c: fix \ trim() bug that restored / to wrong position
+ string/fmtre.c: fix { ^ . $ } translations
+ misc/optget.c: use original string if translation fails -- duh
+ sfio/sfhdr.h: assume <errno.h> assigns proper atttibutes to errno
+ comp/regcmp.c: __ia64 workaround fixed by proper CC.DLL probe
+ comp/getdate.c: __ia64 workaround fixed by proper CC.DLL probe
+ features/lib: add lib getdate
+01-10-18 features/lib: check for strtod static link collision
+ features/float: add another signed cast for old bsd cc
+ features/wchar: add <stdlib.h> <stdio.h> before <wchar.h> for old bsd
+01-10-17 sfio/sfcvt.c: limit max precision to { FLT_DIG DBL_DIG LDBL_DIG }
+ sfio/sfcvt.c: fix %[aA] format to always have leading 0[xX]1.
+ sfio/sfvprintf.c: handle %C %lc %S %ls for wchar_t args
+ sfio/sfvscanf.c: handle %C %lc %S %ls for wchar_t args
+ string/fmtmode.c: fix bug that omitted trailing '\0'
+01-10-12 misc/optget.c: . => \&. for --??nroff
+ comp/wc.c: fix mbstate_t initialization typo
+ features/float: fix max integer / float loop termiation
+ features/float: fix LDBL_UINTMAX_MAX typo that did DBL_UINTMAX_MAX
+01-10-11 include/sfio.h: fix _Sfstd* import/export
+ features/common: fix _UWIN __DYNAMIC__() definition
+01-10-06 features/fcntl.c: { O_BINARY O_TEXT } default to 0
+ features/omitted: add for comp/omitted.c
+ sfio/sfopen.c: O_BINARY default for _WIN32&&!_UWIN
+01-10-05 misc/glob.c: fix `\(x/*' GLOB_NOMATCH bug that returned `(x'
+ misc/optget.c: fix localization lookup that didn't drop doubled : ? ]
+01-10-04 comp/setlocale.c: handle sizeof(wchar_t)!=4 in debug locale
+ comp/conf.sh: handle sytems where _SC_* is both an enum and a macro
+01-09-25 astconf: add LIBPREFIX
+01-09-20 features/common: add __DYNAMIC__() for dll externs
+01-09-19 cdt: kpv update
+ mb*() macros: update for ksh conversion, extend debug locale
+01-09-16 tm/tmlocale.c: add compiled in defaults for C locale
+ misc/glob.c: add gl_nextdir callback for GLOB_COMPLETE
+01-08-14 clarify _WIN32 vs. _UWIN vs. __CYGWIN__
+ tminit: fix standard & daylight initialization
+01-09-11 pathnative.c: add for native fs representation
+ regex.h: fix regerror_t prototype
+01-09-04 regex/regnexec.c: fix REG_ICASE for multi-char collating elements
+ tm/tmlocale.c: fix old ascii LC_TIME load
+ locale*: add new LC_* categories
+ comp/omitted.c: add CYGWIN workarounds
+ features/lib: add CYGWIN workarounds
+01-08-11 features/common: some compilers have long long but no LL constants!
+ features/lib: add mmap64 implementation test (for linux.s390)
+ regex/regcomp.c: fix \ in [...] parse
+ setlocale: retain user locale spelling in setlocale() return value
+ features/limits.c: don't include ./limits.h -- duh
+ fmtesc: don't escape multibyte chars
+ tm/tmlocale.c: fix native C locale default
+01-08-08 features/float: some compilers (msdev) forget long long vs. double
+01-07-31 misc/optget.c: handle suboptions
+01-07-27 cdt.h: add DTDISC()
+01-07-17 iffeio.h: move to include for stdio bootstrap iffe workarounds
+01-06-25 regex: perl extensions added and tested
+01-06-21 misc/error: add ERROR_OPTIONS=prefix=string for message processing
+01-06-15 string/chresc: only 2 hex digits max for \xxx
+ regex/regsub: handle REG_SHELL ~(nnn) rhs backrefs
+01-06-11 regex: handle embedded \0 in pattern and subject string
+ regex: add (?nnn) for backrefs > 9
+ comp/fnmatch: add FNM_LEADING_DIR for gnu compatibility
+ features/float: _ast_flt_unsigned_max_t for bsd.i386 omission
+01-06-06 misc/optget.c: add o option for old ps,ar,tar with optional leading -
+ regex/regcomp.c: REG_LENIENT|REG_DELIMITED \<newline> => <newline>
+ regex/regcomp.c: REG_LENIENT \000 => NUL
+01-06-04 features/dirent: replace Makefile hack with iffe semi-hack
+ regex/regnexec.c: negation must also check REG_SHELL_DOT
+01-06-03 sprintf.c: change buf size from SF_BUFSIZE to INT_MAX
+01-05-31 glob: fix gl_fignore to ignore leading . by default
+ features/lib: add botch_d_ino_dirent64 for linux botch
+01-05-25 port/lc.tab: add a few missing language_territory's
+01-05-23 string/chresc: \C[.collation-element.]
+ fmtmatch,fmtre: update for <regex.h> syntax extensions
+01-05-21 regex: add perl extensions, unicode names for collation elements
+01-05-11 string/chresc: \e == \E == escape, \cX == control X, \x{..} == \x..
+01-05-09 path/pathtemp.c: pathtemp(0,0,0,"/private",0) for mode S_IRUSR|S_IWUSR
+ port/touch.c: handle utime(2) EPERM to fix bug that truncated
+ regex: change REG_MINIMAL to avoid negation -- much faster now
+01-05-08 *.h: add some off_t macro guards for suse linux
+01-05-03 regcomp.c: optimize ((x)!)* to ((x)!)
+ wchar: add <wchar.h> and stdio wchar routines
+01-05-02 feaures/wchar: add <wchar.h> intercept, add stdio wchar functions
+01-05-01 string/strtoi.h: signed strtoi accepts qualified unsigned constants
+01-04-30 comp/setlocale.c: fix code that relied on 2 simultaneous getenv()'s
+ tm/tmlocale.c: check for UTF-8 encoded LC_TIME files
+ misc/magic.tab: add utf-8 and utf-16 U+FEFF magic
+01-04-26 features/common: some cc's have _ast_int8_t but not LL constants
+01-04-24 features/lib: add _std_strtod for mac os X
+01-04-23 ccode: add CC_sub for ms embedded EOF char on ebcdic -- no joke
+01-04-20 iconv: handle ebcdic<=>utf
+ mc.h,mc.c: add mcindex()
+ ast_std.h: add AST_MESSAGE_SET
+01-04-18 features/libpath.sh: fix mvs probe
+ *: sundry mvs fixes
+ glob: fix GLOB_NOCHECK to avoid stat() and properly trim patterns
+01-04-01 strtod,strtold: add
+ strtol,strtoul,strtoll,strtoull,strton,strtonl: handle locale & ERANGE
+ sfvprintf,sfvscanf: handle locale decimal_point,thousands_sep
+ sfvprintf,sfvscanf: handle %a,%A
+ setlocale: add LC_NUMERIC decimal_point,thousands_sep init
+ ast_std.h: __OPTIMIZE_SIZE__==1 to disable non-std __GNUC__ inlines
+ pathexists: path cache to cut down pathpath() access(2) calls
+ features/stdio: __FILE_TAG == _sfio_s for solaris
+01-03-23 iconv: fix iconv_move buffer boundary bug that stopped at 1 block
+01-03-19 glob: add GLOB_AUGMENTED
+ regex: REG_SHELL syntax error implies REG_LITERAL match
+ strto[ln][ll]: add overflow checks
+01-03-17 locale: reimplemented to provide canonical locale namespace
+ locale: add LC_ALL=local for local system user default
+ tm.h: TM_*_3 => TM_*_ABBREV
+ tmfmt: handle standard E and O format modifiers
+ tmlocale: consult nl_langinfo() if defined
+ fmtquote("\"",1) => shell quote
+01-03-08 regex: handle multibyte chars and collation classes
+ strmatch,strgrpmatch: now a wrapper on regex
+ ast_std.h: add mb*() multibyte and collation support
+ sfvscanf: handle locale decimal and thousand
+ proc*,system: handle ignored SIGCHLD
+ sfkeyprintf: handle %*C
+01-03-06 locale: add locale data cache for efficient multiple locale switching
+ optget: fix LC_MESSAGES!=C --man bug
+01-03-01 Makefile: HEADEROPT is not optional for win32.*
+ comp/syslog.h: comply with the de factos
+ optget(): fix \f...\f stack bug that referenced data after pop
+01-02-27 *locale*: a batch of fixes for native LC_MESSAGE&LC_TIME hooks
+01-02-22 pathprobe: reprobe test now checks probe.ini too
+ sfio_s.h: advertize public Sfio_t members with _ prefix
+ sfio.h,features/stdio: add <sfio_s.h> reference
+ sfhdr.h: map <sfio_s.h> _foo to foo
+ sfio.h: SF_APPEND=>SF_APPENDWR, SF_CLOSE=>SF_CLOSING
+01-02-14 comp/conf.sh: probe <unistd.h> for _(CS|PC|SC)_* getconf symbols
+ stdio/*: update for uwin stdio.dll binary compatibility
+ sfread: finally fixed premature pipe read EOF bug
+ fmtscale: format tenths for number > 0 && number < 10
+01-02-09 _sfmode(),_sftype(),_Sfextern: UWIN binary stdio compatibility exports
+01-02-08 sfgetm,sfputm,_sfputm: fix max clash with k&r max() macro
+ setlocale: undef valid for sun4 k&r valid() macro
+01-02-07 catopen.c: don't do native catopen for the debug locale
+01-02-06 sfraise.c: add SF_FINAL check to avoid (posibly) freed disciplines
+01-01-01 features/common: fix uwin __DEFINE__
+ sftable: initialize decimal and thousand
+ magic.tab: add corel wordperfect document
+ syslog: add LOG_LEVEL, add '\n' only if needed
+ include/tm.h: #undef daylight for _WIN32
+ sfio.h: add _SF_APPEND and _SF_CLOSE for native namespace incursion
+ ast_std.h: add AST_LC_multibyte for MB_CUR_MAX>1
+ setlocale: set AST_LC_multibyte
+ strmatch: check AST_LC_multibyte
+ features/limits.c: add _BITS_POSIX1_LIM_H guard for linux
+ features/libpath.sh: fix for aix LIBPATH
+ procopen,procclose: block SIGCHLD if PROC_FOREGROUND (e.g., system(3))
+ optget.c: add enumerated option argument values
+ optget.c: add <!--INTERNAL--> for private --html
+ optget.c: fix memory leak that hit shell builtins hard
+ sfio: drop sfread small chunk logic
+00-12-25 mnt.c: handle " and ' quoting for fstab
+ sftmp.c: let pathtemp() open the fd O_EXCL
+00-12-15 conf.sh: add -v for verbose trace
+ features/(limits|unistd).c: no FEATURE/types because of _POSIX_SOURCE
+ features/time: add default for CLOCKS_PER_SEC
+ features/lib: std_malloc now handles NeXT
+00-12-13 strton: recognize qualifier only if preceded by a digit
+ features/lib: change return in vfork() test to exit() for linux sparc
+ fmtquote: fix $'...' quote logic
+00-12-11 tmdate: fix cron format bug that mishandled months
+00-12-01 optget: handle $Id: ... $ in --?-version
+ features/fcntl.c: fix _STDPP_ mmap munmap
+00-11-27 magic: drop dup sfclose() in load()
+ optget: handle error_info.id==0
+00-11-22 features/stdio: add _FILEDEFED for sol9.sun4
+ strton,stronll: handle [u|U][l|L][ll|LL] qualifiers
+00-10-31 tmdate: add TM_DATESTYLE and mmddHHMM[cc]yy
+ astlicense.c: #include <hashkey.h> MAM workaround
+ astlicense.c: check for non-empty CONTRIBUTORS
+00-10-26 features/stdio: add _FILE and __FILE for gnu
+ misc/stk.c: fix stack pointer check off-by-one (dgk does it too!)
+00-10-23 syslog.h: sync with bsd values
+00-10-18 _STUB_* now functions instead of common symbols
+ all extern data declared with definition to eliminate common symbols
+ fastfind: add mac/bsd /var/db/locate.database
+00-10-17 features/lib: add apple osX (darwin.ppc) workarounds
+00-10-12 add: fmtbuf(), fmtclock(), fmtip4(), strtoip4()
+ fmt*() now use fmtbuf() for tmp fmt buf allocation
+00-10-05 regex: add REG_DISCIPLINE and regdisc_t for alloc/error disc
+00-09-29 features/lib: pipe_rw==0 for sgi: boot rw == bin incompatibility
+00-09-21 astlicense: handle \' and \" in license values
+00-09-20 sfwrite: fix write() error in sfprintf() loop
+00-08-11 hdr,vmhdr.h: check/hide { getpagesize sbrk } prototypes
+ astlicense: add noncommercial
+00-07-31 fflush: don't seek on pipes
+ sfresize: add
+ setlocale: fix bad newof() call
+00-06-01 strmatch: initialize match.current.beg[0] to avoid dump at line 670
+ sfio/stdio: a few more errno tweaks
+ astquery: sfstdin/sfstderr by default
+00-05-26 sfmode: errno=EBADF for invalid stream use
+00-05-22 rewind: fix for xopen test
+00-05-18 mcfind: returns absolute path
+00-05-16 optget: --keys must catch \f...\f too
+ translate,mc: errno cleanup
+00-05-09 magic: add netbsd binary magic
+ fts: PATH_RESOLVE!=logical => FTS_SEEDOTDIR
+ ftwflags: call fts_flags()
+ astconf: astconf(0,0,0) re-syncs with _AST_FEATURES
+00-05-08 optget: --usage & --keys for last -catalog group only
+00-05-02 iconv.c: add; use codes[] in ccmapid() and ccmapname(); "" for native
+00-05-01 pathtmp: copy env values (libshell or putenv may change)
+00-04-01 optget: drop bar from [-foo?bar] for --??keys
+ sfvscanf: add %X -- duh
+ features/common: fix va_listval() for power pc
+ findopen: fix FIND_GENERATE codes file search
+ magic: add ERROR_translate() and msgcat.key
+ tmlocale: add for LC_TIME locale info
+ tmlex: check tm_info.format and tm_data.format
+ tmfix: fix for tm_wday special case (via nl_langinfo on LC_TIME fields)
+ strftime: fix for nl_langinfo special case
+ ast_std.h: provide LC_* defauls if not defined
+ sfnew: check ${_AST_sfio_bufsize} -- don't tell kpv
+ catopen,nl_types.h: add intercept to mc* routines
+ magic.tab: add ast message catalog
+ strerror: add _ast_strerror intercept with ERROR_translate("errno")
+ fmtquote: escapes >0177 only if (flags&2)
+00-03-17 feof: stdio macro functions only for _UWIN
+ optget: proper ERROR_translate() calls
+ astgetconf: add for thread safe error message control
+ astlicense: fix type=special but with non-null notice
+ errorx: add for ERROR_translate() support
+ ERROR_translate: add locale id args for alternate dictionary
+ option.h: move _OPT_PRIVATE_ to pointer to avoid dll size mismatch
+ ftwalk: fix FTW_CHILDREN bug that hit top level non-dirs twice
+ translate.c: default error_info.translate
+ astconf: fix dup loop thrash that never returns, add _AST_VERSION
+00-03-10 ast_std.h: do _LARGEFILE_SOURCE initialization before std headers
+ fmtquote: handle $'...' quotes
+00-03-07 optget: fix numeric option support test
+ sfkeyprintf: add %q for '...' quoting with ansi escapes
+00-03-06 features/stdio: fix _sfflsbuf prototype (dingold@gte.net)
+00-02-14 pathtmp: fix pid cache bug that sometimes repeated after ~10 attempts
+ optget: "..." attribute quote
+ pathfind: eliminate *: prefix in lib, not type
+ proc: PROC_FOREGROUND for system(3) semantics (wait status return)
+ pathtmp: fix mktemp() logic
+ fts: fix FTS_NOSEEDOTDIR bug that botched ./* in top list
+ include/ast/prototyped.h includes include/prototyped.h
+ pathpath: fix strdup(0) bug
+ optget: --html <foo@bar> => ...mailto:foo@bar...
+ sscanf: fix sfsscanf => sfvsscanf typo
+ magic.tab: strengthen tar recognition
+00-02-08 conf.sh: fix ifdef for systems that think sysconf(FOO) is const
+00-02-04 glob: fix globlist_t.gl_flags
+00-02-02 vm*: add NoF() for data only files
+00-01-27 fts: fix top level .==.. statp bug (thanks to dr. ek)
+00-01-25 conf.tab: fix LFS*_*LAGS typo
+00-01-24 astlicense: handle type=verbose, license.notice, author=*
+00-01-11 pathprobe: generate info for first probe script on PATH - duh
+ ast.h: add NoF(x) for files that define no functions
+ tmpfile: fix implementation
+ global change for string ERROR_translate() dictionary names
+ optget: fix new way but no long names off by one
+ optget: handle [--dictionary?name]
+99-11-19 comp/conf.sh: `expr length XXX` is not universal
+ drop sfstdio; stdio via functions everywhere
+ drop Makefile conditionals (and follow our own advice for once)
+ sfio: new stream after atexit() bug fix
+ tm: Tm_zone_t.daylight=0 for standard time within zone
+ stdio: fopen => _ast_fopen: only way short of binary compatibility
+ Makefile: atmain.C falls back to atmain.c
+ optget: add --keys, s<section> option
+ stdio: _UWIN check for foreign stdio
+99-11-11 astlicense: add
+99-10-31 glob: fix regexec pattern; add PATH_ATTRIBUTES case check
+ pathpath: path==0 means malloc space
+99-10-22 tmfmt: %C=2-digit-century, %k=date(1), %y=2-digit-year-in-century
+99-10-18 fastfind: expanded default db lookup
+99-08-11 magic: fix off by one registry malloc
+ features/fs: add __RENAME checks for stat familiy (netbsd)
+ features/fs: major()/minor() fixes for s5
+ features/libpath.sh: netbsd fix -- ld.so not in std places
+ misc/fastfind: fix codes path generation bug
+ optget: beef up --?* description, fix <TR>...</TR> nesting
+ pathprobe: check for override (writable key file) first
+ features/time: int tmtimeofday(struct timeval*);
+ optget: fix opt_info.num, even if opt_info.arg!=0
+ fts: FTS_PHYSICAL => FTS_SEEDOTDIR, add FTS_CHOP
+ fastfind: init dir tab with logical and physical name
+ glob: add gnu GLOB_ALTDIRFUNC
+99-07-17 sfio: kpv update and sfhdr.h sync!
+99-06-24 stdio: fix fflush() to ignore sfseek(0) return value
+99-06-23 magic: '\r' is text not control to placate m$
+99-06-08 stdio: fix fseek,ftell semantics
+ uwin stdio: fflush() => _doflsh() to avoid __cplusplus clash
+ getopt: call liberror() to avoid error() conflict
+ tmfmt,tmscan: %N zone type (nation code), %z zone minutes west offset
+ tmfmt: - no pad _ space pad 0 leading 0 pad
+99-05-28 magic: fix 'x' == '*' for any number, magic.tab tweaks
+ features/lib: verify that stat64 really works
+99-05-21 tm*: add TM_WINDOW==69 for consistent century windowing guard year
+99-05-18 tmtime: add century leap year calc anticipating unsigned time_t
+99-05-17 sfkeyprintf: handle %o and %x!!
+99-05-09 pathprobe: $HOME/.probe if not suid and st_uid!=geteuid()
+99-04-28 magic,magic.tab: add registry()
+99-04-24 regcomp: fix ksh pattern +! parse
+ regfatalpat: add
+ optget: make : ? ] double escape consistent in all contexts
+99-04-01 features: drop iffeio.h and stdio.h when only printf() used
+ regex: fix stats() .l and .k count
+ fmtquote: added; most general fmtesc() form
+99-03-22 fmtesc.c,ast.h: add fmtnesq()
+ optget: --?x works for -x option flag
+99-03-17 features/limits.c: workaround solaris __EXTENSIONS__ _timespec bug
+ workaround limits.h circular prereq with ignore stdio.h
+ sfvprintf: %04e left-pad zero fixed
+99-03-03 fts: uncle already: add FTS_SEEDOTDIR to retain leading ./
+ regex: REG_MULTIPLE, BM for fixed string alternation
+ optget: embedded `-' optional in long options, prefix={0,1,2}
+99-02-14 fastfind: fix dir format bug that emitted wrong paths
+ astconf: fix redef off by one bug
+99-02-11 pathcanon(): don't cache astconf("PATH_LEADING_SLASHES", NiL, NiL)
+99-01-23 optget: move <old_opt.h> back into <option.h>, no open-close
+ optget: add "[index:long-name:description]" for --long-name
+ comp/gross: add weak __libc_attr for irix < 6.5 compatibility
+ features/limits.c: tweak the guards again
+99-01-11 fastfind: handle old format count byte order
+ magic.tab: fix elf to use real phdr offset
+ magic.c,magic.tab: fix | to act like switch/case
+ comp/fross.c,features/hack: for gross hacks
+ features/stdio: avoid sfio namespace pollution
+98-12-25 tmdate: yyyy.mm.dd
+ pathprobe: fix procrun() cmd path bug
+ fmtesq: add
+ features/common: win32.alpha va_list
+ magic: add pc alpha object
+98-11-11 strmatch: add STR_ICASE
+ pathprobe: punt to $HOME/.probe/<key+HOSTTYPE> if not S_ISUID
+ tmzone,tmdate: handle +-minutes, nn/MMM/yyyy
+ stropt: fix nested quote pop
+ tmfmt: add %K => %Y-%m-%d/%H:%M:%S
+ sfio/stdio: fix fseek() SF_PUBLIC omissions
+ fmtesc: catch '\\' (duh)
+ vmalloc: vmbest round bug fix
+98-11-01 fts.c: no pathcanon() if (fts_flags & FTS_PHYSICAL)
+98-10-01 features/stdio prototype fixes
+ optget: strton() instead of strtol() for #
+98-09-22 regcomp: add REG_DELIMITED and REG_ESCAPE delimited re support
+98-09-15 fix _LARGEFILE64_SOURCE stuff
+ ast_std.h: provide mmap() prototype
+98-08-11 fix sfpopen() to ignore SIGPIPE by ignoresig() for sfio but not stdio
+ fix procopen() to ignore SIGPIPE by ignoresig() for PROC_IGNORE
+ sfio sfpopen/popen update
+ magic.src: fix ustar entry
+98-07-17 fix ftwalk() short by one malloc()
+ add fts_notify()
+98-06-25 sfdcmore,sfdcprefix: add
+98-06-19 tokscan: add %f %g
+98-06-01 disc/sf*.c: memset(0) after disc malloc()
+98-05-11 strelapsed: y==Y
+ fts: pathcanon() top list
+98-04-01 error: error_info.time for all msgs, just after cmd id
+ error: no sfsync(sfstdin)
+ sfio: sfpool, Sffmt_t update
+ magic.tab: sgi core dumps -- why aren't these elf?
+ stropt: (v+n) for unknown option is option value if n!=0
+ procopen: fix setsid() for spawnveg() only
+98-03-19 malloc: add realloc foreign region check
+ sfdisc.h: rename to match kpv disciplines
+ fastfind: fix strcasecmp/strcmp directory prefix mixup
+98-03-17 features/fcntl.c,pathtmp,sftmp: add O_TEMPORARY
+98-03-01 pathcanon: fix PATH_LEADING_SLASHES to stat() both slashes
+ pathcanon: add PATH_VERIFIED
+ tmdate: add skip[] to expand separator char set
+ fastfind: FIND_OLD for old 7 bit db, FIND_TYPE for new 8 bit typed db
+ fastfind: default generates gnu LOCATE02 8 bit db
+ magic: handle %s in mime description
+ cdt: kpv update
+ sfio: kpv update
+ stdio: fpos64_t fseek64(), ftell64(), fgetpos64(), fsetpos64()
+ stdio: fseek() => sfseek(SF_PUBLIC) to avoid locking
+ fts: initialize parent stat[bp] from top level *after* statf done
+ astmath: add -lm requirement test
+ *: Astlong_t => _ast_*_t
+ regex: simplify regcollate() (from doug)
+ tmtime: preserve Tm_t*tm when calling tminit()
+ astconf: add readonly PATH_ATTRIBUTES=[cirw]
+98-02-14 fastfind: add FIND_ICASE to ignore case
+ tmdate,tmgoff: handle (+|-)hh[[:]mm[[:]ss]] absolute timezone
+ tmdate: `<n> <part>' now assumes `next <n> <part>' instead of `this'
+ tmfix: fix leap year bug that forgot to add 1900
+ proc: add PROC_ZOMBIE
+98-02-06 strmatch() char class range bug fix
+ regex char class range bug fix
+98-01-23 _WIN32: changed the #if logic again to accomodate _GNUC_
+ mnt: grab the mount options too
+ ast_std.h: hide getopt,getsubopt from stdlib.h
+ features/limits.c: add gnu guard macros to avoid limits.h recursion
+ features/mode.c: include "limits.h" instead of "FEATURE/limits.lcl"
+98-01-11 sfio.h: use Astlong_t, move Sfio_t Sfdisc_t typedef to top for stdio.h
+ sfhdr.h: #undef SETLOCAL for hpux
+ sfvprintf,sfvscanf: %I*x for sizeof(int_arg)
+ handle ftruncate64 and truncate64
+ dtopen.c: __hppa dll needs Dtset Dtlist Dttree refs here
+97-12-18 fmtnum: add
+97-12-11 magic: handle sgi 64 bit core dumps
+97-12-07 pathtmp: add override for TMPPATH,TMPDIR and cycling
+97-11-11 tm: handle 0 return from gmtime(),localtime() (dos negative time_t)
+ features/stdio: fix fflush() macro to do physical sync
+97-10-31 astconf PATH_RESOLVE is logical if 3d&&!std, metaphysical otherwise
+ magic: fix #! mime bug
+ tm: tmtime() now calls tmfix() and adjusts tm_isdst too=>mtime() works
+97-10-11 dllfind,dlfcn: move to separate -ldll so -last can link static, duh
+ Makefile,state.c: move forced header generation state.c => Makefile
+ sfio: update including SF_WHOLE
+97-10-01 sfdostext: add \r\n => \n sfio discipline
+ stropt: NiL table => p=name for all name=value
+97-08-11 pathtmp: check pid to note forks
+ procopen: FD_CLOEXEC rfd && wfd
+ fts: fts_close() after fts_children() with no fts_read() now works
+97-07-17 error: sfsync(sfstdin,sfstdout,sfstderr) instead of sfsync(NiL)
+ _sfcvinit: add sfio internal interface to base conversion tables
+ strton: use _Sfcv* base conversion tables instead of sfsscanf()
+ sfvscanf: use _Sfcv* base conversion tables
+ mime: x- permutations now matched if exact fails
+ mime: original- stripped from content-* headers
+ tmdate: add yyyy-jjj, yyyy-mm-dd
+ dllfind: add
+ ccmapid: fix buf copy loop limit
+ ccmapname,ccmapcpy: add
+ sfstrtmp: add
+97-05-09 streval: fix up casts for pseudo-ansi cc
+ features/types: use _ast_int_8 vars to verify support
+ string/modedata: check for mvs.390 S_IFMT
+ include/ast(_std).h: add #define __FILE_typedef
+ magic: add ccode text check
+ include/ftwalk.h: FTW_PATH=>FTS_NOCHDIR to avoid FTS_AGAIN (duh)
+ fts: clear status for FTS_AGAIN (fixes rm -r bug)
+ mnt: add mvs openedition w_getmntent()
+ sfhdr: _hdr_float && <float.h> for correct MAXDOUBLE
+ vmalloc/vmbest: if _std_malloc then use malloc()/free() not sbrk()
+ remove: check _std_remove
+ procopen: handle pio[{0,1}]=={0,1}
+ setenviron,features/uinstd: test for mvs.390 dll environ hacks
+96-12-25 <sfio_p.h> -> <ast_common.h>
+ __EXTERN__(type,object)
+ __DEFINE__(type,object,value)
+ magic: check strings in !CC_NATIVE code set too
+ system: cmd==0 means check for shell access (xopen)
+ sfhdr.h: fix sfrsrv prototype
+ add __libc_malloc etc for gnu/linux
+ astconf(NiL,path,name) == astconf(name,path,NiL) + no liberror
+ fts_open: if toplist() stat fails return 0
+ ftwalk: handle fts_open()==0 via one phony userf() call
+ sfmode: S_ISFIFO default is SF_SHARE=0
+ features/lib: _WIN32 _lib_vfork=1 by default
+ unsigned<0 comparison and other fixes via sgi.mips4 cc
+ stk.c: use <align.h> ALIGN_BOUND for stkalloc()
+ features/lib,vfork: uwin fix
+ ast_std.h: fix strto[u]ll prototypes with features/types _ast_int_8
+ getsubopt: add for xopen 4.2 compatibility
+ drop function __IMPORT__
+ magic: more magic
+ change #define FILE from Sfio_t to struct _sfio_s
+ state.c: add generated includes that may be hit by std for MAM
+ bytesex: forgot about sizeof(long)=>7; could we fix the name too?
+ vmalloc.h: fix vmnewof() definition
+ sfio.h,stdio.h,ast_common.h: pollution cleanup
+ magic.c: add | op for switch
+ Makefile: stdio.h was on both HEADERSRC and HEADERGEN -- don't do that
+ drop pp:notice to get <sfio.h> ... <ast.h> to work
+ regex: add [[:<:]]==\< and [[:>:]]==\> for bsd compat
+ mime.c: ignore X-* headers while scanning for Content-*
+ magic.c: check for negative indirect offsets
+ magic.tab: fix dos entry that generated negative indirect offsets
+ vmalloc.h: add vmstrdup() prototype
+ hash.h: add hashgetbucket() macro
+ magic.c: MAGIFILE is now a : file list
+ mnt.c: another 4.4 bsd fix -- users must include <sys/crap.h>
+ common: fix _WIN32 chicken&egg with va_copy
+ sfio: forgot to set f->val along with _Sfi in sfexcept()
+ Makefile: add mini target for uwin libmini.a
+ sfcvt.c: workaround for flaky long double optimizers
+ features/common: fix to work with va_list==void*
+ regexec.c: fix REG_STARTEND subexpression offsets
+ strmatch.c: don't forget <wctype.h>
+ regrexec.c: fix REG_INVERT end boundary bug that missed last record
+ astconf.c: notify(0,0,"a=b") called for each setenviron("a=b")
+ pathcanon.c: check astconf(PATH_LEADING_SLASHES) to preserve //*
+96-11-28 _LARGEFILE64_SOURCE by default if possible: NOTE: assumes xopen
+ regerror: fix for xopen
+ getopt: fix for xopen
+ magic: add ciao virtual database
+ astconf: posix/strict/xopen implies "standard" conformance
+ fs3d.h: hide mount prototype
+ ast_std.h,mnt.c,features/fs: ncr port tweaks
+96-10-31 version 5.0
+ add strtoll() strtoull()
+ sfkeyprintf: upgrade to int_max args
+ ast.h: add ssizeof() to work around unsigned botch
+ conf.sh: add shell actions to conf.tab
+ _DLL*: drop for _BLD_<lib> + __EXPORT__ + __IMPORT__
+ sfio,cdt,vmalloc: kpv update
+96-10-11 <ccode.h>: add character code map support
+ procclose: return shell style exit status
+ features/fs: pun statvfs.f_basetype to statvfs.f_reserved7 for mvs
+ uwin: add subdir for uwin additions
+ ast_std.h: swab() is from <stdlib.h>
+ sfio.h: <ast_std.h> if _PACKAGE_ast
+ magic.tab: add mips[1-4], 64-bit
+ port tweaks for sol.sun4 and sun4
+96-09-06 strerror: add
+ fmterror: uses strerror
+ str*search: use sfiso646() order
+ strpsearch: add
+ magic: add Magic_t.mime mime type return for magictype()
+ mime.h: add
+ strton: use sfsscanf()
+ strperm: factor in umask() if no who
+ pathtmp: add TMPPATH check
+ libevent: add
+ magic: add discipline to magicopen()
+ mime: add discipline to mimeopen()
+96-08-31 regex: fix BM fail table generator
+96-08-11 mntread: fix mnt.type for SCO variant
+ conf.tab: add SCO KERNEL_* sysconf() vars
+ fastfind: add findwrite(), fix findread() FF_OFF omission
+ ftwalk: reimplement on top of fts
+ fnmatch,re_comp,regexp: reimplement on top of regex
+ basename,dirname,fmtmsg,fts,ftw,getdate,getsubopt,glob: add
+ hsearch,nftw,realpath,strftime,strptime,swab,tempnam: add
+ tsearch,wordexp: add
+ getcwd: cache last path for easy test
+96-07-17 error: sfsync(NiL) ... write ... sfsync(sfstderr)
+ astconf: handle readonly *(DEV|DIR) vars
+96-04-01 swapop: fix stupid return value bug
+ features/int.c: fix int_swap generation bug
+ regnexec,regrexec: fix unsigned underflow init error
+ ls.h: fix iblocks() to be in units of LS_BLOCKSIZE
+96-02-29 magic: space before function is definition with no call
+ hash: drop hash_info from public interface
+ hash: OBSOLETE hashlast()
+ hash: add Hash_root_t.Hash_last_t to public interface
+ add strsearch() and strnsearch() to complement strlook()
+ add hashkey.h for keyword->long hash
+ pathpath: pathpath(0,0,"",0) disables $0 $_ $PWD relative search
+ sfio: sfstrtod+sfhdr update
+ regex: fix REG_LENIENT to map BRE \[+?|] to ERE [+?|]
+ change _std_malloc iffe test so it doesn't hang on alpha
+ sfhdr.h: features/sfio generates _lib_cvt instead of _i386_cvt
+ ast_hdr.h: add va_copy(a,b) to copy va_list b to a
+ getopt: fix stupid getopt() -> optget() bug
+ sfvprintf: %h? now downcasts
+ regex: handle strto?l() errno in regcomp()
+ sfstrtod: _Sfstrtod_already_defined -> _STUB_sfstrtod
+ ast_std.h: hide valloc() and ignore <strings.h>
+ sfkeyprintf: pass phony va_list for '2'
+ regex: change HIT var type from int to size_t in special()
+ ast.h: add EXIT_STATUS(x) to convert wait() status to sh exit status
+96-02-14 regex: add _ to \<...\> isalnum test
+ regex: fix BM inner loop breakout
+ features/types: size_t is signed on some systems! => _ast_size_t
+ sfio: sfrd discipline peek optimization
+ vmalloc: vmalloc.h malloc family macro upgrade
+ tokopen: fix newline bug for non-restore open
+ sfio: no inline for gcc until it emits for -g too
+96-02-12 sfio: internal upgrade
+96-02-09 regex: Boyer-Moore boundary fix
+ vmalloc: snarf latest
+96-02-06 regex: add regrecord() and regrexec() for Boyer-Moore record filtering
+ regex: rearrange regnexec() args to match buffer,count arg style
+96-01-31 stk: add STK_NULL to stk.h and stk.c
+ regex: privatize regex.h and fix min re length computation
+ workaround lazy strdup() implementations in features/lib _std_malloc
+ fix stkclose() to free(stream) -- purify missed because of sfio links
+ unused var cleanup
+ port/mnt.c must include <ls.h> to get <ast_fs.h>
+ add SF_FINAL to sfio and stk
+ sfio reads now on natural block boundaries
+ add #!!! <level> <message> !!! to tokline()
+ add REX_BM pre-filter to regcomp/regnexec
+96-01-22 add regcomp env.paren overflow checks
+96-01-11 add Doug McIlroy's regex (converted to C from C++ by gsf)
+ AT&T Research now
+ sfgetr optimization
+ regex buglets
+96-01-05 tweak magic.tab for win32
+95-12-25 add !(...) -> (...)! to fmtre()
+ nt tweaks -- functions with no header proto must be defined extern
+95-11-24 version 4.1
+ add mnt.h mntopen mntread mntclose
+ convert fmtfs to mnt.h
+ add RE_LEFTANCHOR and RE_RIGHTANCHOR
+ gcc inlines must also have global library function instantiation!
+ add hashview()
+ fix strtape() internal buffer flow
+ fix mntread() fs/dir transposition for uts mnttab
+95-10-31 change features/unistd.c includes to break limits-param cycle
+ add cdt from kpv
+ sfio snarf from kpv
+ add [ht]search for _WIN32
+95-10-11 clarify PARANOID pathcheck() warning
+ fix procopen() LIB_SPAWN environ bug with setenviron() cache
+ fix setenviron() bug that forgot to reset environ if == 0
+ add %Z '\0' output format to sfkeyprintf()
+ sfio snarf for sfvprintf fix
+ allow multiple hashscan() with scope caveat
+ add comp/fakelink.h to synthesize a few symlink text patterns
+ add !<xxx> magic to misc/magic.tab
+ add FTW_TOP to inhibit recursion (for ftw side effects on top level)
+ add memfatal() common malloc fatal exception message
+ add dos \r\n test to misc/magic.c/cklang()
+ sftmp() O_EXCL+random to avoid collisions
+ pathtemp() uses sftmp() randomizing
+ features/fs uses SF_APPENDWR
+ sftmp() uses pathtemp() -- don't worry, its not circular
+ a few more _WIN32 compatibility additions
+ realloc fixed to use VM_RSCOPY|VM_RSMOVE instead of obsolete 1
+ add hashlook(tab, oldname, HASH_RENAME, newname)
+ a few more tweaks to satisfy port warnings
+ add _SFIO_INLINE_PRIVATE to provide real function too
+ fix <dirent.h> installation test
+ oops object / shared library compat with _sfgetl2 _sfgetu2
+95-09-11 add getopt() compatibility
+ add fstat,lstat,mknod,stat fixes for _x versions in sys/stat.h
+ add getconf CONFORMANCE - posix for things that aren't ast default
+ sfio_t.h: #ifndef _SFIO_H #include "sfio.h" #endif
+ snarf vmalloc from kpv
+95-08-11 fix malloc bug in magic
+ update linux and bsd 386 magic entries
+ error_info.auxilliary returns new level, |=ERROR_OUTPUT if msg done
+ drop fnmatch from strmatch for sparc (solaris) until it collates
+95-07-17 fix port/astconf universe initialization
+ fix misc/optget opt_info.nopt initialization
+ drop tmset() TZ=... because it only worked when TZ=... was ignored
+95-05-09 mongo <ast.h> namespace cleanup
+ drop > 2 year old obsolete interfaces
+ sfvprintf.c fix for (char:8 short:16 int:32 long:64) architectures
+ TMP_MAX back into conf.tab
+ pathbin() and pathshell() now use astconf()
+ fix pathtemp() to not cache getenv("TMPDIR")
+ fix ftwalk() metaphysical to handle non-dirs too
+ initialize *_info = { 0 }; for ancient ld semantics (NeXT)
+ fix magic() to do vmfree()
+ astconf(X_OK) must prefix lines with "getconf"
+ use <wchar.h> and wctype in strmatch() if available
+ _lib_utime_now checks utime(path,0)
+ _lib_poll_notimer checks poll(x,0,timeout)
+ add another _lib_utime_now check to port/touch.c
+ fix dd_buf cast in dir/opendir.c
+ split getconf.h into conftab.h and conftab.c for :READONLY:
+ use mbtowc() only if MB_LEN_MAX>1
+ sfio char* -> Void_t* cleanup
+ handle old syntax in misc/magic.c
+ sigdata.c holds readonly signal strings
+ pathcheck() does AT&T checks for tools matching PARANOID - yuk
+ unused var cleanup
+ deprecate hash_info in favor of hashlast()
+ fix bad conf.sh ksh integer interactions
+ dll cleanup
+ magic.c falls back to malloc for now
+ add environ to <ast.h> -- C library global data syms are *RESERVED*
+ sfhdr.h memccpy(1,2,3,size_t) prototype
+95-04-01 version 4.0
+ convert to vmalloc
+ allow sigcritical() nesting mismatch to work around vfork() bug
+ add strexpr() primitive for streval() with user handle (like ftwalk)
+ add <magic.h> and magic.c file command magic interface
+ update magic mail message entry
+ fix keyprintf() invisible char count nesting bug
+ add sfstrnew(SF_READ|SF_WRITE) for alternate sfstropen() modes
+ sfstrnew(SF_READ) but reading requires sfseek(), sfreserve()
+ add conf.tab and conf.sh to nail C/POSIX limits/unistd macros
+ add getconf() string interface to *conf*
+ _DLL_INTERMEDIATE_DATA for systems that require indirect globals
+ _DLL for building shared libraries with _DLL_INTERMEDIATE_DATA
+ vecfile() restricted to S_ISREG()
+ add spawnveg() for job control
+ convert procopen() PROC_PGRP(id) to spawnveg()
+ fmterror() returns error text given errno (strerror() does same)
+ fmtsignal() returns signal text given errno (strsignal() does same)
+ {sig_name,sig_text,SIG_MAX} -> sig_info.{name,text,sigmax}
+ liberror("",...) omits [%s library] prefix
+ update features/signal.c table
+ add vmdisc() and change vmnewof() to use vmresize()
+ fix conf.sh to allow refs to previously defined limits
+ fix undefined entries in getconf()
+ magic data in magic.tab
+ fix stropt() pointer cast
+ vmalloc() exception handler replaces nomalloc()
+ merge sigdata.c into fmtsignal.c -- sun link needs function w/ data!
+ sftmp() bug fix
+ drop local <unistd.h> even with _POSIX_SOURCE
+ fix vmstrdup() macro arg miscount
+ fix conf.sh to handle enum'd symbolic constants in unistd.h
+ drop malloc() et.al. prototypes from vmalloc.h
+ fix sfvprintf() %d argument reference
+ add OSF/1 AES symbol(s) to conf.tab
+ determine standards prefix from conf.tab
+ add _CS_SHELL to conf.tab
+ getpath() default is confstr(_CS_PATH)
+ getshell() default is confstr(_CS_SHELL)
+ unify keyprintf user function args (should have learned by now!)
+ add quad type to magic
+ add astfeature() to unify universe style dynamic features
+ add ftwflags() to determine FTW_* flags from astfeature()
+95-03-11 fix stropt() to not modify its *const* arg
+ handle "'\ quotes and chresc() in stropt() values
+ , treated like :space: between stropt() options
+ fix procopen() fd dup to ignore self-dups
+ add library id[] to misc/state.c
+ add ftwalk(FTW_METAPHYSICAL) for posix -H
+ sfvprintf() now handles balanced () in %()
+ add tmfmt() with buffer size check to replace tmform()
+ add fmttime() calling tmfmt() to fit fmt*() mold
+ add <keyprintf.h> and keyprintf() to support %(...)? in commands
+ add Hash_table_t for size==0 in stropt()
+ add EXTTYPE extended header to tar.h
+95-02-14 sfmove() buffer size overflow fix
+ add _SFSTDIO_H to sfio.h
+ rename setenv() to setenviron() -- posix finally decided
+ rename <option.h> opt_* to opt_info.*
+ update features/unistd.c for _SC_* and _PC_* posix additions
+95-01-19 (char*)uchar cast in fmtesc()
+ fix hash bucket memory leak in hashlook() [via John Mocenigo]
+ update strings/strtape()
+ fix optget()/optjoin() to handle leading +
+ add ALIGN_ prefix to <align.h> identifiers
+95-01-11 change tm/*.c tmset(0) to tmset(tm_info.zone) to keep user setting
+ fix tmform() %Z null pointer dereference
+95-01-01 add this RELEASE file
+ fix strperm() to properly handle "644 file"
+ fix tokline() to return last '\0' terminated line in string
+ fix tokscan() to properly handle \\n splice
+ add fmtesc() to complement stresc()
+ add LS_NUMBER to fmtls()
+ drop spurious optusage() ' '
diff --git a/src/lib/libast/aso/aso-fcntl.c b/src/lib/libast/aso/aso-fcntl.c
new file mode 100644
index 0000000..7f3f6d9
--- /dev/null
+++ b/src/lib/libast/aso/aso-fcntl.c
@@ -0,0 +1,188 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "asohdr.h"
+
+#if defined(_UWIN) && defined(_BLD_ast) || !_aso_fcntl
+
+NoN(aso_meth_fcntl)
+
+#else
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+typedef struct APL_s
+{
+ int fd;
+ size_t size;
+ char path[1];
+} APL_t;
+
+static void*
+aso_init_fcntl(void* data, const char* details)
+{
+ APL_t* apl = (APL_t*)data;
+ char* path;
+ char* opt;
+ size_t size;
+ size_t references;
+ int n;
+ int fd;
+ int drop;
+ int perm;
+ struct flock lock;
+ char buf[PATH_MAX];
+ char tmp[64];
+
+ if (apl)
+ {
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = apl->size;
+ lock.l_len = sizeof(references);
+ if (fcntl(apl->fd, F_SETLKW, &lock) >= 0)
+ {
+ if (lseek(apl->fd, apl->size, SEEK_SET) != apl->size)
+ references = 0;
+ else if (read(apl->fd, &references, sizeof(references)) != sizeof(references))
+ references = 0;
+ else if (references > 0)
+ {
+ references--;
+ if (lseek(apl->fd, apl->size, SEEK_SET) != apl->size)
+ references = 0;
+ else if (write(apl->fd, &references, sizeof(references)) != sizeof(references))
+ references = 0;
+ }
+ lock.l_type = F_UNLCK;
+ fcntl(apl->fd, F_SETLK, &lock);
+ if (!references)
+ remove(apl->path);
+ }
+ close(apl->fd);
+ free(apl);
+ return 0;
+ }
+ fd = -1;
+ perm = S_IRUSR|S_IWUSR;
+ drop = 0;
+ size = 32 * 1024 - sizeof(references);
+ if (path = (char*)details)
+ while (opt = strchr(path, ','))
+ {
+ if (strneq(path, "perm=", 5))
+ {
+ if ((n = opt - (path + 5)) >= sizeof(tmp))
+ n = sizeof(tmp) - 1;
+ memcpy(tmp, path + 5, n);
+ tmp[n] = 0;
+ perm = strperm(tmp, NiL, perm);
+ }
+ else if (strneq(path, "size=", 5))
+ {
+ size = strtoul(path + 5, NiL, 0);
+ if (size <= sizeof(references))
+ goto bad;
+ size -= sizeof(references);
+ }
+ path = opt + 1;
+ }
+ if (!path || !*path)
+ {
+ if (!(path = pathtemp(buf, sizeof(buf), NiL, "aso", &fd)))
+ return 0;
+ drop = 1;
+ }
+ if (!(apl = newof(0, APL_t, 1, strlen(path))))
+ goto bad;
+ if (fd >= 0 || (fd = open(path, O_RDWR)) < 0 && (fd = open(path, O_CREAT|O_RDWR, perm)) >= 0)
+ {
+ if (lseek(fd, size, SEEK_SET) != size)
+ goto bad;
+ references = 1;
+ if (write(fd, &references, sizeof(references)) != sizeof(references))
+ goto bad;
+ }
+ else
+ {
+ if ((size = lseek(fd, 0, SEEK_END)) <= sizeof(references))
+ goto bad;
+ size -= sizeof(references);
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = sizeof(references);
+ if (fcntl(fd, F_SETLKW, &lock) < 0)
+ goto bad;
+ if (lseek(fd, size, SEEK_SET) != size)
+ goto bad;
+ if (read(fd, &references, sizeof(references)) != sizeof(references))
+ goto bad;
+ references++;
+ if (lseek(fd, size, SEEK_SET) != size)
+ goto bad;
+ if (write(fd, &references, sizeof(references)) != sizeof(references))
+ goto bad;
+ lock.l_type = F_UNLCK;
+ fcntl(fd, F_SETLK, &lock);
+ }
+ apl->fd = fd;
+ apl->size = size;
+ strcpy(apl->path, path);
+ return apl;
+ bad:
+ if (apl)
+ free(apl);
+ if (fd >= 0)
+ close(fd);
+ if (drop)
+ remove(path);
+ return 0;
+}
+
+static ssize_t
+aso_lock_fcntl(void* data, ssize_t k, void volatile* p)
+{
+ APL_t* apl = (APL_t*)data;
+ struct flock lock;
+
+ if (!apl)
+ return -1;
+ if (k > 0)
+ lock.l_type = F_UNLCK;
+ else
+ {
+ lock.l_type = F_WRLCK;
+ k = HASH(p, apl->size) + 1;
+ }
+ lock.l_whence = SEEK_SET;
+ lock.l_start = k - 1;
+ lock.l_len = 1;
+ return fcntl(apl->fd, F_SETLKW, &lock) < 0 ? -1 : k;
+}
+
+Asometh_t _aso_meth_fcntl = { "fcntl", ASO_PROCESS, aso_init_fcntl, aso_lock_fcntl };
+
+#endif
diff --git a/src/lib/libast/aso/aso-sem.c b/src/lib/libast/aso/aso-sem.c
new file mode 100644
index 0000000..5ed9b72
--- /dev/null
+++ b/src/lib/libast/aso/aso-sem.c
@@ -0,0 +1,193 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "asohdr.h"
+
+#if defined(_UWIN) && defined(_BLD_ast) || !_aso_semaphore
+
+NoN(aso_meth_semaphore)
+
+#else
+
+#include <sys/stat.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+
+#define SPIN 1000000
+
+typedef union Semun_u
+{
+ int val;
+ struct semid_ds* ds;
+ unsigned short* array;
+} Semun_t;
+
+typedef struct APL_s
+{
+ int id;
+ size_t size;
+} APL_t;
+
+static void*
+aso_init_semaphore(void* data, const char* details)
+{
+ APL_t* apl = (APL_t*)data;
+ char* path;
+ char* opt;
+ size_t size;
+ size_t n;
+ int key;
+ int id;
+ int perm;
+ struct sembuf sem;
+ char tmp[64];
+
+ if (apl)
+ {
+ /*
+ * semaphore 0 is the reference count
+ * the id is dropped on last reference
+ */
+
+ sem.sem_num = 0;
+ sem.sem_op = -1;
+ sem.sem_flg = IPC_NOWAIT;
+ semop(apl->id, &sem, 1);
+ sem.sem_op = 0;
+ if (!semop(apl->id, &sem, 1))
+ semctl(apl->id, 0, IPC_RMID);
+ free(apl);
+ return 0;
+ }
+ perm = S_IRUSR|S_IWUSR;
+ size = 128;
+ if (path = (char*)details)
+ while (opt = strchr(path, ','))
+ {
+ if (strneq(path, "perm=", 5))
+ {
+ if ((n = opt - (path + 5)) >= sizeof(tmp))
+ n = sizeof(tmp) - 1;
+ memcpy(tmp, path + 5, n);
+ tmp[n] = 0;
+ perm = strperm(tmp, NiL, perm);
+ }
+ else if (strneq(path, "size=", 5))
+ {
+ size = strtoul(path + 5, NiL, 0);
+ if (size <= 1)
+ return 0;
+ }
+ path = opt + 1;
+ }
+ key = (!path || !*path || streq(path, "private")) ? IPC_PRIVATE : (strsum(path, 0) & 0x7fff);
+ for (;;)
+ {
+ if ((id = semget(key, size, IPC_CREAT|IPC_EXCL|perm)) >= 0)
+ {
+ /*
+ * initialize all semaphores to 0
+ * this also sets the semaphore 0 ref count
+ */
+
+ sem.sem_op = 1;
+ sem.sem_flg = 0;
+ for (sem.sem_num = 0; sem.sem_num < size; sem.sem_num++)
+ if (semop(id, &sem, 1) < 0)
+ {
+ (void)semctl(id, 0, IPC_RMID);
+ return 0;
+ }
+ break;
+ }
+ else if (errno == EINVAL && size > 3)
+ size /= 2;
+ else if (errno != EEXIST)
+ return 0;
+ else if ((id = semget(key, size, perm)) >= 0)
+ {
+ struct semid_ds ds;
+ Semun_t arg;
+ unsigned int k;
+
+ /*
+ * make sure all semaphores have been activated
+ */
+
+ arg.ds = &ds;
+ for (k = 0; k < SPIN; ASOLOOP(k))
+ {
+ if (semctl(id, size-1, IPC_STAT, arg) < 0)
+ return 0;
+ if (ds.sem_otime)
+ break;
+ }
+ if (k > SPIN)
+ return 0;
+
+ /*
+ * bump the ref count
+ */
+
+ sem.sem_num = 0;
+ sem.sem_op = 1;
+ sem.sem_flg = 0;
+ if (semop(id, &sem, 1) < 0)
+ return 0;
+ break;
+ }
+ else if (errno == EINVAL && size > 3)
+ size /= 2;
+ else
+ return 0;
+ }
+ if (!(apl = newof(0, APL_t, 1, 0)))
+ return 0;
+ apl->id = id;
+ apl->size = size - 1;
+ return apl;
+}
+
+static ssize_t
+aso_lock_semaphore(void* data, ssize_t k, void volatile* p)
+{
+ APL_t* apl = (APL_t*)data;
+ struct sembuf sem;
+
+ if (!apl)
+ return -1;
+ if (k > 0)
+ sem.sem_op = 1;
+ else
+ {
+ sem.sem_op = -1;
+ k = HASH(p, apl->size) + 1;
+ }
+ sem.sem_num = k;
+ sem.sem_flg = 0;
+ return semop(apl->id, &sem, 1) < 0 ? -1 : k;
+}
+
+Asometh_t _aso_meth_semaphore = { "semaphore", ASO_PROCESS|ASO_THREAD, aso_init_semaphore, aso_lock_semaphore };
+
+#endif
diff --git a/src/lib/libast/aso/aso.c b/src/lib/libast/aso/aso.c
new file mode 100644
index 0000000..6ad4f31
--- /dev/null
+++ b/src/lib/libast/aso/aso.c
@@ -0,0 +1,866 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "asohdr.h"
+
+#if defined(_UWIN) && defined(_BLD_ast)
+
+NoN(aso)
+
+#else
+
+/*
+ * ast atomic scalar operations
+ * AT&T Research
+ *
+ * cas { 8 16 32 [64] } subset snarfed from the work by
+ * Adam Edgar and Kiem-Phong Vo 2010-10-10
+ *
+ * lock methods and emulations by
+ * Glenn Fowler 2011-11-11
+ *
+ * hopefully stable by 2012-12-12
+ */
+
+#if !_PACKAGE_ast
+
+#if _UWIN
+
+extern ssize_t sfsprintf(char*, size_t, const char*, ...);
+
+#else
+
+#include <stdio.h>
+
+#define sfsprintf snprintf
+
+#endif
+
+#endif
+
+#if defined(_aso_casptr) && (defined(_aso_cas32) || defined(_aso_cas64))
+#define ASO_METHOD (&_aso_meth_intrinsic)
+#define ASO_LOCKF 0
+#else
+#define ASO_METHOD (&_aso_meth_signal)
+#define ASO_LOCKF _aso_lock_signal
+#endif
+
+typedef union
+{
+ uint8_t c[2];
+ uint16_t i;
+} U16_8_t;
+
+typedef union
+{
+ uint8_t c[4];
+ uint32_t i;
+} U32_8_t;
+
+typedef union
+{
+ uint16_t c[2];
+ uint32_t i;
+} U32_16_t;
+
+#ifdef _ast_int8_t
+
+typedef union
+{
+ uint8_t c[8];
+ uint64_t i;
+} U64_8_t;
+
+typedef union
+{
+ uint16_t c[4];
+ uint64_t i;
+} U64_16_t;
+
+typedef union
+{
+ uint32_t c[2];
+ uint64_t i;
+} U64_32_t;
+
+#endif
+
+typedef struct State_s
+{
+ Asometh_t* meth;
+ Asolock_f lockf;
+ Asoerror_f errorf;
+ uintmax_t hung;
+ unsigned int hung2;
+ void* data;
+ pid_t pid;
+} State_t;
+
+static unsigned int _aso_data_signal;
+
+static ssize_t
+_aso_lock_signal(void* data, ssize_t k, void volatile* p)
+{
+ if (k >= 0)
+ {
+ _aso_data_signal--;
+ return 0;
+ }
+ while (_aso_data_signal++)
+ _aso_data_signal--;
+ return 1;
+}
+
+static Asometh_t _aso_meth_signal = { "signal", ASO_SIGNAL, 0, _aso_lock_signal };
+extern Asometh_t _aso_meth_semaphore;
+extern Asometh_t _aso_meth_fcntl;
+static Asometh_t _aso_meth_intrinsic = { "intrinsic", ASO_INTRINSIC|ASO_PROCESS|ASO_THREAD|ASO_SIGNAL, 0, 0 };
+
+static Asometh_t* method[] =
+{
+ &_aso_meth_signal,
+#if defined(_ast_int8_t) && defined(_aso_cas64) || !defined(_ast_int8_t) && defined(_aso_cas32)
+ &_aso_meth_intrinsic,
+#endif
+#if _aso_semaphore
+ &_aso_meth_semaphore,
+#endif
+#if _aso_fcntl
+ &_aso_meth_fcntl,
+#endif
+};
+
+static State_t state =
+{
+ ASO_METHOD, ASO_LOCKF
+};
+
+static int
+asoerror(int type, const char* format, const char* a, const char* b, long n)
+{
+ char buf[128];
+
+ if (b)
+ sfsprintf(buf, sizeof(buf), format, a, b, n);
+ else if (a)
+ sfsprintf(buf, sizeof(buf), format, a, n);
+ else
+ sfsprintf(buf, sizeof(buf), format, n);
+ return state.errorf(type, buf);
+}
+
+/*
+ * if type!=0 return lock method for type with name details
+ * else if name!=0 return lock method matching <name>[,<details>]
+ * else return the current lock method
+ * 0 returned on error
+ *
+ * the user visible asometh() calls this function
+ * it allows, e.g., for -ltaso to provide an asometh() intercept
+ * that prepend its ASO_THREAD methods ahead of the _asometh() methods
+ */
+
+Asometh_t*
+_asometh(int type, void* data)
+{
+ size_t n;
+ int i;
+ char* e;
+ Asometh_t* meth;
+ char* name;
+
+ if (type == ASO_NEXT)
+ {
+ if (!(meth = (Asometh_t*)data))
+ return method[0];
+ for (i = 0; i < elementsof(method) - 1; i++)
+ if (meth == method[i])
+ return method[i+1];
+ return 0;
+ }
+ if (type)
+ {
+ for (i = 0; i < elementsof(method); i++)
+ if (method[i]->type & type)
+ {
+ method[i]->details = (char*)data;
+ return method[i];
+ }
+ return 0;
+ }
+ if (!(name = (char*)data))
+ return state.meth;
+ n = (e = strchr(name, ',')) ? (e - name) : strlen(name);
+ for (i = 0; i < elementsof(method); i++)
+ if (strncmp(name, method[i]->name, n) == 0)
+ {
+ if (e)
+ method[i]->details = e + 1;
+ return method[i];
+ }
+ return 0;
+}
+
+/*
+ * clean up lock method on exit
+ */
+
+static void
+asoexit(void)
+{
+ if (state.meth && state.meth->initf && state.data && state.pid == getpid())
+ {
+ state.lockf = ASO_METHOD->lockf;
+ state.meth->initf(state.data, 0);
+ state.data = 0;
+ }
+}
+
+/*
+ * initialize lock method
+ */
+
+int
+asoinit(const char* details, Asometh_t* meth, Asodisc_t* disc)
+{
+ void* data;
+
+ if (disc)
+ {
+ state.errorf = disc->errorf;
+ state.hung2 = disc->hung;
+ state.hung = 1;
+ state.hung <<= state.hung2;
+ state.hung--;
+ }
+ if (!meth)
+ return 0;
+ if (!meth->lockf && !(meth->type & ASO_INTRINSIC))
+ {
+ if (state.errorf)
+ asoerror(ASO_EMETHOD, "%s method has no lock function", meth->name, 0, 0);
+ return -1;
+ }
+ state.lockf = ASO_METHOD->lockf;
+ if (state.meth && state.meth->initf && state.data)
+ {
+ state.meth->initf(state.data, 0);
+ state.data = 0;
+ }
+ if (!meth->initf)
+ data = 0;
+ else if (!(data = meth->initf(0, details ? details : meth->details)))
+ {
+ state.meth = ASO_METHOD;
+ if (state.errorf)
+ asoerror(ASO_EMETHOD, "%s method initialization failed -- reverting to the %s method", meth->name, state.meth->name, 0);
+ return -1;
+ }
+ state.meth = meth;
+ state.data = data;
+ state.lockf = meth->lockf;
+ if (!state.pid)
+ {
+ state.pid = getpid();
+ atexit(asoexit);
+ }
+ return 0;
+}
+
+/*
+ * loop check for hung spin locks
+ * and periodic relinquishing of the processor
+ */
+
+int
+asoloop(uintmax_t rep)
+{
+ if (state.hung && !(rep & state.hung) && state.errorf)
+ return asoerror(ASO_EHUNG, "spin lock possibly hung after 2^%u attempts", 0, 0, state.hung2);
+ return (rep & ASO_RELAX) ? 0 : asorelax(1);
+}
+
+/*
+ * error checking state.lockf() call
+ */
+
+static ssize_t
+lock(void* data, ssize_t k, void volatile* p)
+{
+ ssize_t r;
+
+ if ((r = state.lockf(data, k, p)) < 0 && state.errorf)
+ asoerror(ASO_EMETHOD, "%s method lock failed", state.meth->name, 0, 0);
+ return r;
+}
+
+/*
+ * sync and return "current" value
+ */
+
+uint8_t
+asoget8(uint8_t volatile* p)
+{
+ int o;
+
+ do
+ {
+ o = *p;
+ } while (asocas8(p, o, o) != o);
+ return o;
+}
+
+uint16_t
+asoget16(uint16_t volatile* p)
+{
+ int o;
+
+ do
+ {
+ o = *p;
+ } while (asocas16(p, o, o) != o);
+ return o;
+}
+
+uint32_t
+asoget32(uint32_t volatile* p)
+{
+ uint32_t o;
+
+ do
+ {
+ o = *p;
+ } while (asocas32(p, o, o) != o);
+ return o;
+}
+
+#ifdef _ast_int8_t
+
+uint64_t
+asoget64(uint64_t volatile* p)
+{
+ uint64_t o;
+
+ do
+ {
+ o = *p;
+ } while (asocas64(p, o, o) != o);
+ return o;
+}
+
+#endif
+
+void*
+asogetptr(void volatile* p)
+{
+ void* o;
+
+ do
+ {
+ o = *(void* volatile*)p;
+ } while (asocasptr(p, o, o) != o);
+ return o;
+}
+
+/*
+ * increment and return old value
+ */
+
+uint8_t
+asoinc8(uint8_t volatile* p)
+{
+ ssize_t k;
+ int o;
+
+#if defined(_aso_inc8)
+ if (!state.lockf)
+ return _aso_inc8(p);
+#else
+ if (!state.lockf)
+ {
+ do
+ {
+ o = *p;
+ } while (asocas8(p, o, o + 1) != o);
+ return o;
+ }
+#endif
+ k = lock(state.data, 0, p);
+ o = (*p)++;
+ lock(state.data, k, p);
+ return o;
+}
+
+uint16_t
+asoinc16(uint16_t volatile* p)
+{
+ ssize_t k;
+ int o;
+
+#if defined(_aso_inc16)
+ if (!state.lockf)
+ return _aso_inc16(p);
+#else
+ if (!state.lockf)
+ {
+ do
+ {
+ o = *p;
+ } while (asocas16(p, o, o + 1) != o);
+ return o;
+ }
+#endif
+ k = lock(state.data, 0, p);
+ o = (*p)++;
+ lock(state.data, k, p);
+ return o;
+}
+
+uint32_t
+asoinc32(uint32_t volatile* p)
+{
+ ssize_t k;
+ int o;
+
+#if defined(_aso_inc32)
+ if (!state.lockf)
+ return _aso_inc32(p);
+#else
+ if (!state.lockf)
+ {
+ do
+ {
+ o = *p;
+ } while (asocas32(p, o, o + 1) != o);
+ return o;
+ }
+#endif
+ k = lock(state.data, 0, p);
+ o = (*p)++;
+ lock(state.data, k, p);
+ return o;
+}
+
+#ifdef _ast_int8_t
+
+uint64_t
+asoinc64(uint64_t volatile* p)
+{
+ ssize_t k;
+ uint64_t o;
+
+#if defined(_aso_inc64)
+ if (!state.lockf)
+ return _aso_inc64(p);
+#else
+ if (!state.lockf)
+ {
+ do
+ {
+ o = *p;
+ } while (asocas64(p, o, o + 1) != o);
+ return o;
+ }
+#endif
+ k = lock(state.data, 0, p);
+ o = (*p)++;
+ lock(state.data, k, p);
+ return o;
+}
+
+#endif
+
+/*
+ * decrement and return old value
+ */
+
+uint8_t
+asodec8(uint8_t volatile* p)
+{
+ ssize_t k;
+ int o;
+
+#if defined(_aso_dec8)
+ if (!state.lockf)
+ return _aso_dec8(p);
+#else
+ if (!state.lockf)
+ {
+ do
+ {
+ o = *p;
+ } while (asocas8(p, o, o - 1) != o);
+ return o;
+ }
+#endif
+ k = lock(state.data, 0, p);
+ o = (*p)--;
+ lock(state.data, k, p);
+ return o;
+}
+
+uint16_t
+asodec16(uint16_t volatile* p)
+{
+ ssize_t k;
+ int o;
+
+#if defined(_aso_dec16)
+ if (!state.lockf)
+ return _aso_dec16(p);
+#else
+ if (!state.lockf)
+ {
+ do
+ {
+ o = *p;
+ } while (asocas16(p, o, o - 1) != o);
+ return o;
+ }
+#endif
+ k = lock(state.data, 0, p);
+ o = (*p)--;
+ lock(state.data, k, p);
+ return o;
+}
+
+uint32_t
+asodec32(uint32_t volatile* p)
+{
+ ssize_t k;
+ int o;
+
+#if defined(_aso_dec32)
+ if (!state.lockf)
+ return _aso_dec32(p);
+#else
+ if (!state.lockf)
+ {
+ do
+ {
+ o = *p;
+ } while (asocas32(p, o, o - 1) != o);
+ return o;
+ }
+#endif
+ k = lock(state.data, 0, p);
+ o = (*p)--;
+ lock(state.data, k, p);
+ return o;
+}
+
+#ifdef _ast_int8_t
+
+uint64_t
+asodec64(uint64_t volatile* p)
+{
+ ssize_t k;
+ uint64_t o;
+
+#if defined(_aso_dec64)
+ if (!state.lockf)
+ return _aso_dec64(p);
+#else
+ if (!state.lockf)
+ {
+ do
+ {
+ o = *p;
+ } while (asocas64(p, o, o - 1) != o);
+ return o;
+ }
+#endif
+ k = lock(state.data, 0, p);
+ o = (*p)--;
+ lock(state.data, k, p);
+ return o;
+}
+
+#endif
+
+/*
+ * { 8 16 32 [64] } compare with old, swap with new if same, and return old value
+ */
+
+uint8_t
+asocas8(uint8_t volatile* p, int o, int n)
+{
+ ssize_t k;
+
+#if defined(_aso_cas8)
+ if (!state.lockf)
+ return _aso_cas8(p, o, n);
+#elif defined(_aso_cas16)
+ if (!state.lockf)
+ {
+ U16_8_t u;
+ U16_8_t v;
+ U16_8_t* a;
+ int s;
+ int i;
+
+ s = (int)(integralof(p) & (sizeof(u.i) - 1));
+ a = (U16_8_t*)((char*)0 + (integralof(p) & ~(sizeof(u.i) - 1)));
+ for (;;)
+ {
+ u.i = a->i;
+ u.c[s] = o;
+ v.i = u.i;
+ v.c[s] = n;
+ if (_aso_cas16(&a->i, u.i, v.i) == u.i)
+ break;
+ for (i = 0;; i++)
+ if (i >= elementsof(u.c))
+ return a->c[s];
+ else if (i != s && u.c[i] != a->c[i])
+ break;
+ }
+ return o;
+ }
+#elif defined(_aso_cas32)
+ if (!state.lockf)
+ {
+ U32_8_t u;
+ U32_8_t v;
+ U32_8_t* a;
+ int s;
+ int i;
+
+ s = (int)(integralof(p) & (sizeof(u.i) - 1));
+ a = (U32_8_t*)((char*)0 + (integralof(p) & ~(sizeof(u.i) - 1)));
+ for (;;)
+ {
+ u.i = a->i;
+ u.c[s] = o;
+ v.i = u.i;
+ v.c[s] = n;
+ if (_aso_cas32(&a->i, u.i, v.i) == u.i)
+ break;
+ for (i = 0;; i++)
+ if (i >= elementsof(u.c))
+ return a->c[s];
+ else if (i != s && u.c[i] != a->c[i])
+ break;
+ }
+ return o;
+ }
+#elif defined(_aso_cas64)
+ if (!state.lockf)
+ {
+ U64_8_t u;
+ U64_8_t v;
+ U64_8_t* a;
+ int s;
+ int i;
+
+ s = (int)(integralof(p) & (sizeof(u.i) - 1));
+ a = (U64_8_t*)((char*)0 + (integralof(p) & ~(sizeof(u.i) - 1)));
+ for (;;)
+ {
+ u.i = a->i;
+ u.c[s] = o;
+ v.i = u.i;
+ v.c[s] = n;
+ if (_aso_cas64(&a->i, u.i, v.i) == u.i)
+ break;
+ for (i = 0;; i++)
+ if (i >= elementsof(u.c))
+ return a->c[s];
+ else if (i != s && u.c[i] != a->c[i])
+ break;
+ }
+ return o;
+ }
+#endif
+ k = lock(state.data, 0, p);
+ if (*p == o)
+ *p = n;
+ else
+ o = *p;
+ lock(state.data, k, p);
+ return o;
+}
+
+uint16_t
+asocas16(uint16_t volatile* p, uint16_t o, uint16_t n)
+{
+ ssize_t k;
+
+#if defined(_aso_cas16)
+ if (!state.lockf)
+ return _aso_cas16(p, o, n);
+#elif defined(_aso_cas32)
+ if (!state.lockf)
+ {
+ U32_16_t u;
+ U32_16_t v;
+ U32_16_t* a;
+ int s;
+ int i;
+
+ s = (int)(integralof(p) & (sizeof(u.i) - 1)) / 2;
+ a = (U32_16_t*)((char*)0 + (integralof(p) & ~(sizeof(u.i) - 1)));
+ for (;;)
+ {
+ u.i = a->i;
+ u.c[s] = o;
+ v.i = u.i;
+ v.c[s] = n;
+ if (_aso_cas32(&a->i, u.i, v.i) == u.i)
+ break;
+ for (i = 0;; i++)
+ if (i >= elementsof(u.c))
+ return a->c[s];
+ else if (i != s && u.c[i] != a->c[i])
+ break;
+ }
+ return o;
+ }
+#elif defined(_aso_cas64)
+ if (!state.lockf)
+ {
+ U64_16_t u;
+ U64_16_t v;
+ U64_16_t* a;
+ int s;
+ int i;
+
+ s = (int)(integralof(p) & (sizeof(u.i) - 1)) / 2;
+ a = (U64_16_t*)((char*)0 + (integralof(p) & ~(sizeof(u.i) - 1)));
+ for (;;)
+ {
+ u.i = a->i;
+ u.c[s] = o;
+ v.i = u.i;
+ v.c[s] = n;
+ if (_aso_cas64(&a->i, u.i, v.i) == u.i)
+ break;
+ for (i = 0;; i++)
+ if (i >= elementsof(u.c))
+ return a->c[s];
+ else if (i != s && u.c[i] != a->c[i])
+ break;
+ }
+ return o;
+ }
+#endif
+ k = lock(state.data, 0, p);
+ if (*p == o)
+ *p = n;
+ else
+ o = *p;
+ lock(state.data, k, p);
+ return o;
+}
+
+uint32_t
+asocas32(uint32_t volatile* p, uint32_t o, uint32_t n)
+{
+ ssize_t k;
+
+#if defined(_aso_cas32)
+ if (!state.lockf)
+ return _aso_cas32(p, o, n);
+#elif defined(_aso_cas64)
+ if (!state.lockf)
+ {
+ U64_32_t u;
+ U64_32_t v;
+ U64_32_t* a;
+ int s;
+ int i;
+
+ s = (int)(integralof(p) & (sizeof(u.i) - 1)) / 4;
+ a = (U64_32_t*)((char*)0 + (integralof(p) & ~(sizeof(u.i) - 1)));
+ for (;;)
+ {
+ u.i = a->i;
+ u.c[s] = o;
+ v.i = u.i;
+ v.c[s] = n;
+ if (_aso_cas64(&a->i, u.i, v.i) == u.i)
+ break;
+ for (i = 0;; i++)
+ if (i >= elementsof(u.c))
+ return a->c[s];
+ else if (i != s && u.c[i] != a->c[i])
+ break;
+ }
+ return o;
+ }
+#endif
+ k = lock(state.data, 0, p);
+ if (*p == o)
+ *p = n;
+ else
+ o = *p;
+ lock(state.data, k, p);
+ return o;
+}
+
+#ifdef _ast_int8_t
+
+uint64_t
+asocas64(uint64_t volatile* p, uint64_t o, uint64_t n)
+{
+ ssize_t k;
+
+#if defined(_aso_cas64)
+ if (!state.lockf)
+ return _aso_cas64(p, o, n);
+#endif
+ k = lock(state.data, 0, p);
+ if (*p == o)
+ *p = n;
+ else
+ o = *p;
+ lock(state.data, k, p);
+ return o;
+}
+
+#endif
+
+/*
+ * compare with old, swap with new if same, and return old value
+ */
+
+void*
+asocasptr(void volatile* p, void* o, void* n)
+{
+ ssize_t k;
+
+#if defined(_aso_casptr)
+ if (!state.lockf)
+ return _aso_casptr((void**)p, o, n);
+#endif
+ k = lock(state.data, 0, p);
+ if (*(void* volatile*)p == o)
+ *(void* volatile*)p = n;
+ else
+ o = *(void* volatile*)p;
+ lock(state.data, k, p);
+ return o;
+}
+
+#endif
diff --git a/src/lib/libast/aso/asohdr.h b/src/lib/libast/aso/asohdr.h
new file mode 100644
index 0000000..80bb3bf
--- /dev/null
+++ b/src/lib/libast/aso/asohdr.h
@@ -0,0 +1,71 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _ASOHDR_H
+#define _ASOHDR_H 1
+
+#if _PACKAGE_ast
+
+#include <ast.h>
+#include <error.h>
+#include <fnv.h>
+
+#else
+
+#include <errno.h>
+
+#ifndef elementsof
+#define elementsof(x) (sizeof(x)/sizeof(x[0]))
+#endif
+#ifndef integralof
+#define integralof(x) (((char*)(x))-((char*)0))
+#endif
+#ifndef FNV_MULT
+#define FNV_MULT 0x01000193L
+#endif
+#ifndef NiL
+#define NiL ((void*)0)
+#endif
+#ifndef NoN
+#if defined(__STDC__) || defined(__STDPP__)
+#define NoN(x) void _STUB_ ## x () {}
+#else
+#define NoN(x) void _STUB_/**/x () {}
+#endif
+#if !defined(_STUB_)
+#define _STUB_
+#endif
+#endif
+
+#endif
+
+#include "FEATURE/aso"
+
+#if _UWIN
+#undef _aso_fcntl
+#undef _aso_semaphore
+#endif
+
+#include "aso.h"
+
+#define HASH(p,z) ((integralof(p)*FNV_MULT)%(z))
+
+#endif
diff --git a/src/lib/libast/aso/asolock.c b/src/lib/libast/aso/asolock.c
new file mode 100644
index 0000000..60c7dba
--- /dev/null
+++ b/src/lib/libast/aso/asolock.c
@@ -0,0 +1,55 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "asohdr.h"
+
+#if defined(_UWIN) && defined(_BLD_ast)
+
+NoN(asolock)
+
+#else
+
+int
+asolock(unsigned int volatile* lock, unsigned int key, int type)
+{
+ unsigned int k;
+
+ if (key)
+ switch (type)
+ {
+ case ASO_UNLOCK:
+ return *lock == 0 ? 0 : asocasint(lock, key, 0) == key ? 0 : -1;
+ case ASO_TRYLOCK:
+ return *lock == key ? 0 : asocasint(lock, 0, key) == 0 ? 0 : -1;
+ case ASO_LOCK:
+ if (*lock == key)
+ return 0;
+ /*FALLTHROUGH*/
+ case ASO_SPINLOCK:
+ for (k = 0; asocasint(lock, 0, key) != 0; ASOLOOP(k));
+ return 0;
+ }
+ return -1;
+}
+
+#endif
diff --git a/src/lib/libast/aso/asometh.c b/src/lib/libast/aso/asometh.c
new file mode 100644
index 0000000..e97bbab
--- /dev/null
+++ b/src/lib/libast/aso/asometh.c
@@ -0,0 +1,43 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "asohdr.h"
+
+#if defined(_UWIN) && defined(_BLD_ast)
+
+NoN(asometh)
+
+#else
+
+/*
+ * this is the default user visible asometh()
+ * -ltaso intercepts asometh() to prepend ASO_THREAD methods
+ */
+
+Asometh_t*
+asometh(int type, void* data)
+{
+ return _asometh(type, data);
+}
+
+#endif
diff --git a/src/lib/libast/aso/asorelax.c b/src/lib/libast/aso/asorelax.c
new file mode 100644
index 0000000..9716380
--- /dev/null
+++ b/src/lib/libast/aso/asorelax.c
@@ -0,0 +1,56 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "asohdr.h"
+
+#if defined(_UWIN) && defined(_BLD_ast)
+
+NoN(asorelax)
+
+#else
+
+#if _PACKAGE_ast
+#include <tv.h>
+#else
+#include <time.h>
+#endif
+
+int
+asorelax(long nsec)
+{
+#if _PACKAGE_ast
+ Tv_t tv;
+
+ tv.tv_sec = 0;
+ tv.tv_nsec = nsec;
+ return tvsleep(&tv, 0);
+#else
+ struct timespec ts;
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = nsec;
+ return nanosleep(&ts, 0);
+#endif
+}
+
+#endif
diff --git a/src/lib/libast/astsa/README-astsa b/src/lib/libast/astsa/README-astsa
new file mode 100644
index 0000000..0935f7e
--- /dev/null
+++ b/src/lib/libast/astsa/README-astsa
@@ -0,0 +1,15 @@
+astsa implements a small subset of the ast library for other ast
+standalone commands and libraries using X/Open interfaces.
+
+To get better performance and functionality, consider using any of
+the full-featured ast-* packages at
+
+ http://www.research.att.com/sw/download/
+
+astsa.omk is an old make makefile that builds the headers and objects
+and defines these variables for use in other makefiles
+
+ ASTSA_OPTIMIZE ``-O'' by default
+
+The astsa files may be combined in a single directory with other ast
+standalone packages.
diff --git a/src/lib/libast/astsa/aso.c b/src/lib/libast/astsa/aso.c
new file mode 100644
index 0000000..3b2226d
--- /dev/null
+++ b/src/lib/libast/astsa/aso.c
@@ -0,0 +1,56 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <aso.h>
+
+int
+asolock(unsigned int volatile* lock, unsigned int key, int type)
+{
+ unsigned int k;
+
+ if (key)
+ switch (type)
+ {
+ case ASO_UNLOCK:
+ if (*lock != 0)
+ {
+ if (*lock != key)
+ return -1;
+ *lock = 0;
+ }
+ return 0;
+ case ASO_TRYLOCK:
+ if (*lock != key)
+ {
+ if (*lock != 0)
+ return -1;
+ *lock = key;
+ }
+ return 0;
+ case ASO_LOCK:
+ case ASO_SPINLOCK:
+ *lock = key;
+ return 0;
+ }
+ return -1;
+}
diff --git a/src/lib/libast/astsa/aso.h b/src/lib/libast/astsa/aso.h
new file mode 100644
index 0000000..9c5d2c2
--- /dev/null
+++ b/src/lib/libast/astsa/aso.h
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _ASO_H
+#define _ASO_H 1
+
+#define ASO_UNLOCK 0 /* unlock if key matches */
+#define ASO_TRYLOCK 1 /* matched key means successful attempt */
+#define ASO_LOCK 2 /* matched key first, then spin-lock */
+#define ASO_SPINLOCK 3 /* no matching of key before locking */
+
+extern int asolock(unsigned int volatile*, unsigned int, int);
+
+#endif
diff --git a/src/lib/libast/astsa/ast.c b/src/lib/libast/astsa/ast.c
new file mode 100644
index 0000000..6428ebf
--- /dev/null
+++ b/src/lib/libast/astsa/ast.c
@@ -0,0 +1,85 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * standalone mini ast+sfio implementation
+ */
+
+#include <ast.h>
+
+#define CHUNK 1024
+
+_Ast_info_t ast;
+
+int
+astwinsize(int fd, int* lines, int* columns)
+{
+ if (lines)
+ *lines = 24;
+ if (columns)
+ *columns = 80;
+ return 0;
+}
+
+char*
+sfgetr(Sfio_t* sp, int c, int z)
+{
+ register char* s;
+ register char* e;
+
+ static char* buf;
+ static unsigned long siz;
+
+ if (!buf)
+ {
+ siz = CHUNK;
+ if (!(buf = newof(0, char, siz, 0)))
+ return 0;
+ }
+ if (z < 0)
+ return *buf ? buf : (char*)0;
+ s = buf;
+ e = s + siz;
+ for (;;)
+ {
+ if (s >= e)
+ {
+ siz += CHUNK;
+ if (!(buf = newof(buf, char, siz, 0)))
+ return 0;
+ s = buf + (siz - CHUNK);
+ e = s + siz;
+ }
+ if ((c = sfgetc(sp)) == EOF)
+ {
+ *s = 0;
+ return 0;
+ }
+ if (c == '\n')
+ {
+ *s = z ? 0 : c;
+ break;
+ }
+ *s++ = c;
+ }
+ return buf;
+}
diff --git a/src/lib/libast/astsa/ast.h b/src/lib/libast/astsa/ast.h
new file mode 100644
index 0000000..f25f6a5
--- /dev/null
+++ b/src/lib/libast/astsa/ast.h
@@ -0,0 +1,156 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * standalone mini ast+sfio interface
+ */
+
+#ifndef _AST_H
+#define _AST_H 1
+
+#include <ast_sa.h>
+#include <ast_common.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#define FMT_EXP_CHAR 0x020 /* expand single byte chars */
+#define FMT_EXP_LINE 0x040 /* expand \n and \r */
+#define FMT_EXP_WIDE 0x080 /* expand \u \U \x wide chars */
+#define FMT_EXP_NOCR 0x100 /* skip \r */
+#define FMT_EXP_NONL 0x200 /* skip \n */
+
+#define STR_MAXIMAL 01 /* maximal match */
+#define STR_LEFT 02 /* implicit left anchor */
+#define STR_RIGHT 04 /* implicit right anchor */
+#define STR_ICASE 010 /* ignore case */
+#define STR_GROUP 020 /* (|&) inside [@|&](...) only */
+
+typedef int (*Error_f)(void*, void*, int, ...);
+
+typedef struct
+{
+
+ char* id;
+
+ struct
+ {
+ unsigned int serial;
+ unsigned int set;
+ } locale;
+
+ long tmp_long;
+ size_t tmp_size;
+ short tmp_short;
+ char tmp_char;
+ wchar_t tmp_wchar;
+
+ int (*collate)(const char*, const char*);
+
+ int tmp_int;
+ void* tmp_pointer;
+
+ int mb_cur_max;
+ int (*mb_len)(const char*, size_t);
+ int (*mb_towc)(wchar_t*, const char*, size_t);
+ size_t (*mb_xfrm)(char*, const char*, size_t);
+ int (*mb_width)(wchar_t);
+ int (*mb_conv)(char*, wchar_t);
+
+ unsigned int env_serial;
+
+ char pad[944];
+
+} _Ast_info_t;
+
+#define ast _ast_info_
+
+#define elementsof(x) (sizeof(x)/sizeof(x[0]))
+#define integralof(x) (((char*)(x))-((char*)0))
+#define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x)))
+#define oldof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)malloc(sizeof(t)*(n)+(x)))
+#define pointerof(x) ((void*)((char*)0+(x)))
+#define roundof(x,y) (((x)+(y)-1)&~((y)-1))
+
+#ifndef offsetof
+#define offsetof(type,member) ((unsigned long)&(((type*)0)->member))
+#endif
+
+#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
+#define NiL 0
+#define NoP(x) (void)(x)
+#else
+#define NiL ((char*)0)
+#define NoP(x) (&x,1)
+#endif
+
+#define conformance(a,b) "ast"
+#define fmtident(s) ((char*)(s)+10)
+#define mbchar(s) (*s++)
+#define setlocale(a,b)
+
+#define streq(a,b) (*(a)==*(b)&&!strcmp(a,b))
+#define strneq(a,b,n) (*(a)==*(b)&&!strncmp(a,b,n))
+#define strton(s,t,b,f) strtol(s,t,0)
+#define strtonll(s,t,b,f) strtoll(s,t,0)
+
+#define Sfio_t FILE
+
+#define sfstdin stdin
+#define sfstdout stdout
+#define sfstderr stderr
+
+#define sfclose(f) fclose(f)
+#define sffileno(f) fileno(f)
+#define sfgetc(f) fgetc(f)
+#define sfopen(f,n,m) fopen(n,m)
+#define sfputc(f,c) fputc(c,f)
+#define sfread(f,b,n) fread(b,n,1,f)
+#define sfseek(f,p,w) fseek(f,p,w)
+#define sfset(f,v,n)
+#define sfsync(f) fflush(f)
+#define sfwrite(f,b,n) fwrite(b,n,1,f)
+
+#define sfprintf fprintf
+#define sfsprintf snprintf
+#define sfvprintf vfprintf
+
+#define sfscanf fscanf
+
+#define sfgetr _sf_getr
+
+#include <sfstr.h>
+
+extern _Ast_info_t ast;
+
+extern int astwinsize(int, int*, int*);
+extern int chresc(const char*, char**);
+extern char* fmtbuf(size_t);
+extern char* fmtip4(uint32_t, int);
+extern char* sfgetr(Sfio_t*, int, int);
+extern char* strcopy(char*, const char*);
+extern int strmatch(const char*, const char*);
+extern int strtoip4(const char*, char**, uint32_t*, unsigned char*);
+
+#endif
diff --git a/src/lib/libast/astsa/ast_common.h b/src/lib/libast/astsa/ast_common.h
new file mode 100644
index 0000000..55573d6
--- /dev/null
+++ b/src/lib/libast/astsa/ast_common.h
@@ -0,0 +1,49 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _AST_COMMON_H
+#define _AST_COMMON_H 1
+
+#include <ast_sa.h>
+#include <sys/types.h>
+
+#define Void_t void
+#define _ARG_(x) x
+#define _BEGIN_EXTERNS_
+#define _END_EXTERNS_
+#define __STD_C 1
+
+#if _hdr_stdint
+#include <stdint.h>
+#else
+#include <inttypes.h>
+#endif
+
+#if _hdr_unistd
+#include <unistd.h>
+#endif
+
+#define _typ_int32_t 1
+#ifdef _ast_int8_t
+#define _typ_int64_t 1
+#endif
+
+#endif
diff --git a/src/lib/libast/astsa/astsa.manifest b/src/lib/libast/astsa/astsa.manifest
new file mode 100644
index 0000000..03785fa
--- /dev/null
+++ b/src/lib/libast/astsa/astsa.manifest
@@ -0,0 +1,50 @@
+../../../../include/prototyped.h
+../cdt/cdtlib.h
+../cdt/dtclose.c
+../cdt/dtdisc.c
+../cdt/dthash.c
+../cdt/dthdr.h
+../cdt/dtlist.c
+../cdt/dtmethod.c
+../cdt/dtnew.c
+../cdt/dtopen.c
+../cdt/dtstrhash.c
+../cdt/dttree.c
+../cdt/dtview.c
+../cdt/dtwalk.c
+../include/cdt.h
+../include/hashkey.h
+../include/hashpart.h
+../include/ip6.h
+../include/magicid.h
+../misc/optget.c
+../misc/optlib.h
+../string/chresc.c
+../string/fmtbuf.c
+../string/fmtip4.c
+../string/fmtip6.c
+../string/strcopy.c
+../string/strtoip4.c
+../string/strtoip6.c
+README-astsa
+aso.c
+aso.h
+ast.c
+ast.h
+ast_common.h
+astsa.manifest
+astsa.mm
+astsa.omk
+ccode.h
+debug.h
+error.c
+error.h
+mkast_sa
+option.h
+sfstr.c
+sfstr.h
+strdup.c
+strmatch.c
+times.h
+vmalloc.c
+vmalloc.h
diff --git a/src/lib/libast/astsa/astsa.mm b/src/lib/libast/astsa/astsa.mm
new file mode 100644
index 0000000..eca64c0
--- /dev/null
+++ b/src/lib/libast/astsa/astsa.mm
@@ -0,0 +1,33 @@
+.xx title="astsa"
+.MT 4
+.TL
+
+.H 1 "astsa"
+.B astsa
+implements a small subset of the
+.B ast
+library for other
+.B ast
+standalone commands and libraries using X/Open interfaces.
+.P
+To get better performance and functionality, consider using any of
+the full-featured ast-* packages at
+.DS
+.xx link="http://www.research.att.com/sw/download/"
+.DE
+.P
+astsa.omk is an old make makefile that builds the headers and objects
+and defines these variables for use in other makefiles
+.VL 12
+.LI
+.B ASTSA_GEN
+point -I to these
+.LI
+.B ASTSA_HDRS
+point -I to these
+.LI
+.B AST_OBJS
+link against these
+.LE
+The astsa files may be combined in a single directory with other ast
+standalone packages.
diff --git a/src/lib/libast/astsa/astsa.omk b/src/lib/libast/astsa/astsa.omk
new file mode 100644
index 0000000..92d7882
--- /dev/null
+++ b/src/lib/libast/astsa/astsa.omk
@@ -0,0 +1,82 @@
+#
+# standalone mini libast old make makefile
+#
+
+CC = cc
+CFLAGS = $(ASTSA_CFLAGS)
+
+ASTSA_OPTIMIZE = -O
+ASTSA_CFLAGS = $(ASTSA_OPTIMIZE) -D_PACKAGE_astsa -I.
+
+ASTSA_GEN = \
+ ast_sa.h
+
+ASTSA_BLD = \
+ dthdr.h
+
+ASTSA_HDRS = \
+ ast.h \
+ ast_common.h \
+ ccode.h \
+ cdt.h \
+ debug.h \
+ error.h \
+ hashkey.h \
+ hashpart.h \
+ ip6.h \
+ magicid.h \
+ option.h \
+ optlib.h \
+ prototyped.h \
+ sfstr.h \
+ times.h \
+ vmalloc.h
+
+ASTSA_SRCS = \
+ aso.c \
+ ast.c \
+ chresc.c \
+ error.c \
+ fmtbuf.c \
+ fmtip4.c \
+ fmtip6.c \
+ optget.c \
+ sfstr.c \
+ strcopy.c \
+ strdup.c \
+ strmatch.c \
+ strtoip4.c \
+ strtoip6.c \
+ vmalloc.c \
+ dtclose.c \
+ dtdisc.c \
+ dthash.c \
+ dtlist.c \
+ dtmethod.c \
+ dtnew.c \
+ dtopen.c \
+ dtstrhash.c \
+ dttree.c \
+ dtview.c \
+ dtwalk.c
+
+ASTSA_MANIFEST = \
+ README astsa.omk mkast_sa \
+ $(ASTSA_BLD) $(ASTSA_HDRS) $(ASTSA_SRCS)
+
+astsa : ast_sa.h libastsa.a
+
+libastsa.a : aso.o ast.o chresc.o error.o fmtbuf.o fmtip4.o fmtip6.o optget.o \
+ sfstr.o strcopy.o strdup.o strmatch.o strtoip4.o strtoip6.o \
+ vmalloc.o \
+ dtclose.o dtdisc.o dthash.o dtlist.o dtmethod.o \
+ dtopen.o dtstrhash.o dttree.o dtview.o dtwalk.o
+ ar cr libastsa.a $?
+
+ast_sa.h : mkast_sa
+ ./mkast_sa $(CC) $(CFLAGS) > ast_sa.h
+
+clean :
+ rm -f ast_sa.h *.o *.a
+
+clobber : clean
diff --git a/src/lib/libast/astsa/ccode.h b/src/lib/libast/astsa/ccode.h
new file mode 100644
index 0000000..493e462
--- /dev/null
+++ b/src/lib/libast/astsa/ccode.h
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _CCODE_H
+#define _CCODE_H 1
+
+#define CC_bel '\a'
+#define CC_esc '\033'
+#define CC_vt '\v'
+
+#define CC_ASCII 0
+#define CC_NATIVE CC_ASCII
+
+#define ccmapc(c,f,t) (c)
+
+#endif
diff --git a/src/lib/libast/astsa/debug.h b/src/lib/libast/astsa/debug.h
new file mode 100644
index 0000000..7b93f4b
--- /dev/null
+++ b/src/lib/libast/astsa/debug.h
@@ -0,0 +1,29 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _DEBUG_H
+#define _DEBUG_H 1
+
+#define DEBUG_ASSERT(x)
+
+#define message(p)
+
+#endif
diff --git a/src/lib/libast/astsa/error.c b/src/lib/libast/astsa/error.c
new file mode 100644
index 0000000..84b7728
--- /dev/null
+++ b/src/lib/libast/astsa/error.c
@@ -0,0 +1,103 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * standalone mini error implementation
+ */
+
+#include <ast.h>
+#include <error.h>
+
+Error_info_t error_info;
+
+void
+errorv(const char* id, int level, va_list ap)
+{
+ char* a;
+ char* s;
+ int flags;
+
+ if (level < 0)
+ flags = 0;
+ else
+ {
+ flags = level & ~ERROR_LEVEL;
+ level &= ERROR_LEVEL;
+ }
+ a = va_arg(ap, char*);
+ if (level && ((s = error_info.id) || (s = (char*)id)))
+ {
+ if (!(flags & ERROR_USAGE))
+ sfprintf(sfstderr, "%s: ", s);
+ else if (strcmp(a, "%s"))
+ sfprintf(sfstderr, "Usage: %s ", s);
+ }
+ if (flags & ERROR_USAGE)
+ /*nop*/;
+ else if (level < 0)
+ sfprintf(sfstderr, "debug%d: ", level);
+ else if (level)
+ {
+ if (level == ERROR_WARNING)
+ {
+ sfprintf(sfstderr, "warning: ");
+ error_info.warnings++;
+ }
+ else
+ {
+ error_info.errors++;
+ if (level == ERROR_PANIC)
+ sfprintf(sfstderr, "panic: ");
+ }
+ if (error_info.line)
+ {
+ if (error_info.file && *error_info.file)
+ sfprintf(sfstderr, "\"%s\", ", error_info.file);
+ sfprintf(sfstderr, "line %d: ", error_info.line);
+ }
+ }
+ sfvprintf(sfstderr, a, ap);
+ sfprintf(sfstderr, "\n");
+ if (level >= ERROR_FATAL)
+ exit(level - ERROR_FATAL + 1);
+}
+
+void
+error(int level, ...)
+{
+ va_list ap;
+
+ va_start(ap, level);
+ errorv(NiL, level, ap);
+ va_end(ap);
+}
+
+int
+errorf(void* handle, void* discipline, int level, ...)
+{
+ va_list ap;
+
+ va_start(ap, level);
+ errorv((discipline && handle) ? *((char**)handle) : (char*)handle, level, ap);
+ va_end(ap);
+ return 0;
+}
diff --git a/src/lib/libast/astsa/error.h b/src/lib/libast/astsa/error.h
new file mode 100644
index 0000000..a95809f
--- /dev/null
+++ b/src/lib/libast/astsa/error.h
@@ -0,0 +1,66 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * standalone mini error interface
+ */
+
+#ifndef _ERROR_H
+#define _ERROR_H 1
+
+#include <option.h>
+#include <stdarg.h>
+
+typedef struct Error_info_s
+{
+ int errors;
+ int line;
+ int warnings;
+ char* catalog;
+ char* file;
+ char* id;
+} Error_info_t;
+
+#define ERROR_catalog(s) s
+
+#define ERROR_INFO 0 /* info message -- no err_id */
+#define ERROR_WARNING 1 /* warning message */
+#define ERROR_ERROR 2 /* error message -- no err_exit */
+#define ERROR_FATAL 3 /* error message with err_exit */
+#define ERROR_PANIC ERROR_LEVEL /* panic message with err_exit */
+
+#define ERROR_LEVEL 0x00ff /* level portion of status */
+#define ERROR_SYSTEM 0x0100 /* report system errno message */
+#define ERROR_USAGE 0x0800 /* usage message */
+
+#define error_info _err_info
+#define error _err_msg
+#define errorv _err_msgv
+
+extern Error_info_t error_info;
+
+#define errorx(l,x,c,m) (char*)m
+
+extern void error(int, ...);
+extern int errorf(void*, void*, int, ...);
+extern void errorv(const char*, int, va_list);
+
+#endif
diff --git a/src/lib/libast/astsa/hashkey.h b/src/lib/libast/astsa/hashkey.h
new file mode 100644
index 0000000..7f02842
--- /dev/null
+++ b/src/lib/libast/astsa/hashkey.h
@@ -0,0 +1,61 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * 1-6 char lower-case keyword -> long hash
+ * digit args passed as HASHKEYN('2')
+ */
+
+#ifndef _HASHKEY_H
+#define _HASHKEY_H 1
+
+#define HASHKEYMAX 6
+#define HASHKEYBIT 5
+#define HASHKEYOFF ('a'-1)
+#define HASHKEYPART(h,c) (((h)<<HASHKEYBIT)+HASHKEY1(c))
+
+#define HASHKEYN(n) ((n)-'0'+'z'+1)
+
+#define HASHKEY1(c1) ((c1)-HASHKEYOFF)
+#define HASHKEY2(c1,c2) HASHKEYPART(HASHKEY1(c1),c2)
+#define HASHKEY3(c1,c2,c3) HASHKEYPART(HASHKEY2(c1,c2),c3)
+#define HASHKEY4(c1,c2,c3,c4) HASHKEYPART(HASHKEY3(c1,c2,c3),c4)
+#define HASHKEY5(c1,c2,c3,c4,c5) HASHKEYPART(HASHKEY4(c1,c2,c3,c4),c5)
+#define HASHKEY6(c1,c2,c3,c4,c5,c6) HASHKEYPART(HASHKEY5(c1,c2,c3,c4,c5),c6)
+
+#define HASHNKEY1(n,c1) HASHKEY2((n)+HASHKEYOFF,c1)
+#define HASHNKEY2(n,c2,c1) HASHKEY3((n)+HASHKEYOFF,c2,c1)
+#define HASHNKEY3(n,c3,c2,c1) HASHKEY4((n)+HASHKEYOFF,c3,c2,c1)
+#define HASHNKEY4(n,c4,c3,c2,c1) HASHKEY5((n)+'a',c4,c3,c2,c1)
+#define HASHNKEY5(n,c5,c4,c3,c2,c1) HASHKEY6((n)+'a',c5,c4,c3,c2,c1)
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern long strkey(const char*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/astsa/mkast_sa b/src/lib/libast/astsa/mkast_sa
new file mode 100755
index 0000000..df448f2
--- /dev/null
+++ b/src/lib/libast/astsa/mkast_sa
@@ -0,0 +1,150 @@
+: generate ast_sa.h
+case $# in
+0) set cc ;;
+esac
+cat > _ast_.c <<'!'
+ #define _BYTESEX_H
+
+ #include <stdio.h>
+ #include <sys/types.h>
+
+ #if N == 0
+ #define _ast_int8_t long
+ #define _ast_int8_str "long"
+ #endif
+ #if N == 1
+ #define _ast_int8_t long long
+ #define _ast_int8_str "long long"
+ #endif
+ #if N == 2
+ #define _ast_int8_t __int64_t
+ #define _ast_int8_str "__int64_t"
+ #endif
+ #if N == 3
+ #define _ast_int8_t _int64_t
+ #define _ast_int8_str "_int64_t"
+ #endif
+ #if N == 4
+ #define _ast_int8_t int64_t
+ #define _ast_int8_str "int64_t"
+ #endif
+ #if N == 5
+ #define _ast_int8_t __int64
+ #define _ast_int8_str "__int64"
+ #endif
+ #if N == 6
+ #define _ast_int8_t _int64
+ #define _ast_int8_str "_int64"
+ #endif
+ #if N == 7
+ #define _ast_int8_t int64
+ #define _ast_int8_str "int64"
+ #endif
+
+ #define elementsof(x) (sizeof(x)/sizeof(x[0]))
+
+ static char i_char = 1;
+ static short i_short = 1;
+ static int i_int = 1;
+ static long i_long = 1;
+ #ifdef _ast_int8_t
+ static _ast_int8_t i_long_long = 1;
+ #endif
+
+ static struct
+ {
+ char* name;
+ int size;
+ char* swap;
+ } int_type[] =
+ {
+ "char", sizeof(char), (char*)&i_char,
+ "short", sizeof(short), (char*)&i_short,
+ "int", sizeof(int), (char*)&i_int,
+ "long", sizeof(long), (char*)&i_long,
+ #ifdef _ast_int8_t
+ _ast_int8_str, sizeof(_ast_int8_t), (char*)&i_long_long,
+ #endif
+ };
+
+ static struct
+ {
+ char* name;
+ int size;
+ } flt_type[] =
+ {
+ "float", sizeof(float),
+ "double", sizeof(double),
+ #ifdef _typ_long_double
+ "long double", sizeof(long double),
+ #endif
+ };
+
+ static int int_size[] = { 1, 2, 4, 8 };
+
+ main()
+ {
+ register int t;
+ register int s;
+ register int m = 1;
+ register int b = 1;
+ register int w = 0;
+
+ #ifdef _ast_int8_t
+ if (int_type[elementsof(int_type)-1].size <= 4)
+ return 1;
+ #endif
+ for (s = 0; s < elementsof(int_size); s++)
+ {
+ for (t = 0; t < elementsof(int_type) && int_type[t].size < int_size[s]; t++);
+ if (t < elementsof(int_type))
+ {
+ m = int_size[s];
+ printf("#define _ast_int%d_t %s\n", m, int_type[t].name);
+ if (m > 1)
+ {
+ if (*int_type[t].swap)
+ w |= b;
+ b <<= 1;
+ }
+ }
+ }
+ printf("#define _ast_intmax_t _ast_int%d_t\n", m);
+ if (m == sizeof(long))
+ printf("#define _ast_intmax_long 1\n");
+ printf("#define _ast_intswap %d\n", w);
+ printf("\n");
+ for (t = 0; t < elementsof(flt_type); t++)
+ {
+ while (t < elementsof(flt_type) && flt_type[t].size == flt_type[t + 1].size)
+ t++;
+ m = flt_type[t].size;
+ printf("#define _ast_flt%d_t %s\n", flt_type[t].size, flt_type[t].name);
+ }
+ printf("#define _ast_fltmax_t _ast_flt%d_t\n", m);
+ if (m == sizeof(double))
+ printf("#define _ast_fltmax_double 1\n");
+ return 0;
+ }
+!
+echo "#ifndef _AST_SA_H"
+echo "#define _AST_SA_H 1"
+echo
+for i in '' -DN=0 -DN=1 -DN=2 -DN=3 -DN=4 -DN=5 -DN=6 -DN=7 -DN=8
+do "$@" $i -o _ast_.exe _ast_.c 2> /dev/null &&
+ ./_ast_.exe &&
+ break
+done
+echo '#include <stdint.h>' > _ast_.c
+if "$@" -E _ast_.c > /dev/null 2>&1
+then echo "#define _hdr_stdint 1"
+fi
+echo '#include <unistd.h>' > _ast_.c
+if "$@" -E _ast_.c > /dev/null 2>&1
+then echo "#define _hdr_unistd 1"
+fi
+rm -f _ast_.c _ast_.exe
+echo "#define __DEFINE__(T,obj,val) T obj = val"
+echo "#define __EXTERN__(T,obj) extern T obj"
+echo
+echo "#endif"
diff --git a/src/lib/libast/astsa/option.h b/src/lib/libast/astsa/option.h
new file mode 100644
index 0000000..aa66920
--- /dev/null
+++ b/src/lib/libast/astsa/option.h
@@ -0,0 +1,106 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * command line option parse interface
+ */
+
+#ifndef _OPTION_H
+#define _OPTION_H 1
+
+#include <ast.h>
+
+#define OPT_VERSION 20000401L
+
+#define opt_info _opt_info_
+
+#define OPT_USER (1L<<16) /* first user flag bit */
+
+struct Opt_s;
+struct Optdisc_s;
+
+typedef int (*Optinfo_f)(struct Opt_s*, Sfio_t*, const char*, struct Optdisc_s*);
+
+typedef struct Optdisc_s
+{
+ unsigned long version; /* OPT_VERSION */
+ unsigned long flags; /* OPT_* flags */
+ char* catalog; /* error catalog id */
+ Optinfo_f infof; /* runtime info function */
+} Optdisc_t;
+
+/* NOTE: Opt_t member order fixed by a previous binary release */
+
+#ifndef _OPT_PRIVATE_
+#define _OPT_PRIVATE_ void* _opt_private;
+#endif
+
+typedef struct Opt_s
+{
+ int again; /* see optjoin() */
+ char* arg; /* {:,#} string argument */
+ char** argv; /* most recent argv */
+ int index; /* argv index */
+ char* msg; /* error/usage message buffer */
+ long num; /* # numeric argument */
+ int offset; /* char offset in argv[index] */
+ char option[8]; /* current flag {-,+} + option */
+ char name[64]; /* current long name or flag */
+ Optdisc_t* disc; /* user discipline */
+ intmax_t number; /* # numeric argument */
+ unsigned char assignment; /* option arg assigment op */
+ unsigned char pads[sizeof(void*)-1];
+ _OPT_PRIVATE_
+} Opt_t;
+
+#define optinit(d,f) (memset(d,0,sizeof(*(d))),(d)->version=OPT_VERSION,(d)->infof=(f),opt_info.disc=(d))
+
+#if _BLD_ast && defined(__EXPORT__)
+#define __PUBLIC_DATA__ __EXPORT__
+#else
+#if !_BLD_ast && defined(__IMPORT__)
+#define __PUBLIC_DATA__ __IMPORT__
+#else
+#define __PUBLIC_DATA__
+#endif
+#endif
+
+extern __PUBLIC_DATA__ Opt_t opt_info;
+
+#undef __PUBLIC_DATA__
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int optget(char**, const char*);
+extern int optjoin(char**, ...);
+extern char* opthelp(const char*, const char*);
+extern char* optusage(const char*);
+extern int optstr(const char*, const char*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/astsa/optlib.h b/src/lib/libast/astsa/optlib.h
new file mode 100644
index 0000000..8e09734
--- /dev/null
+++ b/src/lib/libast/astsa/optlib.h
@@ -0,0 +1,105 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * command line option parser and usage formatter private definitions
+ */
+
+#ifndef _OPTLIB_H
+#define _OPTLIB_H 1
+
+#include <ast.h>
+#include <cdt.h>
+
+#define OPT_cache 0x01
+#define OPT_functions 0x02
+#define OPT_ignore 0x04
+#define OPT_long 0x08
+#define OPT_old 0x10
+#define OPT_plus 0x20
+#define OPT_proprietary 0x40
+
+#define OPT_cache_flag 0x01
+#define OPT_cache_invert 0x02
+#define OPT_cache_numeric 0x04
+#define OPT_cache_optional 0x08
+#define OPT_cache_string 0x10
+
+#define OPT_CACHE 128
+#define OPT_FLAGS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+
+struct Optdisc_s;
+
+typedef struct Optpass_s
+{
+ char* opts;
+ char* oopts;
+ char* catalog;
+ unsigned char version;
+ unsigned char prefix;
+ unsigned char flags;
+ unsigned char section;
+} Optpass_t;
+
+typedef struct Optcache_s
+{
+ struct Optcache_s* next;
+ Optpass_t pass;
+ int caching;
+ unsigned char flags[sizeof(OPT_FLAGS)];
+} Optcache_t;
+
+typedef struct Optstate_s
+{
+ Sfio_t* mp; /* opt_info.msg string stream */
+ Sfio_t* vp; /* translation string stream */
+ Sfio_t* xp; /* translation string stream */
+ Sfio_t* cp; /* compatibility string stream */
+ Optpass_t pass[8]; /* optjoin() list */
+ char* argv[2]; /* initial argv copy */
+ char* strv[3]; /* optstr() argv */
+ char* str; /* optstr() string */
+ Sfio_t* strp; /* optstr() stream */
+ int force; /* force this style */
+ int pindex; /* prev index for backup */
+ int poffset; /* prev offset for backup */
+ int npass; /* # optjoin() passes */
+ int join; /* optjoin() pass # */
+ int plus; /* + ok */
+ int style; /* default opthelp() style */
+ int width; /* format line width */
+ int flags; /* display flags */
+ int emphasis; /* ansi term emphasis ok */
+ Dtdisc_t msgdisc; /* msgdict discipline */
+ Dt_t* msgdict; /* default ast.id catalog msgs */
+ Optcache_t* cache; /* OPT_cache cache */
+} Optstate_t;
+
+#define _OPT_PRIVATE_ \
+ char pad[2*sizeof(void*)]; \
+ Optstate_t* state;
+
+#include <error.h>
+
+#endif
diff --git a/src/lib/libast/astsa/sfstr.c b/src/lib/libast/astsa/sfstr.c
new file mode 100644
index 0000000..7fc0be3
--- /dev/null
+++ b/src/lib/libast/astsa/sfstr.c
@@ -0,0 +1,246 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include <ast.h>
+#include <stdarg.h>
+
+#define STR (8*1024)
+
+#define VALID(p,f) ((p=(Sfstr_t*)f)>=&strs[0]&&p<&strs[elementsof(strs)])
+
+static Sfstr_t strs[64];
+
+static int
+extend(Sfstr_t* p, int n)
+{
+ int o;
+
+ if (n < STR)
+ n = STR;
+ n += p->end - p->beg;
+ o = p->nxt - p->beg;
+ if (!(p->beg = realloc(p->beg, n)))
+ return -1;
+ p->nxt = p->beg + o;
+ p->end = p->beg + n;
+ return 0;
+}
+
+int
+sfclose(Sfio_t* f)
+{
+ Sfstr_t* p;
+ int r;
+
+ if (VALID(p, f))
+ {
+ p->nxt = 0;
+ r = 0;
+ }
+ else
+ r = fclose(f);
+ return r;
+}
+
+int
+sfprintf(Sfio_t* f, const char* fmt, ...)
+{
+ Sfstr_t* p;
+ char* s;
+ va_list ap;
+ int r;
+
+ static char buf[STR];
+
+ va_start(ap, fmt);
+ if (!VALID(p, f))
+ r = vfprintf(f, fmt, ap);
+ else if ((r = vsnprintf(buf, sizeof(buf), fmt, ap)) > 0)
+ r = sfwrite(f, buf, r);
+ va_end(ap);
+ return r;
+}
+
+char*
+sfprints(const char* fmt, ...)
+{
+ va_list ap;
+ int r;
+
+ static char buf[STR];
+
+ va_start(ap, fmt);
+ r = vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ return r > 0 ? buf : (char*)0;
+}
+
+int
+sfputc(Sfio_t* f, int c)
+{
+ Sfstr_t* p;
+ int r;
+
+ if (VALID(p, f))
+ {
+ if (p->nxt >= p->end && extend(p, 1))
+ return -1;
+ *p->nxt++ = c;
+ r = 1;
+ }
+ else
+ r = fputc(c, f);
+ return r;
+}
+
+int
+sfputr(Sfio_t* f, const char* buf, int sep)
+{
+ Sfstr_t* p;
+ int r;
+ int n;
+
+ n = strlen(buf);
+ if (VALID(p, f))
+ {
+ r = n + (sep >= 0);
+ if (r > (p->end - p->nxt) && extend(p, r))
+ return -1;
+ memcpy(p->nxt, buf, n);
+ p->nxt += n;
+ if (sep >= 0)
+ *p->nxt++ = sep;
+ }
+ else
+ {
+ r = fwrite(buf, 1, n, f);
+ if (sep >= 0 && fputc(sep, f) != EOF)
+ r++;
+ }
+ return r;
+}
+
+char*
+sfstrbase(Sfio_t* f)
+{
+ Sfstr_t* p;
+
+ if (VALID(p, f))
+ return p->beg;
+ return 0;
+}
+
+Sfio_t*
+sfstropen(void)
+{
+ Sfstr_t* p;
+
+ for (p = &strs[0]; p < &strs[elementsof(strs)]; p++)
+ if (!p->nxt)
+ {
+ if (!p->beg)
+ {
+ if (!(p->beg = malloc(STR)))
+ break;
+ p->end = p->beg + STR;
+ }
+ p->nxt = p->beg;
+ return (Sfio_t*)p;
+ }
+ return 0;
+}
+
+#define _sf_strseek(f,p,m) \
+ ( (m) == SEEK_SET ? \
+ (((p) < 0 || (p) > ((f)->end - (f)->beg)) ? (char*)0 : \
+ (char*)((f)->nxt = (f)->beg+(p)) ) \
+ : (m) == SEEK_CUR ? \
+ ((f)->nxt += (p), \
+ (((f)->nxt < (f)->beg || (f)->nxt > (f)->end) ? \
+ ((f)->nxt -= (p), (char*)0) : (char*)(f)->nxt ) ) \
+ : (m) == SEEK_END ? \
+ ( ((p) > 0 || (((f)->end - (f)->beg) + (p)) < 0) ? (char*)0 : \
+ (char*)((f)->nxt = (f)->end+(p)) ) \
+ : (char*)0 \
+ )
+
+char*
+sfstrseek(Sfio_t* f, int n, int w)
+{
+ Sfstr_t* p;
+
+ if (VALID(p, f))
+ return _sf_strseek(p, n, w);
+ return 0;
+}
+
+char*
+sfstrset(Sfio_t* f, int n)
+{
+ Sfstr_t* p;
+
+ if (VALID(p, f) && n >= 0 && n < (p->nxt - p->beg))
+ return p->nxt = p->beg + n;
+ return 0;
+}
+
+int
+sfstrtell(Sfio_t* f)
+{
+ Sfstr_t* p;
+ int r;
+
+ if (VALID(p, f) && p->nxt)
+ r = p->nxt - p->beg;
+ else
+ r = -1;
+ return r;
+}
+
+char*
+sfstruse(Sfio_t* f)
+{
+ Sfstr_t* p;
+
+ if (VALID(p, f) && (p->nxt < p->end || !extend(p, 1)))
+ {
+ *p->nxt = 0;
+ return p->nxt = p->beg;
+ }
+ return 0;
+}
+
+int
+sfwrite(Sfio_t* f, void* buf, int n)
+{
+ Sfstr_t* p;
+
+ if (VALID(p, f))
+ {
+ if (n > (p->end - p->nxt) && extend(p, n))
+ return -1;
+ memcpy(p->nxt, buf, n);
+ p->nxt += n;
+ }
+ else
+ n = fwrite(buf, 1, n, f);
+ return n;
+}
diff --git a/src/lib/libast/astsa/sfstr.h b/src/lib/libast/astsa/sfstr.h
new file mode 100644
index 0000000..4fe21f5
--- /dev/null
+++ b/src/lib/libast/astsa/sfstr.h
@@ -0,0 +1,60 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _SFSTR_H
+#define _SFSTR_H 1
+
+#include <ast.h>
+
+typedef struct Sfstr_s
+{
+ char* beg;
+ char* nxt;
+ char* end;
+} Sfstr_t;
+
+#undef sfclose
+#undef sfprintf
+#undef sfprints
+#undef sfputc
+#undef sfputr
+#undef sfstrbase
+#undef sfstropen
+#undef sfstrseek
+#undef sfstrset
+#undef sfstrtell
+#undef sfstruse
+#undef sfwrite
+
+extern int sfclose(Sfio_t*);
+extern int sfprintf(Sfio_t*, const char*, ...);
+extern char* sfprints(const char*, ...);
+extern int sfputc(Sfio_t*, int);
+extern int sfputr(Sfio_t*, const char*, int);
+extern char* sfstrbase(Sfio_t*);
+extern Sfio_t* sfstropen(void);
+extern char* sfstrseek(Sfio_t*, int, int);
+extern char* sfstrset(Sfio_t*, int);
+extern int sfstrtell(Sfio_t*);
+extern char* sfstruse(Sfio_t*);
+extern int sfwrite(Sfio_t*, void*, int);
+
+#endif
diff --git a/src/lib/libast/astsa/strdup.c b/src/lib/libast/astsa/strdup.c
new file mode 100644
index 0000000..a4de874
--- /dev/null
+++ b/src/lib/libast/astsa/strdup.c
@@ -0,0 +1,37 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+/*
+ * return a copy of s using malloc
+ */
+
+char*
+strdup(register const char* s)
+{
+ register char* t;
+ register int n;
+
+ return (s && (t = newof(0, char, n = strlen(s) + 1, 0))) ? (char*)memcpy(t, s, n) : (char*)0;
+}
diff --git a/src/lib/libast/astsa/strmatch.c b/src/lib/libast/astsa/strmatch.c
new file mode 100644
index 0000000..f6a9ff3
--- /dev/null
+++ b/src/lib/libast/astsa/strmatch.c
@@ -0,0 +1,597 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * D. G. Korn
+ * G. S. Fowler
+ * AT&T Research
+ *
+ * match shell file patterns -- derived from Bourne and Korn shell gmatch()
+ *
+ * sh pattern egrep RE description
+ * ---------- -------- -----------
+ * * .* 0 or more chars
+ * ? . any single char
+ * [.] [.] char class
+ * [!.] [^.] negated char class
+ * [[:.:]] [[:.:]] ctype class
+ * [[=.=]] [[=.=]] equivalence class
+ * [[...]] [[...]] collation element
+ * *(.) (.)* 0 or more of
+ * +(.) (.)+ 1 or more of
+ * ?(.) (.)? 0 or 1 of
+ * (.) (.) 1 of
+ * @(.) (.) 1 of
+ * a|b a|b a or b
+ * \# () subgroup back reference [1-9]
+ * a&b a and b
+ * !(.) none of
+ *
+ * \ used to escape metacharacters
+ *
+ * *, ?, (, |, &, ), [, \ must be \'d outside of [...]
+ * only ] must be \'d inside [...]
+ *
+ * BUG: unbalanced ) terminates top level pattern
+ */
+
+#include <ast.h>
+#include <ctype.h>
+#include <hashkey.h>
+
+#ifndef isblank
+#define isblank(x) ((x)==' '||(x)=='\t')
+#endif
+
+#ifndef isgraph
+#define isgraph(x) (isprint(x)&&!isblank(x))
+#endif
+
+#define MAXGROUP 10
+
+typedef struct
+{
+ char* beg[MAXGROUP];
+ char* end[MAXGROUP];
+ char* next_s;
+ short groups;
+} Group_t;
+
+typedef struct
+{
+ Group_t current;
+ Group_t best;
+ char* last_s;
+ char* next_p;
+} Match_t;
+
+#define mbgetchar(p) (*p++)
+
+#ifndef isxdigit
+#define isxdigit(c) ((c)>='0'&&(c)<='9'||(c)>='a'&&(c)<='f'||(c)>='A'&&(c)<='F')
+#endif
+
+#define getsource(s,e) (((s)>=(e))?0:mbgetchar(s))
+
+#define COLL_MAX 3
+
+/*
+ * gobble chars up to <sub> or ) keeping track of (...) and [...]
+ * sub must be one of { '|', '&', 0 }
+ * 0 returned if s runs out
+ */
+
+static char*
+gobble(Match_t* mp, register char* s, register int sub, int* g, int clear)
+{
+ register int p = 0;
+ register char* b = 0;
+ int c = 0;
+ int n;
+
+ for (;;)
+ switch (mbgetchar(s))
+ {
+ case '\\':
+ if (mbgetchar(s))
+ break;
+ /*FALLTHROUGH*/
+ case 0:
+ return 0;
+ case '[':
+ if (!b)
+ {
+ if (*s == '!')
+ mbgetchar(s);
+ b = s;
+ }
+ else if (*s == '.' || *s == '=' || *s == ':')
+ c = *s;
+ break;
+ case ']':
+ if (b)
+ {
+ if (*(s - 2) == c)
+ c = 0;
+ else if (b != (s - 1))
+ b = 0;
+ }
+ break;
+ case '(':
+ if (!b)
+ {
+ p++;
+ n = (*g)++;
+ if (clear)
+ {
+ if (!sub)
+ n++;
+ if (n < MAXGROUP)
+ mp->current.beg[n] = mp->current.end[n] = 0;
+ }
+ }
+ break;
+ case ')':
+ if (!b && p-- <= 0)
+ return sub ? 0 : s;
+ break;
+ case '|':
+ if (!b && !p && sub == '|')
+ return s;
+ break;
+ }
+}
+
+static int grpmatch(Match_t*, int, char*, register char*, char*, int);
+
+/*
+ * match a single pattern
+ * e is the end (0) of the substring in s
+ * r marks the start of a repeated subgroup pattern
+ */
+
+static int
+onematch(Match_t* mp, int g, char* s, char* p, char* e, char* r, int flags)
+{
+ register int pc;
+ register int sc;
+ register int n;
+ register int icase;
+ char* olds;
+ char* oldp;
+
+ icase = flags & STR_ICASE;
+ do
+ {
+ olds = s;
+ sc = getsource(s, e);
+ if (icase && isupper(sc))
+ sc = tolower(sc);
+ oldp = p;
+ switch (pc = mbgetchar(p))
+ {
+ case '(':
+ case '*':
+ case '?':
+ case '+':
+ case '@':
+ case '!':
+ if (pc == '(' || *p == '(')
+ {
+ char* subp;
+ int oldg;
+
+ s = olds;
+ subp = p + (pc != '(');
+ oldg = g;
+ n = ++g;
+ if (g < MAXGROUP && (!r || g > mp->current.groups))
+ mp->current.beg[g] = mp->current.end[g] = 0;
+ if (!(p = gobble(mp, subp, 0, &g, !r)))
+ return 0;
+ if (pc == '*' || pc == '?' || pc == '+' && oldp == r)
+ {
+ if (onematch(mp, g, s, p, e, NiL, flags))
+ return 1;
+ if (!sc || !getsource(s, e))
+ {
+ mp->current.groups = oldg;
+ return 0;
+ }
+ }
+ if (pc == '*' || pc == '+')
+ {
+ p = oldp;
+ sc = n - 1;
+ }
+ else
+ sc = g;
+ pc = (pc != '!');
+ do
+ {
+ if (grpmatch(mp, n, olds, subp, s, flags) == pc)
+ {
+ if (n < MAXGROUP)
+ {
+ if (!mp->current.beg[n] || mp->current.beg[n] > olds)
+ mp->current.beg[n] = olds;
+ if (s > mp->current.end[n])
+ mp->current.end[n] = s;
+ }
+ if (onematch(mp, sc, s, p, e, oldp, flags))
+ {
+ if (p == oldp && n < MAXGROUP)
+ {
+ if (!mp->current.beg[n] || mp->current.beg[n] > olds)
+ mp->current.beg[n] = olds;
+ if (s > mp->current.end[n])
+ mp->current.end[n] = s;
+ }
+ return 1;
+ }
+ }
+ } while (s < e && mbgetchar(s));
+ mp->current.groups = oldg;
+ return 0;
+ }
+ else if (pc == '*')
+ {
+ /*
+ * several stars are the same as one
+ */
+
+ while (*p == '*' && *(p + 1) != '(')
+ p++;
+ oldp = p;
+ switch (pc = mbgetchar(p))
+ {
+ case '@':
+ case '!':
+ case '+':
+ n = *p == '(';
+ break;
+ case '(':
+ case '[':
+ case '?':
+ case '*':
+ n = 1;
+ break;
+ case 0:
+ case '|':
+ case '&':
+ case ')':
+ mp->current.next_s = (flags & STR_MAXIMAL) ? e : olds;
+ mp->next_p = oldp;
+ mp->current.groups = g;
+ if (!pc && (!mp->best.next_s || (flags & STR_MAXIMAL) && mp->current.next_s > mp->best.next_s || !(flags & STR_MAXIMAL) && mp->current.next_s < mp->best.next_s))
+ mp->best = mp->current;
+ return 1;
+ case '\\':
+ if (!(pc = mbgetchar(p)))
+ return 0;
+ if (pc >= '0' && pc <= '9')
+ {
+ n = pc - '0';
+ if (n <= g && mp->current.beg[n])
+ pc = *mp->current.beg[n];
+ }
+ /*FALLTHROUGH*/
+ default:
+ if (icase && isupper(pc))
+ pc = tolower(pc);
+ n = 0;
+ break;
+ }
+ p = oldp;
+ for (;;)
+ {
+ if ((n || pc == sc) && onematch(mp, g, olds, p, e, NiL, flags))
+ return 1;
+ if (!sc)
+ return 0;
+ olds = s;
+ sc = getsource(s, e);
+ if ((flags & STR_ICASE) && isupper(sc))
+ sc = tolower(sc);
+ }
+ }
+ else if (pc != '?' && pc != sc)
+ return 0;
+ break;
+ case 0:
+ if (!(flags & STR_MAXIMAL))
+ sc = 0;
+ /*FALLTHROUGH*/
+ case '|':
+ case '&':
+ case ')':
+ if (!sc)
+ {
+ mp->current.next_s = olds;
+ mp->next_p = oldp;
+ mp->current.groups = g;
+ }
+ if (!pc && (!mp->best.next_s || (flags & STR_MAXIMAL) && olds > mp->best.next_s || !(flags & STR_MAXIMAL) && olds < mp->best.next_s))
+ {
+ mp->best = mp->current;
+ mp->best.next_s = olds;
+ mp->best.groups = g;
+ }
+ return !sc;
+ case '[':
+ {
+ /*UNDENT...*/
+
+ int invert;
+ int x;
+ int ok = 0;
+ char* range;
+
+ if (!sc)
+ return 0;
+ range = 0;
+ n = 0;
+ if (invert = *p == '!')
+ p++;
+ for (;;)
+ {
+ oldp = p;
+ if (!(pc = mbgetchar(p)))
+ return 0;
+ else if (pc == '[' && (*p == ':' || *p == '=' || *p == '.'))
+ {
+ x = 0;
+ n = mbgetchar(p);
+ oldp = p;
+ for (;;)
+ {
+ if (!(pc = mbgetchar(p)))
+ return 0;
+ if (pc == n && *p == ']')
+ break;
+ x++;
+ }
+ mbgetchar(p);
+ if (ok)
+ /*NOP*/;
+ else if (n == ':')
+ {
+ switch (HASHNKEY5(x, oldp[0], oldp[1], oldp[2], oldp[3], oldp[4]))
+ {
+ case HASHNKEY5(5,'a','l','n','u','m'):
+ if (isalnum(sc))
+ ok = 1;
+ break;
+ case HASHNKEY5(5,'a','l','p','h','a'):
+ if (isalpha(sc))
+ ok = 1;
+ break;
+ case HASHNKEY5(5,'b','l','a','n','k'):
+ if (isblank(sc))
+ ok = 1;
+ break;
+ case HASHNKEY5(5,'c','n','t','r','l'):
+ if (iscntrl(sc))
+ ok = 1;
+ break;
+ case HASHNKEY5(5,'d','i','g','i','t'):
+ if (isdigit(sc))
+ ok = 1;
+ break;
+ case HASHNKEY5(5,'g','r','a','p','h'):
+ if (isgraph(sc))
+ ok = 1;
+ break;
+ case HASHNKEY5(5,'l','o','w','e','r'):
+ if (islower(sc))
+ ok = 1;
+ break;
+ case HASHNKEY5(5,'p','r','i','n','t'):
+ if (isprint(sc))
+ ok = 1;
+ break;
+ case HASHNKEY5(5,'p','u','n','c','t'):
+ if (ispunct(sc))
+ ok = 1;
+ break;
+ case HASHNKEY5(5,'s','p','a','c','e'):
+ if (isspace(sc))
+ ok = 1;
+ break;
+ case HASHNKEY5(5,'u','p','p','e','r'):
+ if (icase ? islower(sc) : isupper(sc))
+ ok = 1;
+ break;
+ case HASHNKEY5(6,'x','d','i','g','i'):
+ if (oldp[5] == 't' && isxdigit(sc))
+ ok = 1;
+ break;
+ }
+ }
+ else if (range)
+ goto getrange;
+ else if (*p == '-' && *(p + 1) != ']')
+ {
+ mbgetchar(p);
+ range = oldp;
+ }
+ else if (isalpha(*oldp) && isalpha(*olds) && tolower(*oldp) == tolower(*olds) || sc == mbgetchar(oldp))
+ ok = 1;
+ n = 1;
+ }
+ else if (pc == ']' && n)
+ {
+ if (ok != invert)
+ break;
+ return 0;
+ }
+ else if (pc == '\\' && (oldp = p, !(pc = mbgetchar(p))))
+ return 0;
+ else if (ok)
+ /*NOP*/;
+ else if (range)
+ {
+ getrange:
+ if (icase && isupper(pc))
+ pc = tolower(pc);
+ x = mbgetchar(range);
+ if (icase && isupper(x))
+ x = tolower(x);
+ if (sc == x || sc == pc || sc > x && sc < pc)
+ ok = 1;
+ if (*p == '-' && *(p + 1) != ']')
+ {
+ mbgetchar(p);
+ range = oldp;
+ }
+ else
+ range = 0;
+ n = 1;
+ }
+ else if (*p == '-' && *(p + 1) != ']')
+ {
+ mbgetchar(p);
+ range = oldp;
+ n = 1;
+ }
+ else
+ {
+ if (icase && isupper(pc))
+ pc = tolower(pc);
+ if (sc == pc)
+ ok = 1;
+ n = pc;
+ }
+ }
+
+ /*...INDENT*/
+ }
+ break;
+ case '\\':
+ if (!(pc = mbgetchar(p)))
+ return 0;
+ if (pc >= '0' && pc <= '9')
+ {
+ n = pc - '0';
+ if (n <= g && (oldp = mp->current.beg[n]))
+ {
+ while (oldp < mp->current.end[n])
+ if (!*olds || *olds++ != *oldp++)
+ return 0;
+ s = olds;
+ break;
+ }
+ }
+ /*FALLTHROUGH*/
+ default:
+ if (icase && isupper(pc))
+ pc = tolower(pc);
+ if (pc != sc)
+ return 0;
+ break;
+ }
+ } while (sc);
+ return 0;
+}
+
+/*
+ * match any pattern in a group
+ * | and & subgroups are parsed here
+ */
+
+static int
+grpmatch(Match_t* mp, int g, char* s, register char* p, char* e, int flags)
+{
+ register char* a;
+
+ do
+ {
+ for (a = p; onematch(mp, g, s, a, e, NiL, flags); a++)
+ if (*(a = mp->next_p) != '&')
+ return 1;
+ } while (p = gobble(mp, p, '|', &g, 1));
+ return 0;
+}
+
+/*
+ * subgroup match
+ * 0 returned if no match
+ * otherwise number of subgroups matched returned
+ * match group begin offsets are even elements of sub
+ * match group end offsets are odd elements of sub
+ * the matched string is from s+sub[0] up to but not
+ * including s+sub[1]
+ */
+
+int
+strgrpmatch(const char* b, const char* p, int* sub, int n, int flags)
+{
+ register int i;
+ register char* s;
+ char* e;
+ Match_t match;
+
+ s = (char*)b;
+ match.last_s = e = s + strlen(s);
+ for (;;)
+ {
+ match.best.next_s = 0;
+ match.current.groups = 0;
+ if ((i = grpmatch(&match, 0, s, (char*)p, e, flags)) || match.best.next_s)
+ {
+ if (!i)
+ match.current = match.best;
+ match.current.groups++;
+ match.current.end[0] = match.current.next_s;
+ break;
+ }
+ if ((flags & STR_LEFT) || s >= e)
+ return 0;
+ s++;
+ }
+ if ((flags & STR_RIGHT) && match.current.next_s != e)
+ return 0;
+ if (!sub)
+ return 1;
+ match.current.beg[0] = s;
+ s = (char*)b;
+ if (n > match.current.groups)
+ n = match.current.groups;
+ for (i = 0; i < n; i++)
+ {
+ sub[i * 2] = match.current.end[i] ? match.current.beg[i] - s : 0;
+ sub[i * 2 + 1] = match.current.end[i] ? match.current.end[i] - s : 0;
+ }
+ return n;
+}
+
+/*
+ * compare the string s with the shell pattern p
+ * returns 1 for match 0 otherwise
+ */
+
+int
+strmatch(const char* s, const char* p)
+{
+ return strgrpmatch(s, p, NiL, 0, STR_MAXIMAL|STR_LEFT|STR_RIGHT);
+}
diff --git a/src/lib/libast/astsa/times.h b/src/lib/libast/astsa/times.h
new file mode 100644
index 0000000..7b916f7
--- /dev/null
+++ b/src/lib/libast/astsa/times.h
@@ -0,0 +1,27 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _TIMES_H
+#define _TIMES_H 1
+
+#include <sys/times.h>
+
+#endif
diff --git a/src/lib/libast/astsa/vmalloc.c b/src/lib/libast/astsa/vmalloc.c
new file mode 100644
index 0000000..3195b13
--- /dev/null
+++ b/src/lib/libast/astsa/vmalloc.c
@@ -0,0 +1,102 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * standalone mini vmalloc implementation
+ * no resize, no free, no disciplines, no methods
+ */
+
+#include <ast.h>
+#include <vmalloc.h>
+
+Vmalloc_t* Vmregion;
+
+Vmalloc_t*
+_vm_open(void)
+{
+ Vmalloc_t* vp;
+
+ if (vp = newof(0, Vmalloc_t, 1, 0))
+ {
+ vp->current = &vp->base;
+ vp->data = vp->current->data;
+ vp->size = sizeof(vp->current->data);
+ }
+ return vp;
+}
+
+int
+_vm_close(register Vmalloc_t* vp)
+{
+ register Vmchunk_t* cp;
+ register Vmchunk_t* np;
+
+ if (!vp)
+ return -1;
+ np = vp->base.next;
+ while (cp = np)
+ {
+ np = cp->next;
+ free(cp);
+ }
+ free(vp);
+ return 0;
+}
+
+void*
+_vm_resize(register Vmalloc_t* vp, void* o, unsigned long size)
+{
+ char* p;
+ unsigned long n;
+ unsigned long z;
+
+ z = vp->last;
+ vp->last = size;
+ if (o && size < z)
+ return o;
+ if ((o ? (size - z) : size) > vp->size)
+ {
+ n = (size > sizeof(vp->current->data)) ? (size - sizeof(vp->current->data)) : 0;
+ if (!(vp->current->next = newof(0, Vmchunk_t, 1, n)))
+ return 0;
+ vp->current = vp->current->next;
+ vp->data = vp->current->data;
+ vp->size = n ? 0 : sizeof(vp->current->data);
+ if (o)
+ {
+ memcpy(vp->data, o, z);
+ o = (void*)vp->data;
+ }
+ }
+ else if (o)
+ size -= z;
+ p = vp->data;
+ size = roundof(size, VM_ALIGN);
+ if (size >= vp->size)
+ vp->size = 0;
+ else
+ {
+ vp->size -= size;
+ vp->data += size;
+ }
+ return p;
+}
diff --git a/src/lib/libast/astsa/vmalloc.h b/src/lib/libast/astsa/vmalloc.h
new file mode 100644
index 0000000..e3d2e5b
--- /dev/null
+++ b/src/lib/libast/astsa/vmalloc.h
@@ -0,0 +1,61 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * standalone mini vmalloc interface
+ */
+
+#ifndef _VMALLOC_H
+#define _VMALLOC_H 1
+
+#define vmalloc(v,n) _vm_resize(v,(void*)0,n)
+#define vmalign(v,n,a) _vm_resize(v,(void*)0,n)
+#define vmclose(v) _vm_close(v)
+#define vmfree(v,p)
+#define vmnewof(v,o,t,n,x) (t*)_vm_resize(v,(void*)o,sizeof(t)*(n)+(x))
+#define vmopen(a,b,c) _vm_open()
+
+#define VM_CHUNK (32*1024)
+#define VM_ALIGN 16
+
+typedef struct Vmchunk_s
+{
+ struct Vmchunk_s* next;
+ char align[VM_ALIGN - sizeof(struct Vmchunk_s*)];
+ char data[VM_CHUNK - VM_ALIGN];
+} Vmchunk_t;
+
+typedef struct Vmalloc_s
+{
+ Vmchunk_t base;
+ Vmchunk_t* current;
+ char* data;
+ long size;
+ long last;
+} Vmalloc_t;
+
+extern Vmalloc_t* Vmregion;
+
+extern int _vm_close(Vmalloc_t*);
+extern Vmalloc_t* _vm_open(void);
+extern void* _vm_resize(Vmalloc_t*, void*, unsigned long);
+
+#endif
diff --git a/src/lib/libast/cdt/cdtlib.h b/src/lib/libast/cdt/cdtlib.h
new file mode 100644
index 0000000..1972dd2
--- /dev/null
+++ b/src/lib/libast/cdt/cdtlib.h
@@ -0,0 +1,183 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _CDTLIB_H
+#define _CDTLIB_H 1
+
+/* cdt library/method implementation header
+** this header is exported to the method libraries
+** Written by Kiem-Phong Vo (5/25/96)
+*/
+
+#if _PACKAGE_ast
+#include <ast.h>
+#if !_BLD_cdt
+#include <dlldefs.h>
+#endif
+#endif
+
+#include <cdt.h>
+#include <unistd.h>
+#include <aso.h>
+
+#include "debug.h"
+
+/* short-hand notations */
+#define NIL(t) ((t)0)
+#define reg register
+
+/* min #bits for a hash table. (1<<this) is table size */
+#define DT_HTABLE 10
+
+/* convenient types */
+#if !defined(uint)
+#define uint unsigned int
+#endif
+#if !defined(uchar)
+#define uchar unsigned char
+#endif
+
+/* This struct holds private method data created on DT_OPEN */
+struct _dtdata_s
+{ unsigned int lock; /* general dictionary lock */
+ Dtuser_t user; /* application's data */
+ unsigned int type; /* method type, control flags */
+ ssize_t size; /* number of objects */
+ Dt_t dict; /* when DT_INDATA is requested */
+};
+
+/* this structure holds the plugin information */
+typedef struct _dtlib_s
+{
+ char* name; /* short name */
+ char* description; /* short description */
+ char* release; /* release info */
+ char* prefix; /* name prefix */
+ Dtmethod_t** methods; /* method list */
+} Dtlib_t;
+
+#if _BLD_cdt
+
+#if defined(__STDC__)
+#define CDTLIB(m) __DEFINE__(Dtmethod_t*,m,&_##m);
+#else
+#define CDTLIB(m) __DEFINE__(Dtmethod_t*,m,&_/**/m);
+#endif
+
+#else
+
+#if defined(__STDC__)
+#define CDTLIB(m) \
+ void* cdt_lib(const char* name, Dtdisc_t* disc, const char* type) \
+ { \
+ int i; \
+ int n; \
+ if (!type) \
+ return &cdt_lib_##m; \
+ n = strlen(cdt_lib_##m.prefix); \
+ if (!strncmp(type, cdt_lib_##m.prefix, n)) \
+ type += n; \
+ for (i = 0; cdt_lib_##m.methods[i]; i++) \
+ if (!strcmp(type, cdt_lib_##m.methods[i]->name + n)) \
+ return cdt_lib_##m.methods[i]; \
+ return 0; \
+ } \
+ unsigned long plugin_version(void) { return CDT_PLUGIN_VERSION; }
+#else
+#define CDTLIB(m) \
+ void* cdt_lib(name, disc, type) const char* name; Dtdisc_t* disc; const char* type; \
+ { \
+ int i; \
+ int n; \
+ if (!type) \
+ return &cdt_lib_/**/m; \
+ n = strlen(cdt_lib_/**/m.prefix); \
+ if (!strncmp(type, cdt_lib_/**/m.prefix, n)) \
+ type += n; \
+ for (i = 0; cdt_lib_/**/m.methods[i]; i++) \
+ if (!strcmp(type, cdt_lib_/**/m.methods[i]->name + n)) \
+ return cdt_lib_/**/m.methods[i]; \
+ return 0; \
+ } \
+ unsigned long plugin_version() { return CDT_PLUGIN_VERSION; }
+#endif
+
+#endif /* _BLD_cdt */
+
+/* these macros lock/unlock dictionaries. DTRETURN substitutes for "return" */
+#define DTSETLOCK(dt) (((dt)->data->type&DT_SHARE) ? asolock(&(dt)->data->lock,1,ASO_SPINLOCK) : 0 )
+#define DTCLRLOCK(dt) (((dt)->data->type&DT_SHARE) ? asolock(&(dt)->data->lock,1,ASO_UNLOCK) : 0 )
+#define DTRETURN(ob,rv) do { (ob) = (rv); goto dt_return; } while(0)
+#define DTERROR(dt, mesg) (!((dt)->disc && (dt)->disc->eventf) ? 0 : \
+ (*(dt)->disc->eventf)((dt),DT_ERROR,(Void_t*)(mesg),(dt)->disc) )
+
+/* announce completion of an operation of type (ty) on some object (ob) in dictionary (dt) */
+#define DTANNOUNCE(dt,ob,ty) ( ((ob) && ((ty)&DT_TOANNOUNCE) && ((dt)->data->type&DT_ANNOUNCE) && \
+ (dt)->disc && (dt)->disc->eventf ) ? \
+ (*(dt)->disc->eventf)((dt), DT_ANNOUNCE|(ty), (ob), (dt)->disc) : 0 )
+
+/* map bits for upward compabitibility */
+#define DTTYPE(dt,ty) ((dt)->typef ? (*(dt)->typef)((dt), (ty)) : (ty) )
+
+/* short-hands for fields in Dtlink_t.
+** note that __hash is used as a hash value
+** or as the position in the parent table.
+*/
+#define _left lh.__left
+#define _hash lh.__hash
+#define _ppos lh.__hash
+
+#define _rght rh.__rght
+#define _ptbl rh.__ptbl
+
+/* tree rotation/linking functions */
+#define rrotate(x,y) ((x)->_left = (y)->_rght, (y)->_rght = (x))
+#define lrotate(x,y) ((x)->_rght = (y)->_left, (y)->_left = (x))
+#define rlink(r,x) ((r) = (r)->_left = (x) )
+#define llink(l,x) ((l) = (l)->_rght = (x) )
+
+#define RROTATE(x,y) (rrotate(x,y), (x) = (y))
+#define LROTATE(x,y) (lrotate(x,y), (x) = (y))
+#define RRSHIFT(x,t) ((t) = (x)->_left->_left, (x)->_left->_left = (t)->_rght, \
+ (t)->_rght = (x), (x) = (t) )
+#define LLSHIFT(x,t) ((t) = (x)->_rght->_rght, (x)->_rght->_rght = (t)->_left, \
+ (t)->_left = (x), (x) = (t) )
+
+_BEGIN_EXTERNS_
+
+#if _BLD_cdt && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern Dtlink_t* _dtmake _ARG_((Dt_t*, Void_t*, int));
+extern void _dtfree _ARG_((Dt_t*, Dtlink_t*, int));
+extern int _dtlock _ARG_((Dt_t*, int));
+
+#undef extern
+
+#if !_PACKAGE_ast
+extern Void_t* malloc _ARG_((size_t));
+extern Void_t* realloc _ARG_((Void_t*, size_t));
+extern void free _ARG_((Void_t*));
+#endif
+_END_EXTERNS_
+
+#endif /* _CDTLIB_H */
diff --git a/src/lib/libast/cdt/dtclose.c b/src/lib/libast/cdt/dtclose.c
new file mode 100644
index 0000000..45bca76
--- /dev/null
+++ b/src/lib/libast/cdt/dtclose.c
@@ -0,0 +1,66 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "dthdr.h"
+
+/* Close a dictionary
+**
+** Written by Kiem-Phong Vo (11/15/2010)
+*/
+#if __STD_C
+int dtclose(Dt_t* dt)
+#else
+int dtclose(dt)
+Dt_t* dt;
+#endif
+{
+ int ev, type;
+ Dt_t pdt;
+ Dtdisc_t *disc = dt->disc;
+
+ if(!dt || dt->nview > 0 ) /* can't close if being viewed */
+ return -1;
+
+ if(disc && disc->eventf) /* announce closing event */
+ ev = (*disc->eventf)(dt, DT_CLOSE, (Void_t*)1, disc);
+ else ev = 0;
+ if(ev < 0) /* cannot close */
+ return -1;
+
+ if(dt->view) /* turn off viewing at this point */
+ dtview(dt,NIL(Dt_t*));
+
+ type = dt->data->type; /* save before memory is freed */
+ memcpy(&pdt, dt, sizeof(Dt_t));
+
+ if(ev == 0 ) /* release all allocated data */
+ { (void)(*(dt->meth->searchf))(dt,NIL(Void_t*),DT_CLEAR);
+ (void)(*dt->meth->eventf)(dt, DT_CLOSE, (Void_t*)0);
+ /**/DEBUG_ASSERT(!dt->data);
+ }
+ if(!(type&DT_INDATA) )
+ (void)free(dt);
+
+ if(disc && disc->eventf) /* announce end of closing activities */
+ (void)(*disc->eventf)(&pdt, DT_ENDCLOSE, (Void_t*)0, disc);
+
+ return 0;
+}
diff --git a/src/lib/libast/cdt/dtcomp.c b/src/lib/libast/cdt/dtcomp.c
new file mode 100644
index 0000000..5308c70
--- /dev/null
+++ b/src/lib/libast/cdt/dtcomp.c
@@ -0,0 +1,60 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * backwards binary compatibility
+ */
+
+#include <cdt.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#undef dtflatten
+extern Dtlink_t* dtflatten(Dt_t* d)
+{
+ return (Dtlink_t*)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_FLATTEN);
+}
+
+#undef dtextract
+extern Dtlink_t* dtextract(Dt_t* d)
+{
+ return (Dtlink_t*)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_EXTRACT);
+}
+
+#undef dtrestore
+extern Dtlink_t* dtrestore(Dt_t* d, Void_t* l)
+{
+ return (Dtlink_t*)(*(_DT(d)->searchf))((d),(l),DT_RESTORE);
+}
+
+#undef dtsize
+extern ssize_t dtsize(Dt_t* d)
+{
+ return (ssize_t)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_STAT);
+}
+
+#undef dtstat
+extern ssize_t dtstat(Dt_t* d)
+{
+ return (ssize_t)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_STAT);
+}
diff --git a/src/lib/libast/cdt/dtdisc.c b/src/lib/libast/cdt/dtdisc.c
new file mode 100644
index 0000000..166aa7c
--- /dev/null
+++ b/src/lib/libast/cdt/dtdisc.c
@@ -0,0 +1,91 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "dthdr.h"
+
+/* Change discipline.
+** dt : dictionary
+** disc : discipline
+**
+** Written by Kiem-Phong Vo (5/26/96)
+*/
+
+#if __STD_C
+static Void_t* dtmemory(Dt_t* dt, Void_t* addr, size_t size, Dtdisc_t* disc)
+#else
+static Void_t* dtmemory(dt, addr, size, disc)
+Dt_t* dt; /* dictionary */
+Void_t* addr; /* address to be manipulate */
+size_t size; /* size to obtain */
+Dtdisc_t* disc; /* discipline */
+#endif
+{
+ if(addr)
+ { if(size == 0)
+ { free(addr);
+ return NIL(Void_t*);
+ }
+ else return realloc(addr,size);
+ }
+ else return size > 0 ? malloc(size) : NIL(Void_t*);
+}
+
+#if __STD_C
+Dtdisc_t* dtdisc(Dt_t* dt, Dtdisc_t* disc, int type)
+#else
+Dtdisc_t* dtdisc(dt,disc,type)
+Dt_t* dt;
+Dtdisc_t* disc;
+int type;
+#endif
+{
+ Dtsearch_f searchf;
+ Dtdisc_t *old;
+ Dtlink_t *list;
+
+ if(!(old = dt->disc) ) /* initialization call from dtopen() */
+ { dt->disc = disc;
+ if(!(dt->memoryf = disc->memoryf) )
+ dt->memoryf = dtmemory;
+ return disc;
+ }
+
+ if(!disc) /* only want to know current discipline */
+ return old;
+
+ searchf = dt->meth->searchf;
+
+ if(old->eventf && (*old->eventf)(dt,DT_DISC,(Void_t*)disc,old) < 0)
+ return NIL(Dtdisc_t*);
+
+ if((type & (DT_SAMEHASH|DT_SAMECMP)) != (DT_SAMEHASH|DT_SAMECMP) )
+ list = dtextract(dt); /* grab the list of objects if any */
+ else list = NIL(Dtlink_t*);
+
+ dt->disc = disc;
+ if(!(dt->memoryf = disc->memoryf) )
+ dt->memoryf = dtmemory;
+
+ if(list ) /* reinsert extracted objects (with new discipline) */
+ dtrestore(dt, list);
+
+ return old;
+}
diff --git a/src/lib/libast/cdt/dthash.c b/src/lib/libast/cdt/dthash.c
new file mode 100644
index 0000000..984b2a5
--- /dev/null
+++ b/src/lib/libast/cdt/dthash.c
@@ -0,0 +1,431 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "dthdr.h"
+
+/* Hash table with chaining for collisions.
+**
+** Written by Kiem-Phong Vo (05/25/96)
+*/
+
+/* these bits should be outside the scope of DT_METHODS */
+#define H_FIXED 0100000 /* table size is fixed */
+#define H_FLATTEN 0200000 /* table was flattened */
+
+#define HLOAD(n) (n) /* load one-to-one */
+
+/* internal data structure for hash table with chaining */
+typedef struct _dthash_s
+{ Dtdata_t data;
+ int type;
+ Dtlink_t* here; /* fingered object */
+ Dtlink_t** htbl; /* hash table slots */
+ ssize_t tblz; /* size of hash table */
+} Dthash_t;
+
+/* make/resize hash table */
+static int htable(Dt_t* dt)
+{
+ Dtlink_t **htbl, **t, **endt, *l, *next;
+ ssize_t n, k;
+ Dtdisc_t *disc = dt->disc;
+ Dthash_t *hash = (Dthash_t*)dt->data;
+
+ if((n = hash->tblz) > 0 && (hash->type&H_FIXED) )
+ return 0; /* fixed size table */
+
+ if(n == 0 && disc && disc->eventf) /* let user have input */
+ { if((*disc->eventf)(dt, DT_HASHSIZE, &n, disc) > 0 )
+ { if(n < 0) /* fix table size */
+ { hash->type |= H_FIXED;
+ n = -n;
+ }
+ }
+ }
+
+ /* table size should be a power of 2 */
+ n = n < HLOAD(hash->data.size) ? HLOAD(hash->data.size) : n;
+ for(k = (1<<DT_HTABLE); k < n; )
+ k *= 2;
+ if((n = k) <= hash->tblz)
+ return 0;
+
+ /* allocate new table */
+ if(!(htbl = (Dtlink_t**)(*dt->memoryf)(dt, 0, n*sizeof(Dtlink_t*), disc)) )
+ { DTERROR(dt, "Error in allocating an extended hash table");
+ return -1;
+ }
+ memset(htbl, 0, n*sizeof(Dtlink_t*));
+
+ /* move objects into new table */
+ for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t)
+ { for(l = *t; l; l = next)
+ { next = l->_rght;
+ l->_rght = htbl[k = l->_hash&(n-1)];
+ htbl[k] = l;
+ }
+ }
+
+ if(hash->htbl) /* free old table and set new table */
+ (void)(*dt->memoryf)(dt, hash->htbl, 0, disc);
+ hash->htbl = htbl;
+ hash->tblz = n;
+
+ return 0;
+}
+
+static Void_t* hclear(Dt_t* dt)
+{
+ Dtlink_t **t, **endt, *l, *next;
+ Dthash_t *hash = (Dthash_t*)dt->data;
+
+ hash->here = NIL(Dtlink_t*);
+ hash->data.size = 0;
+
+ for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t)
+ { for(l = *t; l; l = next)
+ { next = l->_rght;
+ _dtfree(dt, l, DT_DELETE);
+ }
+ *t = NIL(Dtlink_t*);
+ }
+
+ return NIL(Void_t*);
+}
+
+static Void_t* hfirst(Dt_t* dt)
+{
+ Dtlink_t **t, **endt, *l;
+ Dthash_t *hash = (Dthash_t*)dt->data;
+
+ for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t)
+ { if(!(l = *t) )
+ continue;
+ hash->here = l;
+ return _DTOBJ(dt->disc, l);
+ }
+
+ return NIL(Void_t*);
+}
+
+static Void_t* hnext(Dt_t* dt, Dtlink_t* l)
+{
+ Dtlink_t **t, **endt, *next;
+ Dthash_t *hash = (Dthash_t*)dt->data;
+
+ if((next = l->_rght) )
+ { hash->here = next;
+ return _DTOBJ(dt->disc, next);
+ }
+ else
+ { t = hash->htbl + (l->_hash & (hash->tblz-1)) + 1;
+ endt = hash->htbl + hash->tblz;
+ for(; t < endt; ++t)
+ { if(!(l = *t) )
+ continue;
+ hash->here = l;
+ return _DTOBJ(dt->disc, l);
+ }
+ return NIL(Void_t*);
+ }
+}
+
+static Void_t* hflatten(Dt_t* dt, int type)
+{
+ Dtlink_t **t, **endt, *head, *tail, *l;
+ Dthash_t *hash = (Dthash_t*)dt->data;
+
+ if(type == DT_FLATTEN || type == DT_EXTRACT)
+ { head = tail = NIL(Dtlink_t*);
+ for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t)
+ { for(l = *t; l; l = l->_rght)
+ { if(tail)
+ tail = (tail->_rght = l);
+ else head = tail = l;
+
+ *t = type == DT_FLATTEN ? tail : NIL(Dtlink_t*);
+ }
+ }
+
+ if(type == DT_FLATTEN)
+ { hash->here = head;
+ hash->type |= H_FLATTEN;
+ }
+ else hash->data.size = 0;
+
+ return (Void_t*)head;
+ }
+ else /* restoring a previous flattened list */
+ { head = hash->here;
+ for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t)
+ { if(*t == NIL(Dtlink_t*))
+ continue;
+
+ /* find the tail of the list for this slot */
+ for(l = head; l && l != *t; l = l->_rght)
+ ;
+ if(!l) /* something is seriously wrong */
+ return NIL(Void_t*);
+
+ *t = head; /* head of list for this slot */
+ head = l->_rght; /* head of next list */
+ l->_rght = NIL(Dtlink_t*);
+ }
+
+ hash->here = NIL(Dtlink_t*);
+ hash->type &= ~H_FLATTEN;
+
+ return NIL(Void_t*);
+ }
+}
+
+static Void_t* hlist(Dt_t* dt, Dtlink_t* list, int type)
+{
+ Void_t *obj;
+ Dtlink_t *l, *next;
+ Dtdisc_t *disc = dt->disc;
+
+ if(type&DT_FLATTEN)
+ return hflatten(dt, DT_FLATTEN);
+ else if(type&DT_EXTRACT)
+ return hflatten(dt, DT_EXTRACT);
+ else /* if(type&DT_RESTORE) */
+ { dt->data->size = 0;
+ for(l = list; l; l = next)
+ { next = l->_rght;
+ obj = _DTOBJ(disc,l);
+ if((*dt->meth->searchf)(dt, (Void_t*)l, DT_RELINK) == obj)
+ dt->data->size += 1;
+ }
+ return (Void_t*)list;
+ }
+}
+
+static Void_t* hstat(Dt_t* dt, Dtstat_t* st)
+{
+ ssize_t n;
+ Dtlink_t **t, **endt, *l;
+ Dthash_t *hash = (Dthash_t*)dt->data;
+
+ if(st)
+ { memset(st, 0, sizeof(Dtstat_t));
+ st->meth = dt->meth->type;
+ st->size = hash->data.size;
+ st->space = sizeof(Dthash_t) + hash->tblz*sizeof(Dtlink_t*) +
+ (dt->disc->link >= 0 ? 0 : hash->data.size*sizeof(Dthold_t));
+
+ for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t)
+ { for(n = 0, l = *t; l; l = l->_rght)
+ n += 1;
+ st->mlev = n > st->mlev ? n : st->mlev;
+ if(n < DT_MAXSIZE) /* if chain length is small */
+ { st->msize = n > st->msize ? n : st->msize;
+ st->lsize[n] += n;
+ }
+ }
+ }
+
+ return (Void_t*)hash->data.size;
+}
+
+#if __STD_C
+static Void_t* dthashchain(Dt_t* dt, Void_t* obj, int type)
+#else
+static Void_t* dthashchain(dt,obj,type)
+Dt_t* dt;
+Void_t* obj;
+int type;
+#endif
+{
+ Dtlink_t *lnk, *pp, *ll, *p, *l, **tbl;
+ Void_t *key, *k, *o;
+ uint hsh;
+ Dtdisc_t *disc = dt->disc;
+ Dthash_t *hash = (Dthash_t*)dt->data;
+
+ type = DTTYPE(dt,type); /* map type for upward compatibility */
+ if(!(type&DT_OPERATIONS) )
+ return NIL(Void_t*);
+
+ DTSETLOCK(dt);
+
+ if(!hash->htbl && htable(dt) < 0 ) /* initialize hash table */
+ DTRETURN(obj, NIL(Void_t*));
+
+ if(hash->type&H_FLATTEN) /* restore flattened list */
+ hflatten(dt, 0);
+
+ if(type&(DT_FIRST|DT_LAST|DT_CLEAR|DT_EXTRACT|DT_RESTORE|DT_FLATTEN|DT_STAT) )
+ { if(type&(DT_FIRST|DT_LAST) )
+ DTRETURN(obj, hfirst(dt));
+ else if(type&DT_CLEAR)
+ DTRETURN(obj, hclear(dt));
+ else if(type&DT_STAT)
+ DTRETURN(obj, hstat(dt, (Dtstat_t*)obj));
+ else /*if(type&(DT_EXTRACT|DT_RESTORE|DT_FLATTEN))*/
+ DTRETURN(obj, hlist(dt, (Dtlink_t*)obj, type));
+ }
+
+ lnk = hash->here; /* fingered object */
+ hash->here = NIL(Dtlink_t*);
+
+ if(lnk && obj == _DTOBJ(disc,lnk))
+ { if(type&DT_SEARCH)
+ DTRETURN(obj, obj);
+ else if(type&(DT_NEXT|DT_PREV) )
+ DTRETURN(obj, hnext(dt,lnk));
+ }
+
+ if(type&DT_RELINK)
+ { lnk = (Dtlink_t*)obj;
+ obj = _DTOBJ(disc,lnk);
+ key = _DTKEY(disc,obj);
+ }
+ else
+ { lnk = NIL(Dtlink_t*);
+ if((type&DT_MATCH) )
+ { key = obj;
+ obj = NIL(Void_t*);
+ }
+ else key = _DTKEY(disc,obj);
+ }
+ hsh = _DTHSH(dt,key,disc);
+
+ tbl = hash->htbl + (hsh & (hash->tblz-1));
+ pp = ll = NIL(Dtlink_t*);
+ for(p = NIL(Dtlink_t*), l = *tbl; l; p = l, l = l->_rght)
+ { if(hsh == l->_hash)
+ { o = _DTOBJ(disc,l); k = _DTKEY(disc,o);
+ if(_DTCMP(dt, key, k, disc) != 0 )
+ continue;
+ else if((type&(DT_REMOVE|DT_NEXT|DT_PREV)) && o != obj )
+ { if(type&(DT_NEXT|DT_PREV) )
+ { pp = p; ll = l; }
+ continue;
+ }
+ else break;
+ }
+ }
+ if(l) /* found an object, use it */
+ { pp = p; ll = l; }
+
+ if(ll) /* found object */
+ { if(type&(DT_SEARCH|DT_MATCH|DT_ATLEAST|DT_ATMOST) )
+ { hash->here = ll;
+ DTRETURN(obj, _DTOBJ(disc,ll));
+ }
+ else if(type & (DT_NEXT|DT_PREV) )
+ DTRETURN(obj, hnext(dt, ll));
+ else if(type & (DT_DELETE|DT_DETACH|DT_REMOVE) )
+ { hash->data.size -= 1;
+ if(pp)
+ pp->_rght = ll->_rght;
+ else *tbl = ll->_rght;
+ _dtfree(dt, ll, type);
+ DTRETURN(obj, _DTOBJ(disc,ll));
+ }
+ else
+ { /**/DEBUG_ASSERT(type&(DT_INSERT|DT_ATTACH|DT_APPEND|DT_RELINK));
+ if(!(dt->meth->type&DT_BAG) )
+ { if(type&(DT_INSERT|DT_APPEND|DT_ATTACH) )
+ type |= DT_SEARCH; /* for announcement */
+ else if(lnk && (type&DT_RELINK) )
+ _dtfree(dt, lnk, DT_DELETE);
+ DTRETURN(obj, _DTOBJ(disc,ll));
+ }
+ else goto do_insert;
+ }
+ }
+ else /* no matching object */
+ { if(!(type&(DT_INSERT|DT_APPEND|DT_ATTACH|DT_RELINK)) )
+ DTRETURN(obj, NIL(Void_t*));
+
+ do_insert: /* inserting a new object */
+ if(hash->tblz < HLOAD(hash->data.size) )
+ { htable(dt); /* resize table */
+ tbl = hash->htbl + (hsh & (hash->tblz-1));
+ }
+
+ if(!lnk) /* inserting a new object */
+ { if(!(lnk = _dtmake(dt, obj, type)) )
+ DTRETURN(obj, NIL(Void_t*));
+ hash->data.size += 1;
+ }
+
+ lnk->_hash = hsh; /* memoize the hash value */
+ lnk->_rght = *tbl; *tbl = lnk;
+
+ hash->here = lnk;
+ DTRETURN(obj, _DTOBJ(disc,lnk));
+ }
+
+dt_return:
+ DTANNOUNCE(dt, obj, type);
+ DTCLRLOCK(dt);
+ return obj;
+}
+
+static int hashevent(Dt_t* dt, int event, Void_t* arg)
+{
+ Dtlink_t *list;
+ Dthash_t *hash = (Dthash_t*)dt->data;
+ int rv = -1;
+
+ if(event == DT_OPEN)
+ { if(hash)
+ return 0;
+ if(!(hash = (Dthash_t*)(*dt->memoryf)(dt, 0, sizeof(Dthash_t), dt->disc)) )
+ { DTERROR(dt, "Error in allocating a hash table with chaining");
+ return -1;
+ }
+ memset(hash, 0, sizeof(Dthash_t));
+ dt->data = (Dtdata_t*)hash;
+ return 1;
+ }
+ else if(event == DT_CLOSE)
+ { if(!hash)
+ return 0;
+ if(hash->data.size > 0 )
+ (void)hclear(dt);
+ if(hash->htbl)
+ (void)(*dt->memoryf)(dt, hash->htbl, 0, dt->disc);
+ (void)(*dt->memoryf)(dt, hash, 0, dt->disc);
+ dt->data = NIL(Dtdata_t*);
+ return 0;
+ }
+ else return 0;
+}
+
+static Dtmethod_t _Dtset = { dthashchain, DT_SET, hashevent, "Dtset" };
+static Dtmethod_t _Dtbag = { dthashchain, DT_BAG, hashevent, "Dtbag" };
+__DEFINE__(Dtmethod_t*,Dtset,&_Dtset);
+__DEFINE__(Dtmethod_t*,Dtbag,&_Dtbag);
+
+/* backwards compatibility */
+#undef Dthash
+#if defined(__EXPORT__)
+__EXPORT__
+#endif
+__DEFINE__(Dtmethod_t*,Dthash,&_Dtset);
+
+#ifdef NoF
+NoF(dthashchain)
+#endif
diff --git a/src/lib/libast/cdt/dthdr.h b/src/lib/libast/cdt/dthdr.h
new file mode 100644
index 0000000..d24ae0d
--- /dev/null
+++ b/src/lib/libast/cdt/dthdr.h
@@ -0,0 +1,37 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _DTHDR_H
+#define _DTHDR_H 1
+
+#ifndef _BLD_cdt
+#define _BLD_cdt 1
+#endif
+
+/* Internal definitions for libcdt.
+** Written by Kiem-Phong Vo (5/25/96)
+*/
+
+#undef _DTTRACE
+
+#include <cdtlib.h>
+
+#endif /* _DTHDR_H */
diff --git a/src/lib/libast/cdt/dtlist.c b/src/lib/libast/cdt/dtlist.c
new file mode 100644
index 0000000..af0dfd1
--- /dev/null
+++ b/src/lib/libast/cdt/dtlist.c
@@ -0,0 +1,387 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "dthdr.h"
+
+/* List, Deque, Stack, Queue.
+**
+** Written by Kiem-Phong Vo (05/25/96)
+*/
+
+typedef struct _dtlist_s
+{ Dtdata_t data;
+ Dtlink_t* link; /* list of objects */
+ Dtlink_t* here; /* finger to searched objects */
+} Dtlist_t;
+
+#ifdef DEBUG
+int dtlistprint(Dt_t* dt, Dtlink_t* here, char* (*objprintf)(Void_t*) )
+{
+ int k;
+ char *obj, *endb, buf[1024];
+ Dtdisc_t *disc = dt->disc;
+ Dtlist_t *list = (Dtlist_t*)dt->data;
+
+ if(!here && !(here = list->link) )
+ return -1;
+
+ for(; here; here = here->_rght)
+ { endb = buf; /* indentation */
+ *endb++ = '(';
+ obj = (*objprintf)(_DTOBJ(disc, here));
+ k = strlen(obj); memcpy(endb, obj, k); endb += k;
+ *endb++ = ')';
+ *endb++ = '\n';
+ write(2, buf, endb-buf);
+ }
+
+ return 0;
+}
+#endif
+
+/* terminal objects: DT_FIRST|DT_LAST */
+#if __STD_C
+Void_t* lfirstlast(Dt_t* dt, int type)
+#else
+Void_t* lfirstlast(dt, type)
+Dt_t* dt;
+int type;
+#endif
+{
+ Dtlink_t *lnk;
+ Dtdisc_t *disc = dt->disc;
+ Dtlist_t *list = (Dtlist_t*)dt->data;
+
+ if((lnk = list->link) )
+ { if(type&DT_LAST)
+ lnk = lnk->_left;
+ list->here = lnk; /* finger points to this */
+ }
+
+ return lnk ? _DTOBJ(disc,lnk) : NIL(Void_t*);
+}
+
+/* DT_CLEAR */
+#if __STD_C
+Void_t* lclear(Dt_t* dt)
+#else
+Void_t* lclear(dt)
+Dt_t* dt;
+#endif
+{
+ Dtlink_t *lnk, *next;
+ Dtdisc_t *disc = dt->disc;
+ Dtlist_t *list = (Dtlist_t*)dt->data;
+
+ lnk = list->link;
+ list->link = list->here = NIL(Dtlink_t*);
+ list->data.size = 0;
+
+ if(disc->freef || disc->link < 0)
+ { for(; lnk; lnk = next)
+ { next = lnk->_rght;
+ _dtfree(dt, lnk, DT_DELETE);
+ }
+ }
+
+ return NIL(Void_t*);
+}
+
+/* DT_FLATTEN|DT_EXTRACT|DT_RESTORE */
+#if __STD_C
+Void_t* llist(Dt_t* dt, Dtlink_t* lnk, int type)
+#else
+Void_t* llist(dt, lnk, type)
+Dt_t* dt;
+Dtlink_t* lnk;
+int type;
+#endif
+{
+ Dtlist_t *list = (Dtlist_t*)dt->data;
+
+ if(type&(DT_FLATTEN|DT_EXTRACT) )
+ { if(lnk) /* error on calling */
+ return NIL(Void_t*);
+
+ lnk = list->link;
+ if(type&DT_EXTRACT)
+ { list->link = NIL(Dtlink_t*);
+ dt->data->size = 0;
+ }
+ }
+ else /* if(type&DT_RESTORE) */
+ { if(list->link != NIL(Dtlink_t*))
+ return NIL(Void_t*);
+
+ list->link = lnk;
+
+ dt->data->size = 0;
+ for(; lnk; lnk = lnk->_rght)
+ dt->data->size += 1;
+ }
+
+ return (Void_t*)lnk;
+}
+
+#if __STD_C
+static Void_t* liststat(Dt_t* dt, Dtstat_t* st)
+#else
+static Void_t* liststat(dt, st)
+Dt_t* dt;
+Dtstat_t* st;
+#endif
+{
+ ssize_t size;
+ Dtlink_t *lnk;
+ Dtlist_t *list = (Dtlist_t*)dt->data;
+
+ if(st)
+ { memset(st, 0, sizeof(Dtstat_t));
+ st->meth = dt->meth->type;
+ st->size = dt->data->size;
+ st->space = sizeof(Dtlist_t) + (dt->disc->link >= 0 ? 0 : dt->data->size*sizeof(Dthold_t));
+ }
+
+ return (Void_t*)dt->data->size;
+}
+
+#if __STD_C
+static Void_t* dtlist(Dt_t* dt, Void_t* obj, int type)
+#else
+static Void_t* dtlist(dt, obj, type)
+Dt_t* dt;
+Void_t* obj;
+int type;
+#endif
+{
+ Dtlink_t *r, *t, *h;
+ Void_t *key, *o, *k;
+ Dtdisc_t *disc = dt->disc;
+ Dtlist_t *list = (Dtlist_t*)dt->data;
+
+ type = DTTYPE(dt,type); /* map type for upward compatibility */
+ if(!(type&DT_OPERATIONS) )
+ return NIL(Void_t*);
+
+ DTSETLOCK(dt);
+
+ if(type&(DT_FIRST|DT_LAST) )
+ DTRETURN(obj, lfirstlast(dt, type));
+ else if(type&(DT_EXTRACT|DT_RESTORE|DT_FLATTEN) )
+ DTRETURN(obj, llist(dt, (Dtlink_t*)obj, type));
+ else if(type&DT_CLEAR)
+ DTRETURN(obj, lclear(dt));
+ else if(type&DT_STAT )
+ DTRETURN(obj, liststat(dt, (Dtstat_t*)obj));
+
+ h = list->here; /* save finger to last search object */
+ list->here = NIL(Dtlink_t*);
+
+ if(!obj)
+ { if((type&(DT_DELETE|DT_DETACH|DT_REMOVE)) && (dt->meth->type&(DT_STACK|DT_QUEUE)) )
+ if((r = list->link) ) /* special case for destack or dequeue */
+ goto dt_delete;
+ DTRETURN(obj, NIL(Void_t*)); /* error, needing non-void object */
+ }
+
+ if(type&DT_RELINK) /* relink object after some processing */
+ { r = (Dtlink_t*)obj;
+ goto do_insert;
+ }
+ else if(type&(DT_INSERT|DT_APPEND|DT_ATTACH))
+ { if(!(r = _dtmake(dt, obj, type)) )
+ DTRETURN(obj, NIL(Void_t*));
+ dt->data->size += 1;
+
+ do_insert:
+ if(dt->meth->type&DT_DEQUE)
+ { if(type&DT_APPEND)
+ goto dt_queue; /* append at end */
+ else goto dt_stack; /* insert at top */
+ }
+ else if(dt->meth->type&DT_LIST)
+ { if(type&DT_APPEND)
+ { if(!h || !h->_rght)
+ goto dt_queue;
+ r->_rght = h->_rght;
+ r->_rght->_left = r;
+ r->_left = h;
+ r->_left->_rght = r;
+ }
+ else
+ { if(!h || h == list->link )
+ goto dt_stack;
+ r->_left = h->_left;
+ r->_left->_rght = r;
+ r->_rght = h;
+ r->_rght->_left = r;
+ }
+ }
+ else if(dt->meth->type&DT_STACK)
+ { dt_stack:
+ r->_rght = t = list->link;
+ if(t)
+ { r->_left = t->_left;
+ t->_left = r;
+ }
+ else r->_left = r;
+ list->link = r;
+ }
+ else /* if(dt->meth->type&DT_QUEUE) */
+ { dt_queue:
+ if((t = list->link) )
+ { t->_left->_rght = r;
+ r->_left = t->_left;
+ t->_left = r;
+ }
+ else
+ { list->link = r;
+ r->_left = r;
+ }
+ r->_rght = NIL(Dtlink_t*);
+ }
+
+ list->here = r;
+ DTRETURN(obj, _DTOBJ(disc,r));
+ }
+
+ /* define key to match */
+ if(type&DT_MATCH)
+ { key = obj;
+ obj = NIL(Void_t*);
+ }
+ else key = _DTKEY(disc, obj);
+
+ /* try to find a matching object */
+ if(h && _DTOBJ(disc,h) == obj && (type & (DT_SEARCH|DT_NEXT|DT_PREV)) )
+ r = h; /* match at the finger, no search needed */
+ else /* linear search through the list */
+ { h = NIL(Dtlink_t*); /* track first/last obj with same key */
+ for(r = list->link; r; r = r->_rght)
+ { o = _DTOBJ(disc,r); k = _DTKEY(disc,o);
+ if(_DTCMP(dt, key, k, disc) != 0)
+ continue;
+ else if(type & (DT_REMOVE|DT_NEXT|DT_PREV) )
+ { if(o == obj) /* got exact object, done */
+ break;
+ else if(type&DT_NEXT) /* track last object */
+ h = r;
+ else if(type&DT_PREV) /* track first object */
+ h = h ? h : r;
+ else continue;
+ }
+ else if(type & DT_ATLEAST )
+ h = r; /* track last object */
+ else break;
+ }
+ r = h ? h : r;
+ }
+ if(!r)
+ DTRETURN(obj, NIL(Void_t*));
+
+ if(type&(DT_DELETE|DT_DETACH|DT_REMOVE))
+ { dt_delete:
+ if(r->_rght)
+ r->_rght->_left = r->_left;
+ if(r == (t = list->link) )
+ { list->link = r->_rght;
+ if((h = list->link) )
+ h->_left = t->_left;
+ }
+ else
+ { r->_left->_rght = r->_rght;
+ if(r == t->_left)
+ t->_left = r->_left;
+ }
+
+ list->here = r == list->here ? r->_rght : NIL(Dtlink_t*);
+
+ obj = _DTOBJ(disc,r);
+ _dtfree(dt, r, type);
+ dt->data->size -= 1;
+
+ DTRETURN(obj, obj);
+ }
+
+ if(type&DT_NEXT)
+ r = r->_rght;
+ else if(type&DT_PREV)
+ r = r == list->link ? NIL(Dtlink_t*) : r->_left;
+ /* else: if(type&(DT_SEARCH|DT_MATCH|DT_ATLEAST|DT_ATMOST)) */
+
+ list->here = r;
+ if(r)
+ DTRETURN(obj, _DTOBJ(disc,r));
+ else DTRETURN(obj, NIL(Void_t*));
+
+dt_return:
+ DTANNOUNCE(dt,obj,type);
+ DTCLRLOCK(dt);
+ return obj;
+}
+
+#if __STD_C
+static int listevent(Dt_t* dt, int event, Void_t* arg)
+#else
+static int listevent(dt, event, arg)
+Dt_t* dt;
+int event;
+Void_t* arg;
+#endif
+{
+ Dtlist_t *list = (Dtlist_t*)dt->data;
+
+ if(event == DT_OPEN)
+ { if(list) /* already initialized */
+ return 0;
+ if(!(list = (Dtlist_t*)(*dt->memoryf)(dt, 0, sizeof(Dtlist_t), dt->disc)) )
+ { DTERROR(dt, "Error in allocating a list data structure");
+ return -1;
+ }
+ memset(list, 0, sizeof(Dtlist_t));
+ dt->data = (Dtdata_t*)list;
+ return 1;
+ }
+ else if(event == DT_CLOSE)
+ { if(!list) /* already closed */
+ return 0;
+ if(list->link) /* remove all items */
+ (void)lclear(dt);
+ (void)(*dt->memoryf)(dt, (Void_t*)list, 0, dt->disc);
+ dt->data = NIL(Dtdata_t*);
+ return 0;
+ }
+ else return 0;
+}
+
+static Dtmethod_t _Dtlist = { dtlist, DT_LIST, listevent, "Dtlist" };
+static Dtmethod_t _Dtdeque = { dtlist, DT_DEQUE, listevent, "Dtdeque" };
+static Dtmethod_t _Dtstack = { dtlist, DT_STACK, listevent, "Dtstack" };
+static Dtmethod_t _Dtqueue = { dtlist, DT_QUEUE, listevent, "Dtqueue" };
+
+__DEFINE__(Dtmethod_t*,Dtlist,&_Dtlist);
+__DEFINE__(Dtmethod_t*,Dtdeque,&_Dtdeque);
+__DEFINE__(Dtmethod_t*,Dtstack,&_Dtstack);
+__DEFINE__(Dtmethod_t*,Dtqueue,&_Dtqueue);
+
+#ifdef NoF
+NoF(dtlist)
+#endif
diff --git a/src/lib/libast/cdt/dtmethod.c b/src/lib/libast/cdt/dtmethod.c
new file mode 100644
index 0000000..56a1d25
--- /dev/null
+++ b/src/lib/libast/cdt/dtmethod.c
@@ -0,0 +1,107 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "dthdr.h"
+
+/* Change search method.
+**
+** Written by Kiem-Phong Vo (05/25/96)
+*/
+
+#if __STD_C
+Dtmethod_t* dtmethod(Dt_t* dt, Dtmethod_t* meth)
+#else
+Dtmethod_t* dtmethod(dt, meth)
+Dt_t* dt;
+Dtmethod_t* meth;
+#endif
+{
+ Dtlink_t *list;
+ Dtdisc_t *disc = dt->disc;
+ Dtmethod_t *oldmt = dt->meth;
+ Dtdata_t *newdt, *olddt = dt->data;
+
+ if(!meth || meth == oldmt)
+ return oldmt;
+
+ /* ask discipline if switching to new method is ok */
+ if(disc->eventf && (*disc->eventf)(dt,DT_METH,(Void_t*)meth,disc) < 0)
+ return NIL(Dtmethod_t*);
+
+ list = dtextract(dt); /* extract elements out of dictionary */
+
+ /* try to create internal structure for new method */
+ if(dt->searchf == oldmt->searchf) /* ie, not viewpathing */
+ dt->searchf = meth->searchf;
+ dt->meth = meth;
+ dt->data = NIL(Dtdata_t*);
+ if((*dt->meth->eventf)(dt, DT_OPEN, NIL(Void_t*)) < 0 )
+ newdt = NIL(Dtdata_t*);
+ else newdt = dt->data;
+
+ /* see what need to be done to data of the old method */
+ if(dt->searchf == meth->searchf)
+ dt->searchf = oldmt->searchf;
+ dt->meth = oldmt;
+ dt->data = olddt;
+ if(newdt) /* switch was successful, remove old data */
+ { (void)(*dt->meth->eventf)(dt, DT_CLOSE, NIL(Void_t*));
+
+ if(dt->searchf == oldmt->searchf)
+ dt->searchf = meth->searchf;
+ dt->meth = meth;
+ dt->data = newdt;
+ dtrestore(dt, list);
+ return oldmt;
+ }
+ else /* switch failed, restore dictionary to previous states */
+ { dtrestore(dt, list);
+ return NIL(Dtmethod_t*);
+ }
+}
+
+/* customize certain actions in a container data structure */
+int dtcustomize(Dt_t* dt, int type, int action)
+{
+ int done = 0;
+
+ if((type&DT_SHARE) &&
+ (!dt->meth->eventf || (*dt->meth->eventf)(dt, DT_SHARE, (Void_t*)((long)action)) >= 0) )
+ { if(action <= 0 )
+ dt->data->type &= ~DT_SHARE;
+ else dt->data->type |= DT_SHARE;
+ done |= DT_SHARE;
+ }
+
+ if((type&DT_ANNOUNCE) &&
+ (!dt->meth->eventf || (*dt->meth->eventf)(dt, DT_ANNOUNCE, (Void_t*)((long)action)) >= 0) )
+ { if(action <= 0 )
+ dt->data->type &= ~DT_ANNOUNCE;
+ else dt->data->type |= DT_ANNOUNCE;
+ done |= DT_ANNOUNCE;
+ }
+
+ if((type&DT_OPTIMIZE) &&
+ (!dt->meth->eventf || (*dt->meth->eventf)(dt, DT_OPTIMIZE, (Void_t*)((long)action)) >= 0) )
+ done |= DT_OPTIMIZE;
+
+ return done;
+}
diff --git a/src/lib/libast/cdt/dtnew.c b/src/lib/libast/cdt/dtnew.c
new file mode 100644
index 0000000..5e1bb70
--- /dev/null
+++ b/src/lib/libast/cdt/dtnew.c
@@ -0,0 +1,81 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * dtopen() with handle placed in specific vm region
+ */
+
+#include <dt.h>
+
+typedef struct Dc_s
+{
+ Dtdisc_t ndisc;
+ Dtdisc_t* odisc;
+ Vmalloc_t* vm;
+} Dc_t;
+
+static int
+eventf(Dt_t* dt, int op, void* data, Dtdisc_t* disc)
+{
+ Dc_t* dc = (Dc_t*)disc;
+ int r;
+
+ if (dc->odisc->eventf && (r = (*dc->odisc->eventf)(dt, op, data, dc->odisc)))
+ return r;
+ return op == DT_ENDOPEN ? 1 : 0;
+}
+
+static void*
+memoryf(Dt_t* dt, void* addr, size_t size, Dtdisc_t* disc)
+{
+ return vmresize(((Dc_t*)disc)->vm, addr, size, VM_RSMOVE);
+}
+
+/*
+ * open a dictionary using disc->memoryf if set or vm otherwise
+ */
+
+Dt_t*
+_dtnew(Vmalloc_t* vm, Dtdisc_t* disc, Dtmethod_t* meth, unsigned long version)
+{
+ Dt_t* dt;
+ Dc_t dc;
+
+ dc.odisc = disc;
+ dc.ndisc = *disc;
+ dc.ndisc.eventf = eventf;
+ if (!dc.ndisc.memoryf)
+ dc.ndisc.memoryf = memoryf;
+ dc.vm = vm;
+ if (dt = _dtopen(&dc.ndisc, meth, version))
+ dtdisc(dt, disc, DT_SAMECMP|DT_SAMEHASH);
+ return dt;
+}
+
+#undef dtnew
+
+Dt_t*
+dtnew(Vmalloc_t* vm, Dtdisc_t* disc, Dtmethod_t* meth)
+{
+ return _dtnew(vm, disc, meth, 20050420L);
+}
diff --git a/src/lib/libast/cdt/dtopen.c b/src/lib/libast/cdt/dtopen.c
new file mode 100644
index 0000000..6411969
--- /dev/null
+++ b/src/lib/libast/cdt/dtopen.c
@@ -0,0 +1,177 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "dthdr.h"
+static char* Version = "\n@(#)$Id: cdt (AT&T Labs - Research) 2011-11-11 $\0\n";
+
+/* Make a new dictionary
+**
+** Written by Kiem-Phong Vo (5/25/96)
+*/
+
+/* map operation bits from the 2005 version to the current version */
+static int _dttype2005(Dt_t* dt, int type)
+{
+ if (type == DT_DELETE && (dt->meth->type&(DT_OBAG|DT_BAG)))
+ type = DT_REMOVE;
+ return type;
+}
+
+#if __STD_C
+Dt_t* _dtopen(Dtdisc_t* disc, Dtmethod_t* meth, unsigned long version)
+#else
+Dt_t* _dtopen(disc, meth, version)
+Dtdisc_t* disc;
+Dtmethod_t* meth;
+unsigned long version;
+#endif
+{
+ Dtdata_t *data;
+ Dt_t *dt, pdt;
+ int ev, type;
+
+ if(!disc || !meth)
+ return NIL(Dt_t*);
+
+ dt = NIL(Dt_t*);
+ data = NIL(Dtdata_t*);
+ type = meth->type;
+
+ memset(&pdt, 0, sizeof(Dt_t));
+ pdt.searchf = meth->searchf;
+ pdt.meth = meth;
+ dtdisc(&pdt,disc,0); /* note that this sets pdt.memoryf */
+
+ if(disc->eventf)
+ { if((ev = (*disc->eventf)(&pdt,DT_OPEN,(Void_t*)(&data),disc)) < 0)
+ return NIL(Dt_t*); /* something bad happened */
+ else if(ev > 0)
+ { if(data) /* shared data are being restored */
+ { if((data->type & DT_METHODS) != meth->type)
+ { DTERROR(&pdt, "Error in matching methods to restore dictionary");
+ return NIL(Dt_t*);
+ }
+ pdt.data = data;
+ }
+ }
+ else
+ { if(data) /* dt should be allocated with dt->data */
+ type |= DT_INDATA;
+ }
+ }
+
+ if(!pdt.data) /* allocate method-specific data */
+ if((*meth->eventf)(&pdt, DT_OPEN, NIL(Void_t*)) < 0 || !pdt.data )
+ return NIL(Dt_t*);
+ pdt.data->type |= type;
+
+ /* now allocate/initialize the actual dictionary structure */
+ if(pdt.data->type&DT_INDATA)
+ dt = &pdt.data->dict;
+ else if(!(dt = (Dt_t*) malloc(sizeof(Dt_t))) )
+ { (void)(*meth->eventf)(&pdt, DT_CLOSE, NIL(Void_t*));
+ DTERROR(&pdt, "Error in allocating a new dictionary");
+ return NIL(Dt_t*);
+ }
+
+ *dt = pdt;
+
+ dt->user = &dt->data->user; /* space allocated for application usage */
+
+ if(disc->eventf) /* signal opening is done */
+ (void)(*disc->eventf)(dt, DT_ENDOPEN, (Void_t*)0, disc);
+
+ /* set mapping of operation bits between versions as needed */
+ if(version < 20111111L)
+ dt->typef = _dttype2005;
+
+ return dt;
+}
+
+#undef dtopen /* deal with binary upward compatibility for op bits */
+#if __STD_C
+Dt_t* dtopen(Dtdisc_t* disc, Dtmethod_t* meth)
+#else
+Dt_t* dtopen(disc, meth)
+Dtdisc_t* disc;
+Dtmethod_t* meth;
+#endif
+{
+ return _dtopen(disc, meth, 20050420L);
+}
+
+/* below are private functions used across CDT modules */
+Dtlink_t* _dtmake(Dt_t* dt, Void_t* obj, int type)
+{
+ Dthold_t *h;
+ Dtdisc_t *disc = dt->disc;
+
+ /* if obj is a prototype, make a real one */
+ if(!(type&DT_ATTACH) && disc->makef && !(obj = (*disc->makef)(dt, obj, disc)) )
+ return NIL(Dtlink_t*);
+
+ if(disc->link >= 0) /* holder is embedded in obj itself */
+ return _DTLNK(disc, obj);
+
+ /* create a holder to hold obj */
+ if((h = (Dthold_t*)(dt->memoryf)(dt, NIL(Void_t*), sizeof(Dthold_t), disc)) )
+ h->obj = obj;
+ else
+ { DTERROR(dt, "Error in allocating an object holder");
+ if(!(type&DT_ATTACH) && disc->makef && disc->freef)
+ (void)(*disc->freef)(dt, obj, disc); /* free just-made obj */
+ }
+
+ return (Dtlink_t*)h;
+}
+
+void _dtfree(Dt_t* dt, Dtlink_t* l, int type)
+{
+ Dtdisc_t *disc = dt->disc;
+
+ if(!(type&DT_DETACH) && disc->freef) /* free object */
+ (void)(*disc->freef)(dt, _DTOBJ(disc,l), disc);
+
+ if(disc->link < 0) /* free holder */
+ (void)(*dt->memoryf)(dt, (Void_t*)l, 0, disc);
+}
+
+int dtuserlock(Dt_t* dt, unsigned int key, int type)
+{
+ if(type > 0)
+ return asolock(&dt->data->user.lock, key, ASO_LOCK);
+ else if(type < 0)
+ return asolock(&dt->data->user.lock, key, ASO_UNLOCK);
+ else return asolock(&dt->data->user.lock, key, ASO_TRYLOCK);
+}
+
+Void_t* dtuserdata(Dt_t* dt, Void_t* data, unsigned int key)
+{
+ if(key == 0)
+ return dt->data->user.data;
+ else if(dtuserlock(dt, key, 1) < 0 )
+ return NIL(Void_t*);
+ else
+ { dt->data->user.data = data;
+ dtuserlock(dt, key, -1);
+ return data;
+ }
+}
diff --git a/src/lib/libast/cdt/dtstrhash.c b/src/lib/libast/cdt/dtstrhash.c
new file mode 100644
index 0000000..7eaac89
--- /dev/null
+++ b/src/lib/libast/cdt/dtstrhash.c
@@ -0,0 +1,61 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "dthdr.h"
+
+/* Hashing a string into an unsigned integer.
+** The basic method is to continuingly accumulate bytes and multiply
+** with some given prime. The length n of the string is added last.
+** The recurrent equation is like this:
+** h[k] = (h[k-1] + bytes)*prime for 0 <= k < n
+** h[n] = (h[n-1] + n)*prime
+** The prime is chosen to have a good distribution of 1-bits so that
+** the multiplication will distribute the bits in the accumulator well.
+** The below code accumulates 2 bytes at a time for speed.
+**
+** Written by Kiem-Phong Vo (02/28/03)
+*/
+
+#if __STD_C
+uint dtstrhash(uint h, Void_t* args, ssize_t n)
+#else
+uint dtstrhash(h,args,n)
+reg uint h;
+Void_t* args;
+ssize_t n;
+#endif
+{
+ unsigned char *s = (unsigned char*)args;
+
+ if(n <= 0)
+ { for(; *s != 0; s += s[1] ? 2 : 1)
+ h = (h + (s[0]<<8) + s[1])*DT_PRIME;
+ n = s - (unsigned char*)args;
+ }
+ else
+ { unsigned char* ends;
+ for(ends = s+n-1; s < ends; s += 2)
+ h = (h + (s[0]<<8) + s[1])*DT_PRIME;
+ if(s <= ends)
+ h = (h + (s[0]<<8))*DT_PRIME;
+ }
+ return (h+n)*DT_PRIME;
+}
diff --git a/src/lib/libast/cdt/dttree.c b/src/lib/libast/cdt/dttree.c
new file mode 100644
index 0000000..2dd31d3
--- /dev/null
+++ b/src/lib/libast/cdt/dttree.c
@@ -0,0 +1,696 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "dthdr.h"
+
+/* Ordered set/multiset
+** dt: dictionary being searched
+** obj: the object to look for.
+** type: search type.
+**
+** Written by Kiem-Phong Vo (5/25/96)
+*/
+
+typedef struct _dttree_s
+{ Dtdata_t data;
+ Dtlink_t* root; /* tree root */
+} Dttree_t;
+
+#ifdef CDT_DEBUG
+int dttreeprint(Dt_t* dt, Dtlink_t* here, int lev, char* (*objprintf)(Void_t*) )
+{
+ int k, rv;
+ char *obj, *endb, buf[1024];
+ Dtdisc_t *disc = dt->disc;
+ Dttree_t *tree = (Dttree_t*)dt->data;
+
+ if(!here && !(here = tree->root) )
+ return -1;
+
+ endb = buf; /* indentation */
+ for(k = 0; k < lev; ++k)
+ { *endb++ = ' '; *endb++ = ' '; }
+
+ *endb++ = '(';
+ obj = (*objprintf)(_DTOBJ(disc, here));
+ k = strlen(obj); memcpy(endb, obj, k); endb += k;
+ *endb++ = ')';
+ *endb++ = ':';
+ *endb++ = ' ';
+
+ *endb++ = '<';
+ if(here->_left)
+ obj = (*objprintf)(_DTOBJ(disc,here->_left));
+ else obj = "NIL";
+ k = strlen(obj); memcpy(endb, obj, k); endb += k;
+ *endb++ = '>';
+ *endb++ = ' ';
+
+ *endb++ = '<';
+ if(here->_rght)
+ obj = (*objprintf)(_DTOBJ(disc,here->_rght));
+ else obj = "NIL";
+ k = strlen(obj); memcpy(endb, obj, k); endb += k;
+ *endb++ = '>';
+ *endb++ = '\n';
+ write(2, buf, endb-buf);
+
+ if(here->_left)
+ dttreeprint(dt, here->_left, lev+1, objprintf);
+ if(here->_rght)
+ dttreeprint(dt, here->_rght, lev+1, objprintf);
+
+ return 0;
+}
+#endif
+
+/* terminal object: DT_FIRST|DT_LAST */
+#if __STD_C
+Void_t* tfirstlast(Dt_t* dt, int type)
+#else
+Void_t* tfirstlast(dt, type)
+Dt_t* dt;
+int type;
+#endif
+{
+ Dtlink_t *t, *root;
+ Dtdisc_t *disc = dt->disc;
+ Dttree_t *tree = (Dttree_t*)dt->data;
+
+ if(!(root = tree->root) )
+ return NIL(Void_t*);
+
+ if(type&DT_LAST)
+ { while((t = root->_rght) )
+ LROTATE(root,t);
+ }
+ else /* type&DT_FIRST */
+ { while((t = root->_left) )
+ RROTATE(root,t);
+ }
+ tree->root = root;
+
+ return _DTOBJ(disc, root);
+}
+
+/* DT_CLEAR */
+#if __STD_C
+static Void_t* tclear(Dt_t* dt)
+#else
+static Void_t* tclear(dt)
+Dt_t* dt;
+#endif
+{
+ Dtlink_t *root, *t;
+ Dtdisc_t *disc = dt->disc;
+ Dttree_t *tree = (Dttree_t*)dt->data;
+
+ root = tree->root;
+ tree->root = NIL(Dtlink_t*);
+ tree->data.size = 0;
+
+ if(root && (disc->link < 0 || disc->freef) )
+ { do
+ { while((t = root->_left) )
+ RROTATE(root,t);
+ t = root->_rght;
+ _dtfree(dt, root, DT_DELETE);
+ } while((root = t) );
+ }
+
+ return NIL(Void_t*);
+}
+
+#if __STD_C
+static Void_t* tlist(Dt_t* dt, Dtlink_t* list, int type)
+#else
+static Void_t* tlist(dt, list, type)
+Dt_t* dt;
+Dtlink_t* list;
+int type;
+#endif
+{
+ Void_t *obj;
+ Dtlink_t *last, *r, *t;
+ Dttree_t *tree = (Dttree_t*)dt->data;
+ Dtdisc_t *disc = dt->disc;
+
+ if(type&(DT_FLATTEN|DT_EXTRACT) )
+ { if((list = tree->root) )
+ { while((t = list->_left) ) /* make smallest object root */
+ RROTATE(list, t);
+ for(r = (last = list)->_rght; r; r = (last = r)->_rght)
+ { while((t = r->_left) ) /* no left children */
+ RROTATE(r,t);
+ last->_rght = r;
+ }
+ }
+
+ if(type&DT_FLATTEN)
+ tree->root = list;
+ else
+ { tree->root = NIL(Dtlink_t*);
+ dt->data->size = 0;
+ }
+ }
+ else /* if(type&DT_RESTORE) */
+ { dt->data->size = 0;
+ for(r = list; r; r = t)
+ { t = r->_rght;
+ obj = _DTOBJ(disc,r);
+ if((*dt->meth->searchf)(dt, (Void_t*)r, DT_RELINK) == obj )
+ dt->data->size += 1;
+ }
+ }
+
+ return (Void_t*)list;
+}
+
+#if __STD_C /* compute tree depth and number of nodes */
+static ssize_t tsize(Dtlink_t* root, ssize_t lev, Dtstat_t* st)
+#else
+static ssize_t tsize(root, lev, st)
+Dtlink_t* root;
+ssize_t lev;
+Dtstat_t* st;
+#endif
+{
+ ssize_t size, z;
+
+ if(!root) /* nothing to do */
+ return 0;
+
+ if(lev >= DT_MAXRECURSE) /* avoid blowing the stack */
+ return -1;
+
+ if(st)
+ { st->mlev = lev > st->mlev ? lev : st->mlev;
+ if(lev < DT_MAXSIZE)
+ { st->msize = lev > st->msize ? lev : st->msize;
+ st->lsize[lev] += 1; /* count #objects per level */
+ }
+ }
+
+ size = 1;
+
+ if((z = tsize(root->_left, lev+1, st)) < 0)
+ return -1;
+ else size += z;
+
+ if((z = tsize(root->_rght, lev+1, st)) < 0)
+ return -1;
+ else size += z;
+
+ return size;
+}
+
+#if __STD_C
+static Void_t* tstat(Dt_t* dt, Dtstat_t* st)
+#else
+static Void_t* tstat(dt, st)
+Dt_t* dt;
+Dtstat_t* st;
+#endif
+{
+ ssize_t size;
+ Dttree_t *tree = (Dttree_t*)dt->data;
+
+ if(!st)
+ return (Void_t*)dt->data->size;
+ else
+ { memset(st, 0, sizeof(Dtstat_t));
+ size = tsize(tree->root, 0, st);
+ /**/DEBUG_ASSERT((dt->data->type&DT_SHARE) || size == dt->data->size);
+ st->meth = dt->meth->type;
+ st->size = size;
+ st->space = sizeof(Dttree_t) + (dt->disc->link >= 0 ? 0 : size*sizeof(Dthold_t));
+ return (Void_t*)size;
+ }
+}
+
+#if __STD_C /* make a list into a balanced tree */
+static Dtlink_t* tbalance(Dtlink_t* list, ssize_t size)
+#else
+static Dtlink_t* tbalance(list, size)
+Dtlink_t* list;
+ssize_t size;
+#endif
+{
+ ssize_t n;
+ Dtlink_t *l, *mid;
+
+ if(size <= 2)
+ return list;
+
+ for(l = list, n = size/2 - 1; n > 0; n -= 1)
+ l = l->_rght;
+
+ mid = l->_rght; l->_rght = NIL(Dtlink_t*);
+ mid->_left = tbalance(list, (n = size/2) );
+ mid->_rght = tbalance(mid->_rght, size - (n + 1));
+ return mid;
+}
+
+static void toptimize(Dt_t* dt)
+{
+ ssize_t size;
+ Dtlink_t *l, *list;
+ Dttree_t *tree = (Dttree_t*)dt->data;
+
+ if((list = (Dtlink_t*)tlist(dt, NIL(Void_t*), DT_FLATTEN)) )
+ { for(size = 0, l = list; l; l = l->_rght)
+ size += 1;
+ tree->root = tbalance(list, size);
+ }
+}
+
+static Dtlink_t* troot(Dt_t* dt, Dtlink_t* list, Dtlink_t* link, Void_t* obj, int type)
+{
+ Dtlink_t *root, *last, *t, *r, *l;
+ Void_t *key, *o, *k;
+ Dtdisc_t *disc = dt->disc;
+
+ key = _DTKEY(disc, obj); /* key of object */
+
+ if(type&(DT_ATMOST|DT_ATLEAST) ) /* find the left-most or right-most element */
+ { list->_left = link->_rght;
+ list->_rght = link->_left;
+ if(type&DT_ATMOST)
+ { while((l = list->_left) )
+ { while((r = l->_rght) ) /* get the max elt of left subtree */
+ LROTATE(l,r);
+ list->_left = l;
+
+ o = _DTOBJ(disc,l); k = _DTKEY(disc,o);
+ if(_DTCMP(dt, key, k, disc) != 0 )
+ break;
+ else RROTATE(list,l);
+ }
+ }
+ else
+ { while((r = list->_rght) )
+ { while((l = r->_left) ) /* get the min elt of right subtree */
+ RROTATE(r,l);
+ list->_rght = r;
+
+ o = _DTOBJ(disc,r); k = _DTKEY(disc,o);
+ if(_DTCMP(dt, key, k, disc) != 0 )
+ break;
+ else LROTATE(list,r);
+ }
+ }
+ link->_rght = list->_left;
+ link->_left = list->_rght;
+ return list;
+ }
+
+ last = list; list->_left = list->_rght = NIL(Dtlink_t*);
+ root = NIL(Dtlink_t*);
+
+ while(!root && (t = link->_rght) ) /* link->_rght is the left subtree <= obj */
+ { while((r = t->_rght) ) /* make t the maximum element */
+ LROTATE(t,r);
+
+ o = _DTOBJ(disc,t); k = _DTKEY(disc,o);
+ if(_DTCMP(dt, key, k, disc) != 0 )
+ { link->_rght = t; /* no more of this group in subtree */
+ break;
+ }
+ else if((type & (DT_REMOVE|DT_NEXT|DT_PREV)) && o == obj)
+ { link->_rght = t->_left; /* found the exact object */
+ root = t;
+ }
+ else /* add t to equal list in an order-preserving manner */
+ { link->_rght = t->_left;
+ t->_left = t->_rght = NIL(Dtlink_t*);
+ if(type&DT_NEXT )
+ { last->_left = t; last = t; }
+ else { t->_rght = list; list = t; }
+ }
+ }
+
+ while(!root && (t = link->_left) ) /* link->_left is the right subtree >= obj */
+ { while((l = t->_left) ) /* make t the minimum element */
+ RROTATE(t,l);
+
+ o = _DTOBJ(disc,t); k = _DTKEY(disc,o);
+ if(_DTCMP(dt, key, k, disc) != 0 )
+ { link->_left = t; /* no more of this group in subtree */
+ break;
+ }
+ else if((type & (DT_REMOVE|DT_NEXT|DT_PREV)) && o == obj)
+ { link->_left = t->_rght; /* found the exact object */
+ root = t;
+ }
+ else /* add t to equal list in an order-preserving manner */
+ { link->_left = t->_rght;
+ t->_left = t->_rght = NIL(Dtlink_t*);
+ if(type&DT_NEXT )
+ { t->_left = list; list = t; }
+ else { last->_rght = t; last = t; }
+ }
+ }
+
+ if(!root) /* always set a non-trivial root */
+ { root = list;
+ if(type&DT_NEXT)
+ list = list->_left;
+ else list = list->_rght;
+ }
+
+ if(list) /* add the rest of the equal-list to the proper subtree */
+ { if(type&DT_NEXT)
+ { last->_left = link->_rght;
+ link->_rght = list;
+ }
+ else
+ { last->_rght = link->_left;
+ link->_left = list;
+ }
+ }
+
+ return root;
+}
+
+#if __STD_C
+static Void_t* dttree(Dt_t* dt, Void_t* obj, int type)
+#else
+static Void_t* dttree(dt,obj,type)
+Dt_t* dt;
+Void_t* obj;
+int type;
+#endif
+{
+ int cmp;
+ Void_t *o, *k, *key;
+ Dtlink_t *root, *t, *l, *r, *me, link;
+ Dtdisc_t *disc = dt->disc;
+ Dttree_t *tree = (Dttree_t*)dt->data;
+
+ type = DTTYPE(dt, type); /* map type for upward compatibility */
+ if(!(type&DT_OPERATIONS) )
+ return NIL(Void_t*);
+
+ DTSETLOCK(dt);
+
+ if(type&(DT_FIRST|DT_LAST) )
+ DTRETURN(obj, tfirstlast(dt, type));
+ else if(type&(DT_EXTRACT|DT_RESTORE|DT_FLATTEN))
+ DTRETURN(obj, tlist(dt, (Dtlink_t*)obj, type));
+ else if(type&DT_CLEAR)
+ DTRETURN(obj, tclear(dt));
+ else if(type&DT_STAT)
+ { toptimize(dt); /* balance tree to avoid deep recursion */
+ DTRETURN(obj, tstat(dt, (Dtstat_t*)obj));
+ }
+
+ if(!obj) /* from here on, an object prototype is required */
+ DTRETURN(obj, NIL(Void_t*));
+
+ if(type&DT_RELINK) /* relinking objects after some processing */
+ { me = (Dtlink_t*)obj;
+ obj = _DTOBJ(disc,me);
+ key = _DTKEY(disc,obj);
+ }
+ else
+ { me = NIL(Dtlink_t*);
+ if(type&DT_MATCH) /* no prototype object given, just the key */
+ { key = obj;
+ obj = NIL(Void_t*);
+ }
+ else key = _DTKEY(disc,obj); /* get key from prototype object */
+ }
+
+ memset(&link, 0, sizeof(link));
+ l = r = &link; /* link._rght(_left) will be LEFT(RIGHT) tree after splaying */
+ if((root = tree->root) && _DTOBJ(disc,root) != obj) /* splay-search for a matching object */
+ { while(1)
+ { o = _DTOBJ(disc,root); k = _DTKEY(disc,o);
+ if((cmp = _DTCMP(dt,key,k,disc)) == 0)
+ break;
+ else if(cmp < 0)
+ { if((t = root->_left) )
+ { o = _DTOBJ(disc,t); k = _DTKEY(disc,o);
+ if((cmp = _DTCMP(dt,key,k,disc)) < 0)
+ { rrotate(root,t);
+ rlink(r,t);
+ if(!(root = t->_left) )
+ break;
+ }
+ else if(cmp == 0)
+ { rlink(r,root);
+ root = t;
+ break;
+ }
+ else /* if(cmp > 0) */
+ { llink(l,t);
+ rlink(r,root);
+ if(!(root = t->_rght) )
+ break;
+ }
+ }
+ else
+ { rlink(r,root);
+ root = NIL(Dtlink_t*);
+ break;
+ }
+ }
+ else /* if(cmp > 0) */
+ { if((t = root->_rght) )
+ { o = _DTOBJ(disc,t); k = _DTKEY(disc,o);
+ if((cmp = _DTCMP(dt,key,k,disc)) > 0)
+ { lrotate(root,t);
+ llink(l,t);
+ if(!(root = t->_rght) )
+ break;
+ }
+ else if(cmp == 0)
+ { llink(l,root);
+ root = t;
+ break;
+ }
+ else /* if(cmp < 0) */
+ { rlink(r,t);
+ llink(l,root);
+ if(!(root = t->_left) )
+ break;
+ }
+ }
+ else
+ { llink(l,root);
+ root = NIL(Dtlink_t*);
+ break;
+ }
+ }
+ }
+ }
+ l->_rght = root ? root->_left : NIL(Dtlink_t*);
+ r->_left = root ? root->_rght : NIL(Dtlink_t*);
+
+ if(root)
+ { if(dt->meth->type&DT_OBAG ) /* may need to reset root to the right object */
+ { if((type&(DT_ATLEAST|DT_ATMOST)) ||
+ ((type&(DT_NEXT|DT_PREV|DT_REMOVE)) && _DTOBJ(disc,root) != obj) )
+ root = troot(dt, root, &link, obj, type);
+ }
+
+ if(type&(DT_SEARCH|DT_MATCH|DT_ATMOST|DT_ATLEAST))
+ { has_root: /* reconstitute the tree */
+ root->_left = link._rght;
+ root->_rght = link._left;
+ tree->root = root;
+ DTRETURN(obj, _DTOBJ(disc,root));
+ }
+ else if(type&DT_NEXT)
+ { root->_left = link._rght;
+ root->_rght = NIL(Dtlink_t*);
+ link._rght = root;
+ dt_next:
+ if((root = link._left) )
+ { while((t = root->_left) )
+ RROTATE(root,t);
+ link._left = root->_rght;
+ goto has_root;
+ }
+ else goto no_root;
+ }
+ else if(type&DT_PREV)
+ { root->_rght = link._left;
+ root->_left = NIL(Dtlink_t*);
+ link._left = root;
+ dt_prev:
+ if((root = link._rght) )
+ { while((t = root->_rght) )
+ LROTATE(root,t);
+ link._rght = root->_left;
+ goto has_root;
+ }
+ else goto no_root;
+ }
+ else if(type&DT_REMOVE) /* remove a particular element in the tree */
+ { if(_DTOBJ(disc,root) == obj)
+ goto dt_delete;
+ else
+ { root->_left = link._rght;
+ root->_rght = link._left;
+ tree->root = root;
+ DTRETURN(obj, NIL(Void_t*));
+ }
+ }
+ else if(type&(DT_DELETE|DT_DETACH))
+ { dt_delete: /* remove an object from the dictionary */
+ obj = _DTOBJ(disc,root);
+ _dtfree(dt, root, type);
+ dt->data->size -= 1;
+ goto no_root;
+ }
+ else if(type&(DT_INSERT|DT_APPEND|DT_ATTACH))
+ { if(dt->meth->type&DT_OSET)
+ { type |= DT_SEARCH; /* for announcement */
+ goto has_root;
+ }
+ else
+ { root->_left = NIL(Dtlink_t*);
+ root->_rght = link._left;
+ link._left = root;
+ goto dt_insert;
+ }
+ }
+ else if(type&DT_RELINK) /* a duplicate */
+ { if(dt->meth->type&DT_OSET)
+ _dtfree(dt, me, DT_DELETE);
+ else
+ { me->_left = NIL(Dtlink_t*);
+ me->_rght = link._left;
+ link._left = me;
+ }
+ goto has_root;
+ }
+ }
+ else /* no matching object, tree has been split to LEFT&RIGHT subtrees */
+ { if(type&(DT_SEARCH|DT_MATCH))
+ { no_root:
+ if(!(l = link._rght) ) /* no LEFT subtree */
+ tree->root = link._left; /* tree is RIGHT tree */
+ else
+ { while((t = l->_rght) ) /* maximize root of LEFT tree */
+ { if(t->_rght)
+ LLSHIFT(l,t);
+ else LROTATE(l,t);
+ }
+ l->_rght = link._left; /* hook RIGHT tree to LEFT root */
+ tree->root = l; /* LEFT tree is now the entire tree */
+ }
+
+ if(type&(DT_DELETE|DT_DETACH|DT_REMOVE))
+ DTRETURN(obj, obj);
+ else DTRETURN(obj, NIL(Void_t*));
+ }
+ else if(type&(DT_NEXT|DT_ATLEAST) )
+ goto dt_next;
+ else if(type&(DT_PREV|DT_ATMOST) )
+ goto dt_prev;
+ else if(type&(DT_DELETE|DT_DETACH|DT_REMOVE))
+ { obj = NIL(Void_t*);
+ goto no_root;
+ }
+ else if(type&(DT_INSERT|DT_APPEND|DT_ATTACH))
+ { dt_insert:
+ if(!(root = _dtmake(dt, obj, type)) )
+ { obj = NIL(Void_t*);
+ goto no_root;
+ }
+ else
+ { dt->data->size += 1;
+ goto has_root;
+ }
+ }
+ else if(type&DT_RELINK)
+ { root = me;
+ goto has_root;
+ }
+ }
+ DTRETURN(obj, NIL(Void_t*));
+
+dt_return:
+ DTANNOUNCE(dt,obj,type);
+ DTCLRLOCK(dt);
+ return obj;
+}
+
+static int treeevent(Dt_t* dt, int event, Void_t* arg)
+{
+ Dtlink_t *l, *list;
+ ssize_t size;
+ Dttree_t *tree = (Dttree_t*)dt->data;
+
+ if(event == DT_OPEN)
+ { if(tree) /* already initialized */
+ return 0;
+ if(!(tree = (Dttree_t*)(*dt->memoryf)(dt, 0, sizeof(Dttree_t), dt->disc)) )
+ { DTERROR(dt, "Error in allocating a tree data structure");
+ return -1;
+ }
+ memset(tree, 0, sizeof(Dttree_t));
+ dt->data = (Dtdata_t*)tree;
+ return 1;
+ }
+ else if(event == DT_CLOSE)
+ { if(!tree)
+ return 0;
+ if(tree->root)
+ (void)tclear(dt);
+ (void)(*dt->memoryf)(dt, (Void_t*)tree, 0, dt->disc);
+ dt->data = NIL(Dtdata_t*);
+ return 0;
+ }
+ else if(event == DT_OPTIMIZE) /* balance the search tree */
+ { toptimize(dt);
+ return 0;
+ }
+ else return 0;
+}
+
+#if _UWIN
+
+Void_t* dtfinger(Dt_t* dt)
+{
+ return (dt && dt->meth && (dt->meth->type & DT_ORDERED)) ? (Void_t*)((Dttree_t*)dt->data)->root : NIL(Void_t*);
+}
+
+#endif
+
+/* make this method available */
+static Dtmethod_t _Dtoset = { dttree, DT_OSET, treeevent, "Dtoset" };
+static Dtmethod_t _Dtobag = { dttree, DT_OBAG, treeevent, "Dtobag" };
+__DEFINE__(Dtmethod_t*,Dtoset,&_Dtoset);
+__DEFINE__(Dtmethod_t*,Dtobag,&_Dtobag);
+
+/* backwards compatibility */
+#undef Dttree
+#if defined(__EXPORT__)
+__EXPORT__
+#endif
+__DEFINE__(Dtmethod_t*,Dttree,&_Dtoset);
+
+#ifdef NoF
+NoF(dttree)
+#endif
diff --git a/src/lib/libast/cdt/dtview.c b/src/lib/libast/cdt/dtview.c
new file mode 100644
index 0000000..94f4a54
--- /dev/null
+++ b/src/lib/libast/cdt/dtview.c
@@ -0,0 +1,157 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "dthdr.h"
+
+/* Set a view path from dict to view.
+**
+** Written by Kiem-Phong Vo (5/25/96)
+*/
+
+/* these operations must be done without viewpathing */
+#define DT_NOVIEWPATH (DT_INSERT|DT_APPEND|DT_DELETE|\
+ DT_ATTACH|DT_DETACH|DT_RELINK|DT_CLEAR| \
+ DT_FLATTEN|DT_EXTRACT|DT_RESTORE|DT_STAT)
+
+#if __STD_C
+static Void_t* dtvsearch(Dt_t* dt, reg Void_t* obj, reg int type)
+#else
+static Void_t* dtvsearch(dt,obj,type)
+Dt_t* dt;
+reg Void_t* obj;
+reg int type;
+#endif
+{
+ int cmp;
+ Dt_t *d, *p;
+ Void_t *o, *n, *oky, *nky;
+
+ if(type&DT_NOVIEWPATH)
+ return (*(dt->meth->searchf))(dt,obj,type);
+
+ o = NIL(Void_t*);
+
+ /* these ops look for the first appearance of an object of the right type */
+ if((type & (DT_MATCH|DT_SEARCH)) ||
+ ((type & (DT_FIRST|DT_LAST|DT_ATLEAST|DT_ATMOST)) && !(dt->meth->type&DT_ORDERED) ) )
+ { for(d = dt; d; d = d->view)
+ if((o = (*(d->meth->searchf))(d,obj,type)) )
+ break;
+ dt->walk = d;
+ return o;
+ }
+
+ if(dt->meth->type & DT_ORDERED) /* ordered sets/bags */
+ { if(!(type & (DT_FIRST|DT_LAST|DT_NEXT|DT_PREV|DT_ATLEAST|DT_ATMOST)) )
+ return NIL(Void_t*);
+
+ /* find the min/max element that satisfies the op requirement */
+ n = nky = NIL(Void_t*); p = NIL(Dt_t*);
+ for(d = dt; d; d = d->view)
+ { if(!(o = (*d->meth->searchf)(d, obj, type)) )
+ continue;
+ oky = _DTKEY(d->disc,o);
+
+ if(n) /* get the right one among all dictionaries */
+ { cmp = _DTCMP(d,oky,nky,d->disc);
+ if(((type & (DT_NEXT|DT_FIRST|DT_ATLEAST)) && cmp < 0) ||
+ ((type & (DT_PREV|DT_LAST|DT_ATMOST)) && cmp > 0) )
+ goto b_est;
+ }
+ else
+ { b_est: /* current best element to fit op requirement */
+ p = d;
+ n = o;
+ nky = oky;
+ }
+ }
+
+ dt->walk = p;
+ return n;
+ }
+
+ /* unordered collections */
+ if(!(type&(DT_NEXT|DT_PREV)) )
+ return NIL(Void_t*);
+
+ if(!dt->walk )
+ { for(d = dt; d; d = d->view)
+ if((o = (*(d->meth->searchf))(d, obj, DT_SEARCH)) )
+ break;
+ dt->walk = d;
+ if(!(obj = o) )
+ return NIL(Void_t*);
+ }
+
+ for(d = dt->walk, obj = (*d->meth->searchf)(d, obj, type);; )
+ { while(obj) /* keep moving until finding an uncovered object */
+ { for(p = dt; ; p = p->view)
+ { if(p == d) /* adjacent object is uncovered */
+ return obj;
+ if((*(p->meth->searchf))(p, obj, DT_SEARCH) )
+ break;
+ }
+ obj = (*d->meth->searchf)(d, obj, type);
+ }
+
+ if(!(d = dt->walk = d->view) ) /* move on to next dictionary */
+ return NIL(Void_t*);
+ else if(type&DT_NEXT)
+ obj = (*(d->meth->searchf))(d,NIL(Void_t*),DT_FIRST);
+ else obj = (*(d->meth->searchf))(d,NIL(Void_t*),DT_LAST);
+ }
+}
+
+#if __STD_C
+Dt_t* dtview(reg Dt_t* dt, reg Dt_t* view)
+#else
+Dt_t* dtview(dt,view)
+reg Dt_t* dt;
+reg Dt_t* view;
+#endif
+{
+ reg Dt_t* d;
+
+ if(view && view->meth != dt->meth) /* must use the same method */
+ return NIL(Dt_t*);
+
+ /* make sure there won't be a cycle */
+ for(d = view; d; d = d->view)
+ if(d == dt)
+ return NIL(Dt_t*);
+
+ /* no more viewing lower dictionary */
+ if((d = dt->view) )
+ d->nview -= 1;
+ dt->view = dt->walk = NIL(Dt_t*);
+
+ if(!view)
+ { dt->searchf = dt->meth->searchf;
+ return d;
+ }
+
+ /* ok */
+ dt->view = view;
+ dt->searchf = dtvsearch;
+ view->nview += 1;
+
+ return view;
+}
diff --git a/src/lib/libast/cdt/dtwalk.c b/src/lib/libast/cdt/dtwalk.c
new file mode 100644
index 0000000..05c706c
--- /dev/null
+++ b/src/lib/libast/cdt/dtwalk.c
@@ -0,0 +1,53 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "dthdr.h"
+
+/* Walk a dictionary and all dictionaries viewed through it.
+** userf: user function
+**
+** Written by Kiem-Phong Vo (5/25/96)
+*/
+
+#if __STD_C
+int dtwalk(Dt_t* dt, int (*userf)(Dt_t*, Void_t*, Void_t*), Void_t* data)
+#else
+int dtwalk(dt,userf,data)
+Dt_t* dt;
+int(* userf)();
+Void_t* data;
+#endif
+{
+ Void_t *obj, *next;
+ Dt_t *walk;
+ int rv;
+
+ for(obj = dtfirst(dt); obj; )
+ { if(!(walk = dt->walk) )
+ walk = dt;
+ next = dtnext(dt,obj);
+ if((rv = (*userf)(walk, obj, data )) < 0)
+ return rv;
+ obj = next;
+ }
+
+ return 0;
+}
diff --git a/src/lib/libast/comp/atexit.c b/src/lib/libast/comp/atexit.c
new file mode 100644
index 0000000..d0df2d5
--- /dev/null
+++ b/src/lib/libast/comp/atexit.c
@@ -0,0 +1,115 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * ANSI C atexit()
+ * arrange for func to be called LIFO on exit()
+ */
+
+#include <ast.h>
+
+#if _lib_atexit
+
+NoN(atexit)
+
+#else
+
+#if _lib_onexit || _lib_on_exit
+
+#if !_lib_onexit
+#define onexit on_exit
+#endif
+
+extern int onexit(void(*)(void));
+
+int
+atexit(void (*func)(void))
+{
+ return(onexit(func));
+}
+
+#else
+
+struct list
+{
+ struct list* next;
+ void (*func)(void);
+};
+
+static struct list* funclist;
+
+extern void _exit(int);
+
+int
+atexit(void (*func)(void))
+{
+ register struct list* p;
+
+ if (!(p = newof(0, struct list, 1, 0))) return(-1);
+ p->func = func;
+ p->next = funclist;
+ funclist = p;
+ return(0);
+}
+
+void
+_ast_atexit(void)
+{
+ register struct list* p;
+
+ while (p = funclist)
+ {
+ funclist = p->next;
+ (*p->func)();
+ }
+}
+
+#if _std_cleanup
+
+#if _lib__cleanup
+extern void _cleanup(void);
+#endif
+
+void
+exit(int code)
+{
+ _ast_atexit();
+#if _lib__cleanup
+ _cleanup();
+#endif
+ _exit(code);
+}
+
+#else
+
+void
+_cleanup(void)
+{
+ _ast_atexit();
+}
+
+#endif
+
+#endif
+
+#endif
diff --git a/src/lib/libast/comp/basename.c b/src/lib/libast/comp/basename.c
new file mode 100644
index 0000000..912f8d6
--- /dev/null
+++ b/src/lib/libast/comp/basename.c
@@ -0,0 +1,55 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * basename(3) implementation
+ */
+
+#include <ast_std.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char *basename(register char *pathname)
+{
+ register char *first, *last;
+ for(first=last=pathname; *last; last++);
+ /* back over trailing '/' */
+ if(last>first)
+ while(*--last=='/' && last > first);
+ if(last==first && *last=='/')
+ {
+ /* all '/' or "" */
+ if(*first=='/')
+ if(*++last=='/') /* keep leading // */
+ last++;
+ }
+ else
+ {
+ for(first=last++;first>pathname && *first!='/';first--);
+ if(*first=='/')
+ first++;
+ }
+ *last = 0;
+ return(first);
+}
diff --git a/src/lib/libast/comp/catopen.c b/src/lib/libast/comp/catopen.c
new file mode 100644
index 0000000..7bace39
--- /dev/null
+++ b/src/lib/libast/comp/catopen.c
@@ -0,0 +1,182 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * catopen intercept
+ * the ast catalogs are checked first
+ * the ast mc* and native cat* routines do all the work
+ * catalogs found by mcfind() are converted from utf to ucs
+ *
+ * nl_catd is cast to void*
+ * this is either an Mc_t* (Mc_t.set != 0)
+ * or a Cc_t* where Cc_t.cat is the native nl_catd
+ */
+
+#include <ast.h>
+#include <mc.h>
+#include <nl_types.h>
+#include <iconv.h>
+
+#ifndef DEBUG_trace
+#define DEBUG_trace 0
+#endif
+#if DEBUG_trace
+#undef setlocale
+#endif
+
+#if _lib_catopen
+
+#undef nl_catd
+#undef catopen
+#undef catgets
+#undef catclose
+
+typedef struct
+{
+ Mcset_t* set;
+ nl_catd cat;
+ iconv_t cvt;
+ Sfio_t* tmp;
+} Cc_t;
+
+#else
+
+#define _ast_nl_catd nl_catd
+#define _ast_catopen catopen
+#define _ast_catgets catgets
+#define _ast_catclose catclose
+
+#endif
+
+_ast_nl_catd
+_ast_catopen(const char* name, int flag)
+{
+ Mc_t* mc;
+ char* s;
+ Sfio_t* ip;
+ char path[PATH_MAX];
+
+ /*
+ * first try the ast catalogs
+ */
+
+#if DEBUG_trace
+sfprintf(sfstderr, "AHA#%d:%s %s LC_MESSAGES=%s:%s\n", __LINE__, __FILE__, name, _ast_setlocale(LC_MESSAGES, 0), setlocale(LC_MESSAGES, 0));
+#endif
+ if ((s = mcfind(NiL, name, LC_MESSAGES, flag, path, sizeof(path))) && (ip = sfopen(NiL, s, "r")))
+ {
+#if DEBUG_trace
+sfprintf(sfstderr, "AHA#%d:%s %s\n", __LINE__, __FILE__, s);
+#endif
+ mc = mcopen(ip);
+ sfclose(ip);
+ if (mc)
+ return (_ast_nl_catd)mc;
+ }
+#if _lib_catopen
+ if (strcmp(setlocale(LC_MESSAGES, NiL), "debug"))
+ {
+ Cc_t* cc;
+ nl_catd d;
+
+ /*
+ * now the native catalogs
+ */
+
+ if (s && (d = catopen(s, flag)) != (nl_catd)(-1) || !(s = 0) && (d = catopen(name, flag)) != (nl_catd)(-1))
+ {
+ if (!(cc = newof(0, Cc_t, 1, 0)))
+ {
+ catclose(d);
+ return (_ast_nl_catd)(-1);
+ }
+ cc->cat = d;
+ if ((s || *name == '/') && (ast.locale.set & (1<<AST_LC_MESSAGES)))
+ {
+ if ((cc->cvt = iconv_open("", "utf")) == (iconv_t)(-1) || !(cc->tmp = sfstropen()))
+ {
+ catclose(d);
+ free(cc);
+ return (_ast_nl_catd)(-1);
+ }
+ }
+ else
+ cc->cvt = (iconv_t)(-1);
+#if DEBUG_trace
+sfprintf(sfstderr, "AHA#%d:%s %s %s native %p\n", __LINE__, __FILE__, s, name, cc->cat);
+#endif
+ return (_ast_nl_catd)cc;
+ }
+ }
+#endif
+
+ /*
+ * loser
+ */
+
+ return (_ast_nl_catd)(-1);
+}
+
+char*
+_ast_catgets(_ast_nl_catd cat, int set, int num, const char* msg)
+{
+ if (cat == (_ast_nl_catd)(-1))
+ return (char*)msg;
+#if _lib_catopen
+ if (!((Cc_t*)cat)->set)
+ {
+ char* s;
+ size_t n;
+
+ msg = (char*)catgets(((Cc_t*)cat)->cat, set, num, msg);
+ if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
+ {
+ s = (char*)msg;
+ n = strlen(s);
+ iconv_write(((Cc_t*)cat)->cvt, ((Cc_t*)cat)->tmp, &s, &n, NiL);
+ if (s = sfstruse(((Cc_t*)cat)->tmp))
+ return s;
+ }
+ return (char*)msg;
+ }
+#endif
+ return mcget((Mc_t*)cat, set, num, msg);
+}
+
+int
+_ast_catclose(_ast_nl_catd cat)
+{
+ if (cat == (_ast_nl_catd)(-1))
+ return -1;
+#if _lib_catopen
+ if (!((Cc_t*)cat)->set)
+ {
+ if (((Cc_t*)cat)->cvt != (iconv_t)(-1))
+ iconv_close(((Cc_t*)cat)->cvt);
+ if (((Cc_t*)cat)->tmp)
+ sfclose(((Cc_t*)cat)->tmp);
+ return catclose(((Cc_t*)cat)->cat);
+ }
+#endif
+ return mcclose((Mc_t*)cat);
+}
diff --git a/src/lib/libast/comp/closelog.c b/src/lib/libast/comp/closelog.c
new file mode 100644
index 0000000..b8c848a
--- /dev/null
+++ b/src/lib/libast/comp/closelog.c
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * closelog implementation
+ */
+
+#include <ast.h>
+
+#if _lib_syslog
+
+NoN(closelog)
+
+#else
+
+#include "sysloglib.h"
+
+void
+closelog(void)
+{
+ if (log.fd >= 0)
+ {
+ close(log.fd);
+ log.fd = -1;
+ }
+ log.facility = 0;
+ log.flags = 0;
+ log.mask = ~0;
+ log.attempt = 0;
+}
+
+#endif
diff --git a/src/lib/libast/comp/conf.sh b/src/lib/libast/comp/conf.sh
new file mode 100644
index 0000000..aaf3f3a
--- /dev/null
+++ b/src/lib/libast/comp/conf.sh
@@ -0,0 +1,1635 @@
+########################################################################
+# #
+# This software is part of the ast package #
+# Copyright (c) 1985-2011 AT&T Intellectual Property #
+# and is licensed under the #
+# Eclipse Public License, Version 1.0 #
+# by AT&T Intellectual Property #
+# #
+# A copy of the License is available at #
+# http://www.eclipse.org/org/documents/epl-v10.html #
+# (with md5 checksum b35adb5213ca9657e911e9befb180842) #
+# #
+# Information and Software Systems Research #
+# AT&T Research #
+# Florham Park NJ #
+# #
+# Glenn Fowler <gsf@research.att.com> #
+# David Korn <dgk@research.att.com> #
+# Phong Vo <kpv@research.att.com> #
+# #
+########################################################################
+: generate getconf and limits info
+#
+# @(#)conf.sh (AT&T Research) 2011-08-26
+#
+# this script generates these files from the table file in the first arg
+# the remaining args are the C compiler name and flags
+#
+# conflim.h supplemental limits.h definitions
+# conftab.h readonly string table definitions
+# conftab.c readonly string table data
+#
+# you may think it should be simpler
+# but you shall be confused anyway
+#
+
+case $-:$BASH_VERSION in
+*x*:[0123456789]*) : bash set -x is broken :; set +ex ;;
+esac
+
+LC_ALL=C
+export LC_ALL
+
+command=conf
+
+shell=`eval 'x=123&&integer n=\${#x}\${x#1?}&&((n==330/(10)))&&echo ksh' 2>/dev/null`
+
+append=0
+debug=
+extra=0
+keep_call='*'
+keep_name='*'
+trace=
+verbose=0
+while :
+do case $1 in
+ -a) append=1 ;;
+ -c*) keep_call=${1#-?} ;;
+ -d*) debug=$1 ;;
+ -l) extra=1 ;;
+ -n*) keep_name=${1#-?} ;;
+ -t) trace=1 ;;
+ -v) verbose=1 ;;
+ -*) echo "Usage: $command [-a] [-ccall-pattern] [-dN] [-l] [-nname_pattern] [-t] [-v] conf.tab" >&2; exit 2 ;;
+ *) break ;;
+ esac
+ shift
+done
+head='#include "FEATURE/standards"
+#include "FEATURE/common"'
+tail='#include "FEATURE/param"'
+generated="/* : : generated by $command from $1 : : */"
+hdr=
+ifs=${IFS-'
+ '}
+nl='
+'
+sp=' '
+ob='{'
+cb='}'
+sym=[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]*
+tmp=conf.tmp
+case $verbose:$debug$trace in
+1:?*) echo "$command: debug=$debug trace=$trace keep_call=$keep_call keep_name=$keep_name" >&2 ;;
+esac
+case $trace in
+1) PS4='+$LINENO+ '; set -x ;;
+esac
+
+case $# in
+0) case $extra in
+ 0) echo "$command: table argument expected" >&2
+ exit 1
+ ;;
+ esac
+ tab=/dev/null
+ ;;
+*) tab=$1
+ shift
+ if test ! -f $tab
+ then echo "$command: $tab: cannot read" >&2
+ exit 1
+ fi
+ ;;
+esac
+case $# in
+0) cc=cc ;;
+*) cc=$* ;;
+esac
+
+rm -f $tmp.*
+case $debug in
+'') trap "code=\$?; rm -f $tmp.*; exit \$code" 0 1 2 ;;
+esac
+
+# determine the intmax_t printf format
+
+cat > $tmp.c <<!
+${head}
+int
+main()
+{
+#if _ast_intmax_long
+ return 1;
+#else
+ return 0;
+#endif
+}
+!
+if $cc -o $tmp.exe $tmp.c >/dev/null 2>&1 && ./$tmp.exe
+then LL_format='ll'
+else LL_format='l'
+fi
+
+# determine the intmax_t constant suffix
+
+cat > $tmp.c <<!
+${head}
+int
+main()
+{
+#if _ast_intmax_long
+ return 1;
+#else
+ _ast_intmax_t s = 0x7fffffffffffffffLL;
+ unsigned _ast_intmax_t u = 0xffffffffffffffffLL;
+
+ return 0;
+#endif
+}
+!
+if $cc -o $tmp.exe $tmp.c >/dev/null 2>&1
+then if ./$tmp.exe
+ then LL_suffix='LL'
+ else LL_suffix='L'
+ fi
+else LL_suffix=''
+fi
+
+cat > $tmp.c <<!
+${head}
+int
+main()
+{
+ unsigned int u = 1U;
+ unsigned int ul = 1UL;
+
+ return 0;
+}
+!
+if $cc -o $tmp.exe $tmp.c >/dev/null 2>&1
+then U_suffix='U'
+else U_suffix=''
+fi
+
+# set up the names and keys
+
+keys=
+standards=
+
+case $append$extra in
+00) case $verbose in
+ 1) echo "$command: read $tab" >&2 ;;
+ esac
+ exec < $tab
+ while :
+ do IFS=""
+ read line
+ eof=$?
+ IFS=$ifs
+ case $eof in
+ 0) ;;
+ *) break ;;
+ esac
+ case $line in
+ ""|\#*) ;;
+ *) set x $line
+ shift; name=$1
+ shift; standard=$1
+ shift; call=$1
+ shift; section=$1
+ shift; flags=$1
+ alternates=
+ define=
+ values=
+ script=
+ headers=
+ while :
+ do shift
+ case $# in
+ 0) break ;;
+ esac
+ case $1 in
+ ":") shift
+ eval script='$'script_$1
+ break
+ ;;
+ *"{") case $1 in
+ "sh{") script="# $name" ;;
+ *) script= ;;
+ esac
+ shift
+ args="$*"
+ IFS=""
+ while read line
+ do case $line in
+ "}") break ;;
+ esac
+ script=$script$nl$line
+ done
+ IFS=$ifs
+ break
+ ;;
+ *.h) case $shell in
+ ksh) f=${1%.h} ;;
+ *) f=`echo $1 | sed 's,\.h$,,'` ;;
+ esac
+ case " $hdr " in
+ *" $f "*)
+ headers=$headers$nl#include$sp'<'$1'>'
+ ;;
+ *" -$f- "*)
+ ;;
+ *) if iffe -n - hdr $f | grep _hdr_$f >/dev/null
+ then hdr="$hdr $f"
+ headers=$headers$nl#include$sp'<'$1'>'
+ else hdr="$hdr -$f-"
+ fi
+ ;;
+ esac
+ ;;
+ *) values=$values$sp$1
+ case $1 in
+ $sym) echo "$1" >> $tmp.v ;;
+ esac
+ ;;
+ esac
+ done
+ case " $standards " in
+ *" $standard "*)
+ ;;
+ *) standards="$standards $standard"
+ ;;
+ esac
+ case $name:$flags in
+ *:*S*) ;;
+ VERSION)flags="${flags}S" ;;
+ esac
+ case $name in
+ *VERSION*)key=${standard}${section} ;;
+ *) key= ;;
+ esac
+ case $key in
+ ''|*_) key=${key}${name} ;;
+ *) key=${key}_${name} ;;
+ esac
+ eval sys='$'CONF_call_${key}
+ case $sys in
+ ?*) call=$sys ;;
+ esac
+ case $call in
+ SI) sys=CS ;;
+ *) sys=$call ;;
+ esac
+ key=${sys}_${key}
+ keys="$keys$nl$key"
+ eval CONF_name_${key}='$'name
+ eval CONF_standard_${key}='$'standard
+ eval CONF_call_${key}='$'call
+ eval CONF_section_${key}='$'section
+ eval CONF_flags_${key}='$'flags
+ eval CONF_define_${key}='$'define
+ eval CONF_values_${key}='$'values
+ eval CONF_script_${key}='$'script
+ eval CONF_args_${key}='$'args
+ eval CONF_headers_${key}='$'headers
+ eval CONF_keys_${name}=\"'$'CONF_keys_${name} '$'key\"
+ ;;
+ esac
+ done
+ ;;
+esac
+case $debug in
+-d1) for key in $keys
+ do eval name=\"'$'CONF_name_$key\"
+ case $name in
+ ?*) eval standard=\"'$'CONF_standard_$key\"
+ eval call=\"'$'CONF_call_$key\"
+ eval section=\"'$'CONF_section_$key\"
+ eval flags=\"'$'CONF_flags_$key\"
+ eval define=\"'$'CONF_define_$key\"
+ eval values=\"'$'CONF_values_$key\"
+ eval script=\"'$'CONF_script_$key\"
+ eval args=\"'$'CONF_args_$key\"
+ eval headers=\"'$'CONF_headers_$key\"
+ printf "%29s %35s %8s %2s %1d %5s %s$nl" "$name" "$key" "$standard" "$call" "$section" "$flags" "$define${values:+$sp=$values}${headers:+$sp$headers$nl}${script:+$sp$ob$script$nl$cb}"
+ ;;
+ esac
+ done
+ exit
+ ;;
+esac
+
+systeminfo='
+#if !defined(SYS_NMLEN)
+#define SYS_NMLEN 9
+#endif
+#include <sys/systeminfo.h>'
+echo "$systeminfo" > $tmp.c
+$cc -E $tmp.c >/dev/null 2>&1 || systeminfo=
+
+# check for native getconf(1)
+
+CONF_getconf=
+CONF_getconf_a=
+for d in /usr/bin /bin /usr/sbin /sbin
+do if test -x $d/getconf
+ then case `$d/getconf --?-version 2>&1` in
+ *"AT&T"*"Research"*)
+ : presumably an implementation also configured from conf.tab
+ ;;
+ *) CONF_getconf=$d/getconf
+ if $CONF_getconf -a >/dev/null 2>&1
+ then CONF_getconf_a=-a
+ fi
+ ;;
+ esac
+ break
+ fi
+done
+export CONF_getconf CONF_getconf_a
+
+case $verbose in
+1) echo "$command: check ${CONF_getconf:+$CONF_getconf(1),}confstr(2),pathconf(2),sysconf(2),sysinfo(2) configuration names" >&2 ;;
+esac
+{
+ echo "#include <unistd.h>$systeminfo
+int i = 0;" > $tmp.c
+ $cc -E $tmp.c
+} |
+sed \
+ -e '/^#[^0123456789]*1[ ]*".*".*/!d' \
+ -e 's/^#[^0123456789]*1[ ]*"\(.*\)".*/\1/' |
+sort -u > $tmp.f
+{
+sed \
+ -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789]/ /g' \
+ -e 's/[ ][ ]*/\n/g' \
+ `cat $tmp.f` 2>/dev/null |
+ egrep '^(SI|_(CS|PC|SC|SI))_.'
+ case $CONF_getconf_a in
+ ?*) $CONF_getconf $CONF_getconf_a | sed 's,[=: ].*,,'
+ ;;
+ *) case $CONF_getconf in
+ ?*) for v in `strings $CONF_getconf | grep '^[ABCDEFGHIJKLMNOPQRSTUVWXYZ_][ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789]*$'`
+ do if $CONF_getconf $v >/dev/null
+ then echo $v
+ fi
+ done
+ ;;
+ esac
+ ;;
+ esac 2>/dev/null
+} |
+egrep -v '^_[ABCDEFGHIJKLMNOPQRSTUVWXYZ]+_(COUNT|LAST|N|STR)$' |
+sort -u > $tmp.g
+{
+ grep '^_' $tmp.g
+ grep '^[^_]' $tmp.g
+} > $tmp.t
+mv $tmp.t $tmp.g
+case $debug in
+-d2) exit ;;
+esac
+
+HOST=`package | sed -e 's,[0123456789.].*,,' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ`
+case $HOST in
+'') HOST=SYSTEM ;;
+esac
+
+exec < $tmp.g
+
+while read line
+do flags=F
+ section=
+ underscore=
+ define=$line
+ IFS=_
+ set $line
+ IFS=$ifs
+ case $1 in
+ '') case $# in
+ 0) continue ;;
+ esac
+ shift
+ ;;
+ esac
+ case $1 in
+ CS|PC|SC|SI)
+ call=$1
+ shift
+ standard=$1
+ ;;
+ *) flags=${flags}R
+ standard=$1
+ while :
+ do case $# in
+ 0) continue 2 ;;
+ esac
+ shift
+ case $1 in
+ CS|PC|SC|SI)
+ call=$1
+ shift
+ break
+ ;;
+ O|o|OLD|old)
+ continue 2
+ ;;
+ esac
+ standard=${standard}_$1
+ done
+ ;;
+ esac
+ case $1 in
+ SET) continue ;;
+ esac
+ case $standard in
+ _*) standard=`echo $standard | sed 's,^_*,,'` ;;
+ esac
+ case " $standards " in
+ *" $standard "*)
+ ;;
+ *) case $standard in
+ [0123456789]*)
+ section=$standard
+ standard=POSIX
+ ;;
+ *[0123456789])
+ eval `echo $standard | sed 's,\(.*\)\([0123456789]*\),standard=\1 section=\2,'`
+ ;;
+ esac
+ ;;
+ esac
+ case $flags in
+ *R*) case $call in
+ SI) ;;
+ *) underscore=U ;;
+ esac
+ ;;
+ *) case " $standards " in
+ " C ") shift
+ ;;
+ *" $standard "*)
+ case $call in
+ SI) ;;
+ *) flags=${flags}P
+ underscore=U
+ ;;
+ esac
+ shift
+ ;;
+ *) standard=
+ ;;
+ esac
+ ;;
+ esac
+ case $standard in
+ '') standard=$HOST
+ case $call in
+ SI) ;;
+ *) underscore=U ;;
+ esac
+ case $call in
+ CS|PC|SC)
+ case $define in
+ _${call}_*)
+ standard=POSIX
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ part=$section
+ case $section in
+ '') section=1
+ case $standard in
+ POSIX|XOPEN) part=$section ;;
+ esac
+ ;;
+ esac
+ name=
+ while :
+ do case $# in
+ 0) break ;;
+ esac
+ case $name in
+ '') name=$1 ;;
+ *) name=${name}_$1 ;;
+ esac
+ shift
+ done
+ case $name in
+ '') ;;
+ CONFORMANCE|FS_3D|HOSTTYPE|LIBPATH|LIBPREFIX|LIBSUFFIX|PATH_ATTRIBUTES|PATH_RESOLVE|UNIVERSE)
+ ;;
+ *) values=
+ script=
+ args=
+ headers=
+ case $name in
+ V[123456789]_*|V[123456789][0123456789]_*) underscore=VW ;;
+ esac
+ case $call in
+ CS|SI) key=CS ;;
+ *) key=$call ;;
+ esac
+ case $name in
+ *VERSION*)key=${key}_${standard}${part} ;;
+ esac
+ key=${key}_${name}
+ eval x='$'CONF_keys_$name
+ case $x in
+ '') eval x='$'CONF_name_$key
+ case $x in
+ '') case $call in
+ SI) flags=O$flags ;;
+ esac
+ case $underscore in
+ ?*) flags=${flags}${underscore} ;;
+ esac
+ old=QQ
+ case $name in
+ *VERSION*)old=${old}_${standard}${part} ;;
+ esac
+ old=${old}_${name}
+ eval x='$'CONF_name_$old
+ case $x in
+ ?*) eval CONF_name_$old=
+ eval flags='$'flags'$'CONF_flags_$old
+ eval values='$'CONF_values_$old
+ eval script='$'CONF_script_$old
+ eval args='$'CONF_args_$old
+ eval headers='$'CONF_headers_$old
+ ;;
+ esac
+ keys="$keys$nl$key"
+ eval CONF_name_${key}='$'name
+ eval CONF_standard_${key}='$'standard
+ eval CONF_call_${key}='$'call
+ eval CONF_section_${key}='$'section
+ eval CONF_flags_${key}=d'$'flags
+ eval CONF_define_${key}='$'define
+ eval CONF_values_${key}='$'values
+ eval CONF_script_${key}='$'script
+ eval CONF_args_${key}='$'args
+ eval CONF_headers_${key}='$'headers
+ ;;
+ *) eval x='$'CONF_define_$key
+ case $x in
+ ?*) case $call in
+ CS) eval x='$'CONF_call_$key
+ case $x in
+ SI) ;;
+ *) define= ;;
+ esac
+ ;;
+ *) define=
+ ;;
+ esac
+ ;;
+ esac
+ case $define in
+ ?*) eval CONF_define_${key}='$'define
+ eval CONF_call_${key}='$'call
+ eval x='$'CONF_call_${key}
+ case $x in
+ QQ) ;;
+ *) case $flags in
+ *R*) flags=R ;;
+ *) flags= ;;
+ esac
+ ;;
+ esac
+ case $call in
+ SI) flags=O$flags ;;
+ esac
+ eval CONF_flags_${key}=d'$'flags'$'CONF_flags_${key}
+ ;;
+ esac
+ old=QQ
+ case $name in
+ *VERSION*)old=${old}_${standard}${part} ;;
+ esac
+ old=${old}_${name}
+ eval CONF_name_$old=
+ esac
+ ;;
+ *) for key in $x
+ do eval x='$'CONF_call_${key}
+ case $x in
+ XX) eval CONF_call_${key}=QQ
+ eval CONF_flags_${key}=S'$'CONF_flags_${key}
+ ;;
+ esac
+ done
+ esac
+ ;;
+ esac
+done
+
+# sort keys by name
+
+keys=`for key in $keys
+do eval echo '$'CONF_name_$key '$'key
+done | sort -u | sed 's,.* ,,'`
+case $debug in
+-d3) for key in $keys
+ do eval name=\"'$'CONF_name_$key\"
+ case $name in
+ ?*) eval standard=\"'$'CONF_standard_$key\"
+ eval call=\"'$'CONF_call_$key\"
+ eval section=\"'$'CONF_section_$key\"
+ eval flags=\"'$'CONF_flags_$key\"
+ eval define=\"'$'CONF_define_$key\"
+ eval values=\"'$'CONF_values_$key\"
+ eval script=\"'$'CONF_script_$key\"
+ eval headers=\"'$'CONF_headers_$key\"
+ printf "%29s %35s %8s %2s %1d %5s %s$nl" "$name" "$key" "$standard" "$call" "$section" "$flags" "$define${values:+$sp=$values}${headers:+$sp$headers$nl}${script:+$sp$ob$script$nl$cb}"
+ ;;
+ esac
+ done
+ exit
+ ;;
+esac
+
+# mark the dups CONF_PREFIXED
+
+prev_key=
+prev_name=
+for key in $keys
+do eval name=\"'$'CONF_name_$key\"
+ case $name in
+ '') continue
+ ;;
+ $prev_name)
+ eval p='$'CONF_flags_${prev_key}
+ eval c='$'CONF_flags_${key}
+ case $p:$c in
+ *L*:*L*);;
+ *L*:*) c=L${c} ;;
+ *:*L*) p=L${p} ;;
+ *) p=P$p c=P$c ;;
+ esac
+ eval CONF_flags_${prev_key}=$p
+ eval CONF_flags_${key}=$c
+ ;;
+ esac
+ prev_name=$name
+ prev_key=$key
+done
+
+# collect all the macros/enums
+
+for key in $keys
+do eval name=\"'$'CONF_name_$key\"
+ case $name in
+ '') continue ;;
+ $keep_name) ;;
+ *) continue ;;
+ esac
+ eval call=\"'$'CONF_call_$key\"
+ case $call in
+ $keep_call) ;;
+ *) continue ;;
+ esac
+ eval standard=\"'$'CONF_standard_$key\"
+ eval section=\"'$'CONF_section_$key\"
+ eval flags=\"'$'CONF_flags_$key\"
+ eval define=\"'$'CONF_define_$key\"
+ eval values=\"'$'CONF_values_$key\"
+ eval script=\"'$'CONF_script_$key\"
+ eval args=\"'$'CONF_args_$key\"
+ eval headers=\"'$'CONF_headers_$key\"
+ conf_name=$name
+ case $call in
+ QQ) call=XX
+ for c in SC PC CS
+ do case $flags in
+ *S*) case $section in
+ 1) eval x='$'CONF_call_${c}_${standard}_${name} ;;
+ *) eval x='$'CONF_call_${c}_${standard}${section}_${name} ;;
+ esac
+ ;;
+ *) eval x='$'CONF_call_${c}_${name}
+ ;;
+ esac
+ case $x in
+ ?*) call=$x
+ break
+ ;;
+ esac
+ done
+ case $call in
+ XX) for c in SC PC CS
+ do echo "_${c}_${name}"
+ case $flags in
+ *S*) case $section in
+ 1) echo "_${c}_${standard}_${name}" ;;
+ *) echo "_${c}_${standard}${section}_${name}" ;;
+ esac
+ ;;
+ esac
+ done
+ ;;
+ esac
+ ;;
+ esac
+ case $call in
+ CS|PC|SC|SI|XX)
+ ;;
+ *) echo "$command: $name: $call: invalid call" >&2
+ exit 1
+ ;;
+ esac
+ case $flags in
+ *[ABEGHIJQTYZabcefghijklmnopqrstuvwxyz_123456789]*)
+ echo "$command: $name: $flags: invalid flag(s)" >&2
+ exit 1
+ ;;
+ esac
+ case $section in
+ [01]) ;;
+ *) case $flags in
+ *N*) ;;
+ *) name=${section}_${name} ;;
+ esac
+ standard=${standard}${section}
+ ;;
+ esac
+ case $call in
+ XX) ;;
+ *) case $flags in
+ *d*) conf_op=${define} ;;
+ *O*) conf_op=${call}_${name} ;;
+ *R*) conf_op=_${standard}_${call}_${name} ;;
+ *S*) conf_op=_${call}_${standard}_${name} ;;
+ *) conf_op=_${call}_${name} ;;
+ esac
+ echo "${conf_op}"
+ ;;
+ esac
+ case $standard:$flags in
+ C:*) ;;
+ *:*L*) echo "${conf_name}"
+ echo "_${standard}_${conf_name}"
+ ;;
+ *:*M*) case $section in
+ 1) echo "_${standard}_${conf_name}" ;;
+ *) echo "_${standard}${section}_${conf_name}" ;;
+ esac
+ ;;
+ esac
+done > $tmp.q
+sort -u < $tmp.q > $tmp.t
+mv $tmp.t $tmp.q
+sort -u < $tmp.v > $tmp.t
+mv $tmp.t $tmp.v
+case $debug in
+-d4) exit ;;
+esac
+
+# test all the macros in a few batches (some compilers have an error limit)
+
+defined() # list-file
+{
+ : > $tmp.p
+ while :
+ do {
+ cat <<!
+${head}
+#include <sys/types.h>
+#include <limits.h>
+#include <unistd.h>$systeminfo$headers
+${tail}
+#undef conf
+unsigned int conf[] = {
+!
+ sed 's/$/,/' $1
+ echo "};"
+ } > $tmp.c
+ [ -f $tmp.1.c ] || cp $tmp.c $tmp.1.c
+ if $cc -c $tmp.c > $tmp.e 2>&1
+ then break
+ fi
+ [ -f $tmp.1.e ] || cp $tmp.e $tmp.1.e
+ snl='\
+'
+ sed "s/[^_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789][^_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789]*/${snl}/g" $tmp.e |
+ grep '^[_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz][_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789]*$' |
+ sort -u > $tmp.n
+ cmp -s $tmp.n $tmp.p && break
+ fgrep -x -v -f $tmp.n $1 > $tmp.y
+ mv $tmp.y $1
+ mv $tmp.n $tmp.p
+ done
+ {
+ cat <<!
+${head}
+#include <sys/types.h>
+#include <limits.h>
+#include <unistd.h>$systeminfo$headers
+${tail}
+#undef conf
+!
+ sed 's/.*/conf "&" = &/' $1
+ } > $tmp.c
+ $cc -E $tmp.c 2>/dev/null |
+ sed -e '/conf[ ]*".*"[ ]*=[ ]*/!d' -e '/[_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789][ ]*(/!d' -e 's/.*"\(.*\)".*/\1/' > $tmp.n
+ if test -s $tmp.n
+ then fgrep -x -v -f $tmp.n $1 > $tmp.y
+ mv $tmp.y $1
+ fi
+}
+
+case $verbose in
+1) echo "$command: check macros/enums as static initializers" >&2 ;;
+esac
+defined $tmp.q
+defined $tmp.v
+case $debug in
+-d5) exit ;;
+esac
+
+# mark the constant macros/enums
+
+exec < $tmp.q
+while read line
+do eval CONF_const_${line}=1
+done
+exec < $tmp.v
+while read line
+do eval CONF_const_${line}=1
+done
+
+# mark the string literal values
+
+{
+ cat <<!
+${head}
+#include <sys/types.h>
+#include <limits.h>
+#include <unistd.h>$systeminfo$headers
+${tail}
+#undef conf
+!
+ sed 's/.*/conf "&" = &/' $tmp.q
+} > $tmp.c
+$cc -E $tmp.c 2>/dev/null |
+sed -e '/conf[ ]*".*"[ ]*=[ ]*"/!d' -e 's/.*"\([^"]*\)".*/\1/' > $tmp.e
+exec < $tmp.e
+while read line
+do eval CONF_string_${line}=1
+done
+
+# walk through the table
+
+case $shell in
+ksh) integer len name_max ;;
+esac
+name_max=1
+export tmp name standard call cc
+
+exec > $tmp.t
+for key in $keys
+do eval name=\"'$'CONF_name_$key\"
+ case $name in
+ '') continue ;;
+ $keep_name) ;;
+ *) continue ;;
+ esac
+ eval call=\"'$'CONF_call_$key\"
+ case $call in
+ $keep_call) ;;
+ *) continue ;;
+ esac
+ eval standard=\"'$'CONF_standard_$key\"
+ eval section=\"'$'CONF_section_$key\"
+ eval flags=\"'$'CONF_flags_$key\"
+ eval define=\"'$'CONF_define_$key\"
+ eval values=\"'$'CONF_values_$key\"
+ eval script=\"'$'CONF_script_$key\"
+ eval args=\"'$'CONF_args_$key\"
+ eval headers=\"'$'CONF_headers_$key\"
+ conf_name=$name
+ case $call in
+ QQ) call=XX
+ for c in SC PC CS
+ do case $flags in
+ *S*) case $section in
+ 1) eval x='$'CONF_call_${c}_${standard}_${name} ;;
+ *) eval x='$'CONF_call_${c}_${standard}${section}_${name} ;;
+ esac
+ ;;
+ *) eval x='$'CONF_call_${c}_${name}
+ ;;
+ esac
+ case $x in
+ ?*) call=$x
+ break
+ ;;
+ esac
+ done
+ case $call in
+ XX) for c in SC PC CS
+ do case $flags in
+ *S*) case $section in
+ 1) eval x='$'CONF_const__${c}_${standard}_${name} ;;
+ *) eval x='$'CONF_const__${c}_${standard}${section}_${name} ;;
+ esac
+ ;;
+ *) eval x='$'CONF_const__${c}_${name}
+ ;;
+ esac
+ case $x in
+ 1) call=$c
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+ case $call in
+ XX) case $standard in
+ C) standard=POSIX ;;
+ esac
+ case $flags in
+ *L*) flags=lFU ;;
+ *) flags=FU ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ case " $standards " in
+ *" $standard "*)
+ ;;
+ *) standards="$standards $standard"
+ ;;
+ esac
+ conf_standard=CONF_${standard}
+ case $call in
+ CS) conf_call=CONF_confstr
+ ;;
+ PC) conf_call=CONF_pathconf
+ ;;
+ SC) conf_call=CONF_sysconf
+ ;;
+ SI) conf_call=CONF_sysinfo
+ ;;
+ XX) conf_call=CONF_nop
+ ;;
+ esac
+ conf_op=-1
+ for s in _${call}_${standard}${section}_${name} _${call}_${standard}_${name} _${call}_${section}_${name} _${call}_${name} ${call}_${name}
+ do eval x='$'CONF_const_${s}
+ case $x in
+ 1) conf_op=${s}
+ break
+ ;;
+ esac
+ done
+ conf_section=$section
+ conf_flags=0
+ case $flags in
+ *C*) conf_flags="${conf_flags}|CONF_DEFER_CALL" ;;
+ esac
+ case $flags in
+ *D*) conf_flags="${conf_flags}|CONF_DEFER_MM" ;;
+ esac
+ case $flags in
+ *F*) conf_flags="${conf_flags}|CONF_FEATURE" ;;
+ esac
+ case $flags in
+ *L*) conf_flags="${conf_flags}|CONF_LIMIT" ;;
+ esac
+ case $flags in
+ *M*) conf_flags="${conf_flags}|CONF_MINMAX" ;;
+ esac
+ case $flags in
+ *N*) conf_flags="${conf_flags}|CONF_NOSECTION" ;;
+ esac
+ case $flags in
+ *P*) conf_flags="${conf_flags}|CONF_PREFIXED" ;;
+ esac
+ case $flags in
+ *S*) conf_flags="${conf_flags}|CONF_STANDARD" ;;
+ esac
+ case $flags in
+ *U*) conf_flags="${conf_flags}|CONF_UNDERSCORE" ;;
+ esac
+ case $flags in
+ *V*) conf_flags="${conf_flags}|CONF_NOUNDERSCORE" ;;
+ esac
+ case $flags in
+ *W*) conf_flags="${conf_flags}|CONF_PREFIX_ONLY" ;;
+ esac
+ case $debug in
+ ?*) case $standard in
+ ????) sep=" " ;;
+ ???) sep=" " ;;
+ ??) sep=" " ;;
+ ?) sep=" " ;;
+ *) sep="" ;;
+ esac
+ echo "$command: test: $sep$standard $call $name" >&2
+ ;;
+ esac
+ case $call in
+ CS|SI) conf_flags="${conf_flags}|CONF_STRING"
+ string=1
+ ;;
+ *) eval string='$'CONF_string_${key}
+ ;;
+ esac
+ conf_limit=0
+ case $flags in
+ *[Ll]*) d=
+ case ${conf_name} in
+ LONG_MAX|SSIZE_MAX)
+ x=
+ ;;
+ *) eval x='$'CONF_const_${conf_name}
+ ;;
+ esac
+ case $x in
+ '') for s in ${values}
+ do case $s in
+ $sym) eval x='$'CONF_const_${s}
+ case $x in
+ 1) eval a='$'CONF_const_${standard}_${s}
+ case $a in
+ $x) x= ;;
+ *) x=$s ;;
+ esac
+ break
+ ;;
+ esac
+ ;;
+ [0123456789]*|[-+][0123456789]*)
+ d=$s
+ break
+ ;;
+ esac
+ done
+ case ${x:+1}:$flags:$conf_op in
+ :*:-1|:*X*:*)
+ case $verbose in
+ 1) echo "$command: probe for ${conf_name} <limits.h> value" >&2 ;;
+ esac
+ x=
+ case $CONF_getconf in
+ ?*) if $CONF_getconf $conf_name > $tmp.x 2>/dev/null
+ then x=`cat $tmp.x`
+ case $x in
+ undefined) x= ;;
+ esac
+ fi
+ ;;
+ esac
+ case ${x:+1} in
+ '') case $script in
+ '#'*) echo "$script" > $tmp.sh
+ chmod +x $tmp.sh
+ x=`./$tmp.sh 2>/dev/null`
+ ;;
+ '') case $conf_name in
+ SIZE_*|U*|*_MAX)
+ f="%${LL_format}u"
+ t="unsigned _ast_intmax_t"
+ ;;
+ *) f="%${LL_format}d"
+ t="_ast_intmax_t"
+ ;;
+ esac
+ cat > $tmp.c <<!
+${head}
+#include <stdio.h>
+#include <sys/types.h>
+#include <limits.h>
+#include <unistd.h>$systeminfo$headers
+${tail}
+int
+main()
+{
+ printf("$f\n", ($t)$conf_name);
+ return 0;
+}
+!
+ ;;
+ *) cat > $tmp.c <<!
+${head}
+#include <stdio.h>
+#include <sys/types.h>
+#include <limits.h>
+#include <unistd.h>$systeminfo$headers
+${tail}
+${script}
+!
+ ;;
+ esac
+ case $args in
+ '') set "" ;;
+ *) eval set '""' '"'$args'"'; shift ;;
+ esac
+ for a
+ do case $script in
+ '#'*) ./$tmp.sh $a > $tmp.x 2>/dev/null
+ x=$?
+ ;;
+ *) $cc $a -o $tmp.exe $tmp.c >/dev/null 2>&1 && ./$tmp.exe > $tmp.x 2>/dev/null
+ x=$?
+ ;;
+ esac
+ case $x in
+ 0) x=`cat $tmp.x`
+ case $x in
+ "-") x=$a ;;
+ esac
+ break
+ ;;
+ *) x=
+ ;;
+ esac
+ done
+ ;;
+ esac
+ case $x in
+ '') x=$d ;;
+ esac
+ ;;
+ esac
+ case ${x:+1}:$flags:$conf_op in
+ 1:*:-1|1:*X*:*)
+ conf_limit=$x
+ case $flags in
+ *L*) ;;
+ *) conf_flags="${conf_flags}|CONF_LIMIT" ;;
+ esac
+ conf_flags="${conf_flags}|CONF_LIMIT_DEF"
+ case $string:$x in
+ 1:*) cat >> $tmp.l <<!
+printf("#ifndef ${conf_name}\n");
+printf("#define ${conf_name} \"${x}\"\n");
+printf("#endif\n");
+!
+ ;;
+ *:U*) cat >> $tmp.l <<!
+printf("#ifndef ${conf_name}\n");
+printf("#ifndef ${x}\n");
+printf("#define ${x} %lu\n", ${x});
+printf("#endif\n");
+printf("#define ${conf_name} ${x}\n");
+printf("#endif\n");
+!
+ ;;
+ *:$sym) cat >> $tmp.l <<!
+printf("#ifndef ${conf_name}\n");
+printf("#ifndef ${x}\n");
+printf("#define ${x} %ld\n", ${x});
+printf("#endif\n");
+printf("#define ${conf_name} ${x}\n");
+printf("#endif\n");
+!
+ ;;
+ *) cat >> $tmp.l <<!
+printf("#ifndef ${conf_name}\n");
+printf("#define ${conf_name} ${x}\n");
+printf("#endif\n");
+!
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ case $section in
+ [01]) ;;
+ *) case $flags in
+ *N*) ;;
+ *) name=${section}_${name} ;;
+ esac
+ standard=${standard}${section}
+ ;;
+ esac
+ conf_minmax=0
+ case $call:$standard:$flags in
+ *:C:*M*)for s in _${standard}_${conf_name} ${values}
+ do case $s in
+ $sym) ;;
+ *) conf_minmax=$s
+ conf_flags="${conf_flags}|CONF_MINMAX_DEF"
+ break
+ ;;
+ esac
+ done
+ ;;
+ *:C:*) ;;
+ [CPSX][CSX]:*:*[FM]*)
+ x=
+ for s in _${standard}_${conf_name} ${values}
+ do case $s in
+ $sym) eval x='$'CONF_const_${s} ;;
+ *) x=1 ;;
+ esac
+ case $x in
+ 1) conf_minmax=$s
+ case $flags in
+ *M*) conf_flags="${conf_flags}|CONF_MINMAX_DEF" ;;
+ esac
+ case $conf_minmax in
+ [-+0123456789]*) x= ;;
+ esac
+ break
+ ;;
+ esac
+ done
+ case ${x:+1}:${script:+1} in
+ :1) case $verbose in
+ 1) echo "$command: probe for _${standard}_${conf_name} minmax value" >&2 ;;
+ esac
+ case $CONF_getconf in
+ ?*) if $CONF_getconf _${standard}_${conf_name} > $tmp.x 2>/dev/null
+ then x=`cat $tmp.x`
+ case $x in
+ undefined) x= ;;
+ esac
+ fi
+ ;;
+ esac
+ case $x in
+ '') case $script in
+ '#'*) echo "$script" > $tmp.sh
+ chmod +x $tmp.sh
+ x=`./$tmp.sh 2>/dev/null`
+ ;;
+ *) cat > $tmp.c <<!
+${head}
+#include <sys/types.h>
+#include <limits.h>
+#include <unistd.h>$systeminfo$headers
+${tail}
+${script}
+!
+ ;;
+ esac
+ case $args in
+ '') set "" ;;
+ *) eval set '""' "$args"; shift ;;
+ esac
+ for a
+ do case $script in
+ '#'*) ./$tmp.sh $a > $tmp.x 2>/dev/null
+ x=$?
+ ;;
+ *) $cc $a -o $tmp.exe $tmp.c >/dev/null 2>&1 && ./$tmp.exe > $tmp.x 2>/dev/null
+ x=$?
+ ;;
+ esac
+ case $x in
+ 0) x=`cat $tmp.x`
+ case $x in
+ "-") x=$a ;;
+ esac
+ break
+ ;;
+ *) x=
+ ;;
+ esac
+ done
+ ;;
+ esac
+ case $x in
+ ?*) conf_minmax=$x
+ case $flags in
+ *M*) case "|$conf_flags|" in
+ *'|CONF_MINMAX_DEF|'*)
+ ;;
+ *) conf_flags="${conf_flags}|CONF_MINMAX_DEF"
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ case $string in
+ 1) conf_limit="{ 0, $conf_limit }" conf_minmax="{ 0, $conf_minmax }"
+ ;;
+ *) case $conf_limit in
+ 0[xX]*|-*|+*|[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]*)
+ ;;
+ *[!0123456789abcdefABCDEF]*)
+ conf_limit=0
+ ;;
+ *[!0123456789]*)
+ conf_limit=0x$conf_limit
+ ;;
+ esac
+ case $conf_minmax in
+ 0[xX]*|-*|+*|[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]*)
+ ;;
+ *[!0123456789abcdefABCDEF]*)
+ conf_minmax=0
+ ;;
+ *[!0123456789]*)
+ conf_minmax=0x$conf_minmax
+ ;;
+ esac
+ case $conf_limit in
+ ?*[-+]*|*['()']*)
+ ;;
+ *[lLuU])
+ case $LL_suffix in
+ ??) case $conf_limit in
+ *[!lL][lL]|*[!lL][lL][uU])
+ conf_limit=${conf_limit}L
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ -*[2468])
+ case $shell in
+ ksh) p=${conf_limit%?}
+ s=${conf_limit#$p}
+ ((s=s-1))
+ ;;
+ *) eval `echo '' $conf_limit | sed 's/ *\(.*\)\(.\) */p=\1 s=\2/'`
+ s=`expr $s - 1`
+ ;;
+ esac
+ conf_limit=${p}${s}${LL_suffix}-1${LL_suffix}
+ ;;
+ 0[xX]*[abcdefABCDEF])
+ conf_limit=${conf_limit}${LL_suffix}
+ ;;
+ -*[0123456789])
+ conf_limit=${conf_limit}${LL_suffix}
+ ;;
+ *[0123456789])
+ conf_limit=${conf_limit}${U_suffix}${LL_suffix}
+ ;;
+ esac
+ case $conf_minmax in
+ ?*[-+]*|*['()']*)
+ ;;
+ *[lLuU])
+ case $LL_suffix in
+ ??) case $conf_minmax in
+ *[!lL][lL]|*[!lL][lL][uU])
+ conf_minmax=${conf_minmax}L
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ -*[2468])
+ case $shell in
+ ksh) p=${conf_minmax%?}
+ s=${conf_minmax#$p}
+ ((s=s-1))
+ ;;
+ *) eval `echo '' $conf_minmax | sed 's/ *\(.*\)\(.\) */p=\1 s=\2/'`
+ s=`expr $s - 1`
+ ;;
+ esac
+ conf_minmax=${p}${s}${LL_suffix}-1${LL_suffix}
+ ;;
+ 0[xX]*[abcdefABCDEF])
+ conf_minmax=${conf_minmax}${LL_suffix}
+ ;;
+ -*[0123456789])
+ conf_minmax=${conf_minmax}${LL_suffix}
+ ;;
+ *[0123456789])
+ conf_minmax=${conf_minmax}${U_suffix}${LL_suffix}
+ ;;
+ esac
+ conf_limit="{ $conf_limit, 0 }" conf_minmax="{ $conf_minmax, 0 }"
+ ;;
+ esac
+ case $conf_flags in
+ '0|'*) case $shell in
+ ksh) conf_flags=${conf_flags#0?} ;;
+ *) conf_flags=`echo "$conf_flags" | sed 's/^0.//'` ;;
+ esac
+ ;;
+ esac
+ echo "{ \"$conf_name\", $conf_limit, $conf_minmax, $conf_flags, $conf_standard, $conf_section, $conf_call, $conf_op },"
+ case $shell in
+ ksh) len=${#conf_name}
+ if ((len>=name_max))
+ then ((name_max=len+1))
+ fi
+ ;;
+ *) len=`echo ${conf_name} | wc -c`
+ if expr \( $len - 1 \) \>= ${name_max} >/dev/null
+ then name_max=$len
+ fi
+ ;;
+ esac
+done
+exec > /dev/null
+case $debug in
+-d6) exit ;;
+esac
+
+# conf string table
+
+base=conftab
+case $verbose in
+1) echo "$command: generate ${base}.h string table header" >&2 ;;
+esac
+case $shell in
+ksh) ((name_max=name_max+3)); ((name_max=name_max/4*4)) ;; # bsd /bin/sh !
+*) name_max=`expr \( $name_max + 3 \) / 4 \* 4` ;;
+esac
+{
+cat <<!
+#ifndef _CONFTAB_H
+#define _CONFTAB_H
+$systeminfo
+
+${generated}
+
+#if !defined(const) && !defined(__STDC__) && !defined(__cplusplus) && !defined(c_plusplus)
+#define const
+#endif
+
+#define conf _ast_conf_data
+#define conf_elements _ast_conf_ndata
+
+#define prefix _ast_conf_prefix
+#define prefix_elements _ast_conf_nprefix
+
+#define CONF_nop 0
+#define CONF_confstr 1
+#define CONF_pathconf 2
+#define CONF_sysconf 3
+#define CONF_sysinfo 4
+
+!
+index=0
+for standard in $standards
+do echo "#define CONF_${standard} ${index}"
+ case $shell in
+ ksh) ((index=index+1)) ;;
+ *) index=`expr ${index} + 1` ;;
+ esac
+done
+echo "#define CONF_call ${index}"
+case $CONF_getconf in
+?*) echo
+ echo "#define _pth_getconf \"$CONF_getconf\""
+ case $CONF_getconf_a in
+ ?*) echo "#define _pth_getconf_a \"$CONF_getconf_a\"" ;;
+ esac
+ ;;
+esac
+cat <<!
+
+#define CONF_DEFER_CALL 0x0001
+#define CONF_DEFER_MM 0x0002
+#define CONF_FEATURE 0x0004
+#define CONF_LIMIT 0x0008
+#define CONF_LIMIT_DEF 0x0010
+#define CONF_MINMAX 0x0020
+#define CONF_MINMAX_DEF 0x0040
+#define CONF_NOSECTION 0x0080
+#define CONF_NOUNDERSCORE 0x0100
+#define CONF_PREFIX_ONLY 0x0200
+#define CONF_PREFIXED 0x0400
+#define CONF_STANDARD 0x0800
+#define CONF_STRING 0x1000
+#define CONF_UNDERSCORE 0x2000
+#define CONF_USER 0x4000
+
+struct Conf_s; typedef struct Conf_s Conf_t;
+
+typedef struct Value_s
+{
+ intmax_t number;
+ const char* string;
+} Value_t;
+
+struct Conf_s
+{
+ const char name[${name_max}];
+ Value_t limit;
+ Value_t minmax;
+ unsigned int flags;
+ short standard;
+ short section;
+ short call;
+ short op;
+};
+
+typedef struct Prefix_s
+{
+ const char name[16];
+ short length;
+ short standard;
+ short call;
+} Prefix_t;
+
+extern const Conf_t conf[];
+extern const int conf_elements;
+
+extern const Prefix_t prefix[];
+extern const int prefix_elements;
+
+#endif
+!
+} > $tmp.2
+case $debug in
+-d7) echo $command: $tmp.2 ${base}.h ;;
+*) cmp -s $tmp.2 ${base}.h 2>/dev/null || mv $tmp.2 ${base}.h ;;
+esac
+
+case $verbose in
+1) echo "$command: generate ${base}.c string table" >&2 ;;
+esac
+{
+cat <<!
+${head}
+#include <sys/types.h>
+#include <limits.h>
+#include <unistd.h>$systeminfo$headers
+${tail}
+#include "${base}.h"
+
+${generated}
+
+/*
+ * prefix strings -- the first few are indexed by Conf_t.standard
+ */
+
+const Prefix_t prefix[] =
+{
+!
+for standard in $standards
+do case $shell in
+ ksh) len=${#standard} ;;
+ *) len=`echo ${standard} | wc -c`; len=`expr $len - 1` ;;
+ esac
+ echo " \"${standard}\", ${len}, CONF_${standard}, -1,"
+done
+cat <<!
+ "XX", 2, CONF_POSIX, CONF_nop,
+ "CS", 2, CONF_POSIX, CONF_confstr,
+ "PC", 2, CONF_POSIX, CONF_pathconf,
+ "SC", 2, CONF_POSIX, CONF_sysconf,
+ "SI", 2, CONF_SVID, CONF_sysinfo,
+};
+
+const int prefix_elements = (int)sizeof(prefix) / (int)sizeof(prefix[0]);
+
+/*
+ * conf strings sorted in ascending order
+ */
+
+const Conf_t conf[] =
+{
+!
+cat $tmp.t
+cat <<!
+};
+
+const int conf_elements = (int)sizeof(conf) / (int)sizeof(conf[0]);
+!
+} > $tmp.4
+case $debug in
+-d7) echo $command: $tmp.4 ${base}.c ;;
+*) cmp -s $tmp.4 ${base}.c 2>/dev/null || mv $tmp.4 ${base}.c ;;
+esac
+
+# limits.h generation code
+
+base=conflim
+case $verbose in
+1) echo "$command: generate ${base}.h supplemental <limits.h> values" >&2 ;;
+esac
+{
+cat <<!
+${generated}
+
+/*
+ * supplemental <limits.h> values
+ */
+
+!
+test -f $tmp.l && cat $tmp.l
+} > $tmp.5
+case $debug in
+-d7) echo $command: $tmp.5 ${base}.h ;;
+*) cmp -s $tmp.5 ${base}.h 2>/dev/null || mv $tmp.5 ${base}.h ;;
+esac
+exit 0
diff --git a/src/lib/libast/comp/conf.tab b/src/lib/libast/comp/conf.tab
new file mode 100644
index 0000000..2dc05e0
--- /dev/null
+++ b/src/lib/libast/comp/conf.tab
@@ -0,0 +1,601 @@
+#
+# posix { getconf limits } macro table
+#
+# @(#)conf.tab (AT&T Research) 2010-06-28
+#
+# name standard section call flags [ header ... ] [ value ... ]
+#
+# name: sans prefix
+# standard: AST, C, POSIX, SVID, XOPEN, <vendor> { SCO, SGI, SUN, ... }
+# section: section number in standard
+# call: CS=confstr PC=pathconf SC=sysconf SI=sysinfo QQ=query XX=none
+# flags: 0 no flags
+# C defer call to native getconf(1)
+# D defer minmax to native getconf(1)
+# F unistd.h feature
+# L limits.h constant
+# M has _<standard><section>_<name> minmax value
+# N _<call>_<name>
+# O use original name and definition
+# R _<standard>_<call>_<section>_<name>
+# S _<call>_<standard><section>_<name>
+# U <standard><section>_<name> prefixed by underscore
+# V _ prefix not allowed
+# W standard required
+# X define even if native is dynamic (ast special)
+#
+# default names if <section> <= 1
+#
+# _<call>_<name>
+# <standard>_<name>
+#
+# default names if <section> > 1
+#
+# _<call>_<section>_<name>
+# <standard><section>_<name>
+#
+# the [NSU] flags modify the default names
+#
+
+ABI_AIO_XFER_MAX C QQ 1 L
+ABI_ASYNCHRONOUS_IO C QQ 1 L
+ABI_ASYNC_IO C QQ 1 L
+ADVISORY_INFO POSIX SC 1 FUW
+AIO_LISTIO_MAX POSIX SC 1 LMU 2
+AIO_MAX POSIX SC 1 LMU 1
+AIO_PRIO_DELTA_MAX POSIX SC 1 LMU
+ALLOC_SIZE_MIN POSIX PC 1 LUVW
+ARCHITECTURE SVID SI 1 O
+ARG_MAX POSIX SC 1 CDLMUX NCARGS 4096
+ASYNCHRONOUS_IO POSIX SC 1 CDFUW
+ASYNC_IO POSIX PC 1 FUW
+ATEXIT_MAX XOPEN SC 1 LMU 32
+AUDIT C QQ 1 L
+AVAIL_PROCESSORS C QQ 1 L
+AVPHYS_PAGES SUN SC 1 0
+BARRIERS POSIX SC 1 FUW
+BC_BASE_MAX POSIX SC 2 LMN 99
+BC_DIM_MAX POSIX SC 2 LMN 2048
+BC_SCALE_MAX POSIX SC 2 LMN 99
+BC_STRING_MAX POSIX SC 2 LMN 1000
+BUSTYPES SVID SI 1 O
+CHARCLASS_NAME_MAX XOPEN XX 1 L 14
+CHAR_BIT C XX 1 L 8
+CHAR_MAX C XX 1 L
+CHAR_MIN C XX 1 L
+CHAR_TERM POSIX SC 2 FUW
+CHILD_MAX POSIX SC 1 CDLMUX 6 cc{
+ #if _lib_fork
+ #define child() fork()
+ #else
+ #ifdef _map_spawnve
+ #define spawnve _map_spawnve
+ #endif
+ extern int spawnve(const char*, char* const[], char* const[]);
+ static char* cmd[] = { "/bin/echo", 0 };
+ #define child() spawnve(cmd[0],cmd,(char**)0)
+ #endif
+ int main()
+ {
+ int i;
+ int n;
+ for (i = 3; i < 512 && (n = child()) >= 0; i++)
+ if (!n) _exit(0);
+ while (wait((int*)0) > 0);
+ for (n = 8; n < i; n <<= 1);
+ printf("%d", n);
+ return 0;
+ }
+}
+CHOWN_RESTRICTED POSIX PC 1 FUW
+CKPT POSIX SC 1 FU
+CLK_TCK POSIX SC 1 L HZ 60
+CLOCKRES_MIN POSIX SC 1 MUW 1
+CLOCKS_PER_SEC C QQ 1 L
+CLOCK_SELECTION POSIX SC 1 FUVW
+COLL_WEIGHTS_MAX POSIX SC 2 DLMN 2
+CPUTIME POSIX SC 1 FUW
+CPU_KEYBITS1 C QQ 1 L
+CPU_VERSION C QQ 1 L
+CRYPT XOPEN SC 1 FSUW
+C_BIND POSIX SC 2 CFU
+C_DEV POSIX SC 2 CFU
+C_VERSION POSIX SC 2 CDFU
+DATAKEYS_MAX C QQ 1 0
+DELAYTIMER_MAX POSIX SC 1 LMU 32
+ENH_I18N XOPEN SC 1 FSUW
+EQUIV_CLASS_MAX C QQ 1 L
+EXEC_INTERPRETER_LENGTH C QQ 1 L
+EXPR_NEST_MAX POSIX SC 2 LMN 32
+FCHR_MAX SVID SC 1 LMU LONG_MAX 2147483647
+FILESIZEBITS POSIX PC 1 LMU (8*sizeof(off_t)) 32
+FILE_LOCKING POSIX SC 1 FU
+FORT_DEV POSIX SC 2 CFUW
+FORT_RUN POSIX SC 2 CFUW
+FSYNC POSIX SC 1 CDFUW _lib_fsync
+GETGR_R_SIZE_MAX C QQ 1 L
+GETPW_R_SIZE_MAX C QQ 1 L
+HOSTID C QQ 1 L
+HOSTNAME SVID SI 1 O
+HOST_NAME_MAX POSIX SC 1 LMU 255
+HW_PROVIDER SVID SI 1 O
+HW_SERIAL C QQ 1 L
+ILP32_OFF32 XBS5 SC 1 FU
+ILP32_OFF32_CFLAGS XBS5 CS 1 FU
+ILP32_OFF32_LDFLAGS XBS5 CS 1 FU
+ILP32_OFF32_LIBS XBS5 CS 1 FU
+ILP32_OFF32_LINTFLAGS XBS5 CS 1 FU
+ILP32_OFFBIG XBS5 SC 1 FU
+ILP32_OFFBIG_CFLAGS XBS5 CS 1 FU
+ILP32_OFFBIG_LDFLAGS XBS5 CS 1 FU
+ILP32_OFFBIG_LIBS XBS5 CS 1 FU
+ILP32_OFFBIG_LINTFLAGS XBS5 CS 1 FU
+INITTAB_NAME SVID SI 1 O
+INT_MAX C XX 1 L 32767
+INT_MIN C XX 1 L -32767
+IOV_MAX XOPEN SC 1 LMU 16
+IO_TYPE C QQ 1 L
+IPV6 POSIX SC 1 FUW
+IP_SECOPTS C QQ 1 L
+JOB_CONTROL POSIX SC 1 FUW cc{
+ #include "FEATURE/wait"
+ #if _ok_wif
+ int main()
+ {
+ printf("1");
+ return 0;
+ }
+ #endif
+}
+KERNEL_CLIST SCO SC 1 0
+KERNEL_CLIST_MAX SCO SC 1 0
+KERNEL_DISK SCO SC 1 0
+KERNEL_DISK_MAX SCO SC 1 0
+KERNEL_DMABUF SCO SC 1 0
+KERNEL_DMABUF_MAX SCO SC 1 0
+KERNEL_FILE SCO SC 1 0
+KERNEL_FILE_MAX SCO SC 1 0
+KERNEL_FLCKREC SCO SC 1 0
+KERNEL_FLCKREC_MAX SCO SC 1 0
+KERNEL_INODE SCO SC 1 0
+KERNEL_INODE_MAX SCO SC 1 0
+KERNEL_MOUNT SCO SC 1 0
+KERNEL_MOUNT_MAX SCO SC 1 0
+KERNEL_PINODE SCO SC 1 0
+KERNEL_PINODE_MAX SCO SC 1 0
+KERNEL_PROC SCO SC 1 0
+KERNEL_PROC_MAX SCO SC 1 0
+KERNEL_REGION SCO SC 1 0
+KERNEL_REGION_MAX SCO SC 1 0
+KERNEL_S5INODE SCO SC 1 0
+KERNEL_S5INODE_MAX SCO SC 1 0
+KERNEL_STAMP SVID SI 1 O
+KERN_POINTERS C QQ 1 L
+KERN_SIM C QQ 1 L
+LEGACY XOPEN SC 1 FU
+LFS_CFLAGS POSIX CS 1 MU cc{ -D_LARGEFILE_SOURCE "-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" -D_LARGEFILE64_SOURCE -64
+ #include <sys/types.h>
+ int
+ main()
+ {
+ if (sizeof(off_t) >= sizeof(off_64_t))
+ {
+ printf("-");
+ return 0;
+ }
+ return 1;
+ }
+}
+LFS64_CFLAGS POSIX CS 1 MU : LFS_CFLAGS
+LFS64_LDFLAGS POSIX CS 1 MU : LFS_CFLAGS
+LFS64_LIBS POSIX CS 1 MU
+LFS64_LINTFLAGS POSIX CS 1 MU : LFS_CFLAGS
+LFS_LDFLAGS POSIX CS 1 MU : LFS_CFLAGS
+LFS_LIBS POSIX CS 1 MU
+LFS_LINTFLAGS POSIX CS 1 MU : LFS_CFLAGS
+LINE_MAX POSIX SC 2 LMN 2048
+LINK_MAX POSIX PC 1 LMU MAXLINK SHRT_MAX 8
+LLONG_MAX C XX 1 L
+LLONG_MIN C XX 1 L
+LOCALEDEF POSIX SC 1 FUW
+LOCALEDEF POSIX SC 2 CFUW
+LOGIN_NAME_MAX POSIX SC 1 LMU
+LOGNAME_MAX SVID SC 1 MU 8
+LONG_BIT XOPEN XX 1 L (8*sizeof(long)) 32
+LONG_MAX C XX 1 L 2147483647
+LONG_MIN C XX 1 L -2147483647
+LP64_OFF64 XBS5 SC 1 FU
+LP64_OFF64_CFLAGS XBS5 CS 1 FU
+LP64_OFF64_LDFLAGS XBS5 CS 1 FU
+LP64_OFF64_LIBS XBS5 CS 1 FU
+LP64_OFF64_LINTFLAGS XBS5 CS 1 FU
+LPBIG_OFFBIG XBS5 SC 1 FU
+LPBIG_OFFBIG_CFLAGS XBS5 CS 1 FU
+LPBIG_OFFBIG_LDFLAGS XBS5 CS 1 FU
+LPBIG_OFFBIG_LIBS XBS5 CS 1 FU
+LPBIG_OFFBIG_LINTFLAGS XBS5 CS 1 FU
+MACHINE SVID SI 1 O
+MAPPED_FILES POSIX SC 1 CDFUW _lib_mmap
+MAX_CANON POSIX PC 1 LMU CANBSIZ 255
+MAX_INPUT POSIX PC 1 LMU MAX_CANON 255
+MB_LEN_MAX C XX 1 L 1
+MCAS_OFFSET C QQ 1 L
+MEMLOCK POSIX SC 1 CDFUW
+MEMLOCK_RANGE POSIX SC 1 CDFUW
+MEMORY_PROTECTION POSIX SC 1 CDFUW
+MESSAGE_PASSING POSIX SC 1 CDFUW
+MMAP_FIXED_ALIGNMENT C QQ 1 L _AST_PAGESIZE
+MONOTONIC_CLOCK POSIX SC 1 FUW
+MQ_OPEN_MAX POSIX SC 1 LMU 8
+MQ_PRIO_MAX POSIX SC 1 LMU 32
+MSEM_LOCKID C QQ 1 L
+MULTI_PROCESS POSIX SC 1 FU
+NACLS_MAX SVID SC 1 0
+NAME_MAX POSIX PC 1 LMU 14 cc{
+ int main()
+ {
+ #ifdef MAXNAMLEN
+ printf("%d", MAXNAMLEN);
+ #else
+ #if !defined(remove) && (!_lib_remove || _lib_unlink)
+ #define remove unlink
+ #endif
+ int i;
+ int n;
+ int v;
+ char name[256];
+ for (i = 0; i < sizeof(name); i++)
+ name[i] = 'F';
+ name[8] = '.';
+ name[sizeof(name) - 1] = 0;
+ if ((n = creat(name, 0666)) >= 0)
+ {
+ close(n);
+ for (v = 12; v < sizeof(name); v++)
+ {
+ name[v] = 0;
+ if (remove(name) >= 0) break;
+ name[v] = 'F';
+ }
+ }
+ else for (v = 12; v < sizeof(name); v++)
+ {
+ name[v] = 0;
+ if ((n = creat(name, 0666)) >= 0)
+ {
+ close(n);
+ remove(name);
+ name[v] = 'F';
+ }
+ else
+ {
+ v--;
+ break;
+ }
+ }
+ printf("%d", v);
+ return 0;
+ }
+ #endif
+}
+NGROUPS_MAX POSIX SC 1 CDLMU 8 cc{
+ #if _lib_getgroups
+ int main()
+ {
+ int n;
+ gid_t g;
+ if ((n = getgroups(0, &g)) < 0)
+ #if defined(NGROUPS) && (NGROUPS-0) > 0
+ n = NGROUPS;
+ #else
+ return 1;
+ #endif
+ printf("%d", n);
+ return 0;
+ }
+ #endif
+}
+NL_ARGMAX XOPEN XX 1 L 9
+NL_LANGMAX XOPEN XX 1 L 14
+NL_MAX C QQ 1 L
+NL_MSGMAX XOPEN XX 1 L 32767
+NL_NMAX XOPEN XX 1 L 1
+NL_SETMAX XOPEN XX 1 L 255
+NL_SPECMAX C QQ 1 L
+NL_TEXTMAX XOPEN XX 1 L LINE_MAX
+NO_TRUNC POSIX PC 1 FUW
+NPROCESSORS_CONF SVID SC 1 0
+NPROCESSORS_MAX SVID SC 1 0
+NPROCESSORS_ONLN SVID SC 1 0
+NPROC_CONF C QQ 1 L
+NPROC_ONLN C QQ 1 L
+NSS_BUFLEN_GROUP C QQ 1 L
+NSS_BUFLEN_PASSWD C QQ 1 L
+NUM_PROCESSORS C QQ 1 L
+NZERO XOPEN XX 1 L 20
+OPEN_MAX POSIX SC 1 CDLMUX 16 cc{
+ #if _lib_getdtablesize
+ extern int getdtablesize(void);
+ int main()
+ {
+ printf("%d", getdtablesize());
+ return 0;
+ }
+ #else
+ int main()
+ {
+ int i;
+ int n;
+ int v;
+ n = 0;
+ v = 2;
+ while ((i = dup(0)) >= 0)
+ {
+ if (!n) n = i;
+ if (i > v) v = i;
+ }
+ while (n <= v) close(n++);
+ printf("%d", v);
+ return 0;
+ }
+ #endif
+}
+OPEN_MAX_CEIL AST XX 1 L OPEN_MAX
+OSREL_MAJ C QQ 1 L
+OSREL_MIN C QQ 1 L
+OSREL_PATCH C QQ 1 L
+OS_BASE SVID SI 1 O
+OS_PROVIDER SVID SI 1 O
+OS_VERSION AES SC 1 FSU
+PAGESIZE POSIX SC 1 MU PAGESIZE PAGE_SIZE 4096 cc{
+ int main()
+ {
+ #if _WIN32
+ printf("%ld", 64*1024L);
+ return 0;
+ #else
+ #if _lib_getpagesize
+ #if _npt_getpagesize
+ extern size_t getpagesize(void);
+ #endif
+ printf("%d", getpagesize());
+ return 0;
+ #endif
+ #else
+ return 1;
+ #endif
+ }
+}
+PAGE_SIZE POSIX SC 1 MU _AST_PAGESIZE
+PASS_MAX SVID SC 1 CDLMU 8
+PATH POSIX CS 1 CMU "/bin:/usr/bin"
+PATH_MAX POSIX PC 1 CDLMUX MAXPATHLEN 1024
+PBS POSIX SC 2 FUW
+PBS_ACCOUNTING POSIX SC 2 FUW
+PBS_CHECKPOINT POSIX SC 2 FUW
+PBS_LOCATE POSIX SC 2 FUW
+PBS_MESSAGE POSIX SC 2 FUW
+PBS_TRACK POSIX SC 2 FUW
+PHYS_PAGES SUN SC 1 0
+PID_MAX SVID SC 1 LMU 30000 cc{
+ int main()
+ {
+ long v;
+ int fd;
+ int n;
+ char buf[1024];
+#ifdef PID_MAX
+ v = PID_MAX;
+#else
+ v = 99999;
+#endif
+ if ((fd = open("/proc/sys/kernel/pid_max", 0)) >= 0 && (n = read(fd, buf, sizeof(buf)-1)) > 1)
+ {
+ buf[n] = 0;
+ v = strtol(buf, (char**)0, 0);
+ }
+ else
+ {
+#ifdef __sgi
+ v = 0x7fffffff;
+#endif
+ }
+ printf("%ld", v);
+ return 0;
+ }
+}
+PII POSIX SC 1 FU
+PII_INTERNET POSIX SC 1 FU
+PII_INTERNET_DGRAM POSIX SC 1 FU
+PII_INTERNET_STREAM POSIX SC 1 FU
+PII_OSI POSIX SC 1 FU
+PII_OSI_CLTS POSIX SC 1 FU
+PII_OSI_COTS POSIX SC 1 FU
+PII_OSI_M POSIX SC 1 FU
+PII_SOCKET POSIX SC 1 FU
+PII_XTI POSIX SC 1 FU
+PIPE_BUF POSIX PC 1 LMU 512
+POLL POSIX SC 1 FU
+PRIORITIZED_IO POSIX SC 1 FUW
+PRIORITY_SCHEDULING POSIX SC 1 CDFUW
+PRIO_IO POSIX PC 1 FUW
+PROC_RSRC_MGR C QQ 1 L
+PTHREAD_DESTRUCTOR_ITERATIONS C QQ 1 L
+PTHREAD_KEYS_MAX C QQ 1 L
+PTHREAD_STACK_MIN C QQ 1 L
+PTHREAD_THREADS_MAX C QQ 1 L
+PTRDIFF_MAX C XX 1 LMU stdint.h 65535
+PTRDIFF_MIN C XX 1 LMU stdint.h -65535
+RAW_SOCKETS POSIX SC 1 FUW
+READER_WRITER_LOCKS POSIX SC 1 FUW
+REALTIME XOPEN SC 1 FU
+REALTIME_SIGNALS POSIX SC 1 CDFUW
+REALTIME_THREADS XOPEN SC 1 FU
+REC_INCR_XFER_SIZE POSIX PC 1 LVW
+REC_MAX_XFER_SIZE POSIX PC 1 LVW
+REC_MIN_XFER_SIZE POSIX PC 1 LVW
+REC_XFER_ALIGN POSIX PC 1 LVW
+REENTRANT_FUNCTIONS POSIX SC 1 FU
+REGEXP POSIX SC 1 FUW
+REGEX_VERSION POSIX SC 1 F 20030916
+RELEASE AST XX 1 L
+RESOURCE_LIMITS POSIX SC 1 FU
+RE_DUP_MAX POSIX SC 2 LMN 255
+RTSIG_MAX POSIX SC 1 LMU 8
+SAVED_IDS POSIX SC 1 FUW cc{
+ #if _lib_setuid && !_lib_setreuid
+ int main()
+ {
+ printf("1");
+ return 0;
+ }
+ #endif
+}
+SCHAR_MAX C XX 1 L 127
+SCHAR_MIN C XX 1 L -127
+SECURITY_CLASS C QQ 1 L
+SELECT POSIX SC 1 FU
+SEMAPHORES POSIX SC 1 CDFUW
+SEM_NSEMS_MAX POSIX SC 1 LMU 256
+SEM_VALUE_MAX POSIX SC 1 LMU 32767
+SF_BUFSIZE AST XX 1 MUX sh{
+ sed -e '/[ ]*#[ ]*define[ ][ ]*SF_BUFSIZE[ ]/!d' -e 's/^[^0-9]*//' -e 's/[^0-9]*$//' $PACKAGEROOT/src/lib/libast/include/sfio.h
+}
+SH AST CS 1 MU sh{
+ ifs=$IFS
+ IFS=:
+ set '' `$CONF_getconf PATH 2>/dev/null` /bin /usr/bin /sbin /usr/sbin
+ shift
+ path=$*
+ IFS=$ifs
+ for s in ksh ksh93 sh
+ do for d in $path
+ do if test -x $d/$s
+ then case $s in
+ ksh) case `$d/$s '--?-author' 2>&1` in
+ *'David Korn'*) ;;
+ *) continue ;;
+ esac
+ ;;
+ esac
+ echo '"'$d/$s'"'
+ exit
+ fi
+ done
+ done
+ echo '"/bin/sh"'
+}
+SHARED_MEMORY_OBJECTS POSIX SC 1 CDFUW
+SHELL POSIX SC 1 FUVW
+SHM XOPEN SC 1 FSUW
+SHRT_MAX C XX 1 L 32767
+SHRT_MIN C XX 1 L -32767
+SIG_ATOMIC_MAX C XX 1 L signal.h
+SIG_ATOMIC_MIN C XX 1 L signal.h
+SIGQUEUE_MAX POSIX SC 1 LMU 32
+SIGQUEUE_MAX POSIX SC 1 LMU 32
+SIGRT_MAX SVID SC 1 0
+SIGRT_MIN SVID SC 1 0
+SIZE_MAX C XX 1 LMX stdint.h UINT_MAX 65535
+SLVM_MAXNODES C QQ 1 L
+SOCK_MAXBUF C QQ 1 0
+SOFTPOWER C QQ 1 L
+SPAWN POSIX SC 1 FUW
+SPIN_LOCKS POSIX SC 1 FUW
+SPORADIC_SERVER POSIX SC 1 FUW
+SRPC_DOMAIN C QQ 1 0
+SS_REPL_MAX POSIX SC 1 FUW
+SSIZE_MAX POSIX XX 1 LMUX INT_MAX 32767
+STD_BLK SVID SC 1 LMU 1024
+STREAM_MAX POSIX SC 1 LMU OPEN_MAX 8
+STREAMS XOPEN SC 1 FSUW
+SW_DEV POSIX SC 2 CFUW
+SYMLINK_MAX POSIX PC 1 LMU 255 cc{
+ int main()
+ {
+ printf("%d", PATH_MAX-1);
+ return 0;
+ }
+}
+SYMLINKS POSIX PC 2 FUW
+SYMLOOP_MAX POSIX SC 1 LMU 8
+SYNCHRONIZED_IO POSIX SC 1 CDFUW
+SYNC_IO POSIX PC 1 FUW
+SYSNAME SVID SI 1 O
+SYSPID_MAX SVID SC 1 LMU 2
+THREADS POSIX SC 1 CDFUW
+THREADS_PRIO_CEILING POSIX SC 1 FUW
+THREADS_PRIO_INHERIT POSIX SC 1 FUW
+THREAD_ATTR_STACKADDR POSIX SC 1 CDFUW
+THREAD_ATTR_STACKSIZE POSIX SC 1 CDFUW
+THREAD_CPUTIME POSIX SC 1 FUW
+THREAD_DESTRUCTOR_ITERATIONS POSIX SC 1 LMUW PTHREAD_DESTRUCTOR_ITERATIONS 4
+THREAD_KEYS_MAX POSIX SC 1 LMUW PTHREAD_KEYS_MAX 128
+THREAD_PRIORITY_SCHEDULING POSIX SC 1 CDFUW
+THREAD_PRIO_INHERIT POSIX SC 1 CDFUW
+THREAD_PRIO_PROTECT POSIX SC 1 CDFUW
+THREAD_PROCESS_SHARED POSIX SC 1 CDFUW
+THREAD_SAFE_FUNCTIONS POSIX SC 1 CDFUW
+THREAD_SPORADIC_SERVER POSIX SC 1 FUW
+THREAD_STACK_MIN POSIX SC 1 LUW PTHREAD_STACK_MIN
+THREAD_THREADS_MAX POSIX SC 1 LMUW PTHREAD_THREADS_MAX 64
+TIMEOUTS POSIX SC 1 FUW
+TIMERS POSIX SC 1 CDFUW
+TIMER_MAX POSIX SC 1 LMU 32
+TMP AST CS 1 MU "/tmp"
+TMP_MAX C SC 1 LMU 10000
+TRACE POSIX SC 1 FUW
+TRACE_EVENT_FILTER POSIX SC 1 FUW
+TRACE_EVENT_NAME_MAX POSIX SC 1 FUVW
+TRACE_INHERIT POSIX SC 1 FUW
+TRACE_LOG POSIX SC 1 FUW
+TRACE_NAME_MAX POSIX SC 1 FUVW
+TRACE_SYS_MAX POSIX SC 1 FUVW
+TRACE_USER_EVENT_MAX POSIX SC 1 FUVW
+TTY_NAME_MAX POSIX SC 1 LMU 9
+TYPED_MEMORY_OBJECTS POSIX SC 1 FUW
+TZNAME_MAX POSIX SC 1 CDLMU 6
+T_IOV_MAX C QQ 1 0
+UCHAR_MAX C XX 1 L 255
+UCHAR_MIN C XX 1 L
+UID_MAX SVID SC 1 LMU 60002
+UINT_MAX C XX 1 L 65535
+UIO_MAXIOV C QQ 1 0
+ULLONG_MAX C XX 1 L
+ULONG_MAX C XX 1 L 4294967295
+UNIX XOPEN SC 1 FSUW
+UPE POSIX SC 2 CFUW
+USER_LIMIT SVID SI 1 O
+USHRT_MAX C XX 1 L 65535
+V6_ILP32_OFF32 POSIX SC 1 W
+V6_ILP32_OFFBIG POSIX SC 1 W
+V6_LP64_OFF64 POSIX SC 1 W
+V6_LPBIG_OFFBIG POSIX SC 1 W
+VDISABLE POSIX PC 1 FUW
+VERSION POSIX SC 1 CDFSU 200112
+VERSION POSIX SC 2 CDFSU 200112
+VERSION XOPEN SC 1 CDFSU 600
+VERSION AST XX 1 MS _AST_VERSION
+VERSION SVID SI 1 S
+VERSION XPG SC 3 DFSU
+VERSION XPG SC 4 DFSU
+VERSION_88 C XX 1 L
+VERSION_88 POSIX SC 1 FSU
+VERSION_90 C XX 1 L
+VERSION_90 POSIX SC 1 FSU
+VERSION_93 C XX 1 L
+VERSION_93 POSIX SC 1 FSU
+WCHAR_MAX C XX 1 L stddef.h
+WCHAR_MIN C XX 1 L stddef.h
+WINT_MIN C XX 1 L wchar.h
+WINT_MAX C XX 1 L wchar.h
+WORD_BIT XOPEN XX 1 L (8*sizeof(int))
+XCU_VERSION XOPEN SC 1 CDFSU
+XPG2 XOPEN XX 1 FU
+XPG3 XOPEN XX 1 FU
+XPG4 XOPEN XX 1 FU
+
+# vendor prefixes
+
+VERSION GNU XX 1 S
+VERSION TRUSTEDBSD XX 1 S
diff --git a/src/lib/libast/comp/creat64.c b/src/lib/libast/comp/creat64.c
new file mode 100644
index 0000000..7917f2f
--- /dev/null
+++ b/src/lib/libast/comp/creat64.c
@@ -0,0 +1,38 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if defined(_lib_creat64) || !defined(_lib_open64)
+
+NoN(creat64)
+
+#else
+
+int
+creat64(const char* path, mode_t mode)
+{
+ return open64(path, O_WRONLY|O_CREAT|O_TRUNC, mode);
+}
+
+#endif
diff --git a/src/lib/libast/comp/dirname.c b/src/lib/libast/comp/dirname.c
new file mode 100644
index 0000000..b03d734
--- /dev/null
+++ b/src/lib/libast/comp/dirname.c
@@ -0,0 +1,61 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * dirname(3) implementation
+ */
+
+#include <ast_std.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char *dirname(register char *pathname)
+{
+ register char *last;
+ /* go to end of path */
+ for(last=pathname; *last; last++);
+ /* back over trailing '/' */
+ while(last>pathname && *--last=='/');
+ /* back over non-slash chars */
+ for(;last>pathname && *last!='/';last--);
+ if(last==pathname)
+ {
+ /* all '/' or "" */
+ if(*last!='/')
+ *last = '.';
+ /* preserve // */
+ else if(last[1]=='/')
+ last++;
+ }
+ else
+ {
+ /* back over trailing '/' */
+ for(;*last=='/' && last > pathname; last--);
+ /* preserve // */
+ if(last==pathname && *pathname=='/' && pathname[1]=='/')
+ last++;
+ }
+ *(last + 1) = 0;
+ return(pathname);
+}
diff --git a/src/lib/libast/comp/dup2.c b/src/lib/libast/comp/dup2.c
new file mode 100644
index 0000000..6999972
--- /dev/null
+++ b/src/lib/libast/comp/dup2.c
@@ -0,0 +1,46 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_dup2
+
+NoN(dup2)
+
+#else
+
+#include <error.h>
+
+int
+dup2(int d1, int d2)
+{
+ int save_errno;
+
+ if (d1 == d2) return(d1);
+ save_errno = errno;
+ close(d2);
+ errno = save_errno;
+ return(fcntl(d1, F_DUPFD, d2));
+}
+
+#endif
diff --git a/src/lib/libast/comp/eaccess.c b/src/lib/libast/comp/eaccess.c
new file mode 100644
index 0000000..1fe44a7
--- /dev/null
+++ b/src/lib/libast/comp/eaccess.c
@@ -0,0 +1,139 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * access() euid/egid implementation
+ */
+
+#include <ast.h>
+#include <errno.h>
+#include <ls.h>
+
+#include "FEATURE/eaccess"
+
+#if _lib_eaccess
+
+NoN(eaccess)
+
+#else
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+eaccess(const char* path, register int flags)
+{
+#ifdef EFF_ONLY_OK
+ return access(path, flags|EFF_ONLY_OK);
+#else
+#if _lib_euidaccess
+ return euidaccess(path, flags);
+#else
+ register int mode;
+ struct stat st;
+
+ static int init;
+ static uid_t ruid;
+ static uid_t euid;
+ static gid_t rgid;
+ static gid_t egid;
+
+ if (!init)
+ {
+ ruid = getuid();
+ euid = geteuid();
+ rgid = getgid();
+ egid = getegid();
+ init = (ruid == euid && rgid == egid) ? 1 : -1;
+ }
+ if (init > 0 || flags == F_OK)
+ return access(path, flags);
+ if (stat(path, &st))
+ return -1;
+ mode = 0;
+ if (euid == 0)
+ {
+ if (!S_ISREG(st.st_mode) || !(flags & X_OK) || (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
+ return 0;
+ goto nope;
+ }
+ else if (euid == st.st_uid)
+ {
+ if (flags & R_OK)
+ mode |= S_IRUSR;
+ if (flags & W_OK)
+ mode |= S_IWUSR;
+ if (flags & X_OK)
+ mode |= S_IXUSR;
+ }
+ else if (egid == st.st_gid)
+ {
+#if _lib_getgroups
+ setgroup:
+#endif
+ if (flags & R_OK)
+ mode |= S_IRGRP;
+ if (flags & W_OK)
+ mode |= S_IWGRP;
+ if (flags & X_OK)
+ mode |= S_IXGRP;
+ }
+ else
+ {
+#if _lib_getgroups
+ register int n;
+
+ static int ngroups = -2;
+ static gid_t* groups;
+
+ if (ngroups == -2)
+ {
+ if ((ngroups = getgroups(0, (gid_t*)0)) <= 0)
+ ngroups = NGROUPS_MAX;
+ if (!(groups = newof(0, gid_t, ngroups + 1, 0)))
+ ngroups = -1;
+ else
+ ngroups = getgroups(ngroups, groups);
+ }
+ n = ngroups;
+ while (--n >= 0)
+ if (groups[n] == st.st_gid)
+ goto setgroup;
+#endif
+ if (flags & R_OK)
+ mode |= S_IROTH;
+ if (flags & W_OK)
+ mode |= S_IWOTH;
+ if (flags & X_OK)
+ mode |= S_IXOTH;
+ }
+ if ((st.st_mode & mode) == mode)
+ return 0;
+ nope:
+ errno = EACCES;
+ return -1;
+#endif
+#endif
+}
+
+#endif
diff --git a/src/lib/libast/comp/errno.c b/src/lib/libast/comp/errno.c
new file mode 100644
index 0000000..374a720
--- /dev/null
+++ b/src/lib/libast/comp/errno.c
@@ -0,0 +1,40 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _tst_errno
+
+NoN(errno)
+
+#else
+
+/*
+ * this avoids multiple definitions with some libc's
+ * that define both an ast library supplied routine and
+ * errno in the same .o
+ */
+
+int errno;
+
+#endif
diff --git a/src/lib/libast/comp/execlp.c b/src/lib/libast/comp/execlp.c
new file mode 100644
index 0000000..42de6ef
--- /dev/null
+++ b/src/lib/libast/comp/execlp.c
@@ -0,0 +1,50 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast_lib.h>
+
+#if _lib_execlp
+
+#include <ast.h>
+
+NoN(execlp)
+
+#else
+
+#if defined(__EXPORT__)
+__EXPORT__ int execlp(const char*, const char*, ...);
+#endif
+
+#include <ast.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+execlp(const char* name, const char* arg, ...)
+{
+ return execvp(name, (char *const*)&arg);
+}
+
+#endif
diff --git a/src/lib/libast/comp/execve.c b/src/lib/libast/comp/execve.c
new file mode 100644
index 0000000..9d7e2ff
--- /dev/null
+++ b/src/lib/libast/comp/execve.c
@@ -0,0 +1,70 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_execve
+
+NoN(execve)
+
+#else
+
+#include <sig.h>
+#include <wait.h>
+#include <error.h>
+
+static pid_t childpid;
+
+static void
+execsig(int sig)
+{
+ kill(childpid, sig);
+ signal(sig, execsig);
+}
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+execve(const char* path, char* const argv[], char* const arge[])
+{
+ int status;
+
+ if ((childpid = spawnve(path, argv, arge)) < 0)
+ return(-1);
+ for (status = 0; status < 64; status++)
+ signal(status, execsig);
+ while (waitpid(childpid, &status, 0) == -1)
+ if (errno != EINTR) return(-1);
+ if (WIFSIGNALED(status))
+ {
+ signal(WTERMSIG(status), SIG_DFL);
+ kill(getpid(), WTERMSIG(status));
+ pause();
+ }
+ else status = WEXITSTATUS(status);
+ exit(status);
+}
+
+#endif
diff --git a/src/lib/libast/comp/execvp.c b/src/lib/libast/comp/execvp.c
new file mode 100644
index 0000000..1e34172
--- /dev/null
+++ b/src/lib/libast/comp/execvp.c
@@ -0,0 +1,50 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast_lib.h>
+
+#if _lib_execvp
+
+#include <ast.h>
+
+NoN(execvp)
+
+#else
+
+#if defined(__EXPORT__)
+__EXPORT__ int execvp(const char*, char* const[]);
+#endif
+
+#include <ast.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+execvp(const char* name, char* const argv[])
+{
+ return execvpe(name, argv, environ);
+}
+
+#endif
diff --git a/src/lib/libast/comp/execvpe.c b/src/lib/libast/comp/execvpe.c
new file mode 100644
index 0000000..c711c50
--- /dev/null
+++ b/src/lib/libast/comp/execvpe.c
@@ -0,0 +1,78 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast_lib.h>
+
+#if _lib_execvpe
+
+#include <ast.h>
+
+NoN(execvpe)
+
+#else
+
+#if defined(__EXPORT__)
+__EXPORT__ int execvpe(const char*, char* const[], char* const[]);
+#endif
+
+#include <ast.h>
+#include <errno.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+execvpe(const char* name, char* const argv[], char* const envv[])
+{
+ register const char* path = name;
+ char buffer[PATH_MAX];
+
+ if (*path != '/' && !(path = pathpath(name, NULL, PATH_REGULAR|PATH_EXECUTE, buffer, sizeof(buffer))))
+ path = name;
+ execve(path, argv, envv);
+ if (errno == ENOEXEC)
+ {
+ register char** newargv;
+ register char** ov;
+ register char** nv;
+
+ for (ov = (char**)argv; *ov++;);
+ if (newargv = newof(0, char*, ov + 1 - (char**)argv, 0))
+ {
+ nv = newargv;
+ *nv++ = "sh";
+ *nv++ = (char*)path;
+ ov = (char**)argv;
+ while (*nv++ = *++ov);
+ path = pathshell();
+ execve(path, newargv, envv);
+ free(newargv);
+ }
+ else
+ errno = ENOMEM;
+ }
+ return -1;
+}
+
+#endif
diff --git a/src/lib/libast/comp/fakelink.h b/src/lib/libast/comp/fakelink.h
new file mode 100644
index 0000000..5683541
--- /dev/null
+++ b/src/lib/libast/comp/fakelink.h
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Bell Laboratories
+ *
+ * fake symbolic link private interface
+ */
+
+#ifndef _FAKELINK_H
+#define _FAKELINK_H
+
+#define FAKELINK_MAGIC "!<symlink>"
+
+#endif
diff --git a/src/lib/libast/comp/fcntl.c b/src/lib/libast/comp/fcntl.c
new file mode 100644
index 0000000..70adfee
--- /dev/null
+++ b/src/lib/libast/comp/fcntl.c
@@ -0,0 +1,98 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * -last fcntl
+ */
+
+#include <ast.h>
+
+#ifndef fcntl
+
+NoN(fcntl)
+
+#else
+
+#include <ls.h>
+#include <ast_tty.h>
+#include <error.h>
+
+#if F_SETFD >= _ast_F_LOCAL
+#if _sys_filio
+#include <sys/filio.h>
+#endif
+#endif
+
+#if _lib_fcntl
+#undef fcntl
+extern int fcntl(int, int, ...);
+#endif
+
+int
+_ast_fcntl(int fd, int op, ...)
+{
+ int n;
+ int save_errno;
+ struct stat st;
+ va_list ap;
+
+ save_errno = errno;
+ va_start(ap, op);
+ if (op >= _ast_F_LOCAL) switch (op)
+ {
+#if F_DUPFD >= _ast_F_LOCAL
+ case F_DUPFD:
+ n = va_arg(ap, int);
+ op = dup2(fd, n);
+ break;
+#endif
+#if F_GETFL >= _ast_F_LOCAL
+ case F_GETFL:
+ op = fstat(fd, &st);
+ break;
+#endif
+#if F_SETFD >= _ast_F_LOCAL && defined(FIOCLEX)
+ case F_SETFD:
+ n = va_arg(ap, int);
+ op = ioctl(fd, n == FD_CLOEXEC ? FIOCLEX : FIONCLEX, 0);
+ break;
+#endif
+ default:
+ errno = EINVAL;
+ op = -1;
+ break;
+ }
+ else
+#if _lib_fcntl
+ op = fcntl(fd, op, va_arg(ap, int));
+#else
+ {
+ errno = EINVAL;
+ op = -1;
+ }
+#endif
+ va_end(ap);
+ return(op);
+}
+
+#endif
diff --git a/src/lib/libast/comp/fmtmsg.h b/src/lib/libast/comp/fmtmsg.h
new file mode 100644
index 0000000..9360c41
--- /dev/null
+++ b/src/lib/libast/comp/fmtmsg.h
@@ -0,0 +1,141 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * fmtmsg interface definitions
+ */
+
+#ifndef _FMTMSG_H
+#define _FMTMSG_H
+
+#define MM_VERB_ENV "MSGVERB" /* keyword filter env var */
+#define MM_SEVERITY_ENV "SEV_LEVEL" /* alternate severity env var */
+
+/* max component length */
+
+#define MM_LABEL_1_MAX 10 /* label field 1 length */
+#define MM_LABEL_2_MAX 14 /* label field 2 length */
+
+/* classification type */
+
+#define MM_HARD 0x00000001L /* hardware */
+#define MM_SOFT 0x00000002L /* software */
+#define MM_FIRM 0x00000004L /* firmware */
+
+/* classification source */
+
+#define MM_APPL 0x00000010L /* application */
+#define MM_UTIL 0x00000020L /* utility */
+#define MM_OPSYS 0x00000040L /* kernel */
+
+/* classification display */
+
+#define MM_PRINT 0x00000100L /* stderr */
+#define MM_CONSOLE 0x00000200L /* console */
+
+/* classification status */
+
+#define MM_RECOVER 0x00001000L /* recoverable */
+#define MM_NRECOV 0x00002000L /* non-recoverable */
+
+/* severity */
+
+#define MM_NOSEV 0x0 /* no severity */
+#define MM_HALT 0x1 /* severe fault */
+#define MM_ERROR 0x2 /* fault */
+#define MM_WARNING 0x4 /* could be a problem */
+#define MM_INFO 0x8 /* not an error (noise?) */
+
+/* fmtmsg return value */
+
+#define MM_OK 0 /* succeeded */
+#define MM_NOTOK 3 /* failed completely */
+#define MM_NOMSG 1 /* stderr message failed */
+#define MM_NOCON 2 /* console message failed */
+
+/* null argument values -- 0 just doesn't get any respect */
+
+#define MM_NULLLBL (char*)0 /* label */
+#define MM_NULLSEV 0 /* severity */
+#define MM_NULLMC 0L /* class */
+#define MM_NULLTXT (char*)0 /* text */
+#define MM_NULLACT (char*)0 /* action */
+#define MM_NULLTAG (char*)0 /* tag */
+
+#ifdef MM_TABLES
+
+/* encoding support */
+
+typedef struct
+{
+ const char* name;
+ const char* display;
+ unsigned int value;
+} MM_table_t;
+
+#define mm_class _mm_class
+#define mm_severity _mm_severity()
+#define mm_verb _mm_verb
+
+#define MM_all 0xff
+#define MM_action 0x01
+#define MM_class 0x02
+#define MM_label 0x04
+#define MM_severity 0x08
+#define MM_source 0x10
+#define MM_status 0x20
+#define MM_tag 0x40
+#define MM_text 0x80
+
+#define MM_default (MM_action|MM_label|MM_severity|MM_tag|MM_text)
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+#if !_BLD_ast && defined(__IMPORT__)
+#define extern extern __IMPORT__
+#endif
+
+extern const MM_table_t mm_class[];
+extern const MM_table_t mm_verb[];
+
+#undef extern
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern const MM_table_t* mm_severity;
+
+#undef extern
+
+#endif
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int fmtmsg(long, const char*, int, const char*, const char*, const char*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/comp/fmtmsglib.c b/src/lib/libast/comp/fmtmsglib.c
new file mode 100644
index 0000000..3484223
--- /dev/null
+++ b/src/lib/libast/comp/fmtmsglib.c
@@ -0,0 +1,335 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * fmtmsg implementation
+ */
+
+#include <ast.h>
+
+#if _lib_fmtmsg
+
+NoN(fmtmsg)
+
+#else
+
+#define MM_TABLES
+
+#include <fmtmsg.h>
+
+#define INIT_VERB 0x1
+#define INIT_CONSOLE 0x2
+
+static struct
+{
+ int console;
+ unsigned int init;
+ unsigned int mask;
+} mm;
+
+const MM_table_t mm_class[] =
+{
+ "null", 0, 0,
+ "hard", "HARDWARE", MM_HARD,
+ "soft", "SOFTWARE", MM_SOFT,
+ "firm", "FIRMWARE", MM_FIRM,
+ "appl", "APPLICATION", MM_APPL,
+ "util", "UTILITY", MM_UTIL,
+ "opsys", "KERNEL", MM_OPSYS,
+ "print", 0, MM_PRINT,
+ "console", 0, MM_CONSOLE,
+ "recov", "RECOVERABLE", MM_RECOVER,
+ "nrecov", "PANIC", MM_NRECOV,
+ 0, 0, 0
+};
+
+static const MM_table_t mm_severity_init[] =
+{
+ "nosev", 0, MM_NOSEV,
+ "halt", "HALT", MM_HALT,
+ "error", "ERROR", MM_ERROR,
+ "warn", "WARNING", MM_WARNING,
+ "info", "INFO", MM_INFO,
+ 0, 0, 0
+};
+
+const MM_table_t mm_verb[] =
+{
+ "all", 0, MM_all,
+ "action", 0, MM_action,
+ "class", 0, MM_class,
+ "default", 0, MM_default,
+ "label", 0, MM_label,
+ "severity", 0, MM_severity,
+ "source", 0, MM_source,
+ "tag", 0, MM_tag,
+ "text", 0, MM_text,
+ 0, 0, 0
+};
+
+const MM_table_t*
+_mm_severity(void)
+{
+ static MM_table_t* severity;
+
+ if (!severity)
+ {
+ register char* s;
+ register MM_table_t* p;
+ register int n;
+ register int c;
+ char* e;
+ MM_table_t* q;
+
+ n = 0;
+ if ((s = getenv(MM_SEVERITY_ENV)) && *s)
+ {
+ e = s;
+ c = 0;
+ for (;;)
+ {
+ switch (*s++)
+ {
+ case 0:
+ break;
+ case ',':
+ if (++c > 2)
+ {
+ n = 0;
+ break;
+ }
+ continue;
+ case ':':
+ if (c != 2)
+ {
+ n = 0;
+ break;
+ }
+ c = 0;
+ n++;
+ continue;
+ default:
+ continue;
+ }
+ break;
+ }
+ if (c == 2)
+ n++;
+ else n = 0;
+ if (n)
+ {
+ for (p = (MM_table_t*)mm_severity_init; p->name; p++);
+ n += p - (MM_table_t*)mm_severity_init + 1;
+ if (severity = newof(0, MM_table_t, n, s - e))
+ {
+ s = (char*)severity + n * sizeof(MM_table_t);
+ strcpy(s, e);
+ p = severity;
+ for (q = (MM_table_t*)mm_severity_init; q->name; q++)
+ *p++ = *q;
+ p->name = s;
+ c = 0;
+ for (;;)
+ {
+ switch (*s++)
+ {
+ case 0:
+ break;
+ case ',':
+ switch (c++)
+ {
+ case 0:
+ *(s - 1) = 0;
+ p->value = strtol(s, NiL, 0);
+ break;
+ case 1:
+ p->display = s;
+ break;
+ }
+ continue;
+ case ':':
+ c = 0;
+ *(s - 1) = 0;
+ (++p)->name = s;
+ continue;
+ default:
+ continue;
+ }
+ break;
+ }
+ }
+ }
+ }
+ if (!severity)
+ severity = (MM_table_t*)mm_severity_init;
+ }
+ return (const MM_table_t*)severity;
+}
+
+static char*
+display(register const MM_table_t* tab, int value, int mask)
+{
+ while (tab->name)
+ {
+ if (value == tab->value || mask && (value & tab->value))
+ return (char*)tab->display;
+ tab++;
+ }
+ return 0;
+}
+
+int
+fmtmsg(long classification, const char* label, int severity, const char* text, const char* action, const char* tag)
+{
+ register int c;
+ register char* s;
+ register char* t;
+ register MM_table_t* p;
+ int n;
+ int m;
+ int r;
+ int fd;
+ unsigned int mask;
+ Sfio_t* sp;
+ char lab[MM_LABEL_1_MAX + MM_LABEL_2_MAX + 3];
+
+ if (!mm.init)
+ {
+ mm.init = INIT_VERB;
+ if (!(s = getenv(MM_VERB_ENV)))
+ mm.mask = MM_default;
+ else for (;;)
+ {
+ if (t = strchr(s, ':'))
+ *t = 0;
+ if (!(p = (MM_table_t*)strlook(mm_verb, sizeof(MM_table_t), s)))
+ {
+ mm.mask = MM_default;
+ if (t)
+ *t = ':';
+ break;
+ }
+ mm.mask |= p->value;
+ if (!t)
+ break;
+ *t++ = ':';
+ s = t;
+ }
+ }
+ if (!(classification & (MM_CONSOLE|MM_PRINT)))
+ return 0;
+ if (!(sp = sfstropen()))
+ return MM_NOTOK;
+ r = 0;
+ if (s = (char*)label)
+ {
+ if (t = strchr(s, ':'))
+ {
+ if ((n = t - s) > MM_LABEL_1_MAX)
+ n = MM_LABEL_1_MAX;
+ sfprintf(sp, "%*.*s:", n, n, s);
+ s = ++t;
+ if ((n = strlen(t)) > MM_LABEL_2_MAX)
+ n = MM_LABEL_2_MAX;
+ sfprintf(sp, "%*.*s", n, n, s);
+ }
+ else
+ {
+ if ((n = strlen(t)) > MM_LABEL_1_MAX)
+ n = MM_LABEL_1_MAX;
+ sfprintf(sp, "%*.*s", n, n, s);
+ }
+ if (!(s = sfstruse(sp)))
+ {
+ sfstrclose(sp);
+ return MM_NOTOK;
+ }
+ strcpy(lab, s);
+ }
+ for (;;)
+ {
+ if (classification & MM_CONSOLE)
+ {
+ classification &= ~MM_CONSOLE;
+ if (!(mm.init & INIT_CONSOLE))
+ mm.console = open("/dev/console", O_WRONLY|O_APPEND|O_NOCTTY);
+ if (mm.console < 0)
+ {
+ r |= MM_NOCON;
+ continue;
+ }
+ c = MM_NOCON;
+ fd = mm.console;
+ mask = MM_all;
+ }
+ else if (classification & MM_PRINT)
+ {
+ classification &= ~MM_PRINT;
+ c = MM_NOMSG;
+ fd = 2;
+ mask = mm.mask;
+ }
+ else break;
+ if ((mask & MM_label) && label)
+ sfprintf(sp, "%s: ", lab);
+ if ((mask & MM_severity) && (s = display(mm_severity, severity, 0)))
+ sfprintf(sp, "%s: ", s);
+ n = sfstrtell(sp);
+ if ((mask & MM_text) && text)
+ sfprintf(sp, "%s\n", text);
+ else sfputc(sp, '\n');
+ if ((mask & MM_action) && action || (mask & MM_tag) && (label || tag))
+ {
+ if (fd != mm.console && (n -= 8) > 0)
+ sfprintf(sp, "%*.*s", n, n, "");
+ sfprintf(sp, "TO FIX:");
+ if ((mask & MM_action) && action)
+ sfprintf(sp, " %s", action);
+ if ((mask & MM_tag) && (label || tag))
+ {
+ sfprintf(sp, " ");
+ if (!tag || label && !strchr(tag, ':'))
+ sfprintf(sp, "%s%s", lab, tag ? ":" : "");
+ if (tag)
+ sfprintf(sp, "%s", tag);
+ }
+ if (mask & (MM_class|MM_source|MM_status))
+ {
+ sfputc(sp, ' ');
+ if ((mask & MM_source) && (m = classification & (MM_APPL|MM_UTIL|MM_OPSYS)) && (s = display(mm_class, m, 1)))
+ sfprintf(sp, " %s", s);
+ if ((mask & MM_class) && (m = classification & (MM_HARD|MM_SOFT|MM_FIRM)) && (s = display(mm_class, m, 1)))
+ sfprintf(sp, " %s", s);
+ if ((mask & MM_status) && (m = classification & (MM_RECOVER|MM_NRECOV)) && (s = display(mm_class, m, 1)))
+ sfprintf(sp, " %s", s);
+ }
+ sfputc(sp, '\n');
+ }
+ n = sfstrtell(sp);
+ if (!(s = sfstruse(sp)) || write(fd, s, n) != n)
+ r |= c;
+ }
+ sfstrclose(sp);
+ return r;
+}
+
+#endif
diff --git a/src/lib/libast/comp/fnmatch.c b/src/lib/libast/comp/fnmatch.c
new file mode 100644
index 0000000..6c31998
--- /dev/null
+++ b/src/lib/libast/comp/fnmatch.c
@@ -0,0 +1,79 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * fnmatch implementation
+ */
+
+#include <ast_lib.h>
+
+#include <ast.h>
+#include <regex.h>
+#include <fnmatch.h>
+
+typedef struct
+{
+ int fnm; /* fnmatch flag */
+ int reg; /* regex flag */
+} Map_t;
+
+static const Map_t map[] =
+{
+ FNM_AUGMENTED, REG_AUGMENTED,
+ FNM_ICASE, REG_ICASE,
+ FNM_NOESCAPE, REG_SHELL_ESCAPED,
+ FNM_PATHNAME, REG_SHELL_PATH,
+ FNM_PERIOD, REG_SHELL_DOT,
+};
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+fnmatch(const char* pattern, const char* subject, register int flags)
+{
+ register int reflags = REG_SHELL|REG_LEFT;
+ register const Map_t* mp;
+ regex_t re;
+ regmatch_t match;
+
+ for (mp = map; mp < &map[elementsof(map)]; mp++)
+ if (flags & mp->fnm)
+ reflags |= mp->reg;
+ if (flags & FNM_LEADING_DIR)
+ {
+ if (!(reflags = regcomp(&re, pattern, reflags)))
+ {
+ reflags = regexec(&re, subject, 1, &match, 0);
+ regfree(&re);
+ if (!reflags && (reflags = subject[match.rm_eo]))
+ reflags = reflags == '/' ? 0 : FNM_NOMATCH;
+ }
+ }
+ else if (!(reflags = regcomp(&re, pattern, reflags|REG_RIGHT)))
+ {
+ reflags = regexec(&re, subject, 0, NiL, 0);
+ regfree(&re);
+ }
+ return reflags;
+}
diff --git a/src/lib/libast/comp/fnmatch.h b/src/lib/libast/comp/fnmatch.h
new file mode 100644
index 0000000..945e645
--- /dev/null
+++ b/src/lib/libast/comp/fnmatch.h
@@ -0,0 +1,61 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * posix fnmatch interface definitions
+ */
+
+#ifndef _FNMATCH_H
+#define _FNMATCH_H
+
+#include <ast_common.h>
+
+/* fnmatch flags */
+
+#define FNM_NOESCAPE 0x0001 /* \ is literal */
+#define FNM_PATHNAME 0x0002 /* explicit match for / */
+#define FNM_PERIOD 0x0004 /* explicit match for leading . */
+#define FNM_NOSYS 0x0010 /* not implemented */
+
+/* nonstandard fnmatch() flags */
+
+#define FNM_AUGMENTED 0x0008 /* enable ! & ( | ) */
+#define FNM_ICASE 0x0020 /* ignore case in match */
+#define FNM_LEADING_DIR 0x0040 /* match up to implicit / */
+
+#define FNM_CASEFOLD FNM_ICASE /* gnu/bsd compatibility */
+#define FNM_IGNORECASE FNM_ICASE /* gnu/bsd compatibility */
+#define FNM_FILE_NAME FNM_PATHNAME /* gnu compatibility */
+
+/* fnmatch error codes -- other non-zero values from <regex.h> */
+
+#define FNM_NOMATCH 1 /* == REG_NOMATCH */
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int fnmatch(const char*, const char*, int);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/comp/frexp.c b/src/lib/libast/comp/frexp.c
new file mode 100644
index 0000000..02cd50f
--- /dev/null
+++ b/src/lib/libast/comp/frexp.c
@@ -0,0 +1,153 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * frexp/ldexp implementation
+ */
+
+#include <ast.h>
+
+#include "FEATURE/float"
+
+#if _lib_frexp && _lib_ldexp
+
+NoN(frexp)
+
+#else
+
+#if defined(_ast_dbl_exp_index) && defined(_ast_dbl_exp_shift)
+
+#define INIT() _ast_dbl_exp_t _pow_
+#define pow2(i) (_pow_.f=1,_pow_.e[_ast_dbl_exp_index]+=((i)<<_ast_dbl_exp_shift),_pow_.f)
+
+#else
+
+static double pow2tab[DBL_MAX_EXP + 1];
+
+static int
+init(void)
+{
+ register int x;
+ double g;
+
+ g = 1;
+ for (x = 0; x < elementsof(pow2tab); x++)
+ {
+ pow2tab[x] = g;
+ g *= 2;
+ }
+ return 0;
+}
+
+#define INIT() (pow2tab[0]?0:init())
+
+#define pow2(i) pow2tab[i]
+
+#endif
+
+#if !_lib_frexp
+
+extern double
+frexp(double f, int* p)
+{
+ register int k;
+ register int x;
+ double g;
+
+ INIT();
+
+ /*
+ * normalize
+ */
+
+ x = k = DBL_MAX_EXP / 2;
+ if (f < 1)
+ {
+ g = 1.0L / f;
+ for (;;)
+ {
+ k = (k + 1) / 2;
+ if (g < pow2(x))
+ x -= k;
+ else if (k == 1 && g < pow2(x+1))
+ break;
+ else
+ x += k;
+ }
+ if (g == pow2(x))
+ x--;
+ x = -x;
+ }
+ else if (f > 1)
+ {
+ for (;;)
+ {
+ k = (k + 1) / 2;
+ if (f > pow2(x))
+ x += k;
+ else if (k == 1 && f > pow2(x-1))
+ break;
+ else
+ x -= k;
+ }
+ if (f == pow2(x))
+ x++;
+ }
+ else
+ x = 1;
+ *p = x;
+
+ /*
+ * shift
+ */
+
+ x = -x;
+ if (x < 0)
+ f /= pow2(-x);
+ else if (x < DBL_MAX_EXP)
+ f *= pow2(x);
+ else
+ f = (f * pow2(DBL_MAX_EXP - 1)) * pow2(x - (DBL_MAX_EXP - 1));
+ return f;
+}
+
+#endif
+
+#if !_lib_ldexp
+
+extern double
+ldexp(double f, register int x)
+{
+ INIT();
+ if (x < 0)
+ f /= pow2(-x);
+ else if (x < DBL_MAX_EXP)
+ f *= pow2(x);
+ else
+ f = (f * pow2(DBL_MAX_EXP - 1)) * pow2(x - (DBL_MAX_EXP - 1));
+ return f;
+}
+
+#endif
+
+#endif
diff --git a/src/lib/libast/comp/frexpl.c b/src/lib/libast/comp/frexpl.c
new file mode 100644
index 0000000..5d90ad9
--- /dev/null
+++ b/src/lib/libast/comp/frexpl.c
@@ -0,0 +1,161 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * frexpl/ldexpl implementation
+ */
+
+#include <ast.h>
+
+#include "FEATURE/float"
+
+#if _lib_frexpl && _lib_ldexpl
+
+NoN(frexpl)
+
+#else
+
+#ifndef LDBL_MAX_EXP
+#define LDBL_MAX_EXP DBL_MAX_EXP
+#endif
+
+#if defined(_ast_fltmax_exp_index) && defined(_ast_fltmax_exp_shift)
+
+#define INIT() _ast_fltmax_exp_t _pow_
+#define pow2(i) (_pow_.f=1,_pow_.e[_ast_fltmax_exp_index]+=((i)<<_ast_fltmax_exp_shift),_pow_.f)
+
+#else
+
+static _ast_fltmax_t pow2tab[LDBL_MAX_EXP + 1];
+
+static int
+init(void)
+{
+ register int x;
+ _ast_fltmax_t g;
+
+ g = 1;
+ for (x = 0; x < elementsof(pow2tab); x++)
+ {
+ pow2tab[x] = g;
+ g *= 2;
+ }
+ return 0;
+}
+
+#define INIT() (pow2tab[0]?0:init())
+
+#define pow2(i) (pow2tab[i])
+
+#endif
+
+#if !_lib_frexpl
+
+#undef frexpl
+
+extern _ast_fltmax_t
+frexpl(_ast_fltmax_t f, int* p)
+{
+ register int k;
+ register int x;
+ _ast_fltmax_t g;
+
+ INIT();
+
+ /*
+ * normalize
+ */
+
+ x = k = LDBL_MAX_EXP / 2;
+ if (f < 1)
+ {
+ g = 1.0L / f;
+ for (;;)
+ {
+ k = (k + 1) / 2;
+ if (g < pow2(x))
+ x -= k;
+ else if (k == 1 && g < pow2(x+1))
+ break;
+ else
+ x += k;
+ }
+ if (g == pow2(x))
+ x--;
+ x = -x;
+ }
+ else if (f > 1)
+ {
+ for (;;)
+ {
+ k = (k + 1) / 2;
+ if (f > pow2(x))
+ x += k;
+ else if (k == 1 && f > pow2(x-1))
+ break;
+ else
+ x -= k;
+ }
+ if (f == pow2(x))
+ x++;
+ }
+ else
+ x = 1;
+ *p = x;
+
+ /*
+ * shift
+ */
+
+ x = -x;
+ if (x < 0)
+ f /= pow2(-x);
+ else if (x < LDBL_MAX_EXP)
+ f *= pow2(x);
+ else
+ f = (f * pow2(LDBL_MAX_EXP - 1)) * pow2(x - (LDBL_MAX_EXP - 1));
+ return f;
+}
+
+#endif
+
+#if !_lib_ldexpl
+
+#undef ldexpl
+
+extern _ast_fltmax_t
+ldexpl(_ast_fltmax_t f, register int x)
+{
+ INIT();
+ if (x < 0)
+ f /= pow2(-x);
+ else if (x < LDBL_MAX_EXP)
+ f *= pow2(x);
+ else
+ f = (f * pow2(LDBL_MAX_EXP - 1)) * pow2(x - (LDBL_MAX_EXP - 1));
+ return f;
+}
+
+#endif
+
+#endif
diff --git a/src/lib/libast/comp/fsync.c b/src/lib/libast/comp/fsync.c
new file mode 100644
index 0000000..4223fa0
--- /dev/null
+++ b/src/lib/libast/comp/fsync.c
@@ -0,0 +1,46 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_fsync
+
+NoN(fsync)
+
+#else
+
+#include <error.h>
+
+#ifndef ENOSYS
+#define ENOSYS EINVAL
+#endif
+
+int
+fsync(int fd)
+{
+ NoP(fd);
+ errno = ENOSYS;
+ return -1;
+}
+
+#endif
diff --git a/src/lib/libast/comp/ftw.c b/src/lib/libast/comp/ftw.c
new file mode 100644
index 0000000..4722628
--- /dev/null
+++ b/src/lib/libast/comp/ftw.c
@@ -0,0 +1,50 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * ftw implementation
+ */
+
+#include <ast.h>
+#include <ftw.h>
+
+static int (*ftw_userf)(const char*, const struct stat*, int);
+
+static int
+ftw_user(Ftw_t* ftw)
+{
+ register int n = ftw->info;
+
+ if (n & (FTW_C|FTW_NX))
+ n = FTW_DNR;
+ else if (n & FTW_SL)
+ n = FTW_NS;
+ return (*ftw_userf)(ftw->path, &ftw->statb, n);
+}
+
+int
+ftw(const char* path, int(*userf)(const char*, const struct stat*, int), int depth)
+{
+ NoP(depth);
+ ftw_userf = userf;
+ return ftwalk(path, ftw_user, FTW_DOT, NiL);
+}
diff --git a/src/lib/libast/comp/ftw.h b/src/lib/libast/comp/ftw.h
new file mode 100644
index 0000000..a61f548
--- /dev/null
+++ b/src/lib/libast/comp/ftw.h
@@ -0,0 +1,60 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * ftw,nftw over ftwalk
+ */
+
+#ifndef _FTW_H
+#define _FTW_H
+
+#define FTW FTWALK
+#include <ftwalk.h>
+#undef FTW
+
+#define FTW_SLN (FTW_SL|FTW_NR)
+
+#define FTW_PHYS (FTW_PHYSICAL)
+#define FTW_CHDIR (FTW_DOT)
+#define FTW_DEPTH (FTW_POST)
+#define FTW_OPEN (0)
+
+struct FTW
+{
+ int quit;
+ int base;
+ int level;
+};
+
+#define FTW_SKD FTW_SKIP
+#define FTW_PRUNE FTW_SKIP
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int ftw(const char*, int(*)(const char*, const struct stat*, int), int);
+extern int nftw(const char*, int(*)(const char*, const struct stat*, int, struct FTW*), int, int);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/comp/getdate.c b/src/lib/libast/comp/getdate.c
new file mode 100644
index 0000000..455c5fb
--- /dev/null
+++ b/src/lib/libast/comp/getdate.c
@@ -0,0 +1,83 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * getdate implementation
+ */
+
+#define getdate ______getdate
+
+#include <ast.h>
+#include <tm.h>
+
+#undef getdate
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+#undef _lib_getdate /* we can pass X/Open */
+
+#if _lib_getdate
+
+NoN(getdate)
+
+#else
+
+#ifndef getdate_err
+__DEFINE__(int, getdate_err, 0);
+#endif
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern struct tm*
+getdate(const char* s)
+{
+ char* e;
+ char* f;
+ time_t t;
+ Tm_t* tm;
+
+ static struct tm ts;
+
+ t = tmscan(s, &e, NiL, &f, NiL, TM_PEDANTIC);
+ if (*e || *f)
+ {
+ /* of course we all know what 7 means */
+ getdate_err = 7;
+ return 0;
+ }
+ tm = tmmake(&t);
+ ts.tm_sec = tm->tm_sec;
+ ts.tm_min = tm->tm_min;
+ ts.tm_hour = tm->tm_hour;
+ ts.tm_mday = tm->tm_mday;
+ ts.tm_mon = tm->tm_mon;
+ ts.tm_year = tm->tm_year;
+ ts.tm_wday = tm->tm_wday;
+ ts.tm_yday = tm->tm_yday;
+ ts.tm_isdst = tm->tm_isdst;
+ return &ts;
+}
+
+#endif
diff --git a/src/lib/libast/comp/getgroups.c b/src/lib/libast/comp/getgroups.c
new file mode 100644
index 0000000..8b90bf0
--- /dev/null
+++ b/src/lib/libast/comp/getgroups.c
@@ -0,0 +1,78 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if !defined(getgroups) && defined(_lib_getgroups)
+
+NoN(getgroups)
+
+#else
+
+#include <error.h>
+
+#if defined(getgroups)
+#undef getgroups
+#define ast_getgroups _ast_getgroups
+#define botched 1
+extern int getgroups(int, int*);
+#else
+#define ast_getgroups getgroups
+#endif
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+ast_getgroups(int len, gid_t* set)
+{
+#if botched
+#if NGROUPS_MAX < 1
+#undef NGROUPS_MAX
+#define NGROUPS_MAX 1
+#endif
+ register int i;
+ int big[NGROUPS_MAX];
+#else
+#undef NGROUPS_MAX
+#define NGROUPS_MAX 1
+#endif
+ if (!len) return(NGROUPS_MAX);
+ if (len < 0 || !set)
+ {
+ errno = EINVAL;
+ return(-1);
+ }
+#if botched
+ len = getgroups(len > NGROUPS_MAX ? NGROUPS_MAX : len, big);
+ for (i = 0; i < len; i++)
+ set[i] = big[i];
+ return(len);
+#else
+ *set = getgid();
+ return(1);
+#endif
+}
+
+#endif
diff --git a/src/lib/libast/comp/getlogin.c b/src/lib/libast/comp/getlogin.c
new file mode 100644
index 0000000..7611dbb
--- /dev/null
+++ b/src/lib/libast/comp/getlogin.c
@@ -0,0 +1,42 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_getlogin
+
+NoN(getlogin)
+
+#else
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char*
+getlogin(void)
+{
+ return fmtuid(getuid());
+}
+
+#endif
diff --git a/src/lib/libast/comp/getopt.c b/src/lib/libast/comp/getopt.c
new file mode 100644
index 0000000..c5c6f19
--- /dev/null
+++ b/src/lib/libast/comp/getopt.c
@@ -0,0 +1,78 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#undef _lib_getopt /* we can satisfy the api */
+
+#if _lib_getopt
+
+NoN(getopt)
+
+#else
+
+#undef _BLD_ast /* enable ast imports since we're user static */
+
+#include <error.h>
+#include <option.h>
+
+int opterr = 1;
+int optind = 1;
+int optopt = 0;
+char* optarg = 0;
+
+static int lastoptind;
+
+extern int
+getopt(int argc, char* const* argv, const char* optstring)
+{
+ int n;
+
+ NoP(argc);
+ opt_info.index = (optind > 1 || optind == lastoptind) ? optind : 0;
+ if (opt_info.index >= argc)
+ return -1;
+ switch (n = optget((char**)argv, optstring))
+ {
+ case ':':
+ n = '?';
+ /*FALLTHROUGH*/
+ case '?':
+ if (opterr && (!optstring || *optstring != ':'))
+ {
+ if (!error_info.id)
+ error_info.id = argv[0];
+ errormsg(NiL, 2, opt_info.arg);
+ }
+ optopt = opt_info.option[1];
+ break;
+ case 0:
+ n = -1;
+ break;
+ }
+ optarg = opt_info.arg;
+ lastoptind = optind = opt_info.index;
+ return n;
+}
+
+#endif
diff --git a/src/lib/libast/comp/getopt.h b/src/lib/libast/comp/getopt.h
new file mode 100644
index 0000000..110ce39
--- /dev/null
+++ b/src/lib/libast/comp/getopt.h
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * gnu getopt interface
+ */
+
+#ifndef _GETOPT_H
+#ifdef _AST_STD_I
+#define _GETOPT_H -1
+#else
+#define _GETOPT_H 1
+
+#include <ast_getopt.h>
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+struct option
+{
+ const char* name;
+ int has_arg;
+ int* flag;
+ int val;
+};
+
+extern int getopt_long(int, char* const*, const char*, const struct option*, int*);
+extern int getopt_long_only(int, char* const*, const char*, const struct option*, int*);
+
+#endif
+#endif
diff --git a/src/lib/libast/comp/getoptl.c b/src/lib/libast/comp/getoptl.c
new file mode 100644
index 0000000..edfa4f1
--- /dev/null
+++ b/src/lib/libast/comp/getoptl.c
@@ -0,0 +1,151 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+#include <ast_getopt.h>
+
+#undef _BLD_ast /* enable ast imports since we're user static */
+
+#include <error.h>
+#include <option.h>
+#include <getopt.h>
+#include <ctype.h>
+
+static const char* lastoptstring;
+static const struct option* lastlongopts;
+static char* usage;
+static Sfio_t* up;
+
+static int lastoptind;
+
+static int
+golly(int argc, char* const* argv, const char* optstring, const struct option* longopts, int* longindex, int flags)
+{
+ register char* s;
+ register const struct option* o;
+ register int c;
+ char* t;
+
+ if (!up || optstring != lastoptstring || longopts != lastlongopts)
+ {
+ if (!up && !(up = sfstropen()) || !(t = strdup(optstring)))
+ return -1;
+ sfprintf(up, "[-1p%d]", flags);
+ for (o = longopts; o->name; o++)
+ {
+ if (o->flag || o->val <= 0 || o->val > UCHAR_MAX || !isalnum(o->val))
+ sfprintf(up, "\n[%d:%s]", UCHAR_MAX + 1 + (o - longopts), o->name);
+ else
+ {
+ sfprintf(up, "\n[%c:%s]", o->val, o->name);
+ if (s = strchr(t, o->val))
+ {
+ *s++ = ' ';
+ if (*s == ':')
+ {
+ *s++ = ' ';
+ if (*s == ':')
+ *s = ' ';
+ }
+ }
+ }
+ if (o->has_arg)
+ {
+ sfputc(up, ':');
+ if (o->has_arg == optional_argument)
+ sfputc(up, '?');
+ sfprintf(up, "[string]");
+ }
+ }
+ s = t;
+ while (c = *s++)
+ if (c != ' ')
+ {
+ sfprintf(up, "\n[%c]", c);
+ if (*s == ':')
+ {
+ sfputc(up, *s);
+ if (*++s == ':')
+ {
+ sfputc(up, '?');
+ s++;
+ }
+ sfputc(up, '[');
+ sfputc(up, ']');
+ }
+ }
+ sfputc(up, '\n');
+ free(t);
+ if (!(usage = sfstruse(up)))
+ return -1;
+ lastoptstring = optstring;
+ lastlongopts = longopts;
+ }
+ opt_info.index = (optind > 1 || optind == lastoptind) ? optind : 0;
+ if (opt_info.index >= argc || !(c = optget((char**)argv, usage)))
+ {
+ sfstrclose(up);
+ up = 0;
+ c = -1;
+ }
+ else
+ {
+ if (c == ':' || c == '?')
+ {
+ if (opterr && (!optstring || *optstring != ':'))
+ {
+ if (!error_info.id)
+ error_info.id = argv[0];
+ errormsg(NiL, c == '?' ? (ERROR_USAGE|4) : 2, "%s", opt_info.arg);
+ }
+ optopt = opt_info.option[1];
+ c = '?';
+ }
+ optarg = opt_info.arg;
+ if (c < 0)
+ {
+ o = longopts - c - UCHAR_MAX - 1;
+ if (o->flag)
+ {
+ *o->flag = o->val;
+ c = 0;
+ }
+ else
+ c = o->val;
+ }
+ }
+ lastoptind = optind = opt_info.index;
+ return c;
+}
+
+extern int
+getopt_long(int argc, char* const* argv, const char* optstring, const struct option* longopts, int* longindex)
+{
+ return golly(argc, argv, optstring, longopts, longindex, 2);
+}
+
+extern int
+getopt_long_only(int argc, char* const* argv, const char* optstring, const struct option* longopts, int* longindex)
+{
+ return golly(argc, argv, optstring, longopts, longindex, 1);
+}
diff --git a/src/lib/libast/comp/getpgrp.c b/src/lib/libast/comp/getpgrp.c
new file mode 100644
index 0000000..b38ad8a
--- /dev/null
+++ b/src/lib/libast/comp/getpgrp.c
@@ -0,0 +1,47 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#define getpgrp ______getpgrp
+
+#include <ast_std.h>
+
+#undef getpgrp
+
+/*
+ * bsd int getpgrp(int);
+ * s5 int getpgrp(void);
+ * posix pid_t getpgrp(void);
+ * user SOL
+ */
+
+extern int getpgrp(int);
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+_ast_getpgrp(void)
+{
+ return getpgrp(0);
+}
diff --git a/src/lib/libast/comp/getsubopt.c b/src/lib/libast/comp/getsubopt.c
new file mode 100644
index 0000000..9d7162c
--- /dev/null
+++ b/src/lib/libast/comp/getsubopt.c
@@ -0,0 +1,84 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Xopen 4.2 compatibility
+ */
+
+#include <ast.h>
+
+#undef _lib_getsubopt /* we can satisfy the api */
+
+#if _lib_getsubopt
+
+NoN(getsubopt)
+
+#else
+
+#undef _BLD_ast /* enable ast imports since we're user static */
+
+#include <error.h>
+
+extern int
+getsubopt(register char** op, char* const* tp, char** vp)
+{
+ register char* b;
+ register char* s;
+ register char* v;
+
+ if (*(b = *op))
+ {
+ v = 0;
+ s = b;
+ for (;;)
+ {
+ switch (*s++)
+ {
+ case 0:
+ s--;
+ break;
+ case ',':
+ *(s - 1) = 0;
+ break;
+ case '=':
+ if (!v)
+ {
+ *(s - 1) = 0;
+ v = s;
+ }
+ continue;
+ default:
+ continue;
+ }
+ break;
+ }
+ *op = s;
+ *vp = v;
+ for (op = (char**)tp; *op; op++)
+ if (streq(b, *op))
+ return op - (char**)tp;
+ }
+ *vp = b;
+ return -1;
+}
+
+#endif
diff --git a/src/lib/libast/comp/getwd.c b/src/lib/libast/comp/getwd.c
new file mode 100644
index 0000000..e600155
--- /dev/null
+++ b/src/lib/libast/comp/getwd.c
@@ -0,0 +1,37 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * getwd() using getcwd()
+ *
+ * some getwd()'s are incredible
+ */
+
+#include <ast.h>
+
+char*
+getwd(char* path)
+{
+ if (getcwd(path, PATH_MAX)) return(path);
+ strcpy(path, "getwd: error in . or ..");
+ return(0);
+}
diff --git a/src/lib/libast/comp/gross.c b/src/lib/libast/comp/gross.c
new file mode 100644
index 0000000..cf5be0d
--- /dev/null
+++ b/src/lib/libast/comp/gross.c
@@ -0,0 +1,99 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * porting hacks here
+ */
+
+#include <ast.h>
+#include <ls.h>
+
+#include "FEATURE/hack"
+
+void _STUB_gross(){}
+
+#if _lcl_xstat
+
+extern int fstat(int fd, struct stat* st)
+{
+#if _lib___fxstat
+ return __fxstat(_STAT_VER, fd, st);
+#else
+ return _fxstat(_STAT_VER, fd, st);
+#endif
+}
+
+extern int lstat(const char* path, struct stat* st)
+{
+#if _lib___lxstat
+ return __lxstat(_STAT_VER, path, st);
+#else
+ return _lxstat(_STAT_VER, path, st);
+#endif
+}
+
+extern int stat(const char* path, struct stat* st)
+{
+#if _lib___xstat
+ return __xstat(_STAT_VER, path, st);
+#else
+ return _xstat(_STAT_VER, path, st);
+#endif
+}
+
+#endif
+
+#if _lcl_xstat64
+
+extern int fstat64(int fd, struct stat64* st)
+{
+#if _lib___fxstat64
+ return __fxstat64(_STAT_VER, fd, st);
+#else
+ return _fxstat64(_STAT_VER, fd, st);
+#endif
+}
+
+extern int lstat64(const char* path, struct stat64* st)
+{
+#if _lib___lxstat64
+ return __lxstat64(_STAT_VER, path, st);
+#else
+ return _lxstat64(_STAT_VER, path, st);
+#endif
+}
+
+extern int stat64(const char* path, struct stat64* st)
+{
+#if _lib___xstat64
+ return __xstat64(_STAT_VER, path, st);
+#else
+ return _xstat64(_STAT_VER, path, st);
+#endif
+}
+
+#endif
+
+#if __sgi && _hdr_locale_attr
+
+#include "gross_sgi.h"
+
+#endif
diff --git a/src/lib/libast/comp/gross_sgi.h b/src/lib/libast/comp/gross_sgi.h
new file mode 100644
index 0000000..7469789
--- /dev/null
+++ b/src/lib/libast/comp/gross_sgi.h
@@ -0,0 +1,188 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if __sgi && _hdr_locale_attr
+
+/*
+ * irix 6.5 introduced __libc_attr referenced by
+ * ctype and locale macros; this hack lets
+ * 6.5 a.outs run on irix < 6.5
+ *
+ * NOTE: this hack also freezes the US locale
+ */
+
+#include <locale_attr.h>
+
+static __ctype_t _ast_ctype_tbl =
+{
+ {
+ 0x00000000, 0x00000020, 0x00000020, 0x00000020,
+ 0x00000020, 0x00000020, 0x00000020, 0x00000020,
+ 0x00000020, 0x00000020, 0x80000028, 0x00000028,
+ 0x00000028, 0x00000028, 0x00000028, 0x00000020,
+ 0x00000020, 0x00000020, 0x00000020, 0x00000020,
+ 0x00000020, 0x00000020, 0x00000020, 0x00000020,
+ 0x00000020, 0x00000020, 0x00000020, 0x00000020,
+ 0x00000020, 0x00000020, 0x00000020, 0x00000020,
+ 0x00000020, 0x80008008, 0x00000010, 0x00000010,
+ 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+ 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+ 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+ 0x00000010, 0x00000084, 0x00000084, 0x00000084,
+ 0x00000084, 0x00000084, 0x00000084, 0x00000084,
+ 0x00000084, 0x00000084, 0x00000084, 0x00000010,
+ 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+ 0x00000010, 0x00000010, 0x00000081, 0x00000081,
+ 0x00000081, 0x00000081, 0x00000081, 0x00000081,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+ 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+ 0x00000010, 0x00000010, 0x00000082, 0x00000082,
+ 0x00000082, 0x00000082, 0x00000082, 0x00000082,
+ 0x00000002, 0x00000002, 0x00000002, 0x00000002,
+ 0x00000002, 0x00000002, 0x00000002, 0x00000002,
+ 0x00000002, 0x00000002, 0x00000002, 0x00000002,
+ 0x00000002, 0x00000002, 0x00000002, 0x00000002,
+ 0x00000002, 0x00000002, 0x00000002, 0x00000002,
+ 0x00000010, 0x00000010, 0x00000010, 0x00000010,
+ 0x00000020, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000,
+ },
+ {
+ -1, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 97, 98, 99, 100, 101, 102,
+ 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 115, 116, 117, 118,
+ 119, 120, 121, 122, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102,
+ 103, 104, 105, 106, 107, 108, 109, 110,
+ 111, 112, 113, 114, 115, 116, 117, 118,
+ 119, 120, 121, 122, 123, 124, 125, 126,
+ 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142,
+ 143, 144, 145, 146, 147, 148, 149, 150,
+ 151, 152, 153, 154, 155, 156, 157, 158,
+ 159, 160, 161, 162, 163, 164, 165, 166,
+ 167, 168, 169, 170, 171, 172, 173, 174,
+ 175, 176, 177, 178, 179, 180, 181, 182,
+ 183, 184, 185, 186, 187, 188, 189, 190,
+ 191, 192, 193, 194, 195, 196, 197, 198,
+ 199, 200, 201, 202, 203, 204, 205, 206,
+ 207, 208, 209, 210, 211, 212, 213, 214,
+ 215, 216, 217, 218, 219, 220, 221, 222,
+ 223, 224, 225, 226, 227, 228, 229, 230,
+ 231, 232, 233, 234, 235, 236, 237, 238,
+ 239, 240, 241, 242, 243, 244, 245, 246,
+ 247, 248, 249, 250, 251, 252, 253, 254,
+ 255,
+ },
+ {
+ -1, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46,
+ 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62,
+ 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78,
+ 79, 80, 81, 82, 83, 84, 85, 86,
+ 87, 88, 89, 90, 123, 124, 125, 126,
+ 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142,
+ 143, 144, 145, 146, 147, 148, 149, 150,
+ 151, 152, 153, 154, 155, 156, 157, 158,
+ 159, 160, 161, 162, 163, 164, 165, 166,
+ 167, 168, 169, 170, 171, 172, 173, 174,
+ 175, 176, 177, 178, 179, 180, 181, 182,
+ 183, 184, 185, 186, 187, 188, 189, 190,
+ 191, 192, 193, 194, 195, 196, 197, 198,
+ 199, 200, 201, 202, 203, 204, 205, 206,
+ 207, 208, 209, 210, 211, 212, 213, 214,
+ 215, 216, 217, 218, 219, 220, 221, 222,
+ 223, 224, 225, 226, 227, 228, 229, 230,
+ 231, 232, 233, 234, 235, 236, 237, 238,
+ 239, 240, 241, 242, 243, 244, 245, 246,
+ 247, 248, 249, 250, 251, 252, 253, 254,
+ 255,
+ },
+ {
+ 000, 000, 000, 000, 000, 000, 000,
+ },
+};
+
+extern __attr_t ___libc_attr =
+{
+ &_ast_ctype_tbl,
+ { 0 },
+ { 0 },
+ { 1 },
+};
+
+#pragma weak __libc_attr = ___libc_attr
+
+#endif
diff --git a/src/lib/libast/comp/hsearch.c b/src/lib/libast/comp/hsearch.c
new file mode 100644
index 0000000..43953e4
--- /dev/null
+++ b/src/lib/libast/comp/hsearch.c
@@ -0,0 +1,138 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * hsearch() for systems that have <search.h> but no hsearch()
+ * why would such a system provide the interface but not the
+ * implementation? that's what happens when one slimes their
+ * way through standards compliance
+ *
+ * NOTE: please excuse the crude feature test
+ */
+
+#if !_UWIN
+
+void _STUB_hsearch(){}
+
+#else
+
+#if _PACKAGE_ast
+#include <ast.h>
+#endif
+
+#define hcreate ______hcreate
+#define hdestroy ______hdestroy
+#define hsearch ______hsearch
+
+#include <search.h>
+
+#undef hcreate
+#undef hdestroy
+#undef hsearch
+
+#include "dthdr.h"
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+/* POSIX hsearch library based on libdt
+** Written by Kiem-Phong Vo (AT&T Research, 07/19/95)
+*/
+
+/* type of objects in hash table */
+typedef struct _hash_s
+{ Dtlink_t link;
+ ENTRY item;
+} Hash_t;
+
+/* object delete function */
+#if __STD_C
+static void hashfree(Dt_t* dt, Void_t* obj, Dtdisc_t* disc)
+#else
+static void hashfree(dt, obj, disc)
+Dt_t* dt;
+Void_t* obj;
+Dtdisc_t* disc;
+#endif
+{
+ free(((Hash_t*)obj)->item.key);
+ free(obj);
+}
+
+static Dt_t* Hashtab; /* object dictionary */
+static Dtdisc_t Hashdisc = /* discipline */
+{ sizeof(Dtlink_t), -1,
+ 0,
+ NIL(Dtmake_f), hashfree,
+ NIL(Dtcompar_f), /* always use strcmp */
+ NIL(Dthash_f),
+ NIL(Dtmemory_f),
+ NIL(Dtevent_f)
+};
+
+extern
+#if __STD_C
+int hcreate(size_t nel)
+#else
+int hcreate(nel)
+size_t nel;
+#endif
+{
+ if(Hashtab) /* already opened */
+ return 0;
+
+ if(!(Hashtab = dtopen(&Hashdisc,Dtset)) )
+ return 0;
+
+ return 1;
+}
+
+extern void hdestroy()
+{ if(Hashtab)
+ dtclose(Hashtab);
+ Hashtab = NIL(Dt_t*);
+}
+
+extern
+#if __STD_C
+ENTRY* hsearch(ENTRY item, ACTION action)
+#else
+ENTRY* hsearch(item, action)
+ENTRY item;
+ACTION action;
+#endif
+{
+ reg Hash_t* o;
+
+ if(!Hashtab)
+ return NIL(ENTRY*);
+
+ if(!(o = (Hash_t*)dtmatch(Hashtab,item.key)) && action == ENTER &&
+ (o = (Hash_t*)malloc(sizeof(Hash_t)) ) )
+ { o->item = item;
+ o = (Hash_t*)dtinsert(Hashtab,o);
+ }
+
+ return o ? &(o->item) : NIL(ENTRY*);
+}
+
+#endif
diff --git a/src/lib/libast/comp/iconv.c b/src/lib/libast/comp/iconv.c
new file mode 100644
index 0000000..ba24988
--- /dev/null
+++ b/src/lib/libast/comp/iconv.c
@@ -0,0 +1,1599 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * iconv intercept
+ * minimally provides { utf*<=>bin ascii<=>ebcdic* }
+ */
+
+#include <ast.h>
+#include <dirent.h>
+
+#define DEBUG_TRACE 0
+#define _ICONV_LIST_PRIVATE_
+
+#include <ccode.h>
+#include <ctype.h>
+#include <iconv.h>
+
+#include "lclib.h"
+
+#if !_lib_iconv_open
+
+#define _ast_iconv_t iconv_t
+#define _ast_iconv_f iconv_f
+#define _ast_iconv_list_t iconv_list_t
+#define _ast_iconv_open iconv_open
+#define _ast_iconv iconv
+#define _ast_iconv_close iconv_close
+#define _ast_iconv_list iconv_list
+#define _ast_iconv_move iconv_move
+#define _ast_iconv_name iconv_name
+#define _ast_iconv_write iconv_write
+
+#endif
+
+#ifndef E2BIG
+#define E2BIG ENOMEM
+#endif
+#ifndef EILSEQ
+#define EILSEQ EIO
+#endif
+
+#define RETURN(e,n,fn) \
+ if (*fn && !e) e = E2BIG; \
+ if (e) { errno = e; return (size_t)(-1); } \
+ return n;
+
+typedef struct Map_s
+{
+ char* name;
+ const unsigned char* map;
+ _ast_iconv_f fun;
+ int index;
+} Map_t;
+
+typedef struct Conv_s
+{
+ iconv_t cvt;
+ char* buf;
+ size_t size;
+ Map_t from;
+ Map_t to;
+} Conv_t;
+
+static Conv_t* freelist[4];
+static int freeindex;
+
+static const char name_local[] = "local";
+static const char name_native[] = "native";
+
+static const _ast_iconv_list_t codes[] =
+{
+ {
+ "utf",
+ "un|unicode|utf",
+ "multibyte 8-bit unicode",
+ "UTF-%s",
+ "8",
+ CC_UTF,
+ },
+
+ {
+ "ume",
+ "um|ume|utf?(-)7",
+ "multibyte 7-bit unicode",
+ "UTF-7",
+ 0,
+ CC_UME,
+ },
+
+ {
+ "euc",
+ "(big|euc)*",
+ "euc family",
+ 0,
+ 0,
+ CC_ICONV,
+ },
+
+ {
+ "dos",
+ "dos?(-)?(855)",
+ "dos code page",
+ "DOS855",
+ 0,
+ CC_ICONV,
+ },
+
+ {
+ "ucs",
+ "ucs?(-)?(2)?(be)|utf-16?(be)",
+ "unicode runes",
+ "UCS-%s",
+ "2",
+ CC_UCS,
+ },
+
+ {
+ "ucs-le",
+ "ucs?(-)?(2)le|utf-16le",
+ "little endian unicode runes",
+ "UCS-%sLE",
+ "2",
+ CC_SCU,
+ },
+
+ { 0 },
+};
+
+#if _UWIN
+
+#include <ast_windows.h>
+
+#ifndef CP_UCS2
+#define CP_UCS2 0x0000
+#endif
+
+static char _win_maps[] = "/reg/local_machine/SOFTWARE/Classes/MIME/Database/Charset";
+
+/*
+ * return the codeset index given its name or alias
+ * the map is in the what? oh, the registry
+ */
+
+static int
+_win_codeset(const char* name)
+{
+ register char* s;
+ char* e;
+ int n;
+ Sfio_t* sp;
+ char aka[128];
+ char tmp[128];
+
+#if DEBUG_TRACE
+error(DEBUG_TRACE, "AHA#%d _win_codeset name=%s", __LINE__, name);
+#endif
+ if (name == name_native)
+ return CP_ACP;
+ if (!strcasecmp(name, "utf") || !strcasecmp(name, "utf8") || !strcasecmp(name, "utf-8"))
+ return CP_UTF8;
+ if (!strcasecmp(name, "ucs") || !strcasecmp(name, "ucs2") || !strcasecmp(name, "ucs-2"))
+ return CP_UCS2;
+ if (name[0] == '0' && name[1] == 'x' && (n = strtol(name, &e, 0)) > 0 && !*e)
+ return n;
+ for (;;)
+ {
+ sfsprintf(tmp, sizeof(tmp), "%s/%s", _win_maps, name);
+ if (!(sp = sfopen(0, tmp, "r")))
+ {
+ s = (char*)name;
+ if ((s[0] == 'c' || s[0] == 'C') && (s[1] == 'p' || s[1] == 'P'))
+ s += 2;
+ if (!isdigit(s[0]))
+ break;
+ sfsprintf(tmp, sizeof(tmp), "%s/windows-%s", _win_maps, s);
+ if (!(sp = sfopen(0, tmp, "r")))
+ break;
+ }
+ for (;;)
+ {
+ if (!(s = sfgetr(sp, '\n', 0)))
+ {
+ sfclose(sp);
+ return -1;
+ }
+ if (!strncasecmp(s, "AliasForCharSet=", 16))
+ {
+ n = sfvalue(sp) - 17;
+ s += 16;
+ if (n >= sizeof(aka))
+ n = sizeof(aka) - 1;
+ memcpy(aka, s, n);
+ aka[n] = 0;
+ sfclose(sp);
+ name = (const char*)aka;
+ break;
+ }
+ if (!strncasecmp(s, "CodePage=", 9))
+ {
+ s += 9;
+ n = strtol(s, 0, 0);
+ sfclose(sp);
+ return n;
+ }
+ }
+ }
+ return -1;
+}
+
+/*
+ * get and check the codeset indices
+ */
+
+static _ast_iconv_t
+_win_iconv_open(register Conv_t* cc, const char* t, const char* f)
+{
+#if DEBUG_TRACE
+error(DEBUG_TRACE, "AHA#%d _win_iconv_open f=%s t=%s\n", __LINE__, f, t);
+#endif
+ if ((cc->from.index = _win_codeset(f)) < 0)
+ return (_ast_iconv_t)(-1);
+ if ((cc->to.index = _win_codeset(t)) < 0)
+ return (_ast_iconv_t)(-1);
+#if DEBUG_TRACE
+error(DEBUG_TRACE, "AHA#%d _win_iconv_open f=0x%04x t=0x%04x\n", __LINE__, cc->from.index, cc->to.index);
+#endif
+ return (_ast_iconv_t)cc;
+}
+
+/*
+ * even though the indices already check out
+ * they could still be rejected
+ */
+
+static size_t
+_win_iconv(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
+{
+ Conv_t* cc = (Conv_t*)cd;
+ size_t un;
+ size_t tz;
+ size_t fz;
+ size_t bz;
+ size_t pz;
+ size_t oz;
+ LPWSTR ub;
+
+#if DEBUG_TRACE
+error(DEBUG_TRACE, "AHA#%d _win_iconv from=0x%04x to=0x%04x\n", __LINE__, cc->from.index, cc->to.index);
+#endif
+ if (cc->from.index == cc->to.index || cc->from.index != CP_UCS2 && cc->to.index == 0)
+ {
+ /*
+ * easy
+ */
+
+ fz = tz = (*fn < *tn) ? *fn : *tn;
+ memcpy(*tb, *fb, fz);
+ }
+ else
+ {
+ ub = 0;
+ un = *fn;
+
+ /*
+ * from => ucs-2
+ */
+
+ if (cc->to.index == CP_UCS2)
+ {
+ if ((tz = MultiByteToWideChar(cc->from.index, 0, (LPCSTR)*fb, (int)*fn, (LPWSTR)*tb, *tn)) && tz <= *tn)
+ {
+ fz = *fn;
+ tz *= sizeof(WCHAR);
+ }
+ else
+ {
+ /*
+ * target too small
+ * binary search on input size to make it fit
+ */
+
+ oz = 0;
+ pz = *fn / 2;
+ fz = *fn - pz;
+ for (;;)
+ {
+ while (!(tz = MultiByteToWideChar(cc->from.index, 0, (LPCSTR)*fb, (int)fz, (LPWSTR)*tb, 0)))
+ if (++fz >= *fn)
+ goto nope;
+ tz *= sizeof(WCHAR);
+ if (tz == *tn)
+ break;
+ if (!(pz /= 2))
+ {
+ if (!(fz = oz))
+ goto nope;
+ break;
+ }
+ if (tz > *tn)
+ fz -= pz;
+ else
+ {
+ oz = fz;
+ fz += pz;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (cc->from.index == CP_UCS2)
+ {
+ un = *fn / sizeof(WCHAR);
+ ub = (LPWSTR)*fb;
+ }
+ else if (!(un = MultiByteToWideChar(cc->from.index, 0, (LPCSTR)*fb, (int)*fn, (LPWSTR)*tb, 0)))
+ goto nope;
+ else if (!(ub = (LPWSTR)malloc(un * sizeof(WCHAR))))
+ goto nope;
+ else if (!(un = MultiByteToWideChar(cc->from.index, 0, (LPCSTR)*fb, (int)*fn, (LPWSTR)ub, un)))
+ goto nope;
+
+ /*
+ * ucs-2 => to
+ */
+
+ if (tz = WideCharToMultiByte(cc->to.index, 0, (LPCWSTR)ub, un, *tb, *tn, 0, 0))
+ fz = *fn;
+ else
+ {
+ /*
+ * target too small
+ * binary search on input size to make it fit
+ */
+
+ oz = 0;
+ pz = *fn / 2;
+ bz = *fn - pz;
+ for (;;)
+ {
+ while (!(fz = MultiByteToWideChar(cc->from.index, 0, (LPCSTR)*fb, (int)bz, (LPWSTR)ub, un)))
+ if (++bz > *fn)
+ goto nope;
+ if (!(tz = WideCharToMultiByte(cc->to.index, 0, (LPCWSTR)ub, fz, *tb, 0, 0, 0)))
+ goto nope;
+ if (tz == *tn)
+ break;
+ if (!(pz /= 2))
+ {
+ if (!(fz = oz))
+ goto nope;
+ break;
+ }
+ if (tz > *tn)
+ bz -= pz;
+ else
+ {
+ oz = bz;
+ bz += pz;
+ }
+ }
+ if (!(tz = WideCharToMultiByte(cc->to.index, 0, (LPCWSTR)ub, fz, *tb, tz, 0, 0)))
+ goto nope;
+#if DEBUG_TRACE
+error(DEBUG_TRACE, "AHA#%d _win_iconv *fn=%u fz=%u[%u] *tn=%u tz=%u\n", __LINE__, *fn, fz, fz * sizeof(WCHAR), *tn, tz);
+#endif
+#if 0
+ fz *= sizeof(WCHAR);
+#endif
+ }
+ if (ub != (LPWSTR)*fb)
+ free(ub);
+ }
+ }
+ *fb += fz;
+ *fn -= fz;
+ *tb += tz;
+ *tn -= tz;
+ return fz;
+ nope:
+ if (ub && ub != (LPWSTR)*fb)
+ free(ub);
+ errno = EINVAL;
+ return (size_t)(-1);
+}
+
+#endif
+
+/*
+ * return canonical character code set name for m
+ * if b!=0 then canonical name placed in b of size n
+ * <ccode.h> index returned
+ */
+
+int
+_ast_iconv_name(register const char* m, register char* b, size_t n)
+{
+ register const _ast_iconv_list_t* cp;
+ const _ast_iconv_list_t* bp;
+ register int c;
+ register char* e;
+ int sub[2];
+ char buf[16];
+#if DEBUG_TRACE
+ char* o;
+#endif
+
+ if (!b)
+ {
+ b = buf;
+ n = sizeof(buf);
+ }
+#if DEBUG_TRACE
+ o = b;
+#endif
+ e = b + n - 1;
+ bp = 0;
+ n = 0;
+ cp = ccmaplist(NiL);
+#if DEBUG_TRACE
+if (error_info.trace < DEBUG_TRACE) sfprintf(sfstderr, "%s: debug-%d: AHA%d _ast_iconv_name m=\"%s\"\n", error_info.id, error_info.trace, __LINE__, m);
+#endif
+ for (;;)
+ {
+#if DEBUG_TRACE
+if (error_info.trace < DEBUG_TRACE) sfprintf(sfstderr, "%s: debug-%d: AHA%d _ast_iconv_name n=%d bp=%p cp=%p ccode=%d name=\"%s\"\n", error_info.id, error_info.trace, __LINE__, n, bp, cp, cp->ccode, cp->name);
+#endif
+ if (strgrpmatch(m, cp->match, sub, elementsof(sub) / 2, STR_MAXIMAL|STR_LEFT|STR_ICASE))
+ {
+ if (!(c = m[sub[1]]))
+ {
+ bp = cp;
+ break;
+ }
+ if (sub[1] > n && !isalpha(c))
+ {
+ bp = cp;
+ n = sub[1];
+ }
+ }
+ if (cp->ccode < 0)
+ {
+ if (!(++cp)->name)
+ break;
+ }
+ else if (!(cp = (const _ast_iconv_list_t*)ccmaplist((_ast_iconv_list_t*)cp)))
+ cp = codes;
+ }
+ if (cp = bp)
+ {
+ if (cp->canon)
+ {
+ if (cp->index)
+ {
+ for (m += sub[1]; *m && !isalnum(*m); m++);
+ if (!isdigit(*m))
+ m = cp->index;
+ }
+ else
+ m = "1";
+ b += sfsprintf(b, e - b, cp->canon, m);
+ }
+ else if (cp->ccode == CC_NATIVE)
+ {
+ if ((locales[AST_LC_CTYPE]->flags & LC_default) || !locales[AST_LC_CTYPE]->charset || !(m = locales[AST_LC_CTYPE]->charset->code) || streq(m, "iso8859-1"))
+ switch (CC_NATIVE)
+ {
+ case CC_EBCDIC:
+ m = (const char*)"EBCDIC";
+ break;
+ case CC_EBCDIC_I:
+ m = (const char*)"EBCDIC-I";
+ break;
+ case CC_EBCDIC_O:
+ m = (const char*)"EBCDIC-O";
+ break;
+ default:
+ m = (const char*)"ISO-8859-1";
+ break;
+ }
+ b += sfsprintf(b, e - b, "%s", m);
+ }
+ *b = 0;
+#if DEBUG_TRACE
+if (error_info.trace < DEBUG_TRACE) sfprintf(sfstderr, "%s: debug-%d: AHA%d _ast_iconv_name ccode=%d canon=\"%s\"\n", error_info.id, error_info.trace, __LINE__, cp->ccode, o);
+#endif
+ return cp->ccode;
+ }
+ while (b < e && (c = *m++))
+ {
+ if (islower(c))
+ c = toupper(c);
+ *b++ = c;
+ }
+ *b = 0;
+#if DEBUG_TRACE
+if (error_info.trace < DEBUG_TRACE) sfprintf(sfstderr, "%s: debug-%d: AHA%d _ast_iconv_name ccode=%d canon=\"%s\"\n", error_info.id, error_info.trace, __LINE__, CC_ICONV, o);
+#endif
+ return CC_ICONV;
+}
+
+/*
+ * convert utf-8 to bin
+ */
+
+static size_t
+utf2bin(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
+{
+ register unsigned char* f;
+ register unsigned char* fe;
+ register unsigned char* t;
+ register unsigned char* te;
+ register unsigned char* p;
+ register int c;
+ register int w;
+ size_t n;
+ int e;
+
+ e = 0;
+ f = (unsigned char*)(*fb);
+ fe = f + (*fn);
+ t = (unsigned char*)(*tb);
+ te = t + (*tn);
+ while (t < te && f < fe)
+ {
+ p = f;
+ c = *f++;
+ if (c & 0x80)
+ {
+ if (!(c & 0x40))
+ {
+ f = p;
+ e = EILSEQ;
+ break;
+ }
+ if (c & 0x20)
+ {
+ w = (c & 0x0F) << 12;
+ if (f >= fe)
+ {
+ f = p;
+ e = EINVAL;
+ break;
+ }
+ c = *f++;
+ if (c & 0x40)
+ {
+ f = p;
+ e = EILSEQ;
+ break;
+ }
+ w |= (c & 0x3F) << 6;
+ }
+ else
+ w = (c & 0x1F) << 6;
+ if (f >= fe)
+ {
+ f = p;
+ e = EINVAL;
+ break;
+ }
+ c = *f++;
+ w |= (c & 0x3F);
+ }
+ else
+ w = c;
+ *t++ = w;
+ }
+ *fn -= (char*)f - (*fb);
+ *fb = (char*)f;
+ *tn -= (n = (char*)t - (*tb));
+ *tb = (char*)t;
+ RETURN(e, n, fn);
+}
+
+/*
+ * convert bin to utf-8
+ */
+
+static size_t
+bin2utf(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
+{
+ register unsigned char* f;
+ register unsigned char* fe;
+ register unsigned char* t;
+ register unsigned char* te;
+ register int c;
+ wchar_t w;
+ size_t n;
+ int e;
+
+ e = 0;
+ f = (unsigned char*)(*fb);
+ fe = f + (*fn);
+ t = (unsigned char*)(*tb);
+ te = t + (*tn);
+ while (f < fe && t < te)
+ {
+ if (!mbwide())
+ {
+ c = 1;
+ w = *f;
+ }
+ else if ((c = (*_ast_info.mb_towc)(&w, (char*)f, fe - f)) < 0)
+ {
+ e = EINVAL;
+ break;
+ }
+ else if (!c)
+ c = 1;
+ if (!(w & ~0x7F))
+ *t++ = w;
+ else
+ {
+ if (!(w & ~0x7FF))
+ {
+ if (t >= (te - 2))
+ {
+ e = E2BIG;
+ break;
+ }
+ *t++ = 0xC0 + (w >> 6);
+ }
+ else if (!(w & ~0xffff))
+ {
+ if (t >= (te - 3))
+ {
+ e = E2BIG;
+ break;
+ }
+ *t++ = 0xE0 + (w >> 12);
+ *t++ = 0x80 + ((w >> 6 ) & 0x3F);
+ }
+ else
+ {
+ e = EILSEQ;
+ break;
+ }
+ *t++ = 0x80 + (w & 0x3F);
+ }
+ f += c;
+ }
+ *fn -= (n = (char*)f - (*fb));
+ *fb = (char*)f;
+ *tn -= (char*)t - (*tb);
+ *tb = (char*)t;
+ RETURN(e, n, fn);
+}
+
+static const unsigned char ume_D[] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'(),-./:?!\"#$%&*;<=>@[]^_`{|} \t\n";
+
+static const unsigned char ume_M[] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static unsigned char ume_d[UCHAR_MAX+1];
+
+static unsigned char ume_m[UCHAR_MAX+1];
+
+#define NOE 0xFF
+#define UMEINIT() (ume_d[ume_D[0]]?0:umeinit())
+
+/*
+ * initialize the ume tables
+ */
+
+static int
+umeinit(void)
+{
+ register const unsigned char* s;
+ register int i;
+ register int c;
+
+ if (!ume_d[ume_D[0]])
+ {
+ s = ume_D;
+ while (c = *s++)
+ ume_d[c] = 1;
+ memset(ume_m, NOE, sizeof(ume_m));
+ for (i = 0; c = ume_M[i]; i++)
+ ume_m[c] = i;
+ }
+ return 0;
+}
+
+/*
+ * convert utf-7 to bin
+ */
+
+static size_t
+ume2bin(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
+{
+ register unsigned char* f;
+ register unsigned char* fe;
+ register unsigned char* t;
+ register unsigned char* te;
+ register unsigned char* p;
+ register int s;
+ register int c;
+ register int w;
+ size_t n;
+ int e;
+
+ e = 0;
+ UMEINIT();
+ f = (unsigned char*)(*fb);
+ fe = f + (*fn);
+ t = (unsigned char*)(*tb);
+ te = t + (*tn);
+ s = 0;
+ while (f < fe && t < te)
+ {
+ p = f;
+ c = *f++;
+ if (s)
+ {
+ if (c == '-' && s > 1)
+ s = 0;
+ else if ((w = ume_m[c]) == NOE)
+ {
+ s = 0;
+ *t++ = c;
+ }
+ else if (f >= (fe - 2))
+ {
+ f = p;
+ e = EINVAL;
+ break;
+ }
+ else
+ {
+ s = 2;
+ w = (w << 6) | ume_m[*f++];
+ w = (w << 6) | ume_m[*f++];
+ if (!(w & ~0xFF))
+ *t++ = w;
+ else if (t >= (te - 1))
+ {
+ f = p;
+ e = E2BIG;
+ break;
+ }
+ else
+ {
+ *t++ = (w >> 8) & 0xFF;
+ *t++ = w & 0xFF;
+ }
+ }
+ }
+ else if (c == '+')
+ s = 1;
+ else
+ *t++ = c;
+ }
+ *fn -= (char*)f - (*fb);
+ *fb = (char*)f;
+ *tn -= (n = (char*)t - (*tb));
+ *tb = (char*)t;
+ RETURN(e, n, fn);
+}
+
+/*
+ * convert bin to utf-7
+ */
+
+static size_t
+bin2ume(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
+{
+ register unsigned char* f;
+ register unsigned char* fe;
+ register unsigned char* t;
+ register unsigned char* te;
+ register int c;
+ register int s;
+ wchar_t w;
+ size_t n;
+ int e;
+
+ e = 0;
+ UMEINIT();
+ f = (unsigned char*)(*fb);
+ fe = f + (*fn);
+ t = (unsigned char*)(*tb);
+ te = t + (*tn);
+ s = 0;
+ while (f < fe && t < (te - s))
+ {
+ if (!mbwide())
+ {
+ c = 1;
+ w = *f;
+ }
+ else if ((c = (*_ast_info.mb_towc)(&w, (char*)f, fe - f)) < 0)
+ {
+ e = EINVAL;
+ break;
+ }
+ else if (!c)
+ c = 1;
+ if (!(w & ~0x7F) && ume_d[w])
+ {
+ if (s)
+ {
+ s = 0;
+ *t++ = '-';
+ }
+ *t++ = w;
+ }
+ else if (t >= (te - (4 + s)))
+ {
+ e = E2BIG;
+ break;
+ }
+ else
+ {
+ if (!s)
+ {
+ s = 1;
+ *t++ = '+';
+ }
+ *t++ = ume_M[(w >> 12) & 0x3F];
+ *t++ = ume_M[(w >> 6) & 0x3F];
+ *t++ = ume_M[w & 0x3F];
+ }
+ f += c;
+ }
+ if (s)
+ *t++ = '-';
+ *fn -= (n = (char*)f - (*fb));
+ *fb = (char*)f;
+ *tn -= (char*)t - (*tb);
+ *tb = (char*)t;
+ RETURN(e, n, fn);
+}
+
+/*
+ * convert ucs-2 to bin with no byte swap
+ */
+
+static size_t
+ucs2bin(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
+{
+ register unsigned char* f;
+ register unsigned char* fe;
+ register unsigned char* t;
+ register unsigned char* te;
+ register int w;
+ size_t n;
+ int e;
+
+ e = 0;
+ f = (unsigned char*)(*fb);
+ fe = f + (*fn);
+ t = (unsigned char*)(*tb);
+ te = t + (*tn);
+ while (f < (fe - 1) && t < te)
+ {
+ w = *f++;
+ w = (w << 8) | *f++;
+ if (!(w & ~0xFF))
+ *t++ = w;
+ else if (t >= (te - 1))
+ {
+ f -= 2;
+ e = E2BIG;
+ break;
+ }
+ else
+ {
+ *t++ = (w >> 8) & 0xFF;
+ *t++ = w & 0xFF;
+ }
+ }
+ *fn -= (char*)f - (*fb);
+ *fb = (char*)f;
+ *tn -= (n = (char*)t - (*tb));
+ *tb = (char*)t;
+ RETURN(e, n, fn);
+}
+
+/*
+ * convert bin to ucs-2 with no byte swap
+ */
+
+static size_t
+bin2ucs(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
+{
+ register unsigned char* f;
+ register unsigned char* fe;
+ register unsigned char* t;
+ register unsigned char* te;
+ register int c;
+ wchar_t w;
+ size_t n;
+ int e;
+
+ e = 0;
+ f = (unsigned char*)(*fb);
+ fe = f + (*fn);
+ t = (unsigned char*)(*tb);
+ te = t + (*tn);
+ while (f < fe && t < (te - 1))
+ {
+ if (!mbwide())
+ {
+ c = 1;
+ w = *f;
+ }
+ if ((c = (*_ast_info.mb_towc)(&w, (char*)f, fe - f)) < 0)
+ {
+ e = EINVAL;
+ break;
+ }
+ else if (!c)
+ c = 1;
+ *t++ = (w >> 8) & 0xFF;
+ *t++ = w & 0xFF;
+ f += c;
+ }
+ *fn -= (n = (char*)f - (*fb));
+ *fb = (char*)f;
+ *tn -= (char*)t - (*tb);
+ *tb = (char*)t;
+ RETURN(e, n, fn);
+}
+
+/*
+ * convert ucs-2 to bin with byte swap
+ */
+
+static size_t
+scu2bin(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
+{
+ register unsigned char* f;
+ register unsigned char* fe;
+ register unsigned char* t;
+ register unsigned char* te;
+ register int w;
+ size_t n;
+ int e;
+
+ e = 0;
+ f = (unsigned char*)(*fb);
+ fe = f + (*fn);
+ t = (unsigned char*)(*tb);
+ te = t + (*tn);
+ while (f < (fe - 1) && t < te)
+ {
+ w = *f++;
+ w = w | (*f++ << 8);
+ if (!(w & ~0xFF))
+ *t++ = w;
+ else if (t >= (te - 1))
+ {
+ f -= 2;
+ e = E2BIG;
+ break;
+ }
+ else
+ {
+ *t++ = (w >> 8) & 0xFF;
+ *t++ = w & 0xFF;
+ }
+ }
+ *fn -= (char*)f - (*fb);
+ *fb = (char*)f;
+ *tn -= (n = (char*)t - (*tb));
+ *tb = (char*)t;
+ RETURN(e, n, fn);
+}
+
+/*
+ * convert bin to ucs-2 with byte swap
+ */
+
+static size_t
+bin2scu(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
+{
+ register unsigned char* f;
+ register unsigned char* fe;
+ register unsigned char* t;
+ register unsigned char* te;
+ register int c;
+ wchar_t w;
+ size_t n;
+ int e;
+
+ e = 0;
+ f = (unsigned char*)(*fb);
+ fe = f + (*fn);
+ t = (unsigned char*)(*tb);
+ te = t + (*tn);
+ while (f < fe && t < (te - 1))
+ {
+ if (!mbwide())
+ {
+ c = 1;
+ w = *f;
+ }
+ else if ((c = (*_ast_info.mb_towc)(&w, (char*)f, fe - f)) < 0)
+ {
+ e = EINVAL;
+ break;
+ }
+ else if (!c)
+ c = 1;
+ *t++ = w & 0xFF;
+ *t++ = (w >> 8) & 0xFF;
+ f += c;
+ }
+ *fn -= (n = (char*)f - (*fb));
+ *fb = (char*)f;
+ *tn -= (char*)t - (*tb);
+ *tb = (char*)t;
+ RETURN(e, n, fn);
+}
+
+/*
+ * open a character code conversion map from f to t
+ */
+
+_ast_iconv_t
+_ast_iconv_open(const char* t, const char* f)
+{
+ register Conv_t* cc;
+ int fc;
+ int tc;
+ int i;
+
+ char fr[64];
+ char to[64];
+
+#if DEBUG_TRACE
+error(DEBUG_TRACE, "AHA#%d _ast_iconv_open f=%s t=%s\n", __LINE__, f, t);
+#endif
+ if (!t || !*t || *t == '-' && !*(t + 1) || !strcasecmp(t, name_local) || !strcasecmp(t, name_native))
+ t = name_native;
+ if (!f || !*f || *f == '-' && !*(f + 1) || !strcasecmp(t, name_local) || !strcasecmp(f, name_native))
+ f = name_native;
+
+ /*
+ * the ast identify is always (iconv_t)(0)
+ */
+
+ if (t == f)
+ return (iconv_t)(0);
+ fc = _ast_iconv_name(f, fr, sizeof(fr));
+ tc = _ast_iconv_name(t, to, sizeof(to));
+#if DEBUG_TRACE
+error(DEBUG_TRACE, "AHA#%d _ast_iconv_open f=%s:%s:%d t=%s:%s:%d\n", __LINE__, f, fr, fc, t, to, tc);
+#endif
+ if (fc != CC_ICONV && fc == tc || streq(fr, to))
+ return (iconv_t)(0);
+
+ /*
+ * first check the free list
+ */
+
+ for (i = 0; i < elementsof(freelist); i++)
+ if ((cc = freelist[i]) && streq(to, cc->to.name) && streq(fr, cc->from.name))
+ {
+ freelist[i] = 0;
+#if _lib_iconv_open
+ /*
+ * reset the shift state if any
+ */
+
+ if (cc->cvt != (iconv_t)(-1))
+ iconv(cc->cvt, NiL, NiL, NiL, NiL);
+#endif
+ return cc;
+ }
+
+ /*
+ * allocate a new one
+ */
+
+ if (!(cc = newof(0, Conv_t, 1, strlen(to) + strlen(fr) + 2)))
+ return (iconv_t)(-1);
+ cc->to.name = (char*)(cc + 1);
+ cc->from.name = strcopy(cc->to.name, to) + 1;
+ strcpy(cc->from.name, fr);
+ cc->cvt = (iconv_t)(-1);
+
+ /*
+ * 8 bit maps are the easiest
+ */
+
+ if (fc >= 0 && tc >= 0)
+ cc->from.map = ccmap(fc, tc);
+#if _lib_iconv_open
+ else if ((cc->cvt = iconv_open(t, f)) != (iconv_t)(-1) || (cc->cvt = iconv_open(to, fr)) != (iconv_t)(-1))
+ cc->from.fun = (_ast_iconv_f)iconv;
+#endif
+#if _UWIN
+ else if ((cc->cvt = _win_iconv_open(cc, t, f)) != (_ast_iconv_t)(-1) || (cc->cvt = _win_iconv_open(cc, to, fr)) != (_ast_iconv_t)(-1))
+ cc->from.fun = (_ast_iconv_f)_win_iconv;
+#endif
+ else
+ {
+ switch (fc)
+ {
+ case CC_UTF:
+ cc->from.fun = utf2bin;
+ break;
+ case CC_UME:
+ cc->from.fun = ume2bin;
+ break;
+ case CC_UCS:
+ cc->from.fun = ucs2bin;
+ break;
+ case CC_SCU:
+ cc->from.fun = scu2bin;
+ break;
+ case CC_ASCII:
+ break;
+ default:
+ if (fc < 0)
+ goto nope;
+ cc->from.map = ccmap(fc, CC_ASCII);
+ break;
+ }
+ switch (tc)
+ {
+ case CC_UTF:
+ cc->to.fun = bin2utf;
+ break;
+ case CC_UME:
+ cc->to.fun = bin2ume;
+ break;
+ case CC_UCS:
+ cc->to.fun = bin2ucs;
+ break;
+ case CC_SCU:
+ cc->to.fun = bin2scu;
+ break;
+ case CC_ASCII:
+ break;
+ default:
+ if (tc < 0)
+ goto nope;
+ cc->to.map = ccmap(CC_ASCII, tc);
+ break;
+ }
+ }
+ return (iconv_t)cc;
+ nope:
+ return (iconv_t)(-1);
+}
+
+/*
+ * close a character code conversion map
+ */
+
+int
+_ast_iconv_close(_ast_iconv_t cd)
+{
+ Conv_t* cc;
+ Conv_t* oc;
+ int i;
+ int r = 0;
+
+ if (cd == (_ast_iconv_t)(-1))
+ return -1;
+ if (!(cc = (Conv_t*)cd))
+ return 0;
+
+ /*
+ * add to the free list
+ */
+
+ i = freeindex;
+ for (;;)
+ {
+ if (++ i >= elementsof(freelist))
+ i = 0;
+ if (!freelist[i])
+ break;
+ if (i == freeindex)
+ {
+ if (++ i >= elementsof(freelist))
+ i = 0;
+
+ /*
+ * close the oldest
+ */
+
+ if (oc = freelist[i])
+ {
+#if _lib_iconv_open
+ if (oc->cvt != (iconv_t)(-1))
+ r = iconv_close(oc->cvt);
+#endif
+ if (oc->buf)
+ free(oc->buf);
+ free(oc);
+ }
+ break;
+ }
+ }
+ freelist[freeindex = i] = cc;
+ return r;
+}
+
+/*
+ * copy *fb size *fn to *tb size *tn
+ * fb,fn tb,tn updated on return
+ */
+
+size_t
+_ast_iconv(_ast_iconv_t cd, char** fb, size_t* fn, char** tb, size_t* tn)
+{
+ Conv_t* cc = (Conv_t*)cd;
+ register unsigned char* f;
+ register unsigned char* t;
+ register unsigned char* e;
+ register const unsigned char* m;
+ register size_t n;
+ char* b;
+ char* tfb;
+ size_t tfn;
+ size_t i;
+
+ if (!fb || !*fb)
+ {
+ /* TODO: reset to the initial state */
+ if (!tb || !*tb)
+ return 0;
+ /* TODO: write the initial state shift sequence */
+ return 0;
+ }
+ n = *tn;
+ if (cc)
+ {
+ if (cc->from.fun)
+ {
+ if (cc->to.fun)
+ {
+ if (!cc->buf && !(cc->buf = oldof(0, char, cc->size = SF_BUFSIZE, 0)))
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+ b = cc->buf;
+ i = cc->size;
+ tfb = *fb;
+ tfn = *fn;
+ if ((*cc->from.fun)(cc->cvt, &tfb, &tfn, &b, &i) == (size_t)(-1))
+ return -1;
+ tfn = b - cc->buf;
+ tfb = cc->buf;
+ n = (*cc->to.fun)(cc->cvt, &tfb, &tfn, tb, tn);
+ i = tfb - cc->buf;
+ *fb += i;
+ *fn -= i;
+ return n;
+ }
+ if ((*cc->from.fun)(cc->cvt, fb, fn, tb, tn) == (size_t)(-1))
+ return -1;
+ n -= *tn;
+ if (m = cc->to.map)
+ {
+ e = (unsigned char*)(*tb);
+ for (t = e - n; t < e; t++)
+ *t = m[*t];
+ }
+ return n;
+ }
+ else if (cc->to.fun)
+ {
+ if (!(m = cc->from.map))
+ return (*cc->to.fun)(cc->cvt, fb, fn, tb, tn);
+ if (!cc->buf && !(cc->buf = oldof(0, char, cc->size = SF_BUFSIZE, 0)))
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+ if ((n = *fn) > cc->size)
+ n = cc->size;
+ f = (unsigned char*)(*fb);
+ e = f + n;
+ t = (unsigned char*)(b = cc->buf);
+ while (f < e)
+ *t++ = m[*f++];
+ n = (*cc->to.fun)(cc->cvt, &b, fn, tb, tn);
+ *fb += b - cc->buf;
+ return n;
+ }
+ }
+ if (n > *fn)
+ n = *fn;
+ if (cc && (m = cc->from.map))
+ {
+ f = (unsigned char*)(*fb);
+ e = f + n;
+ t = (unsigned char*)(*tb);
+ while (f < e)
+ *t++ = m[*f++];
+ }
+ else
+ memcpy(*tb, *fb, n);
+ *fb += n;
+ *fn -= n;
+ *tb += n;
+ *tn -= n;
+ return n;
+}
+
+#define OK ((size_t)-1)
+
+/*
+ * write *fb size *fn to op
+ * fb,fn updated on return
+ * total bytes written to op returned
+ */
+
+ssize_t
+_ast_iconv_write(_ast_iconv_t cd, Sfio_t* op, char** fb, size_t* fn, Iconv_disc_t* disc)
+{
+ char* fo = *fb;
+ char* tb;
+ char* ts;
+ size_t* e;
+ size_t tn;
+ size_t r;
+ int ok;
+ Iconv_disc_t compat;
+
+ /*
+ * the old api had optional size_t* instead of Iconv_disc_t*
+ */
+
+ if (!disc || disc->version < 20110101L || disc->version >= 30000101L)
+ {
+ e = (size_t*)disc;
+ disc = &compat;
+ iconv_init(disc, 0);
+ }
+ else
+ e = 0;
+ r = 0;
+ tn = 0;
+ ok = 1;
+ while (ok && *fn > 0)
+ {
+ if (!(tb = (char*)sfreserve(op, -(tn + 1), SF_WRITE|SF_LOCKR)) || !(tn = sfvalue(op)))
+ {
+ if (!r)
+ r = -1;
+ break;
+ }
+ ts = tb;
+#if DEBUG_TRACE
+error(DEBUG_TRACE, "AHA#%d iconv_write ts=%p tn=%d", __LINE__, ts, tn);
+ for (;;)
+#else
+ while (*fn > 0 && _ast_iconv(cd, fb, fn, &ts, &tn) == (size_t)(-1))
+#endif
+ {
+#if DEBUG_TRACE
+ ssize_t _r;
+error(DEBUG_TRACE, "AHA#%d iconv_write %d => %d `%-.*s'", __LINE__, *fn, tn, *fn, *fb);
+ _r = _ast_iconv(cd, fb, fn, &ts, &tn);
+error(DEBUG_TRACE, "AHA#%d iconv_write %d => %d [%d]", __LINE__, *fn, tn, _r);
+ if (_r != (size_t)(-1) || !fn)
+ break;
+#endif
+ switch (errno)
+ {
+ case E2BIG:
+ break;
+ case EINVAL:
+ if (disc->errorf)
+ (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "incomplete multibyte sequence at offset %I*u", sizeof(fo), *fb - fo);
+ goto bad;
+ default:
+ if (disc->errorf)
+ (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "invalid multibyte sequence at offset %I*u", sizeof(fo), *fb - fo);
+ bad:
+ disc->errors++;
+ if (!(disc->flags & ICONV_FATAL))
+ {
+ if (!(disc->flags & ICONV_OMIT) && tn > 0)
+ {
+ *ts++ = (disc->fill >= 0) ? disc->fill : **fb;
+ tn--;
+ }
+ (*fb)++;
+ (*fn)--;
+ continue;
+ }
+ ok = 0;
+ break;
+ }
+ break;
+ }
+#if DEBUG_TRACE
+error(DEBUG_TRACE, "AHA#%d iconv_write %d", __LINE__, ts - tb);
+#endif
+ sfwrite(op, tb, ts - tb);
+ r += ts - tb;
+ }
+ if (e)
+ *e = disc->errors;
+ return r;
+}
+
+/*
+ * move n bytes from ip to op
+ */
+
+ssize_t
+_ast_iconv_move(_ast_iconv_t cd, Sfio_t* ip, Sfio_t* op, size_t n, Iconv_disc_t* disc)
+{
+ char* fb;
+ char* fs;
+ char* tb;
+ char* ts;
+ size_t* e;
+ size_t fe;
+ size_t fn;
+ size_t fo;
+ size_t ft;
+ size_t tn;
+ size_t i;
+ ssize_t r = 0;
+ int ok = 1;
+ int locked;
+ Iconv_disc_t compat;
+
+ /*
+ * the old api had optional size_t* instead of Iconv_disc_t*
+ */
+
+ if (!disc || disc->version < 20110101L || disc->version >= 30000101L)
+ {
+ e = (size_t*)disc;
+ disc = &compat;
+ iconv_init(disc, 0);
+ }
+ else
+ e = 0;
+ tb = 0;
+ fe = OK;
+ ft = 0;
+ fn = n;
+ do
+ {
+ if (n != SF_UNBOUND)
+ n = -((ssize_t)(n & (((size_t)(~0))>>1)));
+ if ((!(fb = (char*)sfreserve(ip, n, locked = SF_LOCKR)) || !(fo = sfvalue(ip))) &&
+ (!(fb = (char*)sfreserve(ip, n, locked = 0)) || !(fo = sfvalue(ip))))
+ break;
+ fs = fb;
+ fn = fo;
+ if (!(tb = (char*)sfreserve(op, SF_UNBOUND, SF_WRITE|SF_LOCKR)))
+ {
+ if (!r)
+ r = -1;
+ break;
+ }
+ ts = tb;
+ tn = sfvalue(op);
+ while (fn > 0 && _ast_iconv(cd, &fs, &fn, &ts, &tn) == (size_t)(-1))
+ {
+ switch (errno)
+ {
+ case E2BIG:
+ break;
+ case EINVAL:
+ if (fe == ft + (fo - fn))
+ {
+ fe = OK;
+ if (disc->errorf)
+ (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "incomplete multibyte sequence at offset %I*u", sizeof(ft), ft + (fo - fn));
+ goto bad;
+ }
+ fe = ft;
+ break;
+ default:
+ if (disc->errorf)
+ (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "invalid multibyte sequence at offset %I*u", sizeof(ft), ft + (fo - fn));
+ bad:
+ disc->errors++;
+ if (!(disc->flags & ICONV_FATAL))
+ {
+ if (!(disc->flags & ICONV_OMIT) && tn > 0)
+ {
+ *ts++ = (disc->fill >= 0) ? disc->fill : *fs;
+ tn--;
+ }
+ fs++;
+ fn--;
+ continue;
+ }
+ ok = 0;
+ break;
+ }
+ break;
+ }
+ sfwrite(op, tb, ts - tb);
+ r += ts - tb;
+ ts = tb;
+ if (locked)
+ sfread(ip, fb, fs - fb);
+ else
+ for (i = fn; --i >= (fs - fb);)
+ sfungetc(ip, fb[i]);
+ if (n != SF_UNBOUND)
+ {
+ if (n <= (fs - fb))
+ break;
+ n -= fs - fb;
+ }
+ ft += (fs - fb);
+ if (fn == fo)
+ fn++;
+ } while (ok);
+ if (fb && locked)
+ sfread(ip, fb, 0);
+ if (tb)
+ {
+ sfwrite(op, tb, 0);
+ if (ts > tb)
+ {
+ sfwrite(op, tb, ts - tb);
+ r += ts - tb;
+ }
+ }
+ if (e)
+ *e = disc->errors;
+ return r;
+}
+
+/*
+ * iconv_list_t iterator
+ * call with arg 0 to start
+ * prev return value is current arg
+ */
+
+_ast_iconv_list_t*
+_ast_iconv_list(_ast_iconv_list_t* cp)
+{
+#if _UWIN
+ struct dirent* ent;
+
+ if (!cp)
+ {
+ if (!(cp = newof(0, _ast_iconv_list_t, 1, 0)))
+ return ccmaplist(NiL);
+ if (!(cp->data = opendir(_win_maps)))
+ {
+ free(cp);
+ return ccmaplist(NiL);
+ }
+ }
+ if (cp->data)
+ {
+ if (ent = readdir((DIR*)cp->data))
+ {
+ cp->name = cp->match = cp->desc = (const char*)ent->d_name;
+ return cp;
+ }
+ closedir((DIR*)cp->data);
+ free(cp);
+ return ccmaplist(NiL);
+ }
+#else
+ if (!cp)
+ return ccmaplist(NiL);
+#endif
+ if (cp->ccode >= 0)
+ return (cp = ccmaplist(cp)) ? cp : (_ast_iconv_list_t*)codes;
+ return (++cp)->name ? cp : (_ast_iconv_list_t*)0;
+}
diff --git a/src/lib/libast/comp/killpg.c b/src/lib/libast/comp/killpg.c
new file mode 100644
index 0000000..725a1f9
--- /dev/null
+++ b/src/lib/libast/comp/killpg.c
@@ -0,0 +1,40 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_killpg
+
+NoN(killpg)
+
+#else
+
+#include <sig.h>
+
+int
+killpg(pid_t g, int s)
+{
+ return(kill(-g, s));
+}
+
+#endif
diff --git a/src/lib/libast/comp/libgen.h b/src/lib/libast/comp/libgen.h
new file mode 100644
index 0000000..a2bb92a
--- /dev/null
+++ b/src/lib/libast/comp/libgen.h
@@ -0,0 +1,52 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * libgen interface definitions
+ */
+
+#ifndef _LIBGEN_H
+#define _LIBGEN_H
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+#if !_BLD_ast && defined(__IMPORT__)
+#define extern extern __IMPORT__
+#endif
+
+extern char* __loc1;
+
+#undef extern
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char* regcmp(const char*, ...);
+extern char* regex(const char*, const char*, ...);
+extern char* basename(char*);
+extern char* dirname(char*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/comp/link.c b/src/lib/libast/comp/link.c
new file mode 100644
index 0000000..571806f
--- /dev/null
+++ b/src/lib/libast/comp/link.c
@@ -0,0 +1,47 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_link
+
+NoN(link)
+
+#else
+
+#include <error.h>
+
+#ifndef ENOSYS
+#define ENOSYS EINVAL
+#endif
+
+int
+link(const char* from, const char* to)
+{
+ NoP(from);
+ NoP(to);
+ errno = ENOSYS;
+ return -1;
+}
+
+#endif
diff --git a/src/lib/libast/comp/localeconv.c b/src/lib/libast/comp/localeconv.c
new file mode 100644
index 0000000..8cdc841
--- /dev/null
+++ b/src/lib/libast/comp/localeconv.c
@@ -0,0 +1,100 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * localeconv() intercept
+ */
+
+#include "lclib.h"
+
+#undef localeconv
+
+static char null[] = "";
+
+static struct lconv debug_lconv =
+{
+ ",",
+ ".",
+ &null[0],
+ &null[0],
+ &null[0],
+ &null[0],
+ &null[0],
+ &null[0],
+ &null[0],
+ &null[0],
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+};
+
+static struct lconv default_lconv =
+{
+ ".",
+ &null[0],
+ &null[0],
+ &null[0],
+ &null[0],
+ &null[0],
+ &null[0],
+ &null[0],
+ &null[0],
+ &null[0],
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+};
+
+#if !_lib_localeconv
+
+struct lconv*
+localeconv(void)
+{
+ return &default_lconv;
+}
+
+#endif
+
+/*
+ * localeconv() intercept
+ */
+
+struct lconv*
+_ast_localeconv(void)
+{
+ if ((locales[AST_LC_MONETARY]->flags | locales[AST_LC_NUMERIC]->flags) & LC_debug)
+ return &debug_lconv;
+ if ((locales[AST_LC_NUMERIC]->flags & (LC_default|LC_local)) == LC_local)
+ return locales[AST_LC_NUMERIC]->territory == &lc_territories[0] ? &default_lconv : &debug_lconv;
+ return localeconv();
+}
diff --git a/src/lib/libast/comp/lstat.c b/src/lib/libast/comp/lstat.c
new file mode 100644
index 0000000..7531215
--- /dev/null
+++ b/src/lib/libast/comp/lstat.c
@@ -0,0 +1,39 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+#include <ls.h>
+
+#if _lib_lstat
+
+NoN(lstat)
+
+#else
+
+int
+lstat(const char* path, struct stat* st)
+{
+ return(stat(path, st));
+}
+
+#endif
diff --git a/src/lib/libast/comp/memccpy.c b/src/lib/libast/comp/memccpy.c
new file mode 100644
index 0000000..c973a2d
--- /dev/null
+++ b/src/lib/libast/comp/memccpy.c
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_memccpy && !_UWIN
+
+NoN(memccpy)
+
+#else
+
+/*
+ * Copy s2 to s1, stopping if character c is copied. Copy no more than n bytes.
+ * Return a pointer to the byte after character c in the copy,
+ * or 0 if c is not found in the first n bytes.
+ */
+
+void*
+memccpy(void* as1, const void* as2, register int c, size_t n)
+{
+ register char* s1 = (char*)as1;
+ register const char* s2 = (char*)as2;
+ register const char* ep = s2 + n;
+
+ while (s2 < ep)
+ if ((*s1++ = *s2++) == c)
+ return(s1);
+ return(0);
+}
+
+#endif
diff --git a/src/lib/libast/comp/memchr.c b/src/lib/libast/comp/memchr.c
new file mode 100644
index 0000000..d294059
--- /dev/null
+++ b/src/lib/libast/comp/memchr.c
@@ -0,0 +1,49 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_memchr
+
+NoN(memchr)
+
+#else
+
+/*
+ * Return the ptr in sp at which the character c appears;
+ * 0 if not found in n chars; don't stop at \0.
+ */
+
+void*
+memchr(const void* asp, register int c, size_t n)
+{
+ register const char* sp = (char*)asp;
+ register const char* ep = sp + n;
+
+ while (sp < ep)
+ if (*sp++ == c)
+ return(--sp);
+ return(0);
+}
+
+#endif
diff --git a/src/lib/libast/comp/memcmp.c b/src/lib/libast/comp/memcmp.c
new file mode 100644
index 0000000..b74540c
--- /dev/null
+++ b/src/lib/libast/comp/memcmp.c
@@ -0,0 +1,45 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_memcmp
+
+NoN(memcmp)
+
+#else
+
+int
+memcmp(const void* ab1, const void* ab2, size_t n)
+{
+ register const unsigned char* b1 = (const unsigned char*)ab1;
+ register const unsigned char* b2 = (const unsigned char*)ab2;
+ register const unsigned char* e = b1 + n;
+
+ while (b1 < e)
+ if (*b1++ != *b2++)
+ return(*--b1 - *--b2);
+ return(0);
+}
+
+#endif
diff --git a/src/lib/libast/comp/memcpy.c b/src/lib/libast/comp/memcpy.c
new file mode 100644
index 0000000..25fa0b7
--- /dev/null
+++ b/src/lib/libast/comp/memcpy.c
@@ -0,0 +1,60 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_memcpy
+
+NoN(memcpy)
+
+#else
+
+#undef memcpy
+
+#if _lib_bcopy
+
+extern void bcopy(void*, void*, size_t);
+
+void*
+memcpy(void* s1, void* s2, size_t n)
+{
+ bcopy(s2, s1, n);
+ return(s1);
+}
+
+#else
+
+void*
+memcpy(void* as1, const void* as2, register size_t n)
+{
+ register char* s1 = (char*)as1;
+ register const char* s2 = (const char*)as2;
+
+ while (n-- > 0)
+ *s1++ = *s2++;
+ return(as1);
+}
+
+#endif
+
+#endif
diff --git a/src/lib/libast/comp/memmove.c b/src/lib/libast/comp/memmove.c
new file mode 100644
index 0000000..9d5ba59
--- /dev/null
+++ b/src/lib/libast/comp/memmove.c
@@ -0,0 +1,53 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_memmove
+
+NoN(memmove)
+
+#else
+
+void*
+memmove(void* to, const void* from, register size_t n)
+{
+ register char* out = (char*)to;
+ register char* in = (char*)from;
+
+ if (n <= 0) /* works if size_t is signed or not */
+ ;
+ else if (in + n <= out || out + n <= in)
+ return(memcpy(to, from, n)); /* hope it's fast*/
+ else if (out < in)
+ do *out++ = *in++; while (--n > 0);
+ else
+ {
+ out += n;
+ in += n;
+ do *--out = *--in; while(--n > 0);
+ }
+ return(to);
+}
+
+#endif
diff --git a/src/lib/libast/comp/memset.c b/src/lib/libast/comp/memset.c
new file mode 100644
index 0000000..359d157
--- /dev/null
+++ b/src/lib/libast/comp/memset.c
@@ -0,0 +1,42 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_memset
+
+NoN(memset)
+
+#else
+
+void*
+memset(void* asp, register int c, register size_t n)
+{
+ register char* sp = (char*)asp;
+
+ while (n-- > 0)
+ *sp++ = c;
+ return(asp);
+}
+
+#endif
diff --git a/src/lib/libast/comp/mkdir.c b/src/lib/libast/comp/mkdir.c
new file mode 100644
index 0000000..37e8e51
--- /dev/null
+++ b/src/lib/libast/comp/mkdir.c
@@ -0,0 +1,62 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_mkdir
+
+NoN(mkdir)
+
+#else
+
+#include <ls.h>
+#include <wait.h>
+#include <error.h>
+
+int
+mkdir(const char* path, mode_t mode)
+{
+ register int n;
+ char* av[3];
+
+ static char* cmd[] = { "/bin/mkdir", "/usr/5bin/mkdir", 0 };
+
+
+ n = errno;
+ if (!access(path, F_OK))
+ {
+ errno = EEXIST;
+ return(-1);
+ }
+ if (errno != ENOENT) return(-1);
+ errno = n;
+ av[0] = "mkdir";
+ av[1] = path;
+ av[2] = 0;
+ for (n = 0; n < elementsof(cmd); n++)
+ if (procclose(procopen(cmd[n], av, NiL, NiL, 0)) != -1)
+ break;
+ return(chmod(path, mode));
+}
+
+#endif
diff --git a/src/lib/libast/comp/mkfifo.c b/src/lib/libast/comp/mkfifo.c
new file mode 100644
index 0000000..e4b26a4
--- /dev/null
+++ b/src/lib/libast/comp/mkfifo.c
@@ -0,0 +1,50 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_mkfifo
+
+NoN(mkfifo)
+
+#else
+
+#include <ls.h>
+#include <error.h>
+
+#ifndef ENOSYS
+#define ENOSYS EINVAL
+#endif
+
+int
+mkfifo(const char* path, mode_t mode)
+{
+#ifdef S_IFIFO
+ return mknod(path, S_IFIFO|(mode & ~S_IFMT), 0);
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+#endif
diff --git a/src/lib/libast/comp/mknod.c b/src/lib/libast/comp/mknod.c
new file mode 100644
index 0000000..8172a13
--- /dev/null
+++ b/src/lib/libast/comp/mknod.c
@@ -0,0 +1,50 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+#include <ls.h>
+
+#if _lib_mknod
+
+NoN(mknod)
+
+#else
+
+#include <error.h>
+
+#ifndef ENOSYS
+#define ENOSYS EINVAL
+#endif
+
+int
+mknod(const char* path, mode_t mode, dev_t dev)
+{
+ if (S_ISFIFO(mode))
+ return mkfifo(path, mode);
+ if (S_ISDIR(mode))
+ return mkdir(path, mode);
+ errno = ENOSYS;
+ return -1;
+}
+
+#endif
diff --git a/src/lib/libast/comp/mktemp.c b/src/lib/libast/comp/mktemp.c
new file mode 100644
index 0000000..c29dc90
--- /dev/null
+++ b/src/lib/libast/comp/mktemp.c
@@ -0,0 +1,85 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * mktemp,mkstemp implementation
+ */
+
+#define mktemp ______mktemp
+#define mkstemp ______mkstemp
+
+#include <ast.h>
+#include <stdio.h>
+
+#undef mktemp
+#undef mkstemp
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+static char*
+temp(char* buf, int* fdp)
+{
+ char* s;
+ char* d;
+ int n;
+ size_t len;
+
+ len = strlen(buf);
+ if (s = strrchr(buf, '/'))
+ {
+ *s++ = 0;
+ d = buf;
+ }
+ else
+ {
+ s = buf;
+ d = "";
+ }
+ if ((n = strlen(s)) < 6 || strcmp(s + n - 6, "XXXXXX"))
+ *buf = 0;
+ else
+ {
+ *(s + n - 6) = 0;
+ if (!pathtemp(buf, len, d, s, fdp))
+ *buf = 0;
+ }
+ return buf;
+}
+
+extern char*
+mktemp(char* buf)
+{
+ return temp(buf, NiL);
+}
+
+extern int
+mkstemp(char* buf)
+{
+ int fd;
+
+ return *temp(buf, &fd) ? fd : -1;
+}
diff --git a/src/lib/libast/comp/mktime.c b/src/lib/libast/comp/mktime.c
new file mode 100644
index 0000000..c39ca40
--- /dev/null
+++ b/src/lib/libast/comp/mktime.c
@@ -0,0 +1,77 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * mktime implementation
+ */
+
+#define mktime ______mktime
+
+#include <ast.h>
+#include <tm.h>
+
+#undef mktime
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+#undef _lib_mktime /* we can pass X/Open */
+
+#if _lib_mktime
+
+NoN(mktime)
+
+#else
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern time_t
+mktime(struct tm* ts)
+{
+ time_t t;
+ Tm_t tm;
+
+ tm.tm_sec = ts->tm_sec;
+ tm.tm_min = ts->tm_min;
+ tm.tm_hour = ts->tm_hour;
+ tm.tm_mday = ts->tm_mday;
+ tm.tm_mon = ts->tm_mon;
+ tm.tm_year = ts->tm_year;
+ tm.tm_wday = ts->tm_wday;
+ tm.tm_yday = ts->tm_yday;
+ tm.tm_isdst = ts->tm_isdst;
+ t = tmtime(&tm, TM_LOCALZONE);
+ ts->tm_sec = tm.tm_sec;
+ ts->tm_min = tm.tm_min;
+ ts->tm_hour = tm.tm_hour;
+ ts->tm_mday = tm.tm_mday;
+ ts->tm_mon = tm.tm_mon;
+ ts->tm_year = tm.tm_year;
+ ts->tm_wday = tm.tm_wday;
+ ts->tm_yday = tm.tm_yday;
+ ts->tm_isdst = tm.tm_isdst;
+ return t;
+}
+
+#endif
diff --git a/src/lib/libast/comp/mount.c b/src/lib/libast/comp/mount.c
new file mode 100644
index 0000000..eaf27e5
--- /dev/null
+++ b/src/lib/libast/comp/mount.c
@@ -0,0 +1,49 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_mount
+
+NoN(mount)
+
+#else
+
+#include <error.h>
+
+#ifndef ENOSYS
+#define ENOSYS EINVAL
+#endif
+
+int
+mount(const char* a, char* b, int c, void* d)
+{
+ NoP(a);
+ NoP(b);
+ NoP(c);
+ NoP(d);
+ errno = ENOSYS;
+ return -1;
+}
+
+#endif
diff --git a/src/lib/libast/comp/nftw.c b/src/lib/libast/comp/nftw.c
new file mode 100644
index 0000000..6c8c97a
--- /dev/null
+++ b/src/lib/libast/comp/nftw.c
@@ -0,0 +1,61 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * nftw implementation
+ */
+
+#include <ast.h>
+#include <ftw.h>
+
+static int nftw_flags;
+static int (*nftw_userf)(const char*, const struct stat*, int, struct FTW*);
+
+static int
+nftw_user(Ftw_t* ftw)
+{
+ register int n = ftw->info;
+ struct FTW nftw;
+ struct stat st;
+
+ if (n & (FTW_C|FTW_NX))
+ n = FTW_DNR;
+ else if ((n & FTW_SL) && (!(nftw_flags & FTW_PHYSICAL) || stat(ftw->path, &st)))
+ n = FTW_SLN;
+ nftw.base = ftw->pathlen - ftw->namelen;
+ nftw.level = ftw->level;
+ nftw.quit = 0;
+ n = (*nftw_userf)(ftw->path, &ftw->statb, n, &nftw);
+ ftw->status = nftw.quit;
+ return n;
+}
+
+int
+nftw(const char* path, int(*userf)(const char*, const struct stat*, int, struct FTW*), int depth, int flags)
+{
+ NoP(depth);
+ nftw_userf = userf;
+ if (flags & FTW_CHDIR) flags &= ~FTW_DOT;
+ else flags |= FTW_DOT;
+ nftw_flags = flags;
+ return ftwalk(path, nftw_user, flags, NiL);
+}
diff --git a/src/lib/libast/comp/omitted.c b/src/lib/libast/comp/omitted.c
new file mode 100644
index 0000000..b517965
--- /dev/null
+++ b/src/lib/libast/comp/omitted.c
@@ -0,0 +1,1152 @@
+#pragma prototyped noticed
+
+/*
+ * workarounds to bring the native interface close to posix and x/open
+ */
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide utime utimes
+#else
+#define utime ______utime
+#define utimes ______utimes
+#endif
+
+#include <ast.h>
+#include <error.h>
+#include <tm.h>
+
+#include "FEATURE/omitted"
+
+#undef OMITTED
+
+#if _win32_botch
+
+#define OMITTED 1
+
+#include <ls.h>
+#include <utime.h>
+
+#if __CYGWIN__
+#include <ast_windows.h>
+#if _win32_botch_execve || _lib_spawn_mode
+#define CONVERT 1
+#endif
+#endif
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide utime utimes
+#else
+#undef utime
+#undef utimes
+#endif
+
+#ifndef MAX_PATH
+#define MAX_PATH PATH_MAX
+#endif
+
+/*
+ * these workarounds assume each system call foo() has a _foo() entry
+ * which is true for __CYGWIN__ and __EMX__ (both gnu based)
+ *
+ * the workarounds handle:
+ *
+ * (1) .exe suffix inconsistencies
+ * (2) /bin/sh reference in execve() and spawnve()
+ * (3) bogus getpagesize() return values
+ * (4) a fork() bug that screws up shell fork()+script
+ *
+ * NOTE: Not all workarounds can be handled by unix syscall intercepts.
+ * In particular, { ksh nmake } have workarounds for case-ignorant
+ * filesystems and { libast } has workarounds for win32 locale info.
+ */
+
+#undef _pathconf
+#undef pathconf
+#undef stat
+
+extern int _access(const char*, int);
+extern unsigned int _alarm(unsigned int);
+extern int _chmod(const char*, mode_t);
+extern int _close(int);
+extern pid_t _execve(const char*, char* const*, char* const*);
+extern uid_t _getuid(void);
+extern int _link(const char*, const char*);
+extern int _open(const char*, int, ...);
+extern long _pathconf(const char*, int);
+extern ssize_t _read(int, void*, size_t);
+extern int _rename(const char*, const char*);
+extern pid_t _spawnve(int, const char*, char* const*, char* const*);
+extern int _stat(const char*, struct stat*);
+extern int _unlink(const char*);
+extern int _utime(const char*, const struct utimbuf*);
+extern int _utimes(const char*, const struct timeval*);
+extern ssize_t _write(int, const void*, size_t);
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#if _win32_botch_access
+#define sysaccess _access
+#else
+#define sysaccess access
+#endif
+#if _win32_botch_alarm
+#define sysalarm _alarm
+#else
+#define sysalarm alarm
+#endif
+#if _win32_botch_chmod
+#define syschmod _chmod
+#else
+#define syschmod chmod
+#endif
+#if _win32_botch_copy
+#define sysclose _close
+#else
+#define sysclose close
+#endif
+#if _win32_botch_execve || _lib_spawn_mode
+#define sysexecve _execve
+#else
+#define sysexecve execve
+#endif
+#if CONVERT
+#define sysgetuid _getuid
+#else
+#define sysgetuid getuid
+#endif
+#if _win32_botch_link
+#define syslink _link
+#else
+#define syslink link
+#endif
+#if _win32_botch_open || _win32_botch_copy
+#define sysopen _open
+#else
+#define sysopen open
+#endif
+#if _win32_botch_pathconf
+#define syspathconf _pathconf
+#else
+#define syspathconf pathconf
+#endif
+#define sysread _read
+#if _win32_botch_rename
+#define sysrename _rename
+#else
+#define sysrename rename
+#endif
+#if _lib_spawn_mode
+#define sysspawnve _spawnve
+#else
+#define sysspawnve spawnve
+#endif
+#if _win32_botch_stat
+#define sysstat _stat
+#else
+#define sysstat stat
+#endif
+#if _win32_botch_truncate
+#define systruncate _truncate
+#else
+#define systruncate truncate
+#endif
+#if _win32_botch_unlink
+#define sysunlink _unlink
+#else
+#define sysunlink unlink
+#endif
+#if _win32_botch_utime
+#define sysutime _utime
+#define sysutimes _utimes
+#else
+#define sysutime utime
+#define sysutimes utimes
+#endif
+#if _win32_botch_copy
+#define syswrite _write
+#else
+#define syswrite write
+#endif
+
+static char*
+suffix(register const char* path)
+{
+ register const char* s = path + strlen(path);
+ register int c;
+
+ while (s > path)
+ if ((c = *--s) == '.')
+ return (char*)s + 1;
+ else if (c == '/' || c == '\\')
+ break;
+ return 0;
+}
+
+static int
+execrate(const char* path, char* buf, int size, int physical)
+{
+ char* s;
+ int n;
+ int oerrno;
+
+ if (suffix(path))
+ return 0;
+ oerrno = errno;
+ if (physical || strlen(path) >= size || !(s = pathcanon(strcpy(buf, path), size, PATH_PHYSICAL|PATH_DOTDOT|PATH_EXISTS)))
+ snprintf(buf, size, "%s.exe", path);
+ else if (!suffix(buf) && ((buf + size) - s) >= 4)
+ strcpy(s, ".exe");
+ errno = oerrno;
+ return 1;
+}
+
+/*
+ * return 0 if path is magic, -1 otherwise
+ * ux!=0 set to 1 if path is unix executable
+ * ux!=0 also retains errno for -1 return
+ */
+
+static int
+magic(const char* path, int* ux)
+{
+ int fd;
+ int r;
+ int n;
+ int m;
+ int oerrno;
+#if CONVERT
+ unsigned char buf[512];
+#else
+ unsigned char buf[2];
+#endif
+
+ oerrno = errno;
+ if ((fd = sysopen(path, O_RDONLY, 0)) >= 0)
+ {
+#if CONVERT
+ if (ux)
+ n = sizeof(buf);
+ else
+#endif
+ n = 2;
+ r = (m = sysread(fd, buf, n)) >= 2 && (buf[1] == 0x5a && (buf[0] == 0x4c || buf[0] == 0x4d) || ux && buf[0] == '#' && buf[1] == '!' && (*ux = 1) && !(ux = 0)) ? 0 : -1;
+ sysclose(fd);
+ if (ux)
+ {
+ if (r)
+ oerrno = ENOEXEC;
+ else if (m > 61 && (n = buf[60] | (buf[61]<<8) + 92) < (m - 1))
+ *ux = (buf[n] | (buf[n+1]<<8)) == 3;
+ else
+ *ux = 0;
+ }
+ }
+ else if (!ux)
+ r = -1;
+ else if (errno == ENOENT)
+ {
+ oerrno = errno;
+ r = -1;
+ }
+ else
+ {
+ r = 0;
+ *ux = 0;
+ }
+ errno = oerrno;
+ return r;
+}
+
+#if _win32_botch_access
+
+extern int
+access(const char* path, int op)
+{
+ int r;
+ int oerrno;
+ char buf[PATH_MAX];
+
+ oerrno = errno;
+ if ((r = sysaccess(path, op)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
+ {
+ errno = oerrno;
+ r = sysaccess(buf, op);
+ }
+ return r;
+}
+
+#endif
+
+#if _win32_botch_alarm
+
+extern unsigned int
+alarm(unsigned int s)
+{
+ unsigned int n;
+ unsigned int r;
+
+ static unsigned int a;
+
+ n = (unsigned int)time(NiL);
+ if (a <= n)
+ r = 0;
+ else
+ r = a - n;
+ a = n + s - 1;
+ (void)sysalarm(s);
+ return r;
+}
+
+#endif
+
+#if _win32_botch_chmod
+
+extern int
+chmod(const char* path, mode_t mode)
+{
+ int r;
+ int oerrno;
+ char buf[PATH_MAX];
+
+ if ((r = syschmod(path, mode)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
+ {
+ errno = oerrno;
+ return syschmod(buf, mode);
+ }
+ if (!(r = syschmod(path, mode)) &&
+ (mode & (S_IXUSR|S_IXGRP|S_IXOTH)) &&
+ !suffix(path) &&
+ (strlen(path) + 4) < sizeof(buf))
+ {
+ oerrno = errno;
+ if (!magic(path, NiL))
+ {
+ snprintf(buf, sizeof(buf), "%s.exe", path);
+ sysrename(path, buf);
+ }
+ errno = oerrno;
+ }
+ return r;
+}
+
+#endif
+
+#if _win32_botch_execve || _lib_spawn_mode
+
+#if _lib_spawn_mode
+
+/*
+ * can anyone get const prototype args straight?
+ */
+
+#define execve ______execve
+#define spawnve ______spawnve
+
+#include <process.h>
+
+#undef execve
+#undef spawnve
+
+#endif
+
+#if CONVERT
+
+/*
+ * this intercept converts dos env vars to unix
+ * we'd rather intercept main but can't twist cc to do it
+ * getuid() gets ksh to do the right thing and
+ * that's our main concern
+ *
+ * DOSPATHVARS='a b c' convert { a b c }
+ */
+
+static int convertinit;
+
+/*
+ * convertvars[0] names the list of env var names
+ * convertvars[i] are not converted
+ */
+
+static const char* convertvars[] = { "DOSPATHVARS", "PATH" };
+
+static int
+convert(register const char* d, const char* s)
+{
+ register const char* t;
+ register const char* v;
+ int i;
+
+ for (i = 0; i < elementsof(convertvars); i++)
+ {
+ for (v = convertvars[i], t = s; *t && *t == *v; t++, v++);
+ if (*t == '=' && *v == 0)
+ return 0;
+ }
+ for (;;)
+ {
+ while (*d == ' ' || *d == '\t')
+ d++;
+ if (!*d)
+ break;
+ for (t = s; *t && *t == *d; d++, t++);
+ if (*t == '=' && (*d == ' ' || *d == '\t' || *d == 0))
+ return t - s + 1;
+ while (*d && *d != ' ' && *d != '\t')
+ d++;
+ }
+ return 0;
+}
+
+uid_t
+getuid(void)
+{
+ register char* d;
+ register char* s;
+ register char* t;
+ register char** e;
+ int n;
+ int m;
+
+ if (!convertinit++ && (d = getenv(convertvars[0])))
+ for (e = environ; s = *e; e++)
+ if ((n = convert(d, s)) && (m = cygwin_win32_to_posix_path_list_buf_size(s + n)) > 0)
+ {
+ if (!(t = malloc(n + m + 1)))
+ break;
+ *e = t;
+ memcpy(t, s, n);
+ cygwin_win32_to_posix_path_list(s + n, t + n);
+ }
+ return sysgetuid();
+}
+
+#endif
+
+#ifndef _P_OVERLAY
+#define _P_OVERLAY (-1)
+#endif
+
+#define DEBUG 1
+
+static pid_t
+runve(int mode, const char* path, char* const* argv, char* const* envv)
+{
+ register char* s;
+ register char** p;
+ register char** v;
+
+ void* m1;
+ void* m2;
+ pid_t pid;
+ int oerrno;
+ int ux;
+ int n;
+#if defined(_P_DETACH) && defined(_P_NOWAIT)
+ int pgrp;
+#endif
+#if CONVERT
+ char* d;
+ char* t;
+ int m;
+#endif
+ struct stat st;
+ char buf[PATH_MAX];
+ char tmp[PATH_MAX];
+
+#if DEBUG
+ static int trace;
+#endif
+
+#if defined(_P_DETACH) && defined(_P_NOWAIT)
+ if (mode == _P_DETACH)
+ {
+ /*
+ * 2004-02-29 cygwin _P_DETACH is useless:
+ * spawn*() returns 0 instead of the spawned pid
+ * spawned { pgid sid } are the same as the parent
+ */
+
+ mode = _P_NOWAIT;
+ pgrp = 1;
+ }
+ else
+ pgrp = 0;
+#endif
+ if (!envv)
+ envv = (char* const*)environ;
+ m1 = m2 = 0;
+ oerrno = errno;
+#if DEBUG
+ if (!trace)
+ trace = (s = getenv("_AST_exec_trace")) ? *s : 'n';
+#endif
+ if (execrate(path, buf, sizeof(buf), 0))
+ {
+ if (!sysstat(buf, &st))
+ path = (const char*)buf;
+ else
+ errno = oerrno;
+ }
+ if (path != (const char*)buf && sysstat(path, &st))
+ return -1;
+ if (!S_ISREG(st.st_mode) || !(st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
+ {
+ errno = EACCES;
+ return -1;
+ }
+ if (magic(path, &ux))
+ {
+#if _CYGWIN_fork_works
+ errno = ENOEXEC;
+ return -1;
+#else
+ ux = 1;
+ p = (char**)argv;
+ while (*p++);
+ if (!(v = (char**)malloc((p - (char**)argv + 2) * sizeof(char*))))
+ {
+ errno = EAGAIN;
+ return -1;
+ }
+ m1 = v;
+ p = v;
+ *p++ = (char*)path;
+ *p++ = (char*)path;
+ path = (const char*)pathshell();
+ if (*argv)
+ argv++;
+ while (*p++ = (char*)*argv++);
+ argv = (char* const*)v;
+#endif
+ }
+
+ /*
+ * the win32 dll search order is
+ * (1) the directory of path
+ * (2) .
+ * (3) /c/(WINNT|WINDOWS)/system32 /c/(WINNT|WINDOWS)
+ * (4) the directories on $PATH
+ * there are no cygwin dlls in (3), so if (1) and (2) fail
+ * to produce the required dlls its up to (4)
+ *
+ * the standard allows PATH to be anything once the path
+ * to an executable is determined; this code ensures that PATH
+ * contains /bin so that at least the cygwin dll, required
+ * by all cygwin executables, will be found
+ */
+
+ if (p = (char**)envv)
+ {
+ n = 1;
+ while (s = *p++)
+ if (strneq(s, "PATH=", 5))
+ {
+ s += 5;
+ do
+ {
+ s = pathcat(s, ':', NiL, "", tmp, sizeof(tmp));
+ if (streq(tmp, "/usr/bin/") || streq(tmp, "/bin/"))
+ {
+ n = 0;
+ break;
+ }
+ } while (s);
+ if (n)
+ {
+ n = 0;
+ snprintf(tmp, sizeof(tmp), "%s:/bin", *(p - 1));
+ *(p - 1) = tmp;
+ }
+ break;
+ }
+ if (n)
+ {
+ n = p - (char**)envv + 1;
+ p = (char**)envv;
+ if (v = (char**)malloc(n * sizeof(char*)))
+ {
+ m2 = v;
+ envv = (char* const*)v;
+ *v++ = strcpy(tmp, "PATH=/bin");
+ while (*v++ = *p++);
+ }
+ }
+#if CONVERT
+ if (!ux && (d = getenv(convertvars[0])))
+ for (p = (char**)envv; s = *p; p++)
+ if ((n = convert(d, s)) && (m = cygwin_posix_to_win32_path_list_buf_size(s + n)) > 0)
+ {
+ if (!(t = malloc(n + m + 1)))
+ break;
+ *p = t;
+ memcpy(t, s, n);
+ cygwin_posix_to_win32_path_list(s + n, t + n);
+ }
+#endif
+ }
+
+#if DEBUG
+ if (trace == 'a' || trace == 'e')
+ {
+ sfprintf(sfstderr, "%s %s [", mode == _P_OVERLAY ? "_execve" : "_spawnve", path);
+ for (n = 0; argv[n]; n++)
+ sfprintf(sfstderr, " '%s'", argv[n]);
+ if (trace == 'e')
+ {
+ sfprintf(sfstderr, " ] [");
+ for (n = 0; envv[n]; n++)
+ sfprintf(sfstderr, " '%s'", envv[n]);
+ }
+ sfprintf(sfstderr, " ]\n");
+ sfsync(sfstderr);
+ }
+#endif
+#if _lib_spawn_mode
+ if (mode != _P_OVERLAY)
+ {
+ pid = sysspawnve(mode, path, argv, envv);
+#if defined(_P_DETACH) && defined(_P_NOWAIT)
+ if (pid > 0 && pgrp)
+ setpgid(pid, 0);
+#endif
+ }
+ else
+#endif
+ {
+#if defined(_P_DETACH) && defined(_P_NOWAIT)
+ if (pgrp)
+ setpgid(0, 0);
+#endif
+ pid = sysexecve(path, argv, envv);
+ }
+ if (m1)
+ free(m1);
+ if (m2)
+ free(m2);
+ return pid;
+}
+
+#if _win32_botch_execve
+
+extern pid_t
+execve(const char* path, char* const* argv, char* const* envv)
+{
+ return runve(_P_OVERLAY, path, argv, envv);
+}
+
+#endif
+
+#if _lib_spawn_mode
+
+extern pid_t
+spawnve(int mode, const char* path, char* const* argv, char* const* envv)
+{
+ return runve(mode, path, argv, envv);
+}
+
+#endif
+
+#endif
+
+#if _win32_botch_getpagesize
+
+extern size_t
+getpagesize(void)
+{
+ return 64 * 1024;
+}
+
+#endif
+
+#if _win32_botch_link
+
+extern int
+link(const char* fp, const char* tp)
+{
+ int r;
+ int oerrno;
+ char fb[PATH_MAX];
+ char tb[PATH_MAX];
+
+ oerrno = errno;
+ if ((r = syslink(fp, tp)) && errno == ENOENT && execrate(fp, fb, sizeof(fb), 1))
+ {
+ if (execrate(tp, tb, sizeof(tb), 1))
+ tp = tb;
+ errno = oerrno;
+ r = syslink(fb, tp);
+ }
+ return r;
+}
+
+#endif
+
+#if _win32_botch_open || _win32_botch_copy
+
+#if _win32_botch_copy
+
+/*
+ * this should intercept the important cases
+ * dup*() and exec*() fd's will not be intercepted
+ */
+
+typedef struct Exe_test_s
+{
+ int test;
+ ino_t ino;
+ char path[PATH_MAX];
+} Exe_test_t;
+
+static Exe_test_t* exe[16];
+
+extern int
+close(int fd)
+{
+ int r;
+ int oerrno;
+ struct stat st;
+ char buf[PATH_MAX];
+
+ if (fd >= 0 && fd < elementsof(exe) && exe[fd])
+ {
+ r = exe[fd]->test;
+ exe[fd]->test = 0;
+ if (r > 0 && !fstat(fd, &st) && st.st_ino == exe[fd]->ino)
+ {
+ if (r = sysclose(fd))
+ return r;
+ oerrno = errno;
+ if (!stat(exe[fd]->path, &st) && st.st_ino == exe[fd]->ino)
+ {
+ snprintf(buf, sizeof(buf), "%s.exe", exe[fd]->path);
+ sysrename(exe[fd]->path, buf);
+ }
+ errno = oerrno;
+ return 0;
+ }
+ }
+ return sysclose(fd);
+}
+
+extern ssize_t
+write(int fd, const void* buf, size_t n)
+{
+ if (fd >= 0 && fd < elementsof(exe) && exe[fd] && exe[fd]->test < 0)
+ exe[fd]->test = n >= 2 && ((unsigned char*)buf)[1] == 0x5a && (((unsigned char*)buf)[0] == 0x4c || ((unsigned char*)buf)[0] == 0x4d) && !lseek(fd, (off_t)0, SEEK_CUR);
+ return syswrite(fd, buf, n);
+}
+
+#endif
+
+extern int
+open(const char* path, int flags, ...)
+{
+ int fd;
+ int mode;
+ int oerrno;
+ char buf[PATH_MAX];
+#if _win32_botch_copy
+ struct stat st;
+#endif
+ va_list ap;
+
+ va_start(ap, flags);
+ mode = (flags & O_CREAT) ? va_arg(ap, int) : 0;
+ oerrno = errno;
+ fd = sysopen(path, flags, mode);
+#if _win32_botch_open
+ if (fd < 0 && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
+ {
+ errno = oerrno;
+ fd = sysopen(buf, flags, mode);
+ }
+#endif
+#if _win32_botch_copy
+ if (fd >= 0 && fd < elementsof(exe) && strlen(path) < PATH_MAX &&
+ (flags & (O_CREAT|O_TRUNC)) == (O_CREAT|O_TRUNC) && (mode & 0111))
+ {
+ if (!suffix(path) && !fstat(fd, &st) && (exe[fd] || (exe[fd] = (Exe_test_t*)malloc(sizeof(Exe_test_t)))))
+ {
+ exe[fd]->test = -1;
+ exe[fd]->ino = st.st_ino;
+ strcpy(exe[fd]->path, path);
+ }
+ errno = oerrno;
+ }
+#endif
+ va_end(ap);
+ return fd;
+}
+
+#endif
+
+#if _win32_botch_pathconf
+
+extern long
+pathconf(const char* path, int op)
+{
+ if (sysaccess(path, F_OK))
+ return -1;
+ return syspathconf(path, op);
+}
+
+#endif
+
+#if _win32_botch_rename
+
+extern int
+rename(const char* fp, const char* tp)
+{
+ int r;
+ int oerrno;
+ char fb[PATH_MAX];
+ char tb[PATH_MAX];
+
+ oerrno = errno;
+ if ((r = sysrename(fp, tp)) && errno == ENOENT && execrate(fp, fb, sizeof(fb), 1))
+ {
+ if (execrate(tp, tb, sizeof(tb), 1))
+ tp = tb;
+ errno = oerrno;
+ r = sysrename(fb, tp);
+ }
+ return r;
+}
+
+#endif
+
+#if _win32_botch_stat
+
+extern int
+stat(const char* path, struct stat* st)
+{
+ int r;
+ int oerrno;
+ char buf[PATH_MAX];
+
+ oerrno = errno;
+ if ((r = sysstat(path, st)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
+ {
+ errno = oerrno;
+ r = sysstat(buf, st);
+ }
+ return r;
+}
+
+#endif
+
+#if _win32_botch_truncate
+
+extern int
+truncate(const char* path, off_t offset)
+{
+ int r;
+ int oerrno;
+ char buf[PATH_MAX];
+
+ oerrno = errno;
+ if ((r = systruncate(path, offset)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
+ {
+ errno = oerrno;
+ r = systruncate(buf, offset);
+ }
+ return r;
+}
+
+#endif
+
+#if _win32_botch_unlink
+
+extern int
+unlink(const char* path)
+{
+ int r;
+ int drive;
+ int mask;
+ int suffix;
+ int stop;
+ int oerrno;
+ unsigned long base;
+ char buf[PATH_MAX];
+ char tmp[MAX_PATH];
+
+#define DELETED_DIR_1 7
+#define DELETED_DIR_2 16
+
+ static char deleted[] = "%c:\\temp\\.deleted\\%08x.%03x";
+
+ static int count = 0;
+
+#if __CYGWIN__
+
+ DWORD fattr = FILE_ATTRIBUTE_NORMAL|FILE_FLAG_DELETE_ON_CLOSE;
+ DWORD share = FILE_SHARE_DELETE;
+ HANDLE hp;
+ struct stat st;
+ char nat[MAX_PATH];
+
+ oerrno = errno;
+ if (lstat(path, &st) || !S_ISREG(st.st_mode))
+ goto try_unlink;
+ cygwin_conv_to_full_win32_path(path, nat);
+ if (!strncasecmp(nat + 1, ":\\temp\\", 7))
+ goto try_unlink;
+ drive = nat[0];
+ path = (const char*)nat;
+ for (;;)
+ {
+ hp = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_DELETE_ON_CLOSE, NULL);
+ if (hp != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(hp);
+ errno = oerrno;
+ return 0;
+ }
+ if (GetLastError() != ERROR_FILE_NOT_FOUND)
+ break;
+ if (path == (const char*)buf || !execrate(path, buf, sizeof(buf), 1))
+ {
+ errno = ENOENT;
+ return -1;
+ }
+ path = (const char*)buf;
+ }
+#else
+ if (sysaccess(path, 0))
+#if _win32_botch_access
+ {
+ if (errno != ENOENT || !execrate(path, buf, sizeof(buf), 1) || sysaccess(buf, 0))
+ return -1;
+ path = (const char*)buf;
+ }
+#else
+ return -1;
+#endif
+ drive = 'C':
+#endif
+
+ /*
+ * rename to a `deleted' path just in case the file is open
+ * otherwise directory readers may choke on phantom entries
+ */
+
+ base = ((getuid() & 0xffff) << 16) | (time(NiL) & 0xffff);
+ suffix = (getpid() & 0xfff) + count++;
+ snprintf(tmp, sizeof(tmp), deleted, drive, base, suffix);
+ if (!sysrename(path, tmp))
+ {
+ path = (const char*)tmp;
+ goto try_delete;
+ }
+ if (errno != ENOTDIR && errno != ENOENT)
+ goto try_unlink;
+ tmp[DELETED_DIR_2] = 0;
+ if (sysaccess(tmp, 0))
+ {
+ mask = umask(0);
+ tmp[DELETED_DIR_1] = 0;
+ if (sysaccess(tmp, 0) && mkdir(tmp, S_IRWXU|S_IRWXG|S_IRWXO))
+ {
+ umask(mask);
+ goto try_unlink;
+ }
+ tmp[DELETED_DIR_1] = '\\';
+ r = mkdir(tmp, S_IRWXU|S_IRWXG|S_IRWXO);
+ umask(mask);
+ if (r)
+ goto try_unlink;
+ errno = 0;
+ }
+ tmp[DELETED_DIR_2] = '\\';
+ if (!errno && !sysrename(path, tmp))
+ {
+ path = (const char*)tmp;
+ goto try_delete;
+ }
+#if !__CYGWIN__
+ if (errno == ENOENT)
+ {
+#if !_win32_botch_access
+ if (execrate(path, buf, sizeof(buf), 1) && !sysrename(buf, tmp))
+ path = (const char*)tmp;
+#endif
+ goto try_unlink;
+ }
+#endif
+ stop = suffix;
+ do
+ {
+ snprintf(tmp, sizeof(tmp), deleted, drive, base, suffix);
+ if (!sysrename(path, tmp))
+ {
+ path = (const char*)tmp;
+ goto try_delete;
+ }
+ if (++suffix > 0xfff)
+ suffix = 0;
+ } while (suffix != stop);
+ try_delete:
+#if __CYGWIN__
+ hp = CreateFile(path, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_DELETE_ON_CLOSE, NULL);
+ if (hp != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(hp);
+ errno = oerrno;
+ return 0;
+ }
+#endif
+ try_unlink:
+ errno = oerrno;
+ return sysunlink(path);
+}
+
+#endif
+
+#if _win32_botch_utime
+
+#if __CYGWIN__
+
+/*
+ * cygwin refuses to set st_ctime for some operations
+ * this rejects that refusal
+ */
+
+static void
+ctime_now(const char* path)
+{
+ HANDLE hp;
+ SYSTEMTIME st;
+ FILETIME ct;
+ WIN32_FIND_DATA ff;
+ struct stat fs;
+ int oerrno;
+ char tmp[MAX_PATH];
+
+ if (sysstat(path, &fs) || (fs.st_mode & S_IWUSR) || syschmod(path, (fs.st_mode | S_IWUSR) & S_IPERM))
+ fs.st_mode = 0;
+ cygwin_conv_to_win32_path(path, tmp);
+ hp = CreateFile(tmp, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hp && hp != INVALID_HANDLE_VALUE)
+ {
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, &ct);
+ SetFileTime(hp, &ct, 0, 0);
+ CloseHandle(hp);
+ }
+ if (fs.st_mode)
+ syschmod(path, fs.st_mode & S_IPERM);
+ errno = oerrno;
+}
+
+#else
+
+#define ctime_now(p)
+
+#endif
+
+extern int
+utimes(const char* path, const struct timeval* ut)
+{
+ int r;
+ int oerrno;
+ char buf[PATH_MAX];
+
+ oerrno = errno;
+ if ((r = sysutimes(path, ut)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
+ {
+ errno = oerrno;
+ r = sysutimes(path = buf, ut);
+ }
+ if (!r)
+ ctime_now(path);
+ return r;
+}
+
+extern int
+utime(const char* path, const struct utimbuf* ut)
+{
+ int r;
+ int oerrno;
+ char buf[PATH_MAX];
+
+ oerrno = errno;
+ if ((r = sysutime(path, ut)) && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
+ {
+ errno = oerrno;
+ r = sysutime(path = buf, ut);
+ }
+ if (!r)
+ ctime_now(path);
+ return r;
+}
+
+#endif
+
+#endif
+
+/*
+ * some systems (sun) miss a few functions required by their
+ * own bsd-like macros
+ */
+
+#if !_lib_bzero || defined(bzero)
+
+#undef bzero
+
+void
+bzero(void* b, size_t n)
+{
+ memset(b, 0, n);
+}
+
+#endif
+
+#if !_lib_getpagesize || defined(getpagesize)
+
+#ifndef OMITTED
+#define OMITTED 1
+#endif
+
+#undef getpagesize
+
+#ifdef _SC_PAGESIZE
+#undef _AST_PAGESIZE
+#define _AST_PAGESIZE (int)sysconf(_SC_PAGESIZE)
+#else
+#ifndef _AST_PAGESIZE
+#define _AST_PAGESIZE 4096
+#endif
+#endif
+
+int
+getpagesize()
+{
+ return _AST_PAGESIZE;
+}
+
+#endif
+
+#if __CYGWIN__ && defined(__IMPORT__) && defined(__EXPORT__)
+
+#ifndef OMITTED
+#define OMITTED 1
+#endif
+
+/*
+ * a few _imp__FUNCTION symbols are needed to avoid
+ * static link multiple definitions
+ */
+
+#ifndef strtod
+__EXPORT__ double (*_imp__strtod)(const char*, char**) = strtod;
+#endif
+
+#endif
+
+#ifndef OMITTED
+
+NoN(omitted)
+
+#endif
diff --git a/src/lib/libast/comp/open.c b/src/lib/libast/comp/open.c
new file mode 100644
index 0000000..6e2530f
--- /dev/null
+++ b/src/lib/libast/comp/open.c
@@ -0,0 +1,119 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * -last 3 arg open
+ */
+
+#include <ast.h>
+
+#if !defined(open) || !defined(_ast_O_LOCAL)
+
+NoN(open)
+
+#else
+
+#undef open
+
+extern int open(const char*, int, ...);
+
+#include <ls.h>
+#include <error.h>
+
+#ifdef O_NOCTTY
+#include <ast_tty.h>
+#endif
+
+int
+_ast_open(const char* path, int op, ...)
+{
+ int fd;
+ int mode;
+ int save_errno;
+ struct stat st;
+ va_list ap;
+
+ save_errno = errno;
+ va_start(ap, op);
+ mode = (op & O_CREAT) ? va_arg(ap, int) : S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
+ va_end(ap);
+ if (op & ~(_ast_O_LOCAL-1))
+ {
+ if (!(op & O_CREAT))
+ op &= ~O_EXCL;
+ for (;;)
+ {
+ if (op & O_TRUNC)
+ {
+ if ((op & O_EXCL) && !access(path, F_OK))
+ {
+ errno = EEXIST;
+ return(-1);
+ }
+ if ((fd = creat(path, (op & O_EXCL) ? 0 : mode)) < 0)
+ return(-1);
+ if (op & O_EXCL)
+ {
+ if (fstat(fd, &st) || (st.st_mode & S_IPERM))
+ {
+ errno = EEXIST;
+ close(fd);
+ return(-1);
+ }
+#if _lib_fchmod
+ if (mode && fchmod(fd, mode))
+#else
+ if (mode && chmod(path, mode))
+#endif
+ errno = save_errno;
+ }
+ if ((op & O_ACCMODE) == O_RDWR)
+ {
+ close(fd);
+ op &= ~(O_CREAT|O_TRUNC);
+ continue;
+ }
+ }
+ else if ((fd = open(path, op & (_ast_O_LOCAL-1), mode)) < 0)
+ {
+ if (op & O_CREAT)
+ {
+ op |= O_TRUNC;
+ continue;
+ }
+ return(-1);
+ }
+ else if ((op & O_APPEND) && lseek(fd, 0L, SEEK_END) == -1L)
+ errno = save_errno;
+#if O_NOCTTY
+ if ((op & O_NOCTTY) && ioctl(fd, TIOCNOTTY, 0))
+ errno = save_errno;
+#endif
+ break;
+ }
+ }
+ else fd = open(path, op, mode);
+ return(fd);
+}
+
+#endif
diff --git a/src/lib/libast/comp/openlog.c b/src/lib/libast/comp/openlog.c
new file mode 100644
index 0000000..518d441
--- /dev/null
+++ b/src/lib/libast/comp/openlog.c
@@ -0,0 +1,58 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * openlog implementation
+ */
+
+#include <ast.h>
+
+#if _lib_syslog
+
+NoN(openlog)
+
+#else
+
+#include "sysloglib.h"
+
+void
+openlog(const char* ident, int flags, int facility)
+{
+ int n;
+
+ if (ident)
+ {
+ n = strlen(ident);
+ if (n >= sizeof(log.ident))
+ n = sizeof(log.ident) - 1;
+ memcpy(log.ident, ident, n);
+ log.ident[n] = 0;
+ }
+ else
+ log.ident[0] = 0;
+ log.facility = facility;
+ log.flags = flags;
+ if (!(log.flags & LOG_ODELAY))
+ sendlog(NiL);
+}
+
+#endif
diff --git a/src/lib/libast/comp/putenv.c b/src/lib/libast/comp/putenv.c
new file mode 100644
index 0000000..72b0f61
--- /dev/null
+++ b/src/lib/libast/comp/putenv.c
@@ -0,0 +1,53 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#define putenv ______putenv
+
+#if _UWIN
+#define _STDLIB_H_ 1
+#endif
+
+#include <ast.h>
+
+#undef putenv
+
+#if _lib_putenv
+
+NoN(putenv)
+
+#else
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+putenv(const char* s)
+{
+ return setenviron(s) ? 0 : -1;
+}
+
+#endif
diff --git a/src/lib/libast/comp/re_comp.c b/src/lib/libast/comp/re_comp.c
new file mode 100644
index 0000000..ad31f24
--- /dev/null
+++ b/src/lib/libast/comp/re_comp.c
@@ -0,0 +1,81 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * re_comp implementation
+ */
+
+#include <ast.h>
+#include <re_comp.h>
+#include <regex.h>
+
+#undef error
+#undef valid
+
+static struct
+{
+ char error[64];
+ regex_t re;
+ int valid;
+} state;
+
+char*
+re_comp(const char* pattern)
+{
+ register int r;
+
+ if (!pattern || !*pattern)
+ {
+ if (state.valid)
+ return 0;
+ r = REG_BADPAT;
+ }
+ else
+ {
+ if (state.valid)
+ {
+ state.valid = 0;
+ regfree(&state.re);
+ }
+ if (!(r = regcomp(&state.re, pattern, REG_LENIENT|REG_NOSUB|REG_NULL)))
+ {
+ state.valid = 1;
+ return 0;
+ }
+ }
+ regerror(r, &state.re, state.error, sizeof(state.error));
+ return state.error;
+}
+
+int
+re_exec(const char* subject)
+{
+ if (state.valid && subject)
+ switch (regexec(&state.re, subject, 0, NiL, 0))
+ {
+ case 0:
+ return 1;
+ case REG_NOMATCH:
+ return 0;
+ }
+ return -1;
+}
diff --git a/src/lib/libast/comp/re_comp.h b/src/lib/libast/comp/re_comp.h
new file mode 100644
index 0000000..616fb4c
--- /dev/null
+++ b/src/lib/libast/comp/re_comp.h
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * re_comp interface definitions
+ *
+ * OBSOLETE: use <regex.h>
+ */
+
+#ifndef _RE_COMP_H
+#define _RE_COMP_H
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char* re_comp(const char*);
+extern int re_exec(const char*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/comp/readlink.c b/src/lib/libast/comp/readlink.c
new file mode 100644
index 0000000..df2129e
--- /dev/null
+++ b/src/lib/libast/comp/readlink.c
@@ -0,0 +1,61 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_readlink
+
+NoN(readlink)
+
+#else
+
+#include "fakelink.h"
+
+#include <error.h>
+
+#ifndef ENOSYS
+#define ENOSYS EINVAL
+#endif
+
+int
+readlink(const char* path, char* buf, int siz)
+{
+ int fd;
+ int n;
+
+ if (siz > sizeof(FAKELINK_MAGIC))
+ {
+ if ((fd = open(path, O_RDONLY)) < 0)
+ return -1;
+ if (read(fd, buf, sizeof(FAKELINK_MAGIC)) == sizeof(FAKELINK_MAGIC) && !strcmp(buf, FAKELINK_MAGIC) && (n = read(fd, buf, siz)) > 0 && !buf[n - 1])
+ {
+ close(fd);
+ return n;
+ }
+ close(fd);
+ }
+ errno = ENOSYS;
+ return -1;
+}
+
+#endif
diff --git a/src/lib/libast/comp/realpath.c b/src/lib/libast/comp/realpath.c
new file mode 100644
index 0000000..54c8703
--- /dev/null
+++ b/src/lib/libast/comp/realpath.c
@@ -0,0 +1,48 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * realpath implementation
+ */
+
+#define realpath ______realpath
+#define resolvepath ______resolvepath
+
+#include <ast.h>
+
+#undef realpath
+#undef resolvepath
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+extern int resolvepath(const char*, char*, size_t);
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char*
+realpath(const char* file, char* path)
+{
+ return resolvepath(file, path, PATH_MAX) > 0 ? path : (char*)0;
+}
diff --git a/src/lib/libast/comp/regcmp.c b/src/lib/libast/comp/regcmp.c
new file mode 100644
index 0000000..ddf5498
--- /dev/null
+++ b/src/lib/libast/comp/regcmp.c
@@ -0,0 +1,224 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * regcmp implementation
+ */
+
+#include <ast.h>
+#include <libgen.h>
+#include <regex.h>
+#include <align.h>
+
+#define INC (2*1024)
+#define TOT (16*1024)
+#define SUB 10
+
+typedef struct
+{
+ char* cur;
+ regex_t re;
+ unsigned char sub[SUB];
+ int nsub;
+ size_t size;
+ char buf[ALIGN_BOUND2];
+} Regex_t;
+
+__DEFINE__(char*, __loc1, 0);
+
+static void*
+block(void* handle, void* data, size_t size)
+{
+ register Regex_t* re = (Regex_t*)handle;
+
+ if (data || (size = roundof(size, ALIGN_BOUND2)) > (re->buf + re->size - re->cur))
+ return 0;
+ data = (void*)re->cur;
+ re->cur += size;
+ return data;
+}
+
+char*
+regcmp(const char* pattern, ...)
+{
+ register char* s;
+ register Regex_t* re;
+ register size_t n;
+ register int c;
+ register int p;
+ int b;
+ int e;
+ int i;
+ int j;
+ int nsub;
+ register Sfio_t* sp;
+ unsigned char paren[128];
+ unsigned char sub[SUB];
+ va_list ap;
+
+ va_start(ap, pattern);
+ if (pattern || !*pattern || !(sp = sfstropen()))
+ e = 1;
+ else
+ {
+ e = 0;
+ memset(paren, 0, sizeof(paren));
+ n = 0;
+ p = -1;
+ b = 0;
+ nsub = 0;
+ s = (char*)pattern;
+ do
+ {
+ while (c = *s++)
+ {
+ if (c == '\\')
+ {
+ sfputc(sp, c);
+ if (!(c = *s++))
+ break;
+ }
+ else if (b)
+ {
+ if (c == ']')
+ b = 0;
+ }
+ else if (c == '[')
+ {
+ b = 1;
+ if (*s == '^')
+ {
+ sfputc(sp, c);
+ c = *s++;
+ }
+ if (*s == ']')
+ {
+ sfputc(sp, c);
+ c = *s++;
+ }
+ }
+ else if (c == '(')
+ {
+ /*
+ * someone explain in one sentence why
+ * a cast is needed to make this work
+ */
+
+ if (p < (int)(elementsof(paren) - 1))
+ p++;
+ paren[p] = ++n;
+ }
+ else if (c == ')' && p >= 0)
+ {
+ for (i = p; i > 0; i--)
+ if (paren[i])
+ break;
+ if (*s == '$' && (j = *(s + 1)) >= '0' && j <= '9')
+ {
+ s += 2;
+ j -= '0';
+ if (nsub <= j)
+ {
+ if (!nsub)
+ memset(sub, 0, sizeof(sub));
+ nsub = j + 1;
+ }
+ sub[j] = paren[i] + 1;
+ }
+ paren[i] = 0;
+ }
+ sfputc(sp, c);
+ }
+ } while (s = va_arg(ap, char*));
+ }
+ va_end(ap);
+ if (e)
+ return 0;
+ if (!(s = sfstruse(sp)))
+ {
+ sfstrclose(sp);
+ return 0;
+ }
+ re = 0;
+ n = 0;
+ do
+ {
+ if ((n += INC) > TOT || !(re = newof(re, Regex_t, 0, n)))
+ {
+ if (re)
+ free(re);
+ sfstrclose(sp);
+ return 0;
+ }
+ re->cur = re->buf;
+ re->size = n + ALIGN_BOUND2 - sizeof(Regex_t);
+ regalloc(re, block, REG_NOFREE);
+ c = regcomp(&re->re, s, REG_EXTENDED|REG_LENIENT|REG_NULL);
+ regalloc(NiL, NiL, 0);
+ } while (c == REG_ESPACE);
+ sfstrclose(sp);
+ if (c)
+ {
+ free(re);
+ return 0;
+ }
+ if (re->nsub = nsub)
+ memcpy(re->sub, sub, (nsub + 1) * sizeof(sub[0]));
+ return (char*)re;
+}
+
+char*
+regex(const char* handle, const char* subject, ...)
+{
+ register Regex_t* re;
+ register int n;
+ register int i;
+ register int k;
+ char* sub[SUB + 1];
+ regmatch_t match[SUB + 1];
+ va_list ap;
+
+ va_start(ap, subject);
+ if (!(re = (Regex_t*)handle) || !subject)
+ k = 1;
+ else
+ {
+ k = 0;
+ for (n = 0; n < re->nsub; n++)
+ sub[n] = va_arg(ap, char*);
+ }
+ va_end(ap);
+ if (k)
+ return 0;
+ if (regexec(&re->re, subject, SUB + 1, match, 0))
+ return 0;
+ for (n = 0; n < re->nsub; n++)
+ if (i = re->sub[n])
+ {
+ i--;
+ k = match[i].rm_eo - match[i].rm_so;
+ strlcpy(sub[n], subject + match[i].rm_so, k);
+ *(sub[n] + k) = 0;
+ }
+ __loc1 = (char*)subject + match[0].rm_so;
+ return (char*)subject + match[0].rm_eo;
+}
diff --git a/src/lib/libast/comp/regexp.c b/src/lib/libast/comp/regexp.c
new file mode 100644
index 0000000..d2e33a4
--- /dev/null
+++ b/src/lib/libast/comp/regexp.c
@@ -0,0 +1,123 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * <regexp.h> library support
+ */
+
+#define _REGEXP_DECLARE
+
+#include <ast.h>
+#include <regexp.h>
+#include <regex.h>
+#include <align.h>
+
+typedef struct
+{
+ regex_t re;
+ char* buf;
+ char* cur;
+ unsigned int size;
+} Env_t;
+
+static void*
+block(void* handle, void* data, size_t size)
+{
+ register Env_t* env = (Env_t*)handle;
+
+ if (data || (size = roundof(size, ALIGN_BOUND2)) > (env->buf + env->size - env->cur))
+ return 0;
+ data = (void*)env->cur;
+ env->cur += size;
+ return data;
+}
+
+int
+_re_comp(regexp_t* re, const char* pattern, char* handle, unsigned int size)
+{
+ register Env_t* env = (Env_t*)handle;
+ register int n;
+
+ if (size <= sizeof(Env_t))
+ return 50;
+ env->buf = env->cur = (char*)env + sizeof(Env_t);
+ env->size = size - sizeof(Env_t);
+ regalloc(env, block, REG_NOFREE);
+ n = regcomp(&env->re, pattern, REG_LENIENT|REG_NULL);
+ switch (n)
+ {
+ case 0:
+ break;
+ case REG_ERANGE:
+ n = 11;
+ break;
+ case REG_BADBR:
+ n = 16;
+ break;
+ case REG_ESUBREG:
+ n = 25;
+ break;
+ case REG_EPAREN:
+ n = 42;
+ break;
+ case REG_EBRACK:
+ n = 49;
+ break;
+ default:
+ n = 50;
+ break;
+ }
+ re->re_nbra = env->re.re_nsub;
+ return n;
+}
+
+int
+_re_exec(regexp_t* re, const char* subject, const char* handle, int anchor)
+{
+ register Env_t* env = (Env_t*)handle;
+ register int n;
+ regmatch_t match[elementsof(re->re_braslist)+1];
+
+ if (regexec(&env->re, subject, elementsof(match), match, 0) || anchor && match[0].rm_so)
+ return 0;
+ re->re_loc1 = (char*)subject + match[0].rm_so;
+ re->re_loc2 = (char*)subject + match[0].rm_eo;
+ for (n = 1; n <= env->re.re_nsub; n++)
+ {
+ re->re_braslist[n-1] = (char*)subject + match[n].rm_so;
+ re->re_braelist[n-1] = (char*)subject + match[n].rm_eo;
+ }
+ return 1;
+}
+
+char*
+_re_putc(int c)
+{
+ static Sfio_t* sp;
+
+ if (!sp && !(sp = sfstropen()))
+ return 0;
+ if (!c)
+ return sfstruse(sp);
+ sfputc(sp, c);
+ return 0;
+}
diff --git a/src/lib/libast/comp/regexp.h b/src/lib/libast/comp/regexp.h
new file mode 100644
index 0000000..93b7185
--- /dev/null
+++ b/src/lib/libast/comp/regexp.h
@@ -0,0 +1,129 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * regexp interface and partial implementation
+ * what a novel approach
+ * don't do it again
+ *
+ * OBSOLETE: use <regex.h>
+ */
+
+#ifndef _REGEXP_H
+#define _REGEXP_H
+
+#define NBRA 9
+
+typedef struct
+{
+ char* re_braslist[NBRA];
+ char* re_braelist[NBRA];
+ char* re_loc1;
+ char* re_loc2;
+ char* re_locs;
+ int re_circf;
+ int re_nbra;
+ int re_nodelim;
+ int re_sed;
+} regexp_t;
+
+#define braslist _re_info.re_braslist
+#define braelist _re_info.re_braelist
+#define circf _re_info.re_circf
+#define loc1 _re_info.re_loc1
+#define loc2 _re_info.re_loc2
+#define locs _re_info.re_locs
+#define nbra _re_info.re_nbra
+#define nodelim _re_info.re_nodelim
+#define sed _re_info.re_sed
+
+#define advance(a,b) _re_exec(&_re_info,a,b,1)
+#define compile(a,b,c,d) _re_read(&_re_info,a,b,c,d)
+#define step(a,b) _re_exec(&_re_info,a,b,0)
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int _re_comp(regexp_t*, const char*, char*, unsigned int);
+extern int _re_exec(regexp_t*, const char*, const char*, int);
+extern char* _re_putc(int);
+extern char* _re_read(regexp_t*, const char*, char*, const char*, int);
+
+#undef extern
+
+#ifndef _REGEXP_DECLARE
+
+regexp_t _re_info;
+
+char*
+_re_read(register regexp_t* re, const char* instring, char* ep, const char* endbuf, int seof)
+{
+ register int c;
+
+ static const char* prev;
+
+#ifdef INIT
+ INIT;
+#endif
+
+ re->re_nodelim = 0;
+ if ((c = GETC()) == seof || c == '\n' || c == -1 || c == 0)
+ {
+ if (c != seof)
+ {
+ UNGETC(c);
+ re->re_nodelim = 1;
+ }
+ if (!re->re_sed && !prev)
+ { ERROR(41); }
+ RETURN((char*)endbuf);
+ }
+ UNGETC(c);
+ prev = 0;
+ for (;;)
+ {
+ if ((c = GETC()) == seof || c == '\n' || c == -1 || c == 0)
+ {
+ if (re->re_sed)
+ { ERROR(36); }
+ UNGETC(c);
+ re->re_nodelim = 1;
+ break;
+ }
+ if (c == '\\')
+ {
+ _re_putc(c);
+ if ((c = GETC()) == seof || c == '\n' || c == -1 || c == 0)
+ { ERROR(36); }
+ }
+ _re_putc(c);
+ }
+ if (c = _re_comp(re, _re_putc(0), ep, (char*)endbuf - ep))
+ { ERROR(c); }
+ prev = endbuf;
+ RETURN((char*)prev);
+}
+
+#endif
+
+#endif
diff --git a/src/lib/libast/comp/remove.c b/src/lib/libast/comp/remove.c
new file mode 100644
index 0000000..32a8e32
--- /dev/null
+++ b/src/lib/libast/comp/remove.c
@@ -0,0 +1,49 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#define remove ______remove
+
+#include <ast.h>
+
+#undef remove
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+#if _std_remove || !_lib_unlink
+
+NoN(remove)
+
+#else
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+remove(const char* path)
+{
+ return unlink(path);
+}
+
+#endif
diff --git a/src/lib/libast/comp/rename.c b/src/lib/libast/comp/rename.c
new file mode 100644
index 0000000..2ab3770
--- /dev/null
+++ b/src/lib/libast/comp/rename.c
@@ -0,0 +1,98 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_rename
+
+NoN(rename)
+
+#else
+
+#include <error.h>
+#include <proc.h>
+
+#ifdef EPERM
+
+static int
+mvdir(const char* from, const char* to)
+{
+ char* argv[4];
+ int oerrno;
+
+ static const char mvdir[] = "/usr/lib/mv_dir";
+
+ oerrno = errno;
+ if (!eaccess(mvdir, X_OK))
+ {
+ argv[0] = mvdir;
+ argv[1] = from;
+ argv[2] = to;
+ argv[3] = 0;
+ if (!procrun(argv[0], argv, 0))
+ {
+ errno = oerrno;
+ return 0;
+ }
+ }
+ errno = EPERM;
+ return -1;
+}
+
+#endif
+
+int
+rename(const char* from, const char* to)
+{
+ int oerrno;
+ int ooerrno;
+
+ ooerrno = errno;
+ while (link(from, to))
+ {
+#ifdef EPERM
+ if (errno == EPERM)
+ {
+ errno = ooerrno;
+ return mvdir(from, to);
+ }
+#endif
+ oerrno = errno;
+ if (unlink(to))
+ {
+#ifdef EPERM
+ if (errno == EPERM)
+ {
+ errno = ooerrno;
+ return mvdir(from, to);
+ }
+#endif
+ errno = oerrno;
+ return -1;
+ }
+ }
+ errno = ooerrno;
+ return unlink(from);
+}
+
+#endif
diff --git a/src/lib/libast/comp/resolvepath.c b/src/lib/libast/comp/resolvepath.c
new file mode 100644
index 0000000..a5cc4c9
--- /dev/null
+++ b/src/lib/libast/comp/resolvepath.c
@@ -0,0 +1,72 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * resolvepath implementation
+ */
+
+#define resolvepath ______resolvepath
+
+#include <ast.h>
+#include <error.h>
+
+#undef resolvepath
+
+#undef _def_map_ast
+#include <ast_map.h>
+#undef _AST_API_H
+#include <ast_api.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+resolvepath(const char* file, char* path, size_t size)
+{
+ register char* s;
+ register int n;
+ register int r;
+
+ r = *file != '/';
+ n = strlen(file) + r + 1;
+ if (n >= size)
+ {
+#ifdef ENAMETOOLONG
+ errno = ENAMETOOLONG;
+#else
+ errno = ENOMEM;
+#endif
+ return 0;
+ }
+ if (!r)
+ s = path;
+ else if (!getcwd(path, size - n))
+ return 0;
+ else
+ {
+ s = path + strlen(path);
+ *s++ = '/';
+ }
+ strlcpy(s, file, size - (s - path));
+ return (s = pathcanon(path, size, PATH_PHYSICAL|PATH_DOTDOT|PATH_EXISTS)) ? (s - path) : -1;
+}
diff --git a/src/lib/libast/comp/rmdir.c b/src/lib/libast/comp/rmdir.c
new file mode 100644
index 0000000..9b3270d
--- /dev/null
+++ b/src/lib/libast/comp/rmdir.c
@@ -0,0 +1,66 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_rmdir
+
+NoN(rmdir)
+
+#else
+
+#include <ls.h>
+#include <error.h>
+
+int
+rmdir(const char* path)
+{
+ register int n;
+ struct stat st;
+ char* av[3];
+
+ static char* cmd[] = { "/bin/rmdir", "/usr/5bin/rmdir", 0 };
+
+ if (stat(path, &st) < 0) return(-1);
+ if (!S_ISDIR(st.st_mode))
+ {
+ errno = ENOTDIR;
+ return(-1);
+ }
+ av[0] = "rmdir";
+ av[1] = path;
+ av[2] = 0;
+ for (n = 0; n < elementsof(cmd); n++)
+ if (procclose(procopen(cmd[n], av, NiL, NiL, 0)) != -1)
+ break;
+ n = errno;
+ if (access(path, F_OK) < 0)
+ {
+ errno = n;
+ return(0);
+ }
+ errno = EPERM;
+ return(-1);
+}
+
+#endif
diff --git a/src/lib/libast/comp/setenv.c b/src/lib/libast/comp/setenv.c
new file mode 100644
index 0000000..c2e3d65
--- /dev/null
+++ b/src/lib/libast/comp/setenv.c
@@ -0,0 +1,58 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#define setenv ______setenv
+
+#include <ast.h>
+
+#undef setenv
+#undef _lib_setenv /* procopen() calls setenv() */
+
+#if _lib_setenv
+
+NoN(setenv)
+
+#else
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+setenv(const char* name, const char* value, int overwrite)
+{
+ char* s;
+
+ if (overwrite || !getenv(name))
+ {
+ if (!(s = sfprints("%s=%s", name, value)) || !(s = strdup(s)))
+ return -1;
+ return setenviron(s) ? 0 : -1;
+ }
+ return 0;
+}
+
+#endif
diff --git a/src/lib/libast/comp/setlocale.c b/src/lib/libast/comp/setlocale.c
new file mode 100644
index 0000000..b2bc760
--- /dev/null
+++ b/src/lib/libast/comp/setlocale.c
@@ -0,0 +1,2865 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * setlocale() intercept
+ * maintains a bitmask of non-default categories
+ * and a permanent locale namespace for pointer comparison
+ * and persistent private data for locale related functions
+ */
+
+#include <ast_standards.h>
+
+#include "lclib.h"
+
+#include <ast_wchar.h>
+#include <ctype.h>
+#include <mc.h>
+#include <namval.h>
+
+#if ( _lib_wcwidth || _lib_wctomb ) && _hdr_wctype
+#include <wctype.h>
+#endif
+
+#if _lib_wcwidth
+#undef wcwidth
+#else
+#define wcwidth 0
+#endif
+
+#if _lib_wctomb
+#undef wctomb
+#else
+#define wctomb 0
+#endif
+
+#ifdef mblen
+#undef mblen
+extern int mblen(const char*, size_t);
+#endif
+
+#undef mbtowc
+#undef setlocale
+#undef strcmp
+#undef strcoll
+#undef strxfrm
+#undef valid
+
+#ifndef AST_LC_CANONICAL
+#define AST_LC_CANONICAL LC_abbreviated
+#endif
+
+static void
+header(void)
+{
+ static int done = 0;
+
+ if (!done)
+ {
+ done = 1;
+ sfprintf(sfstderr, "locale %17s %16s %16s %16s %s\n", "CATEGORY", "AST", "SYSTEM", "PREVIOUS", "ATTRIBUTES");
+ }
+}
+
+#if _UWIN
+
+#include <ast_windows.h>
+
+#undef _lib_setlocale
+#define _lib_setlocale 1
+
+#define setlocale(c,l) native_setlocale(c,l)
+
+extern char* uwin_setlocale(int, const char*);
+
+/*
+ * convert locale to native locale name in buf
+ */
+
+static char*
+native_locale(const char* locale, char* buf, size_t siz)
+{
+ Lc_t* lc;
+ const Lc_attribute_list_t* ap;
+ int i;
+ unsigned long lcid;
+ unsigned long lang;
+ unsigned long ctry;
+ char lbuf[128];
+ char cbuf[128];
+
+ if (locale && *locale)
+ {
+ if (!(lc = lcmake(locale)))
+ return 0;
+ lang = lc->language->index;
+ ctry = 0;
+ for (ap = lc->attributes; ap; ap = ap->next)
+ if (ctry = ap->attribute->index)
+ break;
+ if (!ctry)
+ {
+ for (i = 0; i < elementsof(lc->territory->languages); i++)
+ if (lc->territory->languages[i] == lc->language)
+ {
+ ctry = lc->territory->indices[i];
+ break;
+ }
+ if (!ctry)
+ {
+ if (!lang)
+ return 0;
+ ctry = SUBLANG_DEFAULT;
+ }
+ }
+ lcid = MAKELCID(MAKELANGID(lang, ctry), SORT_DEFAULT);
+ }
+ else
+ lcid = GetUserDefaultLCID();
+ if (GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, lbuf, sizeof(lbuf)) <= 0 ||
+ GetLocaleInfo(lcid, LOCALE_SENGCOUNTRY, cbuf, sizeof(cbuf)) <= 0)
+ return 0;
+ if (lc->charset->ms)
+ sfsprintf(buf, siz, "%s_%s.%s", lbuf, cbuf, lc->charset->ms);
+ else
+ sfsprintf(buf, siz, "%s_%s", lbuf, cbuf);
+ return buf;
+}
+
+/*
+ * locale!=0 here
+ */
+
+static char*
+native_setlocale(int category, const char* locale)
+{
+ char* usr;
+ char* sys;
+ char buf[256];
+
+ if (!(usr = native_locale(locale, buf, sizeof(buf))))
+ return 0;
+
+ /*
+ * win32 doesn't have LC_MESSAGES
+ */
+
+ if (category == LC_MESSAGES)
+ return (char*)locale;
+ sys = uwin_setlocale(category, usr);
+ if (ast.locale.set & AST_LC_debug)
+ sfprintf(sfstderr, "locale uwin %17s %-24s %-24s\n", lc_categories[lcindex(category, 0)].name, usr, sys);
+ return sys;
+}
+
+#else
+
+#define native_locale(a,b,c) ((char*)0)
+
+#endif
+
+/*
+ * LC_COLLATE and LC_CTYPE native support
+ */
+
+#if !_lib_mbtowc || MB_LEN_MAX <= 1
+#define mblen 0
+#define mbtowc 0
+#endif
+
+#if !_lib_strcoll
+#define strcoll 0
+#endif
+
+#if !_lib_strxfrm
+#define strxfrm 0
+#endif
+
+/*
+ * LC_COLLATE and LC_CTYPE debug support
+ *
+ * mutibyte debug encoding
+ *
+ * DL0 [ '0' .. '4' ] c1 ... c4 DR0
+ * DL1 [ '0' .. '4' ] c1 ... c4 DR1
+ *
+ * with these ligatures
+ *
+ * ch CH sst SST
+ *
+ * and private collation order
+ *
+ * wide character display width is the low order 3 bits
+ * wctomb() uses DL1...DR1
+ */
+
+#define DEBUG_MB_CUR_MAX 7
+
+#if DEBUG_MB_CUR_MAX < MB_LEN_MAX
+#undef DEBUG_MB_CUR_MAX
+#define DEBUG_MB_CUR_MAX MB_LEN_MAX
+#endif
+
+#define DL0 '<'
+#define DL1 0xab /* 8-bit mini << on xterm */
+#define DR0 '>'
+#define DR1 0xbb /* 8-bit mini >> on xterm */
+
+#define DB ((int)sizeof(wchar_t)*8-1)
+#define DC 7 /* wchar_t embedded char bits */
+#define DX (DB/DC) /* wchar_t max embedded chars */
+#define DZ (DB-DX*DC+1) /* wchar_t embedded size bits */
+#define DD 3 /* # mb delimiter chars <n...> */
+
+static unsigned char debug_order[] =
+{
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 99, 100, 101, 102, 98, 103, 104, 105,
+ 106, 107, 108, 43, 109, 44, 42, 110,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 111, 112, 113, 114, 115, 116,
+ 117, 71, 72, 73, 74, 75, 76, 77,
+ 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 90, 91, 92, 93,
+ 94, 95, 96, 118, 119, 120, 121, 97,
+ 122, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67,
+ 68, 69, 70, 123, 124, 125, 126, 127,
+ 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199,
+ 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215,
+ 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231,
+ 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247,
+ 248, 249, 250, 251, 252, 253, 254, 255,
+};
+
+static int
+debug_mbtowc(register wchar_t* p, register const char* s, size_t n)
+{
+ register const char* q;
+ register const char* r;
+ register int w;
+ register int dr;
+ wchar_t c;
+
+ if (n < 1)
+ return -1;
+ if (!s || !*s)
+ return 0;
+ switch (((unsigned char*)s)[0])
+ {
+ case DL0:
+ dr = DR0;
+ break;
+ case DL1:
+ dr = DR1;
+ break;
+ default:
+ single:
+ if (p)
+ *p = ((unsigned char*)s)[0] & ((1<<DC)-1);
+ return 1;
+ }
+ if (n < 2)
+ return -1;
+ if ((w = ((unsigned char*)s)[1]) < '0' || w > ('0' + DX))
+ goto single;
+ if ((w -= '0' - DD) > n)
+ return -1;
+ r = s + w - 1;
+ q = s += 2;
+ while (q < r && *q)
+ q++;
+ if (q != r || *((unsigned char*)q) != dr)
+ return -1;
+ if (p)
+ {
+ c = 1;
+ while (--q >= s)
+ {
+ c <<= DC;
+ c |= *((unsigned char*)q);
+ }
+ c <<= DZ;
+ c |= (w - DD);
+ *p = c;
+ }
+ return w;
+}
+
+static int
+debug_wctomb(char* s, wchar_t c)
+{
+ int w;
+ int i;
+ int k;
+
+ w = 0;
+ if (c >= 0 && c <= UCHAR_MAX)
+ {
+ w++;
+ if (s)
+ *s = c;
+ }
+ else if ((i = c & ((1<<DZ)-1)) > DX)
+ return -1;
+ else
+ {
+ w++;
+ if (s)
+ *s++ = DL0;
+ c >>= DZ;
+ w++;
+ if (s)
+ *s++ = i + '0';
+ while (i--)
+ {
+ w++;
+ if (s)
+ *s++ = (k = c & ((1<<DC)-1)) ? k : '?';
+ c >>= DC;
+ }
+ w++;
+ if (s)
+ *s++ = DR0;
+ }
+ return w;
+}
+
+static int
+debug_mblen(const char* s, size_t n)
+{
+ return debug_mbtowc(NiL, s, n);
+}
+
+static int
+debug_wcwidth(wchar_t c)
+{
+ if (c >= 0 && c <= UCHAR_MAX)
+ return 1;
+ if ((c &= ((1<<DZ)-1)) > DX)
+ return -1;
+ return c + DD;
+}
+
+static int
+debug_alpha(wchar_t c)
+{
+ return isalpha((c >> DZ) & ((1<<DC)-1));
+}
+
+static size_t
+debug_strxfrm(register char* t, register const char* s, size_t n)
+{
+ register const char* q;
+ register const char* r;
+ register char* e;
+ char* o;
+ register size_t z;
+ register int w;
+
+ o = t;
+ z = 0;
+ if (e = t)
+ e += n;
+ while (s[0])
+ {
+ if ((((unsigned char*)s)[0] == DL0 || ((unsigned char*)s)[0] == DL1) && (w = s[1]) >= '0' && w <= ('0' + DC))
+ {
+ w -= '0';
+ q = s + 2;
+ r = q + w;
+ while (q < r && *q)
+ q++;
+ if (*((unsigned char*)q) == DR0 || *((unsigned char*)q) == DR1)
+ {
+ if (t)
+ {
+ for (q = s + 2; q < r; q++)
+ if (t < e)
+ *t++ = debug_order[*q];
+ while (w++ < DX)
+ if (t < e)
+ *t++ = 1;
+ }
+ s = r + 1;
+ z += DX;
+ continue;
+ }
+ }
+ if ((s[0] == 'c' || s[0] == 'C') && (s[1] == 'h' || s[1] == 'H'))
+ {
+ if (t)
+ {
+ if (t < e)
+ *t++ = debug_order[s[0]];
+ if (t < e)
+ *t++ = debug_order[s[1]];
+ if (t < e)
+ *t++ = 1;
+ if (t < e)
+ *t++ = 1;
+ }
+ s += 2;
+ z += DX;
+ continue;
+ }
+ if ((s[0] == 's' || s[0] == 'S') && (s[1] == 's' || s[1] == 'S') && (s[2] == 't' || s[2] == 'T'))
+ {
+ if (t)
+ {
+ if (t < e)
+ *t++ = debug_order[s[0]];
+ if (t < e)
+ *t++ = debug_order[s[1]];
+ if (t < e)
+ *t++ = debug_order[s[2]];
+ if (t < e)
+ *t++ = 1;
+ }
+ s += 3;
+ z += DX;
+ continue;
+ }
+ if (t)
+ {
+ if (t < e)
+ *t++ = debug_order[s[0]];
+ if (t < e)
+ *t++ = 1;
+ if (t < e)
+ *t++ = 1;
+ if (t < e)
+ *t++ = 1;
+ }
+ s++;
+ z += DX;
+ }
+ if (!t)
+ return z;
+ if (t < e)
+ *t = 0;
+ return t - o;
+}
+
+static int
+debug_strcoll(const char* a, const char* b)
+{
+ char ab[1024];
+ char bb[1024];
+
+ debug_strxfrm(ab, a, sizeof(ab) - 1);
+ ab[sizeof(ab)-1] = 0;
+ debug_strxfrm(bb, b, sizeof(bb) - 1);
+ bb[sizeof(bb)-1] = 0;
+ return strcmp(ab, bb);
+}
+
+/*
+ * default locale
+ */
+
+static int
+default_wcwidth(wchar_t w)
+{
+ return w >= 0 && w <= 255 && !iscntrl(w) ? 1 : -1;
+}
+
+/*
+ * called when LC_COLLATE initialized or changes
+ */
+
+static int
+set_collate(Lc_category_t* cp)
+{
+ if (locales[cp->internal]->flags & LC_debug)
+ {
+ ast.collate = debug_strcoll;
+ ast.mb_xfrm = debug_strxfrm;
+ }
+ else if (locales[cp->internal]->flags & LC_default)
+ {
+ ast.collate = strcmp;
+ ast.mb_xfrm = 0;
+ }
+ else
+ {
+ ast.collate = strcoll;
+ ast.mb_xfrm = strxfrm;
+ }
+ return 0;
+}
+
+/*
+ * workaround the interesting sjis that translates unshifted 7 bit ascii!
+ */
+
+#if _hdr_wchar && _typ_mbstate_t && _lib_mbrtowc
+
+#define mb_state_zero ((mbstate_t*)&ast.pad[sizeof(ast.pad)-2*sizeof(mbstate_t)])
+#define mb_state ((mbstate_t*)&ast.pad[sizeof(ast.pad)-sizeof(mbstate_t)])
+
+static int
+sjis_mbtowc(register wchar_t* p, register const char* s, size_t n)
+{
+ if (n && p && s && (*s == '\\' || *s == '~') && !memcmp(mb_state, mb_state_zero, sizeof(mbstate_t)))
+ {
+ *p = *s;
+ return 1;
+ }
+ return mbrtowc(p, s, n, mb_state);
+}
+
+#endif
+
+#if 0
+
+#define utf8_wctomb wctomb
+
+#else
+
+static int
+utf8_wctomb(char* u, wchar_t w)
+{
+ if (!u)
+ return 0;
+ if (w >= (1<<11))
+ {
+ *u++ = 0xe0|(w>>12);
+ *u++ = 0x80|((w>>6)&0x3f);
+ *u++ = 0x80|(w&0x3f);
+ return 3;
+ }
+ if (w >= (1<<7))
+ {
+ *u++ = 0xc0|(w>>6);
+ *u++ = 0x80|(w&0x3f);
+ return 2;
+ }
+ *u++ = w;
+ return 1;
+}
+
+#endif
+
+static const uint32_t utf8mask[] =
+{
+ 0x00000000,
+ 0x00000000,
+ 0xffffff80,
+ 0xfffff800,
+ 0xffff0000,
+ 0xffe00000,
+ 0xfc000000,
+};
+
+static const signed char utf8tab[256] =
+{
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6,-1,-1,
+};
+
+static int
+utf8_mbtowc(wchar_t* wp, const char* str, size_t n)
+{
+ register unsigned char* sp = (unsigned char*)str;
+ register int m;
+ register int i;
+ register int c;
+ register wchar_t w = 0;
+
+ if (!sp || !n)
+ return 0;
+ if ((m = utf8tab[*sp]) > 0)
+ {
+ if (m > n)
+ return -1;
+ if (wp)
+ {
+ if (m == 1)
+ {
+ *wp = *sp;
+ return 1;
+ }
+ w = *sp & ((1<<(8-m))-1);
+ for (i = m - 1; i > 0; i--)
+ {
+ c = *++sp;
+ if ((c&0xc0) != 0x80)
+ goto invalid;
+ w = (w<<6) | (c&0x3f);
+ }
+ if (!(utf8mask[m] & w) || w >= 0xd800 && (w <= 0xdfff || w >= 0xfffe && w <= 0xffff))
+ goto invalid;
+ *wp = w;
+ }
+ return m;
+ }
+ if (!*sp)
+ return 0;
+ invalid:
+#ifdef EILSEQ
+ errno = EILSEQ;
+#endif
+ ast.mb_sync = (const char*)sp - str;
+ return -1;
+}
+
+static int
+utf8_mblen(const char* str, size_t n)
+{
+ wchar_t w;
+
+ return utf8_mbtowc(&w, str, n);
+}
+
+static const unsigned char utf8_wcw[] =
+{
+ 0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5d,0x55,0x55,0x55,0x55,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,0xff,0xff,0xff,0xff,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0xff,0xf5,0xdf,0xdf,
+ 0xff,0x55,0xd5,0x5d,0x55,0x55,0x55,0x55,0x75,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0xd5,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,0xff,0xff,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x15,0xc0,0x50,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0xd5,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0xf5,0xff,
+ 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0xd5,0x57,0x55,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0xd7,0xff,0x03,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x10,
+ 0x41,0xfc,0xff,0xff,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,0xff,0x55,0xfd,0xff,0xff,
+ 0xff,0xff,0xff,0xfd,0xff,0xff,0x7f,0x7f,0x57,0x55,0x55,0x55,0x55,0x55,0xd5,0xff,
+ 0x55,0x55,0x15,0x00,0x00,0xf0,0xff,0xff,0x55,0x55,0x55,0x55,0x54,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x05,0x00,0x00,0x00,0x14,0x04,0xf0,0x55,0x55,0x55,0xd5,
+ 0x55,0x55,0x55,0x35,0x51,0x55,0x55,0x55,0x55,0x55,0x55,0xfd,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x05,0x00,0x00,0xf4,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0x43,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0x54,
+ 0x01,0x00,0x54,0xf1,0x01,0xfc,0x55,0x55,0x05,0x55,0x55,0x55,0xfd,0xff,0xff,0xff,
+ 0x53,0x57,0x55,0x7d,0x7d,0x55,0x55,0x55,0x55,0x55,0x5d,0x55,0xdd,0x5f,0xf5,0x5c,
+ 0x01,0x7c,0x7d,0xf1,0xff,0x7f,0xff,0x75,0x05,0x5f,0x55,0x55,0x55,0x55,0xd5,0xff,
+ 0xcf,0x57,0xd5,0x7f,0x7d,0x55,0x55,0x55,0x55,0x55,0x5d,0x55,0x5d,0xd7,0xf5,0x5c,
+ 0xc1,0x3f,0x3c,0xf0,0xff,0xff,0x57,0xdd,0xff,0x5f,0x55,0x55,0x50,0xfd,0xff,0xff,
+ 0x43,0x57,0x55,0x77,0x75,0x55,0x55,0x55,0x55,0x55,0x5d,0x55,0x5d,0x57,0xf5,0x54,
+ 0x01,0x30,0x74,0xf1,0xfd,0xff,0xff,0xff,0xfd,0x5f,0x55,0x55,0xff,0xff,0xff,0xff,
+ 0x53,0x57,0x55,0x7d,0x7d,0x55,0x55,0x55,0x55,0x55,0x5d,0x55,0x5d,0x5f,0xf5,0x14,
+ 0x01,0x7f,0x7d,0xf1,0xff,0x4f,0xff,0x75,0xf5,0x5f,0x55,0x55,0xfd,0xff,0xff,0xff,
+ 0x4f,0x57,0xd5,0x5f,0x5d,0xf5,0xd7,0x5d,0x7f,0xfd,0xd5,0x5f,0x55,0x75,0xf5,0x5f,
+ 0xd4,0x5f,0x5d,0xf1,0xff,0x7f,0xff,0xff,0xff,0x7f,0x55,0x55,0xd5,0xff,0xff,0xff,
+ 0x57,0x57,0x55,0x5d,0x5d,0x55,0x55,0x55,0x55,0x55,0x5d,0x55,0x55,0x57,0xf5,0x0f,
+ 0x54,0x0d,0x0c,0xf0,0xff,0xc3,0xff,0xff,0xf5,0x5f,0x55,0x55,0xff,0xff,0xff,0xff,
+ 0x5f,0x57,0x55,0x5d,0x5d,0x55,0x55,0x55,0x55,0x55,0x5d,0x55,0x55,0x57,0xf5,0x1f,
+ 0x55,0x4d,0x5d,0xf0,0xff,0xd7,0xff,0xdf,0xf5,0x5f,0x55,0x55,0xff,0xff,0xff,0xff,
+ 0x5f,0x57,0x55,0x5d,0x5d,0x55,0x55,0x55,0x55,0x55,0x5d,0x55,0x55,0x55,0xf5,0x5f,
+ 0x01,0x5f,0x5d,0xf1,0xff,0x7f,0xff,0xff,0xf5,0x5f,0x55,0x55,0xff,0xff,0xff,0xff,
+ 0x5f,0x57,0x55,0x55,0x55,0xd5,0x5f,0x55,0x55,0x55,0x55,0x55,0x75,0x55,0x55,0xf7,
+ 0x55,0xd5,0xcf,0x7f,0x05,0xcc,0x55,0x55,0xff,0xff,0xff,0xff,0x5f,0xfd,0xff,0xff,
+ 0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x51,0x00,0xc0,0x7f,
+ 0x55,0x15,0x00,0x40,0x55,0x55,0x55,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xd7,0x7d,0xdd,0xf7,0xff,0x55,0x57,0x55,0x57,0x77,0x5f,0x57,0x51,0x00,0x30,0xf4,
+ 0x55,0xdd,0x00,0xf0,0x55,0x55,0xf5,0xf5,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x50,0x55,0x55,0x55,0x55,0x55,0x55,0x11,0x51,0x55,
+ 0x55,0x55,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,0xff,0x03,0x00,0x00,0x40,
+ 0x00,0x04,0x55,0xff,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5c,
+ 0x55,0x45,0x55,0x7d,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x75,0x55,0xd7,0x01,0xc4,0x0f,0xf1,0xff,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0xf5,0xff,0xff,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x7d,0xff,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xfa,0xbf,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,
+ 0x55,0xd5,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0xd5,0x5d,0xf5,0x55,0xd5,0x5d,0xf5,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0xd5,0x5d,0xf5,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,0x5d,0xf5,0x55,0xd5,
+ 0x5d,0xf5,0x55,0xd5,0x55,0xd5,0x55,0x55,0x55,0x55,0x55,0xd5,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0xd5,0x5d,0xf5,0x55,0xd5,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0xd5,0x55,0x55,0x55,0x55,0xd5,0xff,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0xfd,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xfd,0xff,0xff,
+ 0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,0xff,0xff,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xfd,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xfd,0xff,0xff,0xff,
+ 0x55,0x55,0x55,0x5d,0x05,0xfc,0xff,0xff,0x55,0x55,0x55,0x55,0x05,0xd4,0xff,0xff,
+ 0x55,0x55,0x55,0x55,0x05,0xff,0xff,0xff,0x55,0x55,0x55,0x5d,0x0d,0xff,0xff,0xff,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x15,0x00,0x50,
+ 0x55,0x45,0x01,0x00,0x00,0x55,0x55,0xfd,0x55,0x55,0xf5,0xff,0xff,0xff,0xff,0xff,
+ 0x55,0x55,0x15,0xc0,0x55,0x55,0xf5,0xff,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xff,0xff,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf1,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xff,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0xff,
+ 0x55,0x55,0x55,0x55,0x55,0xf5,0x55,0xf5,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0xf5,0x55,0xf5,0x55,0x55,0x77,0x77,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5d,0x55,0x55,
+ 0x55,0x5d,0x55,0x55,0x55,0x5f,0x55,0x57,0x55,0x55,0x55,0x55,0x5f,0x5d,0x55,0xd5,
+ 0x55,0x55,0x15,0x00,0x55,0x55,0x55,0x55,0x55,0x55,0x0f,0x40,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0xd5,0x7f,0xff,0x7f,0x00,0xff,0x0f,0x00,0xf5,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0xd5,0xff,0xff,0xff,0xff,0x55,0x55,0x55,0x55,0xf5,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff,0xff,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,0x57,
+ 0x55,0x55,0x55,0xff,0x7f,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0xff,0xff,0xff,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x69,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0xd5,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0x55,0x55,0xd5,0xff,0xff,0xff,0xff,0xff,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x5f,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,
+ 0x55,0x55,0xf5,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0x57,0x5d,0xf5,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x57,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x77,0xd5,0xdf,0x55,0xd5,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0xfd,0x55,0x55,0x55,0x55,0x55,0x55,0x57,0x55,0x55,0xd5,
+ 0xff,0xff,0xff,0xff,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xff,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xba,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xff,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0x0a,0x00,0xaa,0xaa,0xaa,0x6a,
+ 0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xea,0x83,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xff,0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xfe,0xab,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xea,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xfe,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xff,0xff,0xff,0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xbf,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xff,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xea,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xea,0xbf,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xfa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xea,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xfa,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xfe,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xfa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xea,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0x55,0xd5,0xff,0xff,0x7f,0x55,0xff,0x47,0x55,0x55,0x55,0x55,0x55,0xd5,0x55,0xdd,
+ 0x75,0x5d,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xf5,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0x7f,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0xff,0xff,0xff,0xff,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x5f,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x55,0x55,0x55,0xfd,
+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xea,0xab,0xaa,0xea,0xaa,0xaa,0xaa,0xaa,0xea,0xaa,0xff,0x55,0x5d,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x3d,
+ 0xab,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
+ 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0x56,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xd5,
+ 0x5f,0x55,0x5f,0x55,0x5f,0x55,0x5f,0xfd,0xaa,0xea,0x55,0xd5,0xff,0xff,0x03,0xf5
+};
+
+static int
+utf8_wcwidth(wchar_t c)
+{
+ int n;
+
+ return (n = (utf8_wcw[(c >> 2) & 0x3fff] >> ((c & 0x3) << 1)) & 0x3) == 3 ? -1 : n;
+}
+
+static const unsigned char utf8_wam[] =
+{
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,0xfe,0xff,0xff,0x07,
+ 0x00,0x00,0x00,0x00,0x00,0x04,0x20,0x04,0xff,0xff,0x7f,0xff,0xff,0xff,0x7f,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xfd,0xff,0x0f,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0x3f,0xff,0xf9,0x03,0x00,0x03,0x00,0x1f,0x40,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x04,
+ 0x40,0xd7,0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0x3f,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0x03,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0x3f,0x03,
+ 0xff,0xff,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0x7f,0x02,0xfe,0xff,0xff,0xff,
+ 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x07,0x07,0x00,
+ 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,0xff,0x07,0x00,0x00,0xff,0xc3,0xfe,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2f,0x00,0x60,0x00,0xff,0x1f,
+ 0x00,0x00,0xfd,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0x3f,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0x23,0x00,0x00,0x01,0xff,0xc3,0xff,0x00,0x00,
+ 0xe0,0x9f,0xf9,0xff,0xff,0xfd,0xc5,0x03,0x00,0x00,0x00,0xb0,0xc3,0xff,0x03,0x00,
+ 0xe0,0x87,0xf9,0xff,0xff,0xfd,0x6d,0x03,0x00,0x00,0x00,0x5e,0xc0,0xff,0x1c,0x00,
+ 0xe0,0xaf,0xfb,0xff,0xff,0xfd,0xed,0x23,0x00,0x00,0x01,0x00,0xc1,0xff,0x00,0x00,
+ 0xe0,0x9f,0xf9,0xff,0xff,0xfd,0xcd,0x23,0x00,0x00,0x00,0xb0,0xc3,0xff,0x00,0x00,
+ 0xe8,0xc7,0x3d,0xd6,0x18,0xc7,0xbf,0x03,0x00,0x00,0x00,0x00,0x80,0xff,0x00,0x00,
+ 0xe0,0xdf,0xfd,0xff,0xff,0xfd,0xef,0x03,0x00,0x00,0x00,0x00,0xc3,0xff,0x00,0x00,
+ 0xe0,0xdf,0xfd,0xff,0xff,0xfd,0xef,0x03,0x00,0x00,0x00,0x40,0xc3,0xff,0x00,0x00,
+ 0xe0,0xdf,0xfd,0xff,0xff,0xfd,0xff,0x03,0x00,0x00,0x00,0x00,0xc3,0xff,0x00,0x00,
+ 0xe0,0xff,0x7f,0xfc,0xff,0xff,0xfb,0x2f,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xfe,0xff,0xff,0xff,0xff,0x7f,0xff,0x07,0xbf,0x7f,0xff,0x03,0x00,0x00,0x00,0x00,
+ 0x96,0x25,0xf0,0xfe,0xae,0xec,0x0d,0x20,0x5f,0x00,0xff,0x33,0x00,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0xff,0x03,0x00,0x00,0xff,0xfe,0xff,0xff,0xff,0x07,0x00,0x00,
+ 0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xfb,0x06,0x00,0x00,0xff,0x03,0x3f,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0x3f,0x00,0xff,0xff,0xff,0xff,0xff,0x01,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x83,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0x07,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,
+ 0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x3d,0x7f,0x3d,0xff,0xff,0xff,0xff,
+ 0x7f,0x3d,0xff,0xff,0xff,0x7f,0x3d,0x7f,0x3d,0x7f,0x7f,0xff,0xff,0x7f,0xff,0xff,
+ 0xff,0x7f,0x3d,0x7f,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0x07,0x00,0xfe,0x03,0x00,
+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,0x00,
+ 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9f,0x7f,0x00,
+ 0xfe,0xff,0xff,0x07,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc7,0x01,0x00,
+ 0xff,0xdf,0x03,0x00,0xff,0xff,0x03,0x00,0xff,0xff,0x03,0x00,0xff,0xdf,0x01,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x80,0x10,0xff,0x03,0x00,0x00,
+ 0x00,0x00,0xff,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0x0f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,
+ 0xff,0xff,0x3f,0x3f,0xff,0xff,0xff,0xff,0x3f,0x3f,0xff,0xaa,0xff,0xff,0xff,0x3f,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x5f,0xdc,0x1f,0xcf,0x0f,0xff,0x1f,0xdc,0x1f,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x80,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x84,0xfc,0x2f,0x3e,0x50,0xbf,0xfb,0xe3,0xe0,0x03,0x00,0x00,0xff,0xff,0xff,0xff,
+ 0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xe0,0x00,0x00,0x00,0xfe,0x03,0x3e,0x1f,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0x7f,0xe0,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,
+ 0xe0,0xff,0xff,0xff,0xff,0x1f,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0x7f,0x00,0x00,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x7f,0x00,0xf8,0xa0,0xff,0xfd,0x7f,0x5f,0xdb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0x03,0x00,0x00,0x00,0xf8,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0xff,0x0f,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdf,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1f,
+ 0x00,0x00,0xff,0x03,0xfe,0xff,0xff,0x07,0xfe,0xff,0xff,0x07,0xc0,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xfc,0xfc,0xfc,0x1c,0x00,0x00,0x00,0x00
+};
+
+static int
+utf8_alpha(wchar_t c)
+{
+ return !!(utf8_wam[(c >> 3) & 0x1fff] & (1 << (c & 0x7)));
+}
+
+#if !_hdr_wchar || !_lib_wctype || !_lib_iswctype
+#undef iswalpha
+#define iswalpha default_iswalpha
+static int
+iswalpha(wchar_t c)
+{
+ return c <= 0x7f ? isalpha(c) : 0;
+}
+#endif
+
+typedef int (*Isw_f)(wchar_t);
+
+/*
+ * called when LC_CTYPE initialized or changes
+ */
+
+static int
+set_ctype(Lc_category_t* cp)
+{
+ ast.mb_sync = 0;
+ ast.mb_alpha = (Isw_f)iswalpha;
+#if AHA
+ if ((ast.locale.set & (AST_LC_debug|AST_LC_setlocale)) && !(ast.locale.set & AST_LC_internal))
+ sfprintf(sfstderr, "locale setf %17s %16s\n", cp->name, locales[cp->internal]->name);
+#endif
+ if (locales[cp->internal]->flags & LC_debug)
+ {
+ ast.mb_cur_max = DEBUG_MB_CUR_MAX;
+ ast.mb_len = debug_mblen;
+ ast.mb_towc = debug_mbtowc;
+ ast.mb_width = debug_wcwidth;
+ ast.mb_conv = debug_wctomb;
+ ast.mb_alpha = debug_alpha;
+ }
+ else if ((locales[cp->internal]->flags & LC_utf8) && !(ast.locale.set & AST_LC_test))
+ {
+ ast.mb_cur_max = 6;
+ ast.mb_len = utf8_mblen;
+ ast.mb_towc = utf8_mbtowc;
+ if ((locales[cp->internal]->flags & LC_local) || !(ast.mb_width = wcwidth))
+ ast.mb_width = utf8_wcwidth;
+ ast.mb_conv = utf8_wctomb;
+ ast.mb_alpha = utf8_alpha;
+ }
+ else if ((locales[cp->internal]->flags & LC_default) || (ast.mb_cur_max = MB_CUR_MAX) <= 1 || !(ast.mb_len = mblen) || !(ast.mb_towc = mbtowc))
+ {
+ ast.mb_cur_max = 1;
+ ast.mb_len = 0;
+ ast.mb_towc = 0;
+ ast.mb_width = default_wcwidth;
+ ast.mb_conv = 0;
+ }
+ else
+ {
+ if (!(ast.mb_width = wcwidth))
+ ast.mb_width = default_wcwidth;
+ ast.mb_conv = wctomb;
+#ifdef mb_state
+ {
+ /*
+ * check for sjis that translates unshifted 7 bit ascii!
+ */
+
+ char* s;
+ char buf[2];
+
+ mbinit();
+ buf[1] = 0;
+ *(s = buf) = '\\';
+ if (mbchar(s) != buf[0])
+ {
+ memcpy(mb_state, mb_state_zero, sizeof(mbstate_t));
+ ast.mb_towc = sjis_mbtowc;
+ }
+ }
+#endif
+ }
+ return 0;
+}
+
+/*
+ * called when LC_NUMERIC initialized or changes
+ */
+
+static int
+set_numeric(Lc_category_t* cp)
+{
+ register int category = cp->internal;
+ struct lconv* lp;
+ Lc_numeric_t* dp;
+
+ static Lc_numeric_t default_numeric = { '.', -1 };
+ static Lc_numeric_t eu_numeric = { ',', '.' };
+ static Lc_numeric_t us_numeric = { '.', ',' };
+
+#if AHA
+ if ((ast.locale.set & (AST_LC_debug|AST_LC_setlocale)) && !(ast.locale.set & AST_LC_internal))
+ sfprintf(sfstderr, "locale setf %17s %16s\n", cp->name, locales[cp->internal]->name);
+#endif
+ if (!LCINFO(category)->data)
+ {
+ if (locales[cp->internal]->flags & LC_local)
+ dp = locales[cp->internal]->territory == &lc_territories[0] ? &default_numeric : *locales[cp->internal]->territory->code == 'e' ? &eu_numeric : &us_numeric;
+ else if ((lp = localeconv()) && (dp = newof(0, Lc_numeric_t, 1, 0)))
+ {
+ dp->decimal = lp->decimal_point && *lp->decimal_point ? *(unsigned char*)lp->decimal_point : '.';
+ dp->thousand = lp->thousands_sep && *lp->thousands_sep ? *(unsigned char*)lp->thousands_sep : -1;
+ }
+ else
+ dp = &default_numeric;
+ LCINFO(category)->data = (void*)dp;
+ }
+ return 0;
+}
+
+/*
+ * this table is indexed by AST_LC_[A-Z]*
+ */
+
+Lc_category_t lc_categories[] =
+{
+{ "LC_ALL", LC_ALL, AST_LC_ALL, 0 },
+{ "LC_COLLATE", LC_COLLATE, AST_LC_COLLATE, set_collate },
+{ "LC_CTYPE", LC_CTYPE, AST_LC_CTYPE, set_ctype },
+{ "LC_MESSAGES", LC_MESSAGES, AST_LC_MESSAGES, 0 },
+{ "LC_MONETARY", LC_MONETARY, AST_LC_MONETARY, 0 },
+{ "LC_NUMERIC", LC_NUMERIC, AST_LC_NUMERIC, set_numeric },
+{ "LC_TIME", LC_TIME, AST_LC_TIME, 0 },
+{ "LC_IDENTIFICATION",LC_IDENTIFICATION,AST_LC_IDENTIFICATION,0 },
+{ "LC_ADDRESS", LC_ADDRESS, AST_LC_ADDRESS, 0 },
+{ "LC_NAME", LC_NAME, AST_LC_NAME, 0 },
+{ "LC_TELEPHONE", LC_TELEPHONE, AST_LC_TELEPHONE, 0 },
+{ "LC_XLITERATE", LC_XLITERATE, AST_LC_XLITERATE, 0 },
+{ "LC_MEASUREMENT", LC_MEASUREMENT, AST_LC_MEASUREMENT, 0 },
+{ "LC_PAPER", LC_PAPER, AST_LC_PAPER, 0 },
+};
+
+static Lc_t* lang;
+static Lc_t* lc_all;
+
+typedef struct Unamval_s
+{
+ char* name;
+ unsigned int value;
+} Unamval_t;
+
+static const Unamval_t options[] =
+{
+ "debug", AST_LC_debug,
+ "find", AST_LC_find,
+ "setlocale", AST_LC_setlocale,
+ "test", AST_LC_test,
+ "translate", AST_LC_translate,
+ 0, 0
+};
+
+/*
+ * called by stropt() to set options
+ */
+
+static int
+setopt(void* a, const void* p, int n, const char* v)
+{
+ if (p)
+ {
+ if (n)
+ ast.locale.set |= ((Unamval_t*)p)->value;
+ else
+ ast.locale.set &= ~((Unamval_t*)p)->value;
+ }
+ return 0;
+}
+
+#if !_lib_setlocale
+
+#define setlocale(c,l) default_setlocale(c,l)
+
+static char*
+default_setlocale(int category, const char* locale)
+{
+ Lc_t* lc;
+
+ if (locale)
+ {
+ if (!(lc = lcmake(locale)) || !(lc->flags & LC_default))
+ return 0;
+ locales[0]->flags &= ~lc->flags;
+ locales[1]->flags &= ~lc->flags;
+ return lc->name;
+ }
+ return (locales[1]->flags & (1<<category)) ? locales[1]->name : locales[0]->name;
+}
+
+#endif
+
+#if !_UWIN
+
+/*
+ * workaround for systems that shall not be named (solaris,freebsd)
+ * the call free() with addresses that look like the came from the stack
+ */
+
+extern int _vmkeep(int);
+
+static char*
+_sys_setlocale(int category, const char* locale)
+{
+ char* r;
+ int k;
+
+ k = _vmkeep(1);
+ r = setlocale(category, locale);
+ (void)_vmkeep(k);
+ return r;
+}
+
+#define setlocale(a,b) _sys_setlocale(a,b)
+
+#endif
+
+/*
+ * set a single AST_LC_* locale category
+ * the caller must validate category
+ * lc==0 restores the previous state
+ */
+
+static char*
+single(int category, Lc_t* lc, unsigned int flags)
+{
+ const char* sys;
+ int i;
+
+#if AHA
+ if ((ast.locale.set & (AST_LC_debug|AST_LC_setlocale)) && !(ast.locale.set & AST_LC_internal))
+ sfprintf(sfstderr, "locale single %16s %16s flags %04x\n", lc_categories[category].name, lc ? lc->name : 0, flags);
+#endif
+ if (flags & (LC_setenv|LC_setlocale))
+ {
+ if (!(ast.locale.set & AST_LC_internal))
+ lc_categories[category].prev = lc;
+ if ((flags & LC_setenv) && lc_all && locales[category])
+ {
+ if (lc_categories[category].setf)
+ (*lc_categories[category].setf)(&lc_categories[category]);
+ return (char*)locales[category]->name;
+ }
+ }
+ if (!lc && (!(lc_categories[category].flags & LC_setlocale) || !(lc = lc_categories[category].prev)) && !(lc = lc_all) && !(lc = lc_categories[category].prev) && !(lc = lang))
+ lc = lcmake(NiL);
+ sys = 0;
+ if (locales[category] != lc)
+ {
+ if (lc_categories[category].external == -lc_categories[category].internal)
+ {
+ for (i = 1; i < AST_LC_COUNT; i++)
+ if (locales[i] == lc)
+ {
+ sys = (char*)lc->name;
+ break;
+ }
+ }
+ else if (lc->flags & (LC_debug|LC_local))
+ sys = setlocale(lc_categories[category].external, lcmake(NiL)->name);
+ else if (!(sys = setlocale(lc_categories[category].external, lc->name)) &&
+ (streq(lc->name, lc->code) || !(sys = setlocale(lc_categories[category].external, lc->code))) &&
+ !streq(lc->code, lc->language->code))
+ sys = setlocale(lc_categories[category].external, lc->language->code);
+ if (sys)
+ lc->flags |= LC_checked;
+ else
+ {
+ /*
+ * check for local override
+ * currently this means an LC_MESSAGES dir exists
+ */
+
+ if (!(lc->flags & LC_checked))
+ {
+ char path[PATH_MAX];
+
+ if (mcfind(lc->code, NiL, LC_MESSAGES, 0, path, sizeof(path)))
+ lc->flags |= LC_local;
+ lc->flags |= LC_checked;
+ }
+ if (!(lc->flags & LC_local))
+ return 0;
+ if (lc_categories[category].external != -lc_categories[category].internal)
+ setlocale(lc_categories[category].external, lcmake(NiL)->name);
+ }
+ locales[category] = lc;
+ if (lc_categories[category].setf && (*lc_categories[category].setf)(&lc_categories[category]))
+ {
+ locales[category] = lc_categories[category].prev;
+ return 0;
+ }
+ if ((lc->flags & LC_default) || category == AST_LC_MESSAGES && lc->name[0] == 'e' && lc->name[1] == 'n' && (lc->name[2] == 0 || lc->name[2] == '_' && lc->name[3] == 'U'))
+ ast.locale.set &= ~(1<<category);
+ else
+ ast.locale.set |= (1<<category);
+
+ }
+ else if (lc_categories[category].flags ^ flags)
+ {
+ lc_categories[category].flags &= ~(LC_setenv|LC_setlocale);
+ lc_categories[category].flags |= flags;
+ }
+ else
+ {
+ if (lc_categories[category].setf)
+ (*lc_categories[category].setf)(&lc_categories[category]);
+ return (char*)lc->name;
+ }
+ if ((ast.locale.set & (AST_LC_debug|AST_LC_setlocale)) && !(ast.locale.set & AST_LC_internal))
+ {
+ header();
+ sfprintf(sfstderr, "locale set %17s %16s %16s %16s", lc_categories[category].name, lc->name, sys, lc_categories[category].prev ? lc_categories[category].prev->name : NiL);
+ if (category == AST_LC_CTYPE)
+ sfprintf(sfstderr, " MB_CUR_MAX=%d%s%s%s%s%s"
+ , ast.mb_cur_max
+ , ast.mb_len == debug_mblen ? " debug_mblen" : ast.mb_len == utf8_mblen ? " utf8_mblen" : ast.mb_len == mblen ? " mblen" : ""
+ , ast.mb_towc == debug_mbtowc ? " debug_mbtowc" : ast.mb_towc == utf8_mbtowc ? " utf8_mbtowc" : ast.mb_towc == mbtowc ? " mbtowc"
+#ifdef mb_state
+ : ast.mb_towc == sjis_mbtowc ? " sjis_mbtowc"
+#endif
+ : ""
+ , ast.mb_width == debug_wcwidth ? " debug_wcwidth" : ast.mb_width == utf8_wcwidth ? " utf8_wcwidth" : ast.mb_width == wcwidth ? " wcwidth" : ast.mb_width == default_wcwidth ? " default_wcwidth" : ""
+ , ast.mb_conv == debug_wctomb ? " debug_wctomb" : ast.mb_conv == utf8_wctomb ? " utf8_wctomb" : ast.mb_conv == wctomb ? " wctomb" : ""
+ , ast.mb_alpha == debug_alpha ? " debug_alpha" : ast.mb_alpha == utf8_alpha ? " utf8_alpha" : ast.mb_alpha == (Isw_f)iswalpha ? " iswalpha" : ""
+ );
+ else if (category == AST_LC_NUMERIC)
+ {
+ Lc_numeric_t* dp = (Lc_numeric_t*)LCINFO(category)->data;
+
+ sfprintf(sfstderr, " decimal='%c' thousands='%c'", dp->decimal, dp->thousand >= 0 ? dp->thousand : 'X');
+ }
+ if ((locales[category]->flags | lc_categories[category].flags) & LC_default)
+ sfprintf(sfstderr, " default");
+ if ((locales[category]->flags | lc_categories[category].flags) & LC_local)
+ sfprintf(sfstderr, " local");
+ if ((locales[category]->flags | lc_categories[category].flags) & LC_setlocale)
+ sfprintf(sfstderr, " setlocale");
+ if ((locales[category]->flags | lc_categories[category].flags) & LC_setenv)
+ sfprintf(sfstderr, " setenv");
+ sfprintf(sfstderr, "\n");
+ }
+ return (char*)lc->name;
+}
+
+/*
+ * set composite AST_LC_ALL locale categories
+ * return <0:composite-error 0:not-composite >0:composite-ok
+ */
+
+static int
+composite(register const char* s, int initialize)
+{
+ register const char* t;
+ register int i;
+ register int j;
+ register int k;
+ int n;
+ int m;
+ const char* w;
+ Lc_t* p;
+ int cat[AST_LC_COUNT];
+ int stk[AST_LC_COUNT];
+ char buf[PATH_MAX / 2];
+
+ k = n = 0;
+ while (s[0] == 'L' && s[1] == 'C' && s[2] == '_')
+ {
+ n++;
+ j = 0;
+ w = s;
+ for (i = 1; i < AST_LC_COUNT; i++)
+ {
+ s = w;
+ t = lc_categories[i].name;
+ while (*t && *s++ == *t++);
+ if (!*t && *s++ == '=')
+ {
+ cat[j++] = i;
+ if (s[0] != 'L' || s[1] != 'C' || s[2] != '_')
+ break;
+ w = s;
+ i = -1;
+ }
+ }
+ for (s = w; *s && *s != '='; s++);
+ if (!*s)
+ {
+ for (i = 0; i < k; i++)
+ single(stk[i], NiL, 0);
+ return -1;
+ }
+ w = ++s;
+ for (;;)
+ {
+ if (!*s)
+ {
+ p = lcmake(w);
+ break;
+ }
+ else if (*s++ == ';')
+ {
+ if ((m = s - w - 1) >= sizeof(buf))
+ m = sizeof(buf) - 1;
+ memcpy(buf, w, m);
+ buf[m] = 0;
+ p = lcmake(buf);
+ break;
+ }
+ }
+ for (i = 0; i < j; i++)
+ if (!initialize)
+ {
+ if (!single(cat[i], p, 0))
+ {
+ for (i = 0; i < k; i++)
+ single(stk[i], NiL, 0);
+ return -1;
+ }
+ stk[k++] = cat[i];
+ }
+ else if (!lc_categories[cat[i]].prev && !(ast.locale.set & AST_LC_internal))
+ lc_categories[cat[i]].prev = p;
+ }
+ while (s[0] == '/' && s[1] && n < (AST_LC_COUNT - 1))
+ {
+ n++;
+ for (w = ++s; *s && *s != '/'; s++);
+ if (!*s)
+ p = lcmake(w);
+ else
+ {
+ if ((j = s - w - 1) >= sizeof(buf))
+ j = sizeof(buf) - 1;
+ memcpy(buf, w, j);
+ buf[j] = 0;
+ p = lcmake(buf);
+ }
+ if (!initialize)
+ {
+ if (!single(n, p, 0))
+ {
+ for (i = 1; i < n; i++)
+ single(i, NiL, 0);
+ return -1;
+ }
+ }
+ else if (!lc_categories[n].prev && !(ast.locale.set & AST_LC_internal))
+ lc_categories[n].prev = p;
+ }
+ return n;
+}
+
+/*
+ * setlocale() intercept
+ *
+ * locale:
+ * 0 query
+ * "" initialize from environment (if LC_ALL)
+ * "" AST_LC_setenv: value unset (defer to LANG)
+ * "*" AST_LC_setenv: value set (defer to LC_ALL)
+ * * set (override LC_ALL)
+ */
+
+char*
+_ast_setlocale(int category, const char* locale)
+{
+ register char* s;
+ register int i;
+ register int j;
+ int k;
+ int f;
+ Lc_t* p;
+ int cat[AST_LC_COUNT];
+
+ static Sfio_t* sp;
+ static int initialized;
+ static const char local[] = "local";
+
+ if ((category = lcindex(category, 0)) < 0)
+ return 0;
+ if (!locale)
+ {
+ /*
+ * return the current state
+ */
+
+ compose:
+ if (category != AST_LC_ALL && category != AST_LC_LANG)
+ return (char*)locales[category]->name;
+ if (!sp && !(sp = sfstropen()))
+ return 0;
+ for (i = 1; i < AST_LC_COUNT; i++)
+ cat[i] = -1;
+ for (i = 1, k = 0; i < AST_LC_COUNT; i++)
+ if (cat[i] < 0)
+ {
+ k++;
+ cat[i] = i;
+ for (j = i + 1; j < AST_LC_COUNT; j++)
+ if (locales[j] == locales[i])
+ cat[j] = i;
+ }
+ if (k == 1)
+ return (char*)locales[1]->name;
+ for (i = 1; i < AST_LC_COUNT; i++)
+ if (cat[i] >= 0 && !(locales[i]->flags & LC_default))
+ {
+ if (sfstrtell(sp))
+ sfprintf(sp, ";");
+ for (j = i, k = cat[i]; j < AST_LC_COUNT; j++)
+ if (cat[j] == k)
+ {
+ cat[j] = -1;
+ sfprintf(sp, "%s=", lc_categories[j].name);
+ }
+ sfprintf(sp, "%s", locales[i]->name);
+ }
+ if (!sfstrtell(sp))
+ return (char*)locales[0]->name;
+ return sfstruse(sp);
+ }
+ if (!ast.locale.serial++)
+ {
+ stropt(getenv("LC_OPTIONS"), options, sizeof(*options), setopt, NiL);
+ initialized = 0;
+ }
+ if ((ast.locale.set & (AST_LC_debug|AST_LC_setlocale)) && !(ast.locale.set & AST_LC_internal))
+ {
+ header();
+ sfprintf(sfstderr, "locale user %17s %16s %16s %16s%s%s\n", category == AST_LC_LANG ? "LANG" : lc_categories[category].name, locale && !*locale ? "''" : locale, "", "", initialized ? "" : " initial", (ast.locale.set & AST_LC_setenv) ? " setenv" : "");
+ }
+ if (ast.locale.set & AST_LC_setenv)
+ {
+ f = LC_setenv;
+ p = *locale ? lcmake(locale) : (Lc_t*)0;
+ }
+ else if (*locale)
+ {
+ f = LC_setlocale;
+ p = lcmake(locale);
+ }
+ else if (category == AST_LC_ALL)
+ {
+ if (!initialized)
+ {
+ char* u;
+ char tmp[256];
+
+ /*
+ * initialize from the environment
+ * precedence determined by X/Open
+ */
+
+ u = 0;
+ if ((s = getenv("LANG")) && *s)
+ {
+ if (streq(s, local) && (u || (u = native_locale(locale, tmp, sizeof(tmp)))))
+ s = u;
+ lang = lcmake(s);
+ }
+ else
+ lang = 0;
+ if ((s = getenv("LC_ALL")) && *s)
+ {
+ if (streq(s, local) && (u || (u = native_locale(locale, tmp, sizeof(tmp)))))
+ s = u;
+ lc_all = lcmake(s);
+ }
+ else
+ lc_all = 0;
+ for (i = 1; i < AST_LC_COUNT; i++)
+ if (lc_categories[i].flags & LC_setlocale)
+ /* explicitly set by setlocale() */;
+ else if ((s = getenv(lc_categories[i].name)) && *s)
+ {
+ if (streq(s, local) && (u || (u = native_locale(locale, tmp, sizeof(tmp)))))
+ s = u;
+ lc_categories[i].prev = lcmake(s);
+ }
+ else
+ lc_categories[i].prev = 0;
+ for (i = 1; i < AST_LC_COUNT; i++)
+ if (!single(i, lc_all && !(lc_categories[i].flags & LC_setlocale) ? lc_all : lc_categories[i].prev, 0))
+ {
+ while (i--)
+ single(i, NiL, 0);
+ return 0;
+ }
+ if (ast.locale.set & AST_LC_debug)
+ for (i = 1; i < AST_LC_COUNT; i++)
+ sfprintf(sfstderr, "locale env %17s %16s %16s %16s\n", lc_categories[i].name, locales[i]->name, "", lc_categories[i].prev ? lc_categories[i].prev->name : (char*)0);
+ initialized = 1;
+ }
+ goto compose;
+ }
+ else if (category == AST_LC_LANG || !(p = lc_categories[category].prev))
+ {
+ f = 0;
+ p = lcmake("C");
+ }
+ else
+ f = 0;
+ if (category == AST_LC_LANG)
+ {
+ if (lang != p)
+ {
+ lang = p;
+ if (!lc_all)
+ for (i = 1; i < AST_LC_COUNT; i++)
+ if (!single(i, lc_categories[i].prev, 0))
+ {
+ while (i--)
+ single(i, NiL, 0);
+ return 0;
+ }
+ }
+ }
+ else if (category != AST_LC_ALL)
+ {
+ if (f || !lc_all)
+ return single(category, p, f);
+ if (p && !(ast.locale.set & AST_LC_internal))
+ lc_categories[category].prev = p;
+ return (char*)locales[category]->name;
+ }
+ else if (composite(locale, 0) < 0)
+ return 0;
+ else if (lc_all != p)
+ {
+ lc_all = p;
+ for (i = 1; i < AST_LC_COUNT; i++)
+ if (!single(i, lc_all && !(lc_categories[i].flags & LC_setlocale) ? lc_all : lc_categories[i].prev, 0))
+ {
+ while (i--)
+ single(i, NiL, 0);
+ return 0;
+ }
+ }
+ goto compose;
+}
diff --git a/src/lib/libast/comp/setlogmask.c b/src/lib/libast/comp/setlogmask.c
new file mode 100644
index 0000000..f1851a7
--- /dev/null
+++ b/src/lib/libast/comp/setlogmask.c
@@ -0,0 +1,48 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * syslog implementation
+ */
+
+#include <ast.h>
+
+#if _lib_syslog
+
+NoN(setlogmask)
+
+#else
+
+#include "sysloglib.h"
+
+int
+setlogmask(int mask)
+{
+ int old_mask;
+
+ old_mask = log.mask;
+ if (mask)
+ log.mask = mask;
+ return old_mask;
+}
+
+#endif
diff --git a/src/lib/libast/comp/setpgid.c b/src/lib/libast/comp/setpgid.c
new file mode 100644
index 0000000..c966919
--- /dev/null
+++ b/src/lib/libast/comp/setpgid.c
@@ -0,0 +1,80 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_setpgid
+
+NoN(setpgid)
+
+#else
+
+#include <error.h>
+
+#ifndef ENOSYS
+#define ENOSYS EINVAL
+#endif
+
+#if _lib_setpgrp2
+#define setpgrp setpgrp2
+#else
+#if _lib_BSDsetpgrp
+#define _lib_setpgrp2 1
+#define setpgrp BSDsetpgrp
+#else
+#if _lib_wait3
+#define _lib_setpgrp2 1
+#endif
+#endif
+#endif
+
+#if _lib_setpgrp2
+extern int setpgrp(int, int);
+#else
+extern int setpgrp(void);
+#endif
+
+/*
+ * set process group id
+ */
+
+int
+setpgid(pid_t pid, pid_t pgid)
+{
+#if _lib_setpgrp2
+ return(setpgrp(pid, pgid));
+#else
+#if _lib_setpgrp
+ int caller = getpid();
+
+ if ((pid == 0 || pid == caller) && (pgid == 0 || pgid == caller))
+ return(setpgrp());
+ errno = EINVAL;
+#else
+ errno = ENOSYS;
+#endif
+ return(-1);
+#endif
+}
+
+#endif
diff --git a/src/lib/libast/comp/setsid.c b/src/lib/libast/comp/setsid.c
new file mode 100644
index 0000000..10544bb
--- /dev/null
+++ b/src/lib/libast/comp/setsid.c
@@ -0,0 +1,90 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_setsid
+
+NoN(setsid)
+
+#else
+
+#include <ast_tty.h>
+#include <error.h>
+
+/*
+ * become new process group leader and drop control tty
+ */
+
+pid_t
+setsid(void)
+{
+ int pg;
+#ifdef TIOCNOTTY
+ int fd;
+#endif
+
+ /*
+ * become a new process group leader
+ */
+
+ if ((pg = getpid()) == getpgrp())
+ {
+ errno = EPERM;
+ return(-1);
+ }
+ setpgid(pg, pg);
+#ifdef TIOCNOTTY
+
+ /*
+ * drop the control tty
+ */
+
+ if ((fd = open("/dev/tty", O_RDONLY)) >= 0)
+ {
+ ioctl(fd, TIOCNOTTY, 0);
+ close(fd);
+ }
+#else
+
+ /*
+ * second child in s5 to avoid reacquiring the control tty
+ */
+
+#if _lib_fork && HUH920711 /* some s5's botch this */
+ switch (fork())
+ {
+ case -1:
+ exit(1);
+ case 0:
+ break;
+ default:
+ exit(0);
+ }
+#endif
+
+#endif
+ return(pg);
+}
+
+#endif
diff --git a/src/lib/libast/comp/sigflag.c b/src/lib/libast/comp/sigflag.c
new file mode 100644
index 0000000..05ea22b
--- /dev/null
+++ b/src/lib/libast/comp/sigflag.c
@@ -0,0 +1,52 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_sigflag
+
+NoN(sigflag)
+
+#else
+
+#include <sig.h>
+
+int
+sigflag(int sig, int flags, int set)
+{
+#if _lib_sigaction
+ struct sigaction sa;
+
+ if (sigaction(sig, NiL, &sa))
+ return -1;
+ if (set)
+ sa.sa_flags |= flags;
+ else
+ sa.sa_flags &= ~flags;
+ return sigaction(sig, &sa, NiL);
+#else
+ return -1;
+#endif
+}
+
+#endif
diff --git a/src/lib/libast/comp/sigunblock.c b/src/lib/libast/comp/sigunblock.c
new file mode 100644
index 0000000..dfcb28b
--- /dev/null
+++ b/src/lib/libast/comp/sigunblock.c
@@ -0,0 +1,63 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_sigunblock
+
+NoN(sigunblock)
+
+#else
+
+#include <sig.h>
+
+#ifndef SIG_UNBLOCK
+#undef _lib_sigprocmask
+#endif
+
+int
+sigunblock(int s)
+{
+#if _lib_sigprocmask
+ int op;
+ sigset_t mask;
+
+ sigemptyset(&mask);
+ if (s)
+ {
+ sigaddset(&mask, s);
+ op = SIG_UNBLOCK;
+ }
+ else op = SIG_SETMASK;
+ return(sigprocmask(op, &mask, NiL));
+#else
+#if _lib_sigsetmask
+ return(sigsetmask(s ? (sigsetmask(0L) & ~sigmask(s)) : 0L));
+#else
+ NoP(s);
+ return(0);
+#endif
+#endif
+}
+
+#endif
diff --git a/src/lib/libast/comp/spawnveg.c b/src/lib/libast/comp/spawnveg.c
new file mode 100644
index 0000000..6117e3a
--- /dev/null
+++ b/src/lib/libast/comp/spawnveg.c
@@ -0,0 +1,296 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * spawnveg -- spawnve with process group or session control
+ *
+ * pgid <0 setsid() [session group leader]
+ * 0 nothing [retain session and process group]
+ * 1 setpgid(0,0) [process group leader]
+ * >1 setpgid(0,pgid) [join process group]
+ */
+
+#include <ast.h>
+
+#if _lib_spawnveg
+
+NoN(spawnveg)
+
+#else
+
+#if _lib_posix_spawn > 1 /* reports underlying exec() errors */
+
+#include <spawn.h>
+#include <error.h>
+#include <wait.h>
+
+pid_t
+spawnveg(const char* path, char* const argv[], char* const envv[], pid_t pgid)
+{
+ int err;
+ pid_t pid;
+ posix_spawnattr_t attr;
+
+ if (err = posix_spawnattr_init(&attr))
+ goto nope;
+ if (pgid)
+ {
+ if (pgid <= 1)
+ pgid = 0;
+ if (err = posix_spawnattr_setpgroup(&attr, pgid))
+ goto bad;
+ if (err = posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETPGROUP))
+ goto bad;
+ }
+ if (err = posix_spawn(&pid, path, NiL, &attr, argv, envv ? envv : environ))
+ goto bad;
+ posix_spawnattr_destroy(&attr);
+#if _lib_posix_spawn < 2
+ if (waitpid(pid, &err, WNOHANG|WNOWAIT) == pid && EXIT_STATUS(err) == 127)
+ {
+ while (waitpid(pid, NiL, 0) == -1 && errno == EINTR);
+ if (!access(path, X_OK))
+ errno = ENOEXEC;
+ pid = -1;
+ }
+#endif
+ return pid;
+ bad:
+ posix_spawnattr_destroy(&attr);
+ nope:
+ errno = err;
+ return -1;
+}
+
+#else
+
+#if _lib_spawn_mode
+
+#include <process.h>
+
+#ifndef P_NOWAIT
+#define P_NOWAIT _P_NOWAIT
+#endif
+#ifndef P_DETACH
+#define P_DETACH _P_DETACH
+#endif
+
+pid_t
+spawnveg(const char* path, char* const argv[], char* const envv[], pid_t pgid)
+{
+ return spawnve(pgid ? P_DETACH : P_NOWAIT, path, argv, envv ? envv : environ);
+}
+
+#else
+
+#if _lib_spawn && _hdr_spawn && _mem_pgroup_inheritance
+
+#include <spawn.h>
+
+/*
+ * open-edition/mvs/zos fork+exec+(setpgid)
+ */
+
+pid_t
+spawnveg(const char* path, char* const argv[], char* const envv[], pid_t pgid)
+{
+ struct inheritance inherit;
+
+ inherit.flags = 0;
+ if (pgid)
+ {
+ inherit.flags |= SPAWN_SETGROUP;
+ inherit.pgroup = (pgid > 1) ? pgid : SPAWN_NEWPGROUP;
+ }
+ return spawn(path, 0, (int*)0, &inherit, (const char**)argv, (const char**)envv);
+}
+
+#else
+
+#include <error.h>
+#include <wait.h>
+#include <sig.h>
+#include <ast_tty.h>
+#include <ast_vfork.h>
+
+#ifndef ENOSYS
+#define ENOSYS EINVAL
+#endif
+
+#if _lib_spawnve && _hdr_process
+#include <process.h>
+#if defined(P_NOWAIT) || defined(_P_NOWAIT)
+#undef _lib_spawnve
+#endif
+#endif
+
+#if !_lib_vfork
+#undef _real_vfork
+#endif
+
+/*
+ * fork+exec+(setsid|setpgid)
+ */
+
+pid_t
+spawnveg(const char* path, char* const argv[], char* const envv[], pid_t pgid)
+{
+#if _lib_fork || _lib_vfork
+ int n;
+ int m;
+ pid_t pid;
+ pid_t rid;
+#if _real_vfork
+ volatile int exec_errno;
+ volatile int* volatile exec_errno_ptr;
+#else
+ int err[2];
+#endif
+#endif
+
+#if 0
+ if (access(path, X_OK))
+ return -1;
+#endif
+ if (!envv)
+ envv = environ;
+#if _lib_spawnve
+#if _lib_fork || _lib_vfork
+ if (!pgid)
+#endif
+ return spawnve(path, argv, envv);
+#endif
+#if _lib_fork || _lib_vfork
+ n = errno;
+#if _real_vfork
+ exec_errno = 0;
+ exec_errno_ptr = &exec_errno;
+#else
+ if (pipe(err) < 0)
+ err[0] = -1;
+ else
+ {
+ fcntl(err[0], F_SETFD, FD_CLOEXEC);
+ fcntl(err[1], F_SETFD, FD_CLOEXEC);
+ }
+#endif
+ sigcritical(SIG_REG_EXEC|SIG_REG_PROC);
+#if _lib_vfork
+ pid = vfork();
+#else
+ pid = fork();
+#endif
+ if (pid == -1)
+ n = errno;
+ else if (!pid)
+ {
+ sigcritical(0);
+ if (pgid == -1)
+ setsid();
+ else if (pgid)
+ {
+ m = 0;
+ if (pgid == 1 || pgid == -2 && (m = 1))
+ pgid = getpid();
+ if (setpgid(0, pgid) < 0 && errno == EPERM)
+ setpgid(pgid, 0);
+#if _lib_tcgetpgrp
+ if (m)
+ tcsetpgrp(2, pgid);
+#else
+#ifdef TIOCSPGRP
+ if (m)
+ ioctl(2, TIOCSPGRP, &pgid);
+#endif
+#endif
+ }
+ execve(path, argv, envv);
+#if _real_vfork
+ *exec_errno_ptr = errno;
+#else
+ if (err[0] != -1)
+ {
+ m = errno;
+ write(err[1], &m, sizeof(m));
+ }
+#endif
+ _exit(errno == ENOENT ? EXIT_NOTFOUND : EXIT_NOEXEC);
+ }
+ rid = pid;
+#if _real_vfork
+ if (pid != -1 && (m = *exec_errno_ptr))
+ {
+ while (waitpid(pid, NiL, 0) == -1 && errno == EINTR);
+ rid = pid = -1;
+ n = m;
+ }
+#else
+ if (err[0] != -1)
+ {
+ close(err[1]);
+ if (pid != -1)
+ {
+ m = 0;
+ while (read(err[0], &m, sizeof(m)) == -1)
+ if (errno != EINTR)
+ {
+ m = errno;
+ break;
+ }
+ if (m)
+ {
+ while (waitpid(pid, &n, 0) && errno == EINTR);
+ rid = pid = -1;
+ n = m;
+ }
+ }
+ close(err[0]);
+ }
+#endif
+ sigcritical(0);
+ if (pid != -1 && pgid > 0)
+ {
+ /*
+ * parent and child are in a race here
+ */
+
+ if (pgid == 1)
+ pgid = pid;
+ if (setpgid(pid, pgid) < 0 && pid != pgid && errno == EPERM)
+ setpgid(pid, pid);
+ }
+ errno = n;
+ return rid;
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+#endif
+
+#endif
+
+#endif
+
+#endif
diff --git a/src/lib/libast/comp/statvfs.c b/src/lib/libast/comp/statvfs.c
new file mode 100644
index 0000000..b9bbf68
--- /dev/null
+++ b/src/lib/libast/comp/statvfs.c
@@ -0,0 +1,163 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+#include <ls.h>
+
+#if _lib_statvfs
+
+NoN(statvfs)
+
+#else
+
+#include <error.h>
+
+#define HUH (-1)
+
+#if _lib_statfs && _mem_f_files_statfs && ( _sys_statfs || _sys_vfs || _sys_mount )
+
+#if _sys_statfs
+#include <sys/statfs.h>
+#else
+#if _sys_vfs
+#include <sys/vfs.h>
+#else
+#if _sys_mount
+#if _lib_getmntinfo
+#include <sys/param.h> /* expect some macro redefinitions here */
+#endif
+#include <sys/mount.h>
+#endif
+#endif
+#endif
+
+#if _lib_statfs4
+#define FSTATFS(a,b) fstatfs(a,b,sizeof(struct statfs),0)
+#define STATFS(a,b) statfs(a,b,sizeof(struct statfs),0)
+#else
+#define FSTATFS(a,b) fstatfs(a,b)
+#define STATFS(a,b) statfs(a,b)
+#endif
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+static void
+us2v(register struct statfs* ufs, register struct stat* st, register struct statvfs* vfs)
+{
+ memset(vfs, 0, sizeof(*vfs));
+ vfs->f_bsize = vfs->f_frsize = ufs->f_bsize;
+ vfs->f_blocks = ufs->f_blocks;
+ vfs->f_bfree = ufs->f_bfree;
+ vfs->f_bavail =
+#if _mem_f_bavail_statfs
+ ufs->f_bavail;
+#else
+ ufs->f_bfree;
+#endif
+ vfs->f_files = ufs->f_files;
+ vfs->f_ffree = ufs->f_ffree;
+ vfs->f_favail = (ufs->f_ffree > 10) ? (ufs->f_ffree - 10) : 0;
+ vfs->f_fsid = st->st_dev;
+ strlcpy(vfs->f_basetype, FS_default, sizeof(vfs->f_basetype) - 1);
+ vfs->f_namemax = 14;
+ strlcpy(vfs->f_fstr, vfs->f_basetype, sizeof(vfs->f_fstr) - 1);
+}
+
+extern int
+fstatvfs(int fd, struct statvfs* vfs)
+{
+ struct statfs ufs;
+ struct stat st;
+
+ if (FSTATFS(fd, &ufs) || fstat(fd, &st))
+ return(-1);
+ us2v(&ufs, &st, vfs);
+ return(0);
+}
+
+extern int
+statvfs(const char* path, struct statvfs* vfs)
+{
+ struct statfs ufs;
+ struct stat st;
+
+ if (STATFS(path, &ufs) || stat(path, &st))
+ return(-1);
+ us2v(&ufs, &st, vfs);
+ return(0);
+}
+
+#else
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+static void
+s2v(register struct stat* st, register struct statvfs* vfs)
+{
+ memset(vfs, 0, sizeof(*vfs));
+ vfs->f_bsize = vfs->f_frsize =
+#if _mem_st_blksize_stat
+ st->st_blksize;
+#else
+ 512;
+#endif
+ vfs->f_blocks = HUH;
+ vfs->f_bfree = HUH;
+ vfs->f_files = HUH;
+ vfs->f_ffree = HUH;
+ vfs->f_favail = HUH;
+ vfs->f_fsid = st->st_dev;
+ strlcpy(vfs->f_basetype, FS_default, sizeof(vfs->f_basetype));
+ vfs->f_namemax = 14;
+ strlcpy(vfs->f_fstr, vfs->f_basetype, sizeof(vfs->f_fstr));
+}
+
+extern int
+fstatvfs(int fd, struct statvfs* vfs)
+{
+ struct stat st;
+
+ if (fstat(fd, &st))
+ return(-1);
+ s2v(&st, vfs);
+ return(0);
+}
+
+extern int
+statvfs(const char* path, struct statvfs* vfs)
+{
+ struct stat st;
+
+ if (stat(path, &st))
+ return(-1);
+ s2v(&st, vfs);
+ return(0);
+}
+
+#endif
+
+#endif
diff --git a/src/lib/libast/comp/strcasecmp.c b/src/lib/libast/comp/strcasecmp.c
new file mode 100644
index 0000000..0ea1869
--- /dev/null
+++ b/src/lib/libast/comp/strcasecmp.c
@@ -0,0 +1,58 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_strcasecmp
+
+NoN(strcasecmp)
+
+#else
+
+#include <ctype.h>
+
+#undef strcasecmp
+
+int
+strcasecmp(register const char* a, register const char* b)
+{
+ register int ac;
+ register int bc;
+ register int d;
+
+ for (;;)
+ {
+ ac = *a++;
+ if (isupper(ac))
+ ac = tolower(ac);
+ bc = *b++;
+ if (isupper(bc))
+ bc = tolower(bc);
+ if (d = ac - bc)
+ return d;
+ if (!ac)
+ return 0;
+ }
+}
+
+#endif
diff --git a/src/lib/libast/comp/strchr.c b/src/lib/libast/comp/strchr.c
new file mode 100644
index 0000000..7b556c5
--- /dev/null
+++ b/src/lib/libast/comp/strchr.c
@@ -0,0 +1,57 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_strchr
+
+NoN(strchr)
+
+#else
+
+#undef strchr
+
+#if _lib_index
+
+#undef index
+
+extern char* index(const char*, int);
+
+char*
+strchr(const char* s, int c)
+{
+ return(index(s, c));
+}
+
+#else
+
+char*
+strchr(register const char* s, register int c)
+{
+ do if (*s == c) return((char*)s); while(*s++);
+ return(0);
+}
+
+#endif
+
+#endif
diff --git a/src/lib/libast/comp/strftime.c b/src/lib/libast/comp/strftime.c
new file mode 100644
index 0000000..5c8d5bd
--- /dev/null
+++ b/src/lib/libast/comp/strftime.c
@@ -0,0 +1,104 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * strftime implementation
+ */
+
+#define strftime ______strftime
+
+#include <ast.h>
+#include <tm.h>
+
+#undef strftime
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+#undef _lib_strftime /* we can pass X/Open */
+
+#if _lib_strftime
+
+NoN(strftime)
+
+#else
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern size_t
+strftime(char* buf, size_t len, const char* format, const struct tm* tm)
+{
+ register char* s;
+ time_t t;
+ Tm_t tl;
+
+ memset(&tl, 0, sizeof(tl));
+
+ /*
+ * nl_langinfo() may call strftime() with bogus tm except for
+ * one value -- what a way to go
+ */
+
+ if (tm->tm_sec < 0 || tm->tm_sec > 60 ||
+ tm->tm_min < 0 || tm->tm_min > 59 ||
+ tm->tm_hour < 0 || tm->tm_hour > 23 ||
+ tm->tm_wday < 0 || tm->tm_wday > 6 ||
+ tm->tm_mday < 1 || tm->tm_mday > 31 ||
+ tm->tm_mon < 0 || tm->tm_mon > 11 ||
+ tm->tm_year < 0 || tm->tm_year > (2138 - 1900))
+ {
+ if (tm->tm_sec >= 0 && tm->tm_sec <= 60)
+ tl.tm_sec = tm->tm_sec;
+ if (tm->tm_min >= 0 && tm->tm_min <= 59)
+ tl.tm_min = tm->tm_min;
+ if (tm->tm_hour >= 0 && tm->tm_hour <= 23)
+ tl.tm_hour = tm->tm_hour;
+ if (tm->tm_wday >= 0 && tm->tm_wday <= 6)
+ tl.tm_wday = tm->tm_wday;
+ if (tm->tm_mday >= 0 && tm->tm_mday <= 31)
+ tl.tm_mday = tm->tm_mday;
+ if (tm->tm_mon >= 0 && tm->tm_mon <= 11)
+ tl.tm_mon = tm->tm_mon;
+ if (tm->tm_year >= 0 && tm->tm_year <= (2138 - 1900))
+ tl.tm_year = tm->tm_year;
+ }
+ else
+ {
+ tl.tm_sec = tm->tm_sec;
+ tl.tm_min = tm->tm_min;
+ tl.tm_hour = tm->tm_hour;
+ tl.tm_mday = tm->tm_mday;
+ tl.tm_mon = tm->tm_mon;
+ tl.tm_year = tm->tm_year;
+ tl.tm_wday = tm->tm_wday;
+ tl.tm_yday = tm->tm_yday;
+ tl.tm_isdst = tm->tm_isdst;
+ }
+ t = tmtime(&tl, TM_LOCALZONE);
+ if (!(s = tmfmt(buf, len, format, &t)))
+ return 0;
+ return s - buf;
+}
+
+#endif
diff --git a/src/lib/libast/comp/strncasecmp.c b/src/lib/libast/comp/strncasecmp.c
new file mode 100644
index 0000000..c312526
--- /dev/null
+++ b/src/lib/libast/comp/strncasecmp.c
@@ -0,0 +1,62 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_strncasecmp
+
+NoN(strncasecmp)
+
+#else
+
+#include <ctype.h>
+
+#undef strncasecmp
+
+int
+strncasecmp(register const char* a, register const char* b, size_t n)
+{
+ register const char* e;
+ register int ac;
+ register int bc;
+ register int d;
+
+ e = a + n;
+ for (;;)
+ {
+ if (a >= e)
+ return 0;
+ ac = *a++;
+ if (isupper(ac))
+ ac = tolower(ac);
+ bc = *b++;
+ if (isupper(bc))
+ bc = tolower(bc);
+ if (d = ac - bc)
+ return d;
+ if (!ac)
+ return 0;
+ }
+}
+
+#endif
diff --git a/src/lib/libast/comp/strptime.c b/src/lib/libast/comp/strptime.c
new file mode 100644
index 0000000..981c98b
--- /dev/null
+++ b/src/lib/libast/comp/strptime.c
@@ -0,0 +1,82 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * strptime implementation
+ */
+
+#define strptime ______strptime
+
+#include <ast.h>
+#include <tmx.h>
+
+#undef strptime
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+#if _lib_strptime
+
+NoN(strptime)
+
+#else
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char*
+strptime(const char* s, const char* format, struct tm* ts)
+{
+ char* e;
+ char* f;
+ time_t t;
+ Tm_t tm;
+
+ memset(&tm, 0, sizeof(tm));
+ tm.tm_sec = ts->tm_sec;
+ tm.tm_min = ts->tm_min;
+ tm.tm_hour = ts->tm_hour;
+ tm.tm_mday = ts->tm_mday;
+ tm.tm_mon = ts->tm_mon;
+ tm.tm_year = ts->tm_year;
+ tm.tm_wday = ts->tm_wday;
+ tm.tm_yday = ts->tm_yday;
+ tm.tm_isdst = ts->tm_isdst;
+ t = tmtime(&tm, TM_LOCALZONE);
+ t = tmscan(s, &e, format, &f, &t, 0);
+ if (e == (char*)s || *f)
+ return 0;
+ tmxtm(&tm, tmxclock(&t), NiL);
+ ts->tm_sec = tm.tm_sec;
+ ts->tm_min = tm.tm_min;
+ ts->tm_hour = tm.tm_hour;
+ ts->tm_mday = tm.tm_mday;
+ ts->tm_mon = tm.tm_mon;
+ ts->tm_year = tm.tm_year;
+ ts->tm_wday = tm.tm_wday;
+ ts->tm_yday = tm.tm_yday;
+ ts->tm_isdst = tm.tm_isdst;
+ return e;
+}
+
+#endif
diff --git a/src/lib/libast/comp/strrchr.c b/src/lib/libast/comp/strrchr.c
new file mode 100644
index 0000000..4e192ce
--- /dev/null
+++ b/src/lib/libast/comp/strrchr.c
@@ -0,0 +1,60 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_strrchr
+
+NoN(strrchr)
+
+#else
+
+#undef strrchr
+
+#if _lib_rindex
+
+#undef rindex
+
+extern char* rindex(const char*, int);
+
+char*
+strrchr(const char* s, int c)
+{
+ return(rindex(s, c));
+}
+
+#else
+
+char*
+strrchr(register const char* s, register int c)
+{
+ register const char* r;
+
+ r = 0;
+ do if (*s == c) r = s; while(*s++);
+ return((char*)r);
+}
+
+#endif
+
+#endif
diff --git a/src/lib/libast/comp/strstr.c b/src/lib/libast/comp/strstr.c
new file mode 100644
index 0000000..aa50058
--- /dev/null
+++ b/src/lib/libast/comp/strstr.c
@@ -0,0 +1,76 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide strstr
+#else
+#define strstr ______strstr
+#endif
+
+#include <ast.h>
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide strstr
+#else
+#undef strstr
+#endif
+
+#if _lib_strstr
+
+NoN(strstr)
+
+#else
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char*
+strstr(register const char* s1, register const char* s2)
+{
+ register int c1;
+ register int c2;
+ register const char* t1;
+ register const char* t2;
+
+ if (s2)
+ {
+ if (!*s2)
+ return (char*)s1;
+ c2 = *s2++;
+ while (c1 = *s1++)
+ if (c1 == c2)
+ {
+ t1 = s1;
+ t2 = s2;
+ do
+ {
+ if (!*t2)
+ return (char*)s1 - 1;
+ } while (*t1++ == *t2++);
+ }
+ }
+ return 0;
+}
+
+#endif
diff --git a/src/lib/libast/comp/strtod.c b/src/lib/libast/comp/strtod.c
new file mode 100644
index 0000000..f0fb9af
--- /dev/null
+++ b/src/lib/libast/comp/strtod.c
@@ -0,0 +1,31 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strtod() implementation
+ */
+
+#include <ast.h>
+
+#define S2F_function strtod
+#define S2F_type 1
+
+#include "sfstrtof.h"
diff --git a/src/lib/libast/comp/strtol.c b/src/lib/libast/comp/strtol.c
new file mode 100644
index 0000000..de0367f
--- /dev/null
+++ b/src/lib/libast/comp/strtol.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strtol() implementation
+ */
+
+#if ! __CYGWIN__ /* 1.3.* static link conflict -- no iffe for this yet */
+
+#define S2I_function strtol
+#define S2I_number long
+#define S2I_unumber unsigned long
+
+#include "strtoi.h"
+
+#endif
diff --git a/src/lib/libast/comp/strtold.c b/src/lib/libast/comp/strtold.c
new file mode 100644
index 0000000..8f8c5b5
--- /dev/null
+++ b/src/lib/libast/comp/strtold.c
@@ -0,0 +1,50 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strtold() implementation
+ */
+
+#define S2F_function strtold
+#define S2F_type 2
+
+/*
+ * ast strtold() => strtod() when double == long double
+ */
+
+#define _AST_STD_H 1
+
+#include <ast_common.h>
+
+#if _ast_fltmax_double
+#define strtold ______strtold
+#endif
+
+#include <ast_lib.h>
+#include <ast_sys.h>
+
+#if _ast_fltmax_double
+#undef strtold
+#endif
+
+#undef _AST_STD_H
+
+#include "sfstrtof.h"
diff --git a/src/lib/libast/comp/strtoll.c b/src/lib/libast/comp/strtoll.c
new file mode 100644
index 0000000..b5cf852
--- /dev/null
+++ b/src/lib/libast/comp/strtoll.c
@@ -0,0 +1,44 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strtoll() implementation
+ */
+
+#define strtoll ______strtoll
+
+#include <ast.h>
+
+#undef strtoll
+
+#if !_UWIN
+
+#undef _def_map_ast
+
+#include <ast_map.h>
+
+#endif
+
+#define S2I_function strtoll
+#define S2I_number intmax_t
+#define S2I_unumber uintmax_t
+
+#include "strtoi.h"
diff --git a/src/lib/libast/comp/strtoul.c b/src/lib/libast/comp/strtoul.c
new file mode 100644
index 0000000..82d964a
--- /dev/null
+++ b/src/lib/libast/comp/strtoul.c
@@ -0,0 +1,35 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strtoul() implementation
+ */
+
+#if ! __CYGWIN__ /* 1.3.* static link conflict -- no iffe for this yet */
+
+#define S2I_function strtoul
+#define S2I_number long
+#define S2I_unumber unsigned long
+#define S2I_unsigned 1
+
+#include "strtoi.h"
+
+#endif
diff --git a/src/lib/libast/comp/strtoull.c b/src/lib/libast/comp/strtoull.c
new file mode 100644
index 0000000..bc197f6
--- /dev/null
+++ b/src/lib/libast/comp/strtoull.c
@@ -0,0 +1,45 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strtoull() implementation
+ */
+
+#define strtoull ______strtoull
+
+#include <ast.h>
+
+#undef strtoull
+
+#if !_UWIN
+
+#undef _def_map_ast
+
+#include <ast_map.h>
+
+#endif
+
+#define S2I_function strtoull
+#define S2I_number intmax_t
+#define S2I_unumber uintmax_t
+#define S2I_unsigned 1
+
+#include "strtoi.h"
diff --git a/src/lib/libast/comp/swab.c b/src/lib/libast/comp/swab.c
new file mode 100644
index 0000000..4bc905d
--- /dev/null
+++ b/src/lib/libast/comp/swab.c
@@ -0,0 +1,60 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * swab implementation
+ */
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide swab
+#else
+#define swab ______swab
+#endif
+
+#include <ast.h>
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide swab
+#else
+#undef swab
+#endif
+
+#if _lib_swab
+
+NoN(swab)
+
+#else
+
+#include <swap.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern void
+swab(const void* src, void* dst, ssize_t n)
+{
+ if (n > 1)
+ swapmem(1, src, dst, n & ~1);
+}
+
+#endif
diff --git a/src/lib/libast/comp/symlink.c b/src/lib/libast/comp/symlink.c
new file mode 100644
index 0000000..b0a5787
--- /dev/null
+++ b/src/lib/libast/comp/symlink.c
@@ -0,0 +1,59 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_symlink
+
+NoN(symlink)
+
+#else
+
+#include "fakelink.h"
+
+#include <error.h>
+
+#ifndef ENOSYS
+#define ENOSYS EINVAL
+#endif
+
+int
+symlink(const char* a, char* b)
+{
+ if (*a == '/' && (*(a + 1) == 'd' || *(a + 1) == 'p' || *(a + 1) == 'n') && (!strncmp(a, "/dev/tcp/", 9) || !strncmp(a, "/dev/udp/", 9) || !strncmp(a, "/proc/", 6) || !strncmp(a, "/n/", 3)))
+ {
+ int n;
+ int fd;
+
+ if ((fd = open(b, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0)
+ return -1;
+ n = strlen(a) + 1;
+ n = (write(fd, FAKELINK_MAGIC, sizeof(FAKELINK_MAGIC)) != sizeof(FAKELINK_MAGIC) || write(fd, a, n) != n) ? -1 : 0;
+ close(fd);
+ return n;
+ }
+ errno = ENOSYS;
+ return -1;
+}
+
+#endif
diff --git a/src/lib/libast/comp/syslog.c b/src/lib/libast/comp/syslog.c
new file mode 100644
index 0000000..08554e1
--- /dev/null
+++ b/src/lib/libast/comp/syslog.c
@@ -0,0 +1,367 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * syslog implementation
+ */
+
+#include <ast.h>
+
+#if _lib_syslog
+
+NoN(syslog)
+
+#else
+
+#define LOG_TABLES
+
+#include "sysloglib.h"
+
+#include <error.h>
+#include <tm.h>
+
+Syslog_state_t log = { LOG_USER, -1, 0, ~0 };
+
+static const Namval_t attempt[] =
+{
+#if _UWIN
+ "/var/log/syslog", 0,
+#endif
+ "/dev/log", 0,
+ "var/log/syslog", 0,
+ "lib/syslog/log", 0,
+ "/dev/console", LOG_CONS,
+};
+
+const Namval_t log_facility[] =
+{
+ "default", 0,
+ "user", LOG_USER,
+ "kernel", LOG_KERN,
+ "mail", LOG_MAIL,
+ "daemon", LOG_DAEMON,
+ "security", LOG_AUTH,
+ "syslog", LOG_SYSLOG,
+ "lpr", LOG_LPR,
+ "news", LOG_NEWS,
+ "uucp", LOG_UUCP,
+ "cron", LOG_CRON,
+ "audit", LOG_AUDIT,
+ "logalert", LOG_LFMT,
+#ifdef LOG_SYSTEM2
+ "system2", LOG_SYSTEM2,
+#endif
+#ifdef LOG_SYSTEM1
+ "system1", LOG_SYSTEM1,
+#endif
+#ifdef LOG_SYSTEM0
+ "system0", LOG_SYSTEM0,
+#endif
+ 0, 0
+};
+
+const Namval_t log_severity[] =
+{
+ "panic", LOG_EMERG,
+ "alert", LOG_ALERT,
+ "critical", LOG_CRIT,
+ "error", LOG_ERR,
+ "warning", LOG_WARNING,
+ "notice", LOG_NOTICE,
+ "info", LOG_INFO,
+ "debug", LOG_DEBUG,
+ 0, 0
+};
+
+#if _UWIN
+
+/*
+ * open /dev/(fdp|tcp|udp)/HOST/SERVICE for read
+ */
+
+#include <ctype.h>
+#include <ls.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netdb.h>
+#include <netinet/in.h>
+
+#if !defined(htons) && !_lib_htons
+# define htons(x) (x)
+#endif
+#if !defined(htonl) && !_lib_htonl
+# define htonl(x) (x)
+#endif
+
+#ifndef INADDR_LOOPBACK
+#define INADDR_LOOPBACK 0x7f000001L
+#endif
+
+/*
+ * convert s to sockaddr_in
+ * -1 returned on error
+ */
+
+static int
+str2inet(register char* s, char* prot, struct sockaddr_in* addr)
+{
+ register int c;
+ register int v;
+ register int n = 0;
+ unsigned long a = 0;
+ unsigned short p = 0;
+
+ if (!memcmp(s, "local/", 6))
+ {
+ a = INADDR_LOOPBACK;
+ n = 4;
+ s += 6;
+ }
+ else if (!isdigit(*s))
+ {
+ struct hostent* hp;
+ char* e = strchr(s, '/');
+
+ if (!(e = strchr(s, '/')))
+ return -1;
+ *e = 0;
+ hp = gethostbyname(s);
+ *e = '/';
+ if (!hp || hp->h_addrtype != AF_INET || hp->h_length > sizeof(struct in_addr))
+ return -1;
+ a = (unsigned long)((struct in_addr*)hp->h_addr)->s_addr;
+ n = 6;
+ s = e + 1;
+ }
+ for (;;)
+ {
+ v = 0;
+ while ((c = *s++) >= '0' && c <= '9')
+ v = v * 10 + c - '0';
+ if (++n <= 4)
+ a = (a << 8) | (v & 0xff);
+ else
+ {
+ if (n <= 5)
+ a = htonl(a);
+ if (c)
+ {
+ struct servent* sp;
+
+ if (!(sp = getservbyname(s - 1, prot)))
+ return -1;
+ p = sp->s_port;
+ }
+ else
+ p = htons(v);
+ break;
+ }
+ if (c != '.' && c != '/')
+ return -1;
+ }
+ memset((char*)addr, 0, sizeof(*addr));
+ addr->sin_family = AF_INET;
+ addr->sin_addr.s_addr = a;
+ addr->sin_port = p;
+ return 0;
+}
+
+/*
+ * call this after open fails to see if path is a socket
+ */
+
+int
+sockopen(const char* path)
+{
+ int fd;
+ struct sockaddr_in addr;
+ char buf[PATH_MAX];
+
+ if (pathgetlink(path, buf, sizeof(buf)) <= 0)
+ {
+ if (strlen(path) >= sizeof(buf))
+ return -1;
+ strcpy(buf, path);
+ }
+#if LOCAL
+ {
+ int ul;
+ struct sockaddr_un ua;
+ struct stat st;
+
+ if ((ul = strlen(buf)) < sizeof(ua.sun_path) && !stat(buf, &st) && S_ISSOCK(st.st_mode))
+ {
+ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ return -1;
+ ua.sun_family = AF_UNIX;
+ strcpy(ua.sun_path, buf);
+ ul += sizeof(ua.sun_family) + 1;
+ if (!connect(fd, (struct sockaddr*)&ua, ul))
+ return fd;
+ close(fd);
+ return -1;
+ }
+ }
+#endif
+ if (!strmatch(buf, "/dev/(tcp|udp)/*/*"))
+ return -1;
+ buf[8] = 0;
+ if (str2inet(buf + 9, buf + 5, &addr))
+ return -1;
+ if ((fd = socket(AF_INET, buf[5] == 't' ? SOCK_STREAM : SOCK_DGRAM, 0)) < 0)
+ return -1;
+ if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)))
+ {
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+#else
+
+int
+sockopen(const char* path)
+{
+ return -1;
+}
+
+#endif
+
+void
+sendlog(const char* msg)
+{
+ register char* s;
+ register Namval_t* p;
+ register int n;
+
+ n = msg ? strlen(msg) : 0;
+ for (;;)
+ {
+ if (log.fd < 0)
+ {
+ char buf[PATH_MAX];
+
+ if (log.attempt >= elementsof(attempt))
+ break;
+ p = (Namval_t*)&attempt[log.attempt++];
+ if (p->value && !(p->value & log.flags))
+ continue;
+ if (*(s = p->name) != '/' && !(s = pathpath(buf, s, "", PATH_REGULAR|PATH_READ, sizeof(buf))))
+ continue;
+ if ((log.fd = open(s, O_WRONLY|O_APPEND|O_NOCTTY)) < 0 && (log.fd = sockopen(s)) < 0)
+ continue;
+ fcntl(log.fd, F_SETFD, FD_CLOEXEC);
+ }
+ if (!n || write(log.fd, msg, n) > 0)
+ break;
+ close(log.fd);
+ log.fd = -1;
+ }
+ if (n && (log.flags & LOG_PERROR))
+ write(2, msg, n);
+}
+
+static int
+extend(Sfio_t* sp, void* vp, Sffmt_t* dp)
+{
+ if (dp->fmt == 'm')
+ {
+ dp->flags |= SFFMT_VALUE;
+ dp->fmt = 's';
+ dp->size = -1;
+ *((char**)vp) = fmterror(errno);
+ }
+ return 0;
+}
+
+void
+vsyslog(int priority, const char* format, va_list ap)
+{
+ register int c;
+ register char* s;
+ Sfio_t* sp;
+ Sffmt_t fmt;
+ char buf[16];
+
+ if (!LOG_FACILITY(priority))
+ priority |= log.facility;
+ if (!(priority & log.mask))
+ return;
+ if (sp = sfstropen())
+ {
+ sfputr(sp, fmttime("%b %d %H:%M:%S", time(NiL)), -1);
+ if (log.flags & LOG_LEVEL)
+ {
+ if ((c = LOG_SEVERITY(priority)) < elementsof(log_severity))
+ s = (char*)log_severity[c].name;
+ else
+ sfsprintf(s = buf, sizeof(buf), "debug%d", c);
+ sfprintf(sp, " %-8s ", s);
+ if ((c = LOG_FACILITY(priority)) < elementsof(log_facility))
+ s = (char*)log_facility[c].name;
+ else
+ sfsprintf(s = buf, sizeof(buf), "local%d", c);
+ sfprintf(sp, " %-8s ", s);
+ }
+#if _lib_gethostname
+ if (!*log.host && gethostname(log.host, sizeof(log.host)-1))
+ strcpy(log.host, "localhost");
+ sfprintf(sp, " %s", log.host);
+#endif
+ if (*log.ident)
+ sfprintf(sp, " %s", log.ident);
+ if (log.flags & LOG_PID)
+ {
+ if (!*log.ident)
+ sfprintf(sp, " ");
+ sfprintf(sp, "[%d]", getpid());
+ }
+ if (format)
+ {
+ sfprintf(sp, ": ");
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.version = SFIO_VERSION;
+ fmt.form = (char*)format;
+ fmt.extf = extend;
+ va_copy(fmt.args, ap);
+ sfprintf(sp, "%!", &fmt);
+ }
+ if ((s = sfstrseek(sp, 0, SEEK_CUR)) && *(s - 1) != '\n')
+ sfputc(sp, '\n');
+ if (s = sfstruse(sp))
+ sendlog(s);
+ sfstrclose(sp);
+ }
+}
+
+void
+syslog(int priority, const char* format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vsyslog(priority, format, ap);
+ va_end(ap);
+}
+
+#endif
diff --git a/src/lib/libast/comp/syslog.h b/src/lib/libast/comp/syslog.h
new file mode 100644
index 0000000..4856034
--- /dev/null
+++ b/src/lib/libast/comp/syslog.h
@@ -0,0 +1,132 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * posix syslog interface definitions
+ */
+
+#ifndef _SYSLOG_H
+#define _SYSLOG_H
+
+#include <stdarg.h>
+
+#define LOG_PRIBITS 3 /* priority bits */
+#define LOG_FACBITS 7 /* facility bits */
+
+#define LOG_PRIMASK ((1<<LOG_PRIBITS)-1)
+#define LOG_FACMASK (((1<<LOG_FACBITS)-1)<<LOG_PRIBITS)
+
+#define LOG_PRI(p) ((p)&((1<<LOG_PRIBITS)-1))
+#define LOG_FAC(p) (((p)>>LOG_PRIBITS)&((1<<LOG_FACBITS)-1))
+
+#define LOG_MAKEPRI(f,p) (((f)<<LOG_PRIBITS)|(p))
+
+/* syslog priority severity levels */
+
+#define LOG_EMERG 0 /* panic condition */
+#define LOG_ALERT 1 /* should be corrected immediately */
+#define LOG_CRIT 2 /* critical condition */
+#define LOG_ERR 3 /* error condition */
+#define LOG_WARNING 4 /* warning condition */
+#define LOG_NOTICE 5 /* no error but may need intervention */
+#define LOG_INFO 6 /* informational message */
+#define LOG_DEBUG 7 /* debug message */
+
+/* setlogmask masks */
+
+#define LOG_MASK(s) (1<<(s)) /* individual severity s */
+#define LOG_UPTO(s) ((1<<((s)+1))-1)/* up to and including s */
+
+/* syslog facilities */
+
+#define LOG_KERN (0<<LOG_PRIBITS) /* kernel */
+#define LOG_USER (1<<LOG_PRIBITS) /* user process -- default */
+#define LOG_MAIL (2<<LOG_PRIBITS) /* mail */
+#define LOG_DAEMON (3<<LOG_PRIBITS) /* daemon */
+#define LOG_AUTH (4<<LOG_PRIBITS) /* security/authorization */
+#define LOG_SYSLOG (5<<LOG_PRIBITS) /* syslog internal */
+#define LOG_LPR (6<<LOG_PRIBITS) /* line printer */
+#define LOG_NEWS (7<<LOG_PRIBITS) /* network news */
+#define LOG_UUCP (8<<LOG_PRIBITS) /* uucp */
+#define LOG_CRON (9<<LOG_PRIBITS) /* cron */
+#define LOG_AUDIT (13<<LOG_PRIBITS) /* audit daemon */
+#define LOG_LFMT (14<<LOG_PRIBITS) /* logalert */
+#define LOG_LOCAL0 (16<<LOG_PRIBITS) /* reserved for local use */
+#define LOG_LOCAL1 (17<<LOG_PRIBITS) /* reserved for local use */
+#define LOG_LOCAL2 (18<<LOG_PRIBITS) /* reserved for local use */
+#define LOG_LOCAL3 (19<<LOG_PRIBITS) /* reserved for local use */
+#define LOG_LOCAL4 (20<<LOG_PRIBITS) /* reserved for local use */
+#define LOG_LOCAL5 (21<<LOG_PRIBITS) /* reserved for local use */
+#define LOG_LOCAL6 (22<<LOG_PRIBITS) /* reserved for local use */
+#define LOG_LOCAL7 (23<<LOG_PRIBITS) /* reserved for local use */
+
+#define LOG_NFACILITIES 24
+
+/* openlog flags */
+
+#define LOG_PID 0x01 /* log the pid with each message */
+#define LOG_CONS 0x02 /* log to console if errors in sending */
+#define LOG_NDELAY 0x08 /* open right now */
+#define LOG_ODELAY 0x04 /* delay open until syslog() is called */
+#define LOG_NOWAIT 0x10 /* don't wait() for any child processes */
+#define LOG_PERROR 0x20 /* log to stderr too */
+#define LOG_LEVEL 0x40 /* tag messages with facility/level */
+
+#ifdef LOG_TABLES
+
+/* encoding support */
+
+#include <ast_namval.h>
+
+#define log_facility _log_facility
+#define log_severity _log_severity
+
+#define LOG_FACILITY(p) LOG_FAC(p) /* get facility index from pri */
+#define LOG_SEVERITY(p) LOG_PRI(p) /* get severity from pri */
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+#if !_BLD_ast && defined(__IMPORT__)
+#define extern extern __IMPORT__
+#endif
+
+extern const Namval_t log_facility[];
+extern const Namval_t log_severity[];
+
+#undef extern
+
+#endif
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern void closelog(void);
+extern void openlog(const char*, int, int);
+extern int setlogmask(int);
+extern void syslog(int, const char*, ...);
+extern void vsyslog(int, const char*, va_list);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/comp/sysloglib.h b/src/lib/libast/comp/sysloglib.h
new file mode 100644
index 0000000..5a894c4
--- /dev/null
+++ b/src/lib/libast/comp/sysloglib.h
@@ -0,0 +1,54 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * posix syslog implementation definitions
+ */
+
+#ifndef _SYSLOGLIB_H
+#define _SYSLOGLIB_H
+
+#include <syslog.h>
+
+#define log _log_info_
+#define sendlog _log_send_
+
+/*
+ * NOTE: syslog() has a static initializer for Syslog_state_t log
+ */
+
+typedef struct
+{
+ int facility; /* openlog facility */
+ int fd; /* log to this fd */
+ int flags; /* openlog flags */
+ unsigned int mask; /* setlogmask mask */
+ int attempt; /* logfile attempt state */
+ char ident[64]; /* openlog ident */
+ char host[64]; /* openlog host name */
+} Syslog_state_t;
+
+extern Syslog_state_t log;
+
+extern void sendlog(const char*);
+
+#endif
diff --git a/src/lib/libast/comp/system.c b/src/lib/libast/comp/system.c
new file mode 100644
index 0000000..c0a3aa3
--- /dev/null
+++ b/src/lib/libast/comp/system.c
@@ -0,0 +1,55 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * ast library system(3)
+ */
+
+#define system ______system
+
+#define _STDLIB_H_ 1 /* uwin workaround */
+
+#include <ast.h>
+#include <proc.h>
+
+#undef system
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+system(const char* cmd)
+{
+ char* sh[4];
+
+ if (!cmd)
+ return !eaccess(pathshell(), X_OK);
+ sh[0] = "sh";
+ sh[1] = "-c";
+ sh[2] = (char*)cmd;
+ sh[3] = 0;
+ return procrun(NiL, sh, 0);
+}
diff --git a/src/lib/libast/comp/tempnam.c b/src/lib/libast/comp/tempnam.c
new file mode 100644
index 0000000..3cf375c
--- /dev/null
+++ b/src/lib/libast/comp/tempnam.c
@@ -0,0 +1,58 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * tempnam implementation
+ */
+
+#include <ast_std.h>
+
+#ifdef tempnam
+#define _def_tempnam 1
+#else
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide tempnam
+#else
+#define tempnam ______tempnam
+#endif
+#endif
+
+#include <ast.h>
+#include <stdio.h>
+
+#if !_def_tempnam
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide tempnam
+#else
+#undef tempnam
+#endif
+#endif
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char*
+tempnam(const char* dir, const char* pfx)
+{
+ return pathtmp(NiL, dir, pfx, NiL);
+}
diff --git a/src/lib/libast/comp/tmpnam.c b/src/lib/libast/comp/tmpnam.c
new file mode 100644
index 0000000..543ccdb
--- /dev/null
+++ b/src/lib/libast/comp/tmpnam.c
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * tmpnam implementation
+ */
+
+#define tmpnam ______tmpnam
+
+#include <ast.h>
+#include <stdio.h>
+
+#undef tmpnam
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#ifndef L_tmpnam
+#define L_tmpnam 25
+#endif
+
+extern char*
+tmpnam(char* s)
+{
+ static char buf[L_tmpnam];
+
+ return pathtemp(s ? s : buf, L_tmpnam, NiL, "tn", NiL);
+}
diff --git a/src/lib/libast/comp/transition.c b/src/lib/libast/comp/transition.c
new file mode 100644
index 0000000..ba65370
--- /dev/null
+++ b/src/lib/libast/comp/transition.c
@@ -0,0 +1,86 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * transient code to aid transition between releases
+ */
+
+#include <ast.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#define STUB 1
+
+/*
+ * 2006-09-28
+ *
+ * on some systems the _std_strtol iffe changed (due to a faulty
+ * test prototype) and the cause programs dynamically linked to
+ * an updated -last to fail at runtime with missing _ast_strtol etc.
+ */
+
+#if !_std_strtol
+
+#ifndef strtol
+#undef STUB
+extern long
+_ast_strtol(const char* a, char** b, int c)
+{
+ return strtol(a, b, c);
+}
+#endif
+
+#ifndef strtoul
+#undef STUB
+extern unsigned long
+_ast_strtoul(const char* a, char** b, int c)
+{
+ return strtoul(a, b, c);
+}
+#endif
+
+#ifndef strtoll
+#undef STUB
+extern intmax_t
+_ast_strtoll(const char* a, char** b, int c)
+{
+ return strtoll(a, b, c);
+}
+#endif
+
+#ifndef strtoull
+#undef STUB
+extern uintmax_t
+_ast_strtoull(const char* a, char** b, int c)
+{
+ return strtoull(a, b, c);
+}
+#endif
+
+#endif
+
+#if STUB
+NoN(transition)
+#endif
diff --git a/src/lib/libast/comp/tsearch.c b/src/lib/libast/comp/tsearch.c
new file mode 100644
index 0000000..486f082
--- /dev/null
+++ b/src/lib/libast/comp/tsearch.c
@@ -0,0 +1,240 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * tsearch() for systems that have <search.h> but no tsearch()
+ * why would such a system provide the interface but not the
+ * implementation? that's what happens when one slimes their
+ * way through standards compliance
+ *
+ * NOTE: please excuse the crude feature test
+ */
+
+#if !_UWIN
+
+void _STUB_tsearch(){}
+
+#else
+
+#if _PACKAGE_ast
+#include <ast.h>
+#endif
+
+#define tdelete ______tdelete
+#define tfind ______tfind
+#define tsearch ______tsearch
+#define twalk ______twalk
+
+#include <search.h>
+
+#undef tdelete
+#undef tfind
+#undef tsearch
+#undef twalk
+
+#include "dthdr.h"
+
+extern Void_t* dtfinger(Dt_t*);
+
+/* POSIX tsearch library based on libcdt
+** Written by Kiem-Phong Vo (AT&T Research, 07/19/95)
+*/
+
+typedef struct _tree_s
+{ Dtlink_t link;
+ Void_t* key;
+} Tree_t;
+
+typedef struct _treedisc_s
+{ Dtdisc_t disc;
+ int(* comparf)_ARG_((const Void_t*, const Void_t*));
+} Treedisc_t;
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+/* compare function */
+#if __STD_C
+static int treecompare(Dt_t* dt, char* one, char* two, Dtdisc_t* disc)
+#else
+static int treecompare(dt, one, two, disc)
+Dt_t* dt;
+char* one;
+char* two;
+Dtdisc_t* disc;
+#endif
+{
+ return (*((Treedisc_t*)disc)->comparf)((Void_t*)one,(Void_t*)two);
+}
+
+static Treedisc_t Treedisc =
+{ { sizeof(Dtlink_t), -1, /* object is key */
+ 0,
+ NIL(Dtmake_f), NIL(Dtfree_f),
+ treecompare,
+ NIL(Dthash_f),
+ NIL(Dtmemory_f),
+ NIL(Dtevent_f)
+ },
+ 0
+};
+
+extern
+#if __STD_C
+Void_t* tsearch(const Void_t* key, Void_t** rootp,
+ int(*comparf)(const Void_t*,const Void_t*) )
+#else
+Void_t* tsearch(key, rootp, comparf)
+Void_t* key;
+Void_t** rootp;
+int(* comparf)();
+#endif
+{
+ reg Dt_t* dt;
+ reg Tree_t* o;
+
+ if(!rootp ||
+ (!(dt = *((Dt_t**)rootp)) && !(dt = dtopen((Dtdisc_t*)(&Treedisc),Dtoset))) )
+ return NIL(Void_t*);
+
+ /* dangerous to set comparf on each call but that's tsearch */
+ Treedisc.comparf = comparf;
+
+ if(!(o = (Tree_t*)dtmatch(dt,key)) )
+ { if(!(o = (Tree_t*)malloc(sizeof(Tree_t))) )
+ return NIL(Void_t*);
+ o->key = (Void_t*)key;
+ dtinsert(dt,o);
+ }
+
+ if(o)
+ *rootp = (Void_t*)dt;
+ else if(*rootp == NIL(Void_t*) )
+ dtclose(dt);
+
+ return (Void_t*)(&o->key);
+}
+
+extern
+#if __STD_C
+Void_t* tfind(const Void_t* key, Void_t*const* rootp,
+ int(*comparf)(const Void_t*, const Void_t*) )
+#else
+Void_t* tfind(key, rootp, comparf)
+Void_t* key;
+Void_t** rootp;
+int(* comparf)();
+#endif
+{
+ reg Dt_t* dt;
+ reg Tree_t* o;
+
+ if(!rootp || !(dt = *((Dt_t**)rootp)) )
+ return NIL(Void_t*);
+ Treedisc.comparf = comparf;
+
+ return (o = (Tree_t*)dtmatch(dt,key)) ? (Void_t*)(&o->key) : NIL(Void_t*);
+}
+
+/* the original tdelete() specifies that it will return the parent pointer
+** in the tree if there is one. Since we are using a splay tree, a deleted
+** node is always rotated to the root first. So this implementation always
+** returns the key of the new root.
+*/
+extern
+#if __STD_C
+Void_t* tdelete(const Void_t* key, Void_t** rootp,
+ int(*comparf)(const Void_t*, const Void_t*) )
+#else
+Void_t* tdelete(key, rootp, comparf)
+Void_t* key;
+Void_t** rootp;
+int(* comparf)();
+#endif
+{
+ reg Dt_t* dt;
+ reg Tree_t* o;
+ Tree_t obj;
+
+ if(!rootp || !(dt = *((Dt_t**)rootp)) )
+ return NIL(Void_t*);
+
+ Treedisc.comparf = comparf;
+
+ obj.key = (Void_t*)key;
+ dtdelete(dt,&obj);
+
+ if(!(o = dtfinger(dt)) )
+ { dtclose(dt);
+ *rootp = NIL(Void_t*);
+ }
+
+ return o ? (Void_t*)(&o->key) : NIL(Void_t*);
+}
+
+/* the below routine assumes a particular layout of Dtlink_t.
+** If this ever gets changed, this routine should be redone.
+*/
+#define lchild link.lh.__left
+#define rchild link.rh.__rght
+
+#if __STD_C
+static void _twalk(Tree_t* obj, void(*action)(const Void_t*,VISIT,int), int level)
+#else
+static void _twalk(obj,action,level)
+Tree_t* obj;
+void(* action)();
+int level;
+#endif
+{ if(!obj->lchild && !obj->rchild)
+ (*action)((Void_t*)obj,leaf,level);
+ else
+ { (*action)((Void_t*)obj,preorder,level);
+ if(obj->lchild)
+ _twalk((Tree_t*)obj->lchild,action,level+1);
+ (*action)((Void_t*)obj,postorder,level);
+ if(obj->rchild)
+ _twalk((Tree_t*)obj->rchild,action,level+1);
+ (*action)((Void_t*)obj,endorder,level);
+ }
+}
+
+/* the original twalk allows specifying arbitrary node to start traversal.
+** Since our root is a dictionary structure, the search here will start
+** at whichever node happens to be current root.
+*/
+extern
+#if __STD_C
+void twalk(const Void_t* root, void(*action)(const Void_t*,VISIT,int) )
+#else
+void twalk(root, action)
+Void_t* root;
+void(* action)();
+#endif
+{
+ reg Tree_t* o;
+
+ if(root && (o = (Tree_t*)dtfinger((Dt_t*)root)) )
+ _twalk(o,action,0);
+}
+
+#endif
diff --git a/src/lib/libast/comp/unlink.c b/src/lib/libast/comp/unlink.c
new file mode 100644
index 0000000..5450848
--- /dev/null
+++ b/src/lib/libast/comp/unlink.c
@@ -0,0 +1,38 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_unlink
+
+NoN(unlink)
+
+#else
+
+int
+unlink(const char* path)
+{
+ return(remove(path));
+}
+
+#endif
diff --git a/src/lib/libast/comp/unsetenv.c b/src/lib/libast/comp/unsetenv.c
new file mode 100644
index 0000000..867892a
--- /dev/null
+++ b/src/lib/libast/comp/unsetenv.c
@@ -0,0 +1,50 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#define unsetenv ______unsetenv
+
+#include <ast.h>
+
+#undef unsetenv
+
+#if _lib_unsetenv
+
+NoN(unsetenv)
+
+#else
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern void
+unsetenv(const char *name)
+{
+ if (!strchr(name, '='))
+ setenviron(name);
+}
+
+#endif
diff --git a/src/lib/libast/comp/vfork.c b/src/lib/libast/comp/vfork.c
new file mode 100644
index 0000000..dfe2fd6
--- /dev/null
+++ b/src/lib/libast/comp/vfork.c
@@ -0,0 +1,55 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_vfork
+
+NoN(vfork)
+
+#else
+
+#include <error.h>
+
+#ifndef ENOSYS
+#define ENOSYS EINVAL
+#endif
+
+#undef vfork
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern pid_t
+vfork(void)
+{
+#if _lib_fork
+ return(fork());
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+#endif
diff --git a/src/lib/libast/comp/waitpid.c b/src/lib/libast/comp/waitpid.c
new file mode 100644
index 0000000..2995b19
--- /dev/null
+++ b/src/lib/libast/comp/waitpid.c
@@ -0,0 +1,199 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * POSIX waitpid()
+ *
+ * pid < -1 WUNTRACED may not be fully supported
+ * process group specifics ignored by non-{waitpid,wait4}
+ */
+
+#include <ast.h>
+#include <wait.h>
+
+#if _lib_waitpid
+
+NoN(waitpid)
+
+#else
+
+#if _lib_wait4
+
+struct rusage;
+
+extern int wait4(int, int*, int, struct rusage*);
+
+pid_t
+waitpid(pid_t pid, int* status, int flags)
+{
+ return(wait4(pid, status, flags, NiL));
+}
+
+#else
+
+#undef SIGCLD
+
+#if _lib_wait3
+
+extern int wait3(int*, int, struct rusage*);
+
+#else
+
+#if _lib_wait2
+
+#define wait3(s,f,u) wait2(s,f)
+
+extern int wait2(int*, int);
+
+#else
+
+#include <sig.h>
+
+#define wait3(s,f,u) wait(s)
+
+static int caught;
+
+static void
+catch(sig)
+int sig;
+{
+ NoP(sig);
+ caught = 1;
+}
+
+#endif
+
+#endif
+
+#include <error.h>
+
+struct zombie
+{
+ struct zombie* next;
+ int status;
+ pid_t pid;
+};
+
+pid_t
+waitpid(pid_t pid, int* status, int flags)
+{
+ register struct zombie* zp;
+ register struct zombie* pp;
+ register int p;
+ int s;
+#if !_lib_wait2 && !_lib_wait3
+#if !defined(SIGCLD)
+ int n;
+ int oerrno;
+#endif
+ Sig_handler_t handler;
+#endif
+
+ static struct zombie* zombies;
+
+ pp = 0;
+ zp = zombies;
+ while (zp)
+ {
+ if (zp->pid >= 0 && (zp->pid == pid || pid <= 0))
+ {
+ if (pp) pp->next = zp->next;
+ else zombies = zp->next;
+ if (status) *status = zp->status;
+ pid = zp->pid;
+ free(zp);
+ return(pid);
+ }
+ }
+ if (pid > 0 && kill(pid, 0) < 0) return(-1);
+ for (;;)
+ {
+#if !_lib_wait2 && !_lib_wait3
+#if !defined(SIGCLD)
+ oerrno = errno;
+#endif
+ if (flags & WNOHANG)
+ {
+ caught = 0;
+#if defined(SIGCLD)
+ handler = signal(SIGCLD, catch);
+ if (!caught)
+ {
+ signal(SIGCLD, handler);
+ return(0);
+ }
+#else
+#if defined(SIGALRM)
+ handler = signal(SIGALRM, catch);
+ n = alarm(1);
+#endif
+#endif
+ }
+#endif
+ p = wait3(&s, flags, NiL);
+#if !_lib_wait3
+#if !_lib_wait2
+#if defined(SIGCLD)
+ if (flags & WNOHANG) signal(SIGCLD, handler);
+#else
+#if defined(SIGALRM)
+ if (flags & WNOHANG)
+ {
+ if (n == 0 && !caught || n == 1) alarm(n);
+ else if (n > 1) alarm(n - caught);
+ signal(SIGALRM, handler);
+ }
+ if (p == -1 && errno == EINTR)
+ {
+ errno = oerrno;
+ p = 0;
+ s = 0;
+ }
+#endif
+#endif
+#else
+ if (p == -1 && errno == EINVAL && (flags & ~WNOHANG))
+ p = wait3(&s, flags & WNOHANG, NiL);
+#endif
+#endif
+ if (p <= 0)
+ {
+ if (p == 0 && status) *status = s;
+ return(p);
+ }
+ if (pid <= 0 || p == pid)
+ {
+ if (status) *status = s;
+ return(p);
+ }
+ if (!(zp = newof(0, struct zombie, 1, 0))) return(-1);
+ zp->pid = p;
+ zp->status = s;
+ zp->next = zombies;
+ zombies = zp;
+ }
+ /*NOTREACHED*/
+}
+
+#endif
+
+#endif
diff --git a/src/lib/libast/comp/wc.c b/src/lib/libast/comp/wc.c
new file mode 100644
index 0000000..521b55a
--- /dev/null
+++ b/src/lib/libast/comp/wc.c
@@ -0,0 +1,139 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * NOTE: mbs* and wcs* are provided to avoid link errors only
+ */
+
+#include <ast.h>
+#include <wchar.h>
+
+#define STUB 1
+
+#if !_lib_mbtowc
+#undef STUB
+size_t
+mbtowc(wchar_t* t, const char* s, size_t n)
+{
+ if (t && n > 0)
+ *t = *s;
+ return 1;
+}
+#endif
+
+#if !_lib_mbrtowc
+#undef STUB
+size_t
+mbrtowc(wchar_t* t, const char* s, size_t n, mbstate_t* q)
+{
+#if _lib_mbtowc
+#undef STUB
+ memset(q, 0, sizeof(*q));
+ return mbtowc(t, s, n);
+#else
+ *q = 0;
+ if (t && n > 0)
+ *t = *s;
+ return 1;
+#endif
+}
+#endif
+
+#if !_lib_mbstowcs
+#undef STUB
+size_t
+mbstowcs(wchar_t* t, const char* s, size_t n)
+{
+ register wchar_t* p = t;
+ register wchar_t* e = t + n;
+ register unsigned char* u = (unsigned char*)s;
+
+ if (t)
+ while (p < e && (*p++ = *u++));
+ else
+ while (p++, *u++);
+ return p - t;
+}
+#endif
+
+#if !_lib_wctomb
+#undef STUB
+int
+wctomb(char* s, wchar_t c)
+{
+ if (s)
+ *s = c;
+ return 1;
+}
+#endif
+
+#if !_lib_wcrtomb
+#undef STUB
+size_t
+wcrtomb(char* s, wchar_t c, mbstate_t* q)
+{
+#if _lib_wctomb
+#undef STUB
+ memset(q, 0, sizeof(*q));
+ return wctomb(s, c);
+#else
+ if (s)
+ *s = c;
+ *q = 0;
+ return 1;
+#endif
+}
+#endif
+
+#if !_lib_wcslen
+#undef STUB
+size_t
+wcslen(const wchar_t* s)
+{
+ register const wchar_t* p = s;
+
+ while (*p)
+ p++;
+ return p - s;
+}
+#endif
+
+#if !_lib_wcstombs
+#undef STUB
+size_t
+wcstombs(char* t, register const wchar_t* s, size_t n)
+{
+ register char* p = t;
+ register char* e = t + n;
+
+ if (t)
+ while (p < e && (*p++ = *s++));
+ else
+ while (p++, *s++);
+ return p - t;
+}
+#endif
+
+#if STUB
+NoN(wc)
+#endif
diff --git a/src/lib/libast/comp/wordexp.c b/src/lib/libast/comp/wordexp.c
new file mode 100644
index 0000000..33016dc
--- /dev/null
+++ b/src/lib/libast/comp/wordexp.c
@@ -0,0 +1,217 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * POSIX 1003.2 wordexp implementation
+ */
+
+#include <ast.h>
+#include <wordexp.h>
+#include <stak.h>
+
+struct list
+{
+ struct list *next;
+};
+
+/*
+ * elimnates shell quoting as inserted with sh_fmtq
+ * result relaces <string>
+ * length of resulting string is returned.
+ */
+static int sh_unquote(char* string)
+{
+ register char *sp=string, *dp;
+ register int c;
+ while((c= *sp) && c!='\'')
+ sp++;
+ if(c==0)
+ return(sp-string);
+ if((dp=sp) > string && sp[-1]=='$')
+ {
+ register int n=stresc(sp+1);
+ /* copy all but trailing ' */
+ while(--n>0)
+ *dp++ = *++sp;
+ }
+ else
+ {
+ while((c= *++sp) && c!='\'')
+ *dp++ = c;
+ }
+ *dp=0;
+ return(dp-string);
+}
+
+int wordexp(const char *string, wordexp_t *wdarg, register int flags)
+{
+ register Sfio_t *iop;
+ register char *cp=(char*)string;
+ register int c,quoted=0,literal=0,ac=0;
+ int offset;
+ char *savebase,**av;
+ if(offset=staktell())
+ savebase = stakfreeze(0);
+ if(flags&WRDE_REUSE)
+ wordfree(wdarg);
+ else if(!(flags&WRDE_APPEND))
+ {
+ wdarg->we_wordv = 0;
+ wdarg->we_wordc = 0;
+ }
+ if(flags&WRDE_UNDEF)
+ stakwrite("set -u\n",7);
+ if(!(flags&WRDE_SHOWERR))
+ stakwrite("exec 2> /dev/null\n",18);
+ stakwrite("print -f \"%q\\n\" ",16);
+ if(*cp=='#')
+ stakputc('\\');
+ while(c = *cp++)
+ {
+ if(c=='\'' && !quoted)
+ literal = !literal;
+ else if(!literal)
+ {
+ if(c=='\\' && (!quoted || strchr("\\\"`\n$",c)))
+ {
+ stakputc('\\');
+ if(c= *cp)
+ cp++;
+ else
+ c = '\\';
+ }
+ else if(c=='"')
+ quoted = !quoted;
+ else if(c=='`' || (c=='$' && *cp=='('))
+ {
+ if(flags&WRDE_NOCMD)
+ {
+ c=WRDE_CMDSUB;
+ goto err;
+ }
+ /* only the shell can parse the rest */
+ stakputs(cp-1);
+ break;
+ }
+ else if(!quoted && strchr("|&\n;<>"+ac,c))
+ {
+ c=WRDE_BADCHAR;
+ goto err;
+ }
+ else if(c=='(') /* allow | and & inside pattern */
+ ac=2;
+ }
+ stakputc(c);
+ }
+ stakputc(0);
+ if(!(iop = sfpopen((Sfio_t*)0,stakptr(0),"r")))
+ {
+ c = WRDE_NOSHELL;
+ goto err;
+ }
+ stakseek(0);
+ ac = 0;
+ while((c=sfgetc(iop)) != EOF)
+ {
+ if(c=='\'')
+ quoted = ! quoted;
+ else if(!quoted && (c==' ' || c=='\n'))
+ {
+ ac++;
+ c = 0;
+ }
+ stakputc(c);
+ }
+ if(c=sfclose(iop))
+ {
+ if(c==3 || !(flags&WRDE_UNDEF))
+ c=WRDE_SYNTAX;
+ else
+ c=WRDE_BADVAL;
+ goto err;
+ }
+ c = ac+2;
+ if(flags&WRDE_DOOFFS)
+ c += wdarg->we_offs;
+ if(flags&WRDE_APPEND)
+ av = (char**)realloc((void*)&wdarg->we_wordv[-1], (wdarg->we_wordc+c)*sizeof(char*));
+ else if(av = (char**)malloc(c*sizeof(char*)))
+ {
+ if(flags&WRDE_DOOFFS)
+ memset((void*)av,0,(wdarg->we_offs+1)*sizeof(char*));
+ else
+ av[0] = 0;
+ }
+ if(!av)
+ return(WRDE_NOSPACE);
+ c = staktell();
+ if(!(cp = (char*)malloc(sizeof(char*)+c)))
+ {
+ c=WRDE_NOSPACE;
+ goto err;
+ }
+ ((struct list*)cp)->next = (struct list*)(*av);
+ *av++ = (char*)cp;
+ cp += sizeof(char*);
+ wdarg->we_wordv = av;
+ if(flags&WRDE_APPEND)
+ av += wdarg->we_wordc;
+ wdarg->we_wordc += ac;
+ if(flags&WRDE_DOOFFS)
+ av += wdarg->we_offs;
+ memcpy((void*)cp,stakptr(offset),c);
+ while(ac-- > 0)
+ {
+ *av++ = cp;
+ sh_unquote(cp);
+ while(c= *cp++);
+ }
+ *av = 0;
+ c=0;
+err:
+ if(offset)
+ stakset(savebase,offset);
+ else
+ stakseek(0);
+ return(c);
+}
+
+/*
+ * free fields in <wdarg>
+ */
+int wordfree(register wordexp_t *wdarg)
+{
+ struct list *arg, *argnext;
+ if(wdarg->we_wordv)
+ {
+ argnext = (struct list*)wdarg->we_wordv[-1];
+ while(arg=argnext)
+ {
+ argnext = arg->next;
+ free((void*)arg);
+ }
+ free((void*)&wdarg->we_wordv[-1]);
+ wdarg->we_wordv = 0;
+ }
+ wdarg->we_wordc=0;
+ return(0);
+}
diff --git a/src/lib/libast/comp/wordexp.h b/src/lib/libast/comp/wordexp.h
new file mode 100644
index 0000000..69a1bb4
--- /dev/null
+++ b/src/lib/libast/comp/wordexp.h
@@ -0,0 +1,63 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * posix wordexp interface definitions
+ */
+
+#ifndef _WORDEXP_H
+#define _WORDEXP_H
+
+#include <ast_common.h>
+
+#define WRDE_APPEND 01
+#define WRDE_DOOFFS 02
+#define WRDE_NOCMD 04
+#define WRDE_NOSYS 0100
+#define WRDE_REUSE 010
+#define WRDE_SHOWERR 020
+#define WRDE_UNDEF 040
+
+#define WRDE_BADCHAR 1
+#define WRDE_BADVAL 2
+#define WRDE_CMDSUB 3
+#define WRDE_NOSPACE 4
+#define WRDE_SYNTAX 5
+#define WRDE_NOSHELL 6
+
+typedef struct _wdarg
+{
+ size_t we_wordc;
+ char **we_wordv;
+ size_t we_offs;
+} wordexp_t;
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int wordexp(const char*, wordexp_t*, int);
+extern int wordfree(wordexp_t*);
+
+#undef extern
+
+#endif /* _WORDEXP_H */
diff --git a/src/lib/libast/dir/dirlib.h b/src/lib/libast/dir/dirlib.h
new file mode 100644
index 0000000..509ed0c
--- /dev/null
+++ b/src/lib/libast/dir/dirlib.h
@@ -0,0 +1,174 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Research
+ *
+ * directory stream access library private definitions
+ * library routines should include this file rather than <dirent.h>
+ */
+
+#ifndef _DIRLIB_H
+#define _DIRLIB_H
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide getdents getdirentries
+#else
+#undef getdents
+#define getdents ______getdents
+#undef getdirentries
+#define getdirentries ______getdirentries
+#endif
+
+#include <ast.h>
+#include <errno.h>
+
+#if _lib_opendir && ( _hdr_dirent || _hdr_ndir || _sys_dir )
+
+#define _dir_ok 1
+
+#include <ls.h>
+
+#ifndef _DIRENT_H
+#if _hdr_dirent
+#if _typ_off64_t
+#undef off_t
+#endif
+#include <dirent.h>
+#if _typ_off64_t
+#define off_t off64_t
+#endif
+#else
+#if _hdr_ndir
+#include <ndir.h>
+#else
+#include <sys/dir.h>
+#endif
+#ifndef dirent
+#define dirent direct
+#endif
+#endif
+#endif
+
+#define DIRdirent dirent
+
+#else
+
+#define dirent DIRdirent
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide DIR closedir opendir readdir seekdir telldir
+#else
+#undef DIR
+#define DIR ______DIR
+#undef closedir
+#define closedir ______closedir
+#undef opendir
+#define opendir ______opendir
+#undef readdir
+#define readdir ______readdir
+#undef seekdir
+#define seekdir ______seekdir
+#undef telldir
+#define telldir ______telldir
+#endif
+
+#include <ast_param.h>
+
+#include <ls.h>
+#include <limits.h>
+
+#ifndef _DIRENT_H
+#if _hdr_dirent
+#if _typ_off64_t
+#undef off_t
+#endif
+#include <dirent.h>
+#if _typ_off64_t
+#define off_t off64_t
+#endif
+#else
+#if _hdr_direntry
+#include <direntry.h>
+#else
+#include <sys/dir.h>
+#endif
+#endif
+#endif
+
+#undef dirent
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide DIR closedir opendir readdir seekdir telldir
+#else
+#undef DIR
+#undef closedir
+#undef opendir
+#undef readdir
+#undef seekdir
+#undef telldir
+#endif
+
+#define _DIR_PRIVATE_ \
+ int dd_loc; /* offset in block */ \
+ int dd_size; /* valid data in block */ \
+ char* dd_buf; /* directory block */
+
+#ifdef _BLD_3d
+#define DIR DIRDIR
+#endif
+#undef _DIRENT_H
+#include "dirstd.h"
+#ifndef _DIRENT_H
+#define _DIRENT_H 1
+#endif
+#ifdef _BLD_3d
+#undef DIR
+#endif
+
+#ifndef DIRBLKSIZ
+#ifdef DIRBLK
+#define DIRBLKSIZ DIRBLK
+#else
+#ifdef DIRBUF
+#define DIRBLKSIZ DIRBUF
+#else
+#define DIRBLKSIZ 8192
+#endif
+#endif
+#endif
+
+#endif
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide getdents getdirentries
+#else
+#undef getdents
+#undef getdirentries
+#endif
+
+#ifndef errno
+extern int errno;
+#endif
+
+extern ssize_t getdents(int, void*, size_t);
+
+#endif
diff --git a/src/lib/libast/dir/dirstd.h b/src/lib/libast/dir/dirstd.h
new file mode 100644
index 0000000..79dc6ea
--- /dev/null
+++ b/src/lib/libast/dir/dirstd.h
@@ -0,0 +1,63 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Bell Laboratories
+ *
+ * <dirent.h> for systems with no opendir()
+ */
+
+#ifndef _DIRENT_H
+#define _DIRENT_H
+
+typedef struct
+{
+ int dd_fd; /* file descriptor */
+#ifdef _DIR_PRIVATE_
+ _DIR_PRIVATE_
+#endif
+} DIR;
+
+struct dirent
+{
+ long d_fileno; /* entry serial number */
+ int d_reclen; /* entry length */
+ int d_namlen; /* entry name length */
+ char d_name[1]; /* entry name */
+};
+
+#ifndef _BLD_3d
+
+#ifdef rewinddir
+#undef rewinddir
+#define rewinddir(p) seekdir(p,0L)
+#endif
+
+extern DIR* opendir(const char*);
+extern void closedir(DIR*);
+extern struct dirent* readdir(DIR*);
+extern void seekdir(DIR*, long);
+extern long telldir(DIR*);
+
+#endif
+
+#endif
diff --git a/src/lib/libast/dir/getdents.c b/src/lib/libast/dir/getdents.c
new file mode 100644
index 0000000..22228cd
--- /dev/null
+++ b/src/lib/libast/dir/getdents.c
@@ -0,0 +1,166 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "dirlib.h"
+
+#if _dir_ok || _lib_getdents
+
+NoN(getdents)
+
+#else
+
+/*
+ * getdents
+ *
+ * read directory entries into directory block
+ *
+ * NOTE: directory entries must fit within DIRBLKSIZ boundaries
+ */
+
+#ifndef MAXNAMLEN
+#define MAXNAMLEN 255
+#endif
+
+#if _lib_dirread
+extern int dirread(int, char*, int);
+#endif
+#if _lib_getdirentries
+extern int getdirentries(int, char*, int, long*);
+#endif
+
+ssize_t
+getdents(int fd, void* buf, size_t siz)
+{
+ struct stat st;
+
+ if (siz < DIRBLKSIZ)
+ {
+ errno = EINVAL;
+ return(-1);
+ }
+ if (fstat(fd, &st)) return(-1);
+ if (!S_ISDIR(st.st_mode))
+ {
+#ifdef ENOTDIR
+ errno = ENOTDIR;
+#else
+ errno = EBADF;
+#endif
+ return(-1);
+ }
+#if _lib_getdirentries
+ {
+ long off;
+ return(getdirentries(fd, buf, siz, &off));
+ }
+#else
+#if _lib_dirread
+ {
+ register char* sp; /* system */
+ register struct dirent* up; /* user */
+ char* u;
+ int n;
+ int m;
+ int i;
+
+ m = (siz * 6) / 10;
+ m = roundof(m, 8);
+ sp = (char*)buf + siz - m - 1;
+ if (!(n = dirread(fd, sp, m))) return(0);
+ if (n > 0)
+ {
+ up = (struct dirent*)buf;
+ sp[n] = 0;
+ while (sp < (char*)buf + siz - m + n)
+ {
+ i = 0;
+ while (*sp >= '0' && *sp <= '9')
+ i = 10 * i + *sp++ - '0';
+ while (*sp && *sp != '\t') sp++;
+ if (*sp++)
+ {
+ up->d_fileno = i;
+ u = up->d_name;
+ while ((*u = *sp++) && u < up->d_name + MAXNAMLEN) u++;
+ *u = 0;
+ up->d_reclen = sizeof(struct dirent) - sizeof(up->d_name) + (up->d_namlen = u - up->d_name) + 1;
+ up->d_reclen = roundof(up->d_reclen, 8);
+ up = (struct dirent*)((char*)up + up->d_reclen);
+ }
+ }
+ return((char*)up - (char*)buf);
+ }
+ }
+#else
+#if _mem_d_reclen_direct
+ return(read(fd, buf, siz));
+#else
+ {
+
+#define MAXREC roundof(sizeof(*up)-sizeof(up->d_name)+sizeof(sp->d_name)+1,8)
+
+ register struct direct* sp; /* system */
+ register struct dirent* up; /* user */
+ register char* s;
+ register char* u;
+ int n;
+ int m;
+ char tmp[sizeof(sp->d_name) + 1];
+
+ /*
+ * we assume sizeof(struct dirent) > sizeof(struct direct)
+ */
+
+ up = (struct dirent*)buf;
+ n = (siz / MAXREC) * sizeof(struct direct);
+ if ((!(m = n & ~511) || m < MAXREC) && (!(m = n & ~255) || m < MAXREC)) m = n;
+ do
+ {
+ if ((n = read(fd, (char*)buf + siz - m, m)) <= 0) break;
+ sp = (struct direct*)((char*)buf + siz - m);
+ while (sp < (struct direct*)((char*)buf + siz - m + n))
+ {
+ if (sp->d_ino)
+ {
+ up->d_fileno = sp->d_ino;
+ s = sp->d_name;
+ u = tmp;
+ while (s < sp->d_name + sizeof(sp->d_name) && *s)
+ *u++ = *s++;
+ *u = 0;
+ strcpy(up->d_name, tmp);
+ up->d_reclen = sizeof(struct dirent) - sizeof(up->d_name) + (up->d_namlen = u - tmp) + 1;
+ up->d_reclen = roundof(up->d_reclen, 8);
+ up = (struct dirent*)((char*)up + up->d_reclen);
+ }
+ sp++;
+ }
+ } while (up == (struct dirent*)buf);
+ return((char*)up - (char*)buf);
+ }
+#endif
+#endif
+#endif
+}
+
+#endif
diff --git a/src/lib/libast/dir/opendir.c b/src/lib/libast/dir/opendir.c
new file mode 100644
index 0000000..bb9177e
--- /dev/null
+++ b/src/lib/libast/dir/opendir.c
@@ -0,0 +1,95 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * opendir, closedir
+ *
+ * open|close directory stream
+ *
+ * POSIX compatible directory stream access routines:
+ *
+ * #include <sys/types.h>
+ * #include <dirent.h>
+ *
+ * NOTE: readdir() returns a pointer to struct dirent
+ */
+
+#include "dirlib.h"
+
+#if _dir_ok
+
+NoN(opendir)
+
+#else
+
+static const char id_dir[] = "\n@(#)$Id: directory (AT&T Research) 1993-04-01 $\0\n";
+
+static DIR* freedirp; /* always keep one dirp */
+
+DIR*
+opendir(register const char* path)
+{
+ register DIR* dirp = 0;
+ register int fd;
+ struct stat st;
+
+ if ((fd = open(path, O_RDONLY)) < 0) return(0);
+ if (fstat(fd, &st) < 0 ||
+ !S_ISDIR(st.st_mode) && (errno = ENOTDIR) ||
+ fcntl(fd, F_SETFD, FD_CLOEXEC) ||
+ !(dirp = freedirp ? freedirp :
+#if defined(_DIR_PRIVATE_) || _ptr_dd_buf
+ newof(0, DIR, 1, DIRBLKSIZ)
+#else
+ newof(0, DIR, 1, 0)
+#endif
+ ))
+ {
+ close(fd);
+ if (dirp)
+ {
+ if (!freedirp) freedirp = dirp;
+ else free(dirp);
+ }
+ return(0);
+ }
+ freedirp = 0;
+ dirp->dd_fd = fd;
+ dirp->dd_loc = dirp->dd_size = 0; /* refill needed */
+#if defined(_DIR_PRIVATE_) || _ptr_dd_buf
+ dirp->dd_buf = (void*)((char*)dirp + sizeof(DIR));
+#endif
+ return(dirp);
+}
+
+void
+closedir(register DIR* dirp)
+{
+ if (dirp)
+ {
+ close(dirp->dd_fd);
+ if (!freedirp) freedirp = dirp;
+ else free(dirp);
+ }
+}
+
+#endif
diff --git a/src/lib/libast/dir/readdir.c b/src/lib/libast/dir/readdir.c
new file mode 100644
index 0000000..1c595b7
--- /dev/null
+++ b/src/lib/libast/dir/readdir.c
@@ -0,0 +1,61 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * readdir
+ *
+ * read from directory stream
+ *
+ * NOTE: directory entries must fit within DIRBLKSIZ boundaries
+ */
+
+#include "dirlib.h"
+
+#if _dir_ok
+
+NoN(readdir)
+
+#else
+
+struct dirent*
+readdir(register DIR* dirp)
+{
+ register struct dirent* dp;
+
+ for (;;)
+ {
+ if (dirp->dd_loc >= dirp->dd_size)
+ {
+ if (dirp->dd_size < 0) return(0);
+ dirp->dd_loc = 0;
+ if ((dirp->dd_size = getdents(dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ)) <= 0)
+ return(0);
+ }
+ dp = (struct dirent*)((char*)dirp->dd_buf + dirp->dd_loc);
+ if (dp->d_reclen <= 0) return(0);
+ dirp->dd_loc += dp->d_reclen;
+ if (dp->d_fileno) return(dp);
+ }
+ /*NOTREACHED*/
+}
+
+#endif
diff --git a/src/lib/libast/dir/rewinddir.c b/src/lib/libast/dir/rewinddir.c
new file mode 100644
index 0000000..244690a
--- /dev/null
+++ b/src/lib/libast/dir/rewinddir.c
@@ -0,0 +1,46 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * rewinddir
+ *
+ * rewind directory stream
+ * provided for POSIX compatibility
+ */
+
+#include "dirlib.h"
+
+#if _dir_ok && ( defined(rewinddir) || _lib_rewinddir )
+
+NoN(rewinddir)
+
+#else
+
+#undef rewinddir
+
+void
+rewinddir(DIR* dirp)
+{
+ seekdir(dirp, 0L);
+}
+
+#endif
diff --git a/src/lib/libast/dir/seekdir.c b/src/lib/libast/dir/seekdir.c
new file mode 100644
index 0000000..8113584
--- /dev/null
+++ b/src/lib/libast/dir/seekdir.c
@@ -0,0 +1,56 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * seekdir
+ *
+ * seek on directory stream
+ * this is not optimal because there aren't portable
+ * semantics for directory seeks
+ */
+
+#include "dirlib.h"
+
+#if _dir_ok
+
+NoN(seekdir)
+
+#else
+
+void
+seekdir(register DIR* dirp, long loc)
+{
+ off_t base; /* file location of block */
+ off_t offset; /* offset within block */
+
+ if (telldir(dirp) != loc)
+ {
+ lseek(dirp->dd_fd, 0L, SEEK_SET);
+ dirp->dd_loc = dirp->dd_size = 0;
+ while (telldir(dirp) != loc)
+ if (!readdir(dirp))
+ break; /* "can't happen" */
+ }
+}
+
+#endif
diff --git a/src/lib/libast/dir/telldir.c b/src/lib/libast/dir/telldir.c
new file mode 100644
index 0000000..611d9e7
--- /dev/null
+++ b/src/lib/libast/dir/telldir.c
@@ -0,0 +1,43 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * telldir
+ *
+ * get directory stream pointer offset for seekdir()
+ */
+
+#include "dirlib.h"
+
+#if _dir_ok
+
+NoN(telldir)
+
+#else
+
+long
+telldir(DIR* dirp)
+{
+ return(lseek(dirp->dd_fd, 0L, SEEK_CUR) + (long)dirp->dd_loc);
+}
+
+#endif
diff --git a/src/lib/libast/disc/memfatal.c b/src/lib/libast/disc/memfatal.c
new file mode 100644
index 0000000..9016d36
--- /dev/null
+++ b/src/lib/libast/disc/memfatal.c
@@ -0,0 +1,82 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * install error message handler for fatal malloc exceptions
+ */
+
+#include <ast.h>
+#include <error.h>
+#include <vmalloc.h>
+
+#include "FEATURE/vmalloc"
+
+#if _std_malloc
+
+void
+memfatal(void)
+{
+}
+
+#else
+
+/*
+ * print message and fail on VM_BADADDR,VM_NOMEM
+ */
+
+static int
+nomalloc(Vmalloc_t* region, int type, void* obj, Vmdisc_t* disc)
+{
+ Vmstat_t st;
+
+ NoP(disc);
+ switch (type)
+ {
+#ifdef VM_BADADDR
+ case VM_BADADDR:
+ error(ERROR_SYSTEM|3, "invalid pointer %p passed to free or realloc", obj);
+ return(-1);
+#endif
+ case VM_NOMEM:
+ vmstat(region, &st);
+ error(ERROR_SYSTEM|3, "storage allocator out of space on %lu byte request ( region %lu segments %lu busy %lu:%lu:%lu free %lu:%lu:%lu )", (size_t)obj, st.extent, st.n_seg, st.n_busy, st.s_busy, st.m_busy, st.n_free, st.s_free, st.m_free);
+ return(-1);
+ }
+ return(0);
+}
+
+/*
+ * initialize the malloc exception handler
+ */
+
+void
+memfatal(void)
+{
+ Vmdisc_t* disc;
+
+ malloc(0);
+ if (disc = vmdisc(Vmregion, NiL))
+ disc->exceptf = nomalloc;
+}
+
+#endif
diff --git a/src/lib/libast/disc/sfdcdio.c b/src/lib/libast/disc/sfdcdio.c
new file mode 100644
index 0000000..e8277f1
--- /dev/null
+++ b/src/lib/libast/disc/sfdcdio.c
@@ -0,0 +1,229 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfdchdr.h"
+
+/* Discipline to turn on direct IO capability.
+** This currently only works for XFS on SGI's.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998.
+*/
+
+#ifndef FDIRECT
+#undef F_FIOINFO
+#endif
+
+typedef struct _direct_s
+{ Sfdisc_t disc; /* Sfio discipline */
+ int cntl; /* file control flags */
+#ifdef F_DIOINFO
+ struct dioattr dio; /* direct IO params */
+#endif
+} Direct_t;
+
+/* convert a pointer to an int */
+#define P2I(p) (Sfulong_t)((char*)(p) - (char*)0)
+
+#if __STD_C
+static ssize_t diordwr(Sfio_t* f, Void_t* buf, size_t n, Direct_t* di, int type)
+#else
+static ssize_t diordwr(f, buf, n, di, type)
+Sfio_t* f;
+Void_t* buf;
+size_t n;
+Direct_t* di;
+int type;
+#endif
+{
+ size_t rw, done;
+ ssize_t rv;
+
+ done = 0; /* amount processed by direct IO */
+ rv = 0;
+
+#ifdef F_DIOINFO
+ if((P2I(buf)%di->dio.d_mem) == 0 &&
+ (f->here%di->dio.d_miniosz) == 0 && n >= di->dio.d_miniosz )
+ { /* direct IO ok, make sure we're in the right mode */
+ if(!(di->cntl & FDIRECT) )
+ { di->cntl |= FDIRECT;
+ (void)fcntl(f->file, F_SETFL, di->cntl);
+ }
+
+ for(rw = (n/di->dio.d_miniosz)*di->dio.d_miniosz;; )
+ { size_t io;
+
+ if((io = rw) > di->dio.d_maxiosz )
+ io = di->dio.d_maxiosz;
+ if(type == SF_READ)
+ rv = read(f->file,buf,io);
+ else rv = write(f->file,buf,io);
+
+ if(rv > 0)
+ { rw -= rv; done += rv;
+ buf = (Void_t*)((char*)buf + rv);
+ }
+
+ if(rv < io || rw < di->dio.d_miniosz)
+ break;
+ }
+ }
+
+ if(done < n && (di->cntl & FDIRECT) )
+ { /* turn off directIO for remaining IO operation */
+ di->cntl &= ~FDIRECT;
+ (void)fcntl(f->file, F_SETFL, di->cntl);
+ }
+#endif /*F_DIOINFO*/
+
+ if((rw = n-done) > 0 &&
+ (rv = type == SF_READ ? read(f->file,buf,rw) : write(f->file,buf,rw)) > 0 )
+ done += rv;
+
+ return done ? done : rv;
+}
+
+#if __STD_C
+static ssize_t dioread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc)
+#else
+static ssize_t dioread(f, buf, n, disc)
+Sfio_t* f;
+Void_t* buf;
+size_t n;
+Sfdisc_t* disc;
+#endif
+{
+ return diordwr(f, buf, n, (Direct_t*)disc, SF_READ);
+}
+
+#if __STD_C
+static ssize_t diowrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc)
+#else
+static ssize_t diowrite(f, buf, n, disc)
+Sfio_t* f;
+Void_t* buf;
+size_t n;
+Sfdisc_t* disc;
+#endif
+{
+ return diordwr(f, (Void_t*)buf, n, (Direct_t*)disc, SF_WRITE);
+}
+
+#if __STD_C
+static int dioexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc)
+#else
+static int dioexcept(f,type,data,disc)
+Sfio_t* f;
+int type;
+Void_t* data;
+Sfdisc_t* disc;
+#endif
+{
+ Direct_t* di = (Direct_t*)disc;
+
+ if(type == SF_FINAL || type == SF_DPOP)
+ {
+#ifdef F_DIOINFO
+ if(di->cntl&FDIRECT)
+ { di->cntl &= ~FDIRECT;
+ (void)fcntl(f->file,F_SETFL,di->cntl);
+ }
+#endif
+ free(disc);
+ }
+
+ return 0;
+}
+
+#if __STD_C
+int sfdcdio(Sfio_t* f, size_t bufsize)
+#else
+int sfdcdio(f, bufsize)
+Sfio_t* f;
+size_t bufsize;
+#endif
+{
+#ifndef F_DIOINFO
+ return -1;
+#else
+ int cntl;
+ struct dioattr dio;
+ Void_t* buf;
+ Direct_t* di;
+
+ if(f->extent < 0 || (f->flags&SF_STRING))
+ return -1;
+
+ if((cntl = fcntl(f->file,F_GETFL,0)) < 0)
+ return -1;
+
+ if(!(cntl&FDIRECT) )
+ { cntl |= FDIRECT;
+ if(fcntl(f->file,F_SETFL,cntl) < 0)
+ return -1;
+ }
+
+ if(fcntl(f->file,F_DIOINFO,&dio) < 0)
+ goto no_direct;
+
+ if(bufsize > 0)
+ bufsize = (bufsize/dio.d_miniosz)*dio.d_miniosz;
+ if(bufsize <= 0)
+ bufsize = dio.d_miniosz*64;
+ if(bufsize > dio.d_maxiosz)
+ bufsize = dio.d_maxiosz;
+
+ if(!(di = (Direct_t*)malloc(sizeof(Direct_t))) )
+ goto no_direct;
+
+ if(!(buf = (Void_t*)memalign(dio.d_mem,bufsize)) )
+ { free(di);
+ goto no_direct;
+ }
+
+ sfsetbuf(f,buf,bufsize);
+ if(sfsetbuf(f,buf,0) == buf)
+ sfset(f,SF_MALLOC,1);
+ else
+ { free(buf);
+ free(di);
+ goto no_direct;
+ }
+
+ di->disc.readf = dioread;
+ di->disc.writef = diowrite;
+ di->disc.seekf = NIL(Sfseek_f);
+ di->disc.exceptf = dioexcept;
+ di->cntl = cntl;
+ di->dio = dio;
+
+ if(sfdisc(f,(Sfdisc_t*)di) != (Sfdisc_t*)di)
+ { free(di);
+ no_direct:
+ cntl &= ~FDIRECT;
+ (void)fcntl(f->file,F_SETFL,cntl);
+ return -1;
+ }
+
+ return 0;
+
+#endif /*F_DIOINFO*/
+}
diff --git a/src/lib/libast/disc/sfdcdos.c b/src/lib/libast/disc/sfdcdos.c
new file mode 100644
index 0000000..15b7865
--- /dev/null
+++ b/src/lib/libast/disc/sfdcdos.c
@@ -0,0 +1,416 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfdchdr.h"
+
+/* Discipline to turn \r\n into \n.
+** This is useful to deal with DOS text files.
+**
+** Written by David Korn (03/18/1998).
+*/
+
+#define MINMAP 8
+#define CHUNK 1024
+
+struct map
+{
+ Sfoff_t logical;
+ Sfoff_t physical;
+};
+
+typedef struct _dosdisc
+{
+ Sfdisc_t disc;
+ struct map *maptable;
+ int mapsize;
+ int maptop;
+ Sfoff_t lhere;
+ Sfoff_t llast;
+ Sfoff_t lmax;
+ Sfoff_t pmax;
+ Sfoff_t phere;
+ Sfoff_t plast;
+ Sfoff_t begin;
+ int skip;
+ void *buff;
+ char last;
+ char extra;
+ int bsize;
+} Dosdisc_t;
+
+#if __STD_C
+static void addmapping(register Dosdisc_t *dp)
+#else
+static void addmapping(dp)
+register Dosdisc_t *dp;
+#endif
+{
+ register int n;
+ if((n=dp->maptop++)>=dp->mapsize)
+ {
+ dp->mapsize *= 2;
+ if(!(dp->maptable=(struct map*)realloc((void*)dp->maptable,(dp->mapsize+1)*sizeof(struct map))))
+ {
+ dp->maptop--;
+ dp->mapsize *= 2;
+ return;
+ }
+ }
+ dp->maptable[n].physical = dp->phere;
+ dp->maptable[n].logical = dp->lhere;
+ dp->maptable[dp->maptop].logical=0;
+}
+
+#if __STD_C
+static struct map *getmapping(Dosdisc_t *dp, Sfoff_t offset, register int whence)
+#else
+static struct map *getmapping(dp, offset, whence)
+Dosdisc_t *dp;
+Sfoff_t offset;
+register int whence;
+#endif
+{
+ register struct map *mp;
+ static struct map dummy;
+ if(offset <= dp->begin)
+ {
+ dummy.logical = dummy.physical = offset;
+ return(&dummy);
+ }
+ if(!(mp=dp->maptable))
+ {
+ dummy.logical = dp->begin;
+ dummy.physical = dummy.logical+1;
+ return(&dummy);
+ }
+ while((++mp)->logical && (whence==SEEK_CUR?mp->physical:mp->logical) <= offset);
+ return(mp-1);
+}
+
+#if __STD_C
+static ssize_t dos_read(Sfio_t *iop, void *buff, size_t size, Sfdisc_t* disc)
+#else
+static ssize_t dos_read(iop, buff, size, disc)
+Sfio_t *iop;
+void *buff;
+size_t size;
+Sfdisc_t* disc;
+#endif
+{
+ register Dosdisc_t *dp = (Dosdisc_t*)disc;
+ register char *cp = (char*)buff, *first, *cpmax;
+ register int n, count, m;
+ if(dp->extra)
+ {
+ dp->extra=0;
+ *cp = dp->last;
+ return(1);
+ }
+ while(1)
+ {
+ if((n = sfrd(iop,buff,size,disc)) <= 0)
+ return(n);
+ dp->plast=dp->phere;
+ dp->phere +=n;
+ dp->llast = dp->lhere;
+ cpmax = cp+n-1;
+ if(dp->last=='\r' && *cp!='\n')
+ {
+ /* should insert a '\r' */ ;
+ }
+ dp->last = *cpmax;
+ if(n>1)
+ break;
+ if(dp->last!='\r')
+ {
+ dp->lhere++;
+ return(1);
+ }
+ }
+ if(dp->last=='\r')
+ n--;
+ else if(dp->last!='\n' || cpmax[-1]!='\r')
+ *cpmax = '\r';
+ dp->lhere += n;
+ while(1)
+ {
+ while(*cp++ != '\r');
+ if(cp > cpmax || *cp=='\n')
+ break;
+ }
+ dp->skip = cp-1 - (char*)buff;
+ /* if not \r\n in buffer, just return */
+ if((count = cpmax+1-cp) <=0)
+ {
+ *cpmax = dp->last;
+ if(!dp->maptable)
+ dp->begin +=n;
+ dp->skip++;
+ count=0;
+ goto done;
+ }
+ if(!dp->maptable)
+ {
+ dp->begin += cp - (char*)buff-1;
+ if(dp->maptable=(struct map*)malloc((MINMAP+1)*sizeof(struct map)))
+ {
+ dp->mapsize = MINMAP;
+ dp->maptable[0].logical= dp->begin;
+ dp->maptable[0].physical = dp->maptable[0].logical+1;
+ dp->maptable[1].logical=0;
+ dp->maptop = 1;
+ }
+ }
+ /* save original discipline inside buffer */
+ if(count>dp->bsize)
+ {
+ if(dp->bsize==0)
+ dp->buff = malloc(count);
+ else
+ dp->buff = realloc(dp->buff,count);
+ dp->bsize = count;
+ if(!dp->buff)
+ return(-1);
+ }
+ memcpy(dp->buff, cp, count);
+ count=1;
+ while(1)
+ {
+ first=cp;
+ if(cp==cpmax)
+ cp++;
+ else
+ while(*cp++ != '\r');
+ if(cp<=cpmax && *cp!='\n')
+ continue;
+ if((m=(cp-first)-1) >0)
+ memcpy(first-count, first, m);
+ if(cp > cpmax)
+ break;
+ count++;
+ }
+ cpmax[-count] = dp->last;
+ dp->lhere -= count;
+done:
+ if(dp->lhere>dp->lmax)
+ {
+ dp->lmax = dp->lhere;
+ dp->pmax = dp->phere;
+ if(dp->maptable && dp->lmax > dp->maptable[dp->maptop-1].logical+CHUNK)
+ addmapping(dp);
+ }
+ return(n-count);
+}
+
+/*
+ * returns the current offset
+ * <offset> must be in the current buffer
+ * if <whence> is SEEK_CUR, physical offset converted to logical offset
+ * otherwise, logical offset is converted to physical offset
+ */
+#if __STD_C
+static Sfoff_t cur_offset(Dosdisc_t *dp, Sfoff_t offset,Sfio_t *iop,register int whence)
+#else
+static Sfoff_t cur_offset(dp, offset, iop, whence)
+Dosdisc_t *dp;
+Sfoff_t offset;
+Sfio_t *iop;
+register int whence;
+#endif
+{
+ register Sfoff_t n,m=0;
+ register char *cp;
+
+ if(whence==SEEK_CUR)
+ {
+ whence= -1;
+ n = offset - dp->plast;
+ iop->next = iop->data + n;
+ offset = dp->llast;
+ }
+ else
+ {
+ whence = 1;
+ n = offset - dp->llast;
+ offset = dp->plast;
+ }
+ offset +=n;
+ if((n -= dp->skip) > 0)
+ {
+ m=whence;
+ cp = (char*)dp->buff;
+ while(n--)
+ {
+ if(*cp++=='\r' && *cp=='\n')
+ {
+ m += whence;
+ if(whence>0)
+ n++;
+ }
+ }
+ }
+ if(whence<0)
+ iop->next += m;
+ return(offset+m);
+}
+
+#if __STD_C
+static Sfoff_t dos_seek(Sfio_t *iop, Sfoff_t offset, register int whence, Sfdisc_t* disc)
+#else
+static Sfoff_t dos_seek(iop, offset, whence, disc)
+Sfio_t *iop;
+Sfoff_t offset;
+register int whence;
+Sfdisc_t* disc;
+#endif
+{
+ register Dosdisc_t *dp = (Dosdisc_t*)disc;
+ struct map dummy, *mp=0;
+ Sfoff_t physical;
+ register int n,size;
+retry:
+ switch(whence)
+ {
+ case SEEK_CUR:
+ offset = sfsk(iop, (Sfoff_t)0,SEEK_CUR,disc);
+ if(offset<=dp->begin)
+ return(offset);
+ /* check for seek outside buffer */
+ if(offset==dp->phere)
+ return(dp->lhere);
+ else if(offset==dp->plast)
+ return(dp->llast);
+ else if(offset<dp->plast || offset>dp->phere)
+ mp = getmapping(dp,offset,whence);
+ break;
+ case SEEK_SET:
+ /* check for seek outside buffer */
+ if(offset<dp->llast || offset > dp->lhere)
+ mp = getmapping(dp,offset,whence);
+ break;
+ case SEEK_END:
+ if(!dp->maptable)
+ return(sfsk(iop,offset,SEEK_END,disc));
+ mp = &dummy;
+ mp->physical = dp->plast;
+ mp->logical = dp->llast;
+ break;
+ }
+ if(sfsetbuf(iop,(char*)iop,0))
+ size = sfvalue(iop);
+ else
+ size = iop->endb-iop->data;
+ if(mp)
+ {
+ sfsk(iop,mp->physical,SEEK_SET,disc);
+ dp->phere = mp->physical;
+ dp->lhere = mp->logical;
+ if((*disc->readf)(iop,iop->data,size,disc)<0)
+ return(-1);
+ }
+ while(1)
+ {
+ if(whence==SEEK_CUR && dp->phere>=offset)
+ break;
+ if(whence==SEEK_SET && dp->lhere>=offset)
+ break;
+ n=(*disc->readf)(iop,iop->data,size,disc);
+ if(n < 0)
+ return(-1);
+ if(n==0)
+ {
+ if(whence==SEEK_END && offset<0)
+ {
+ offset = dp->lhere;
+ whence=SEEK_SET;
+ goto retry;
+ }
+ break;
+ }
+ }
+ if(whence==SEEK_END)
+ offset += dp->lhere;
+ else
+ {
+ physical = cur_offset(dp,offset,iop,whence);
+ if(whence==SEEK_SET)
+ {
+ sfsk(iop, physical ,SEEK_SET,disc);
+ dp->phere = physical;
+ dp->lhere = offset;
+ }
+ else
+ offset = physical;
+ }
+ return(offset);
+}
+
+#if __STD_C
+static int dos_except(Sfio_t *iop, int type, void *arg, Sfdisc_t *disc)
+#else
+static int dos_except(iop, type, arg, disc)
+Sfio_t *iop;
+int type;
+void *arg;
+Sfdisc_t *disc;
+#endif
+{
+ register Dosdisc_t *dp = (Dosdisc_t*)disc;
+ if(type==SF_DPOP || type==SF_FINAL)
+ {
+ if(dp->bsize>0)
+ free((void*)dp->buff);
+ if(dp->mapsize)
+ free((void*)dp->maptable);
+ free((void*)disc);
+ }
+ return(0);
+}
+
+#if __STD_C
+int sfdcdos(Sfio_t *f)
+#else
+int sfdcdos(f)
+Sfio_t *f;
+#endif
+{
+ Dosdisc_t *dos;
+
+ /* this is a readonly discipline */
+ if(sfset(f,0,0)&SF_WRITE)
+ return(-1);
+
+ if(!(dos = (Dosdisc_t*)malloc(sizeof(Dosdisc_t))) )
+ return -1;
+ memset(dos,'\0',sizeof(Dosdisc_t));
+
+ dos->disc.readf = dos_read;
+ dos->disc.writef = NIL(Sfwrite_f);
+ dos->disc.seekf = dos_seek;
+ dos->disc.exceptf = dos_except;
+
+ if(sfdisc(f,(Sfdisc_t*)dos) != (Sfdisc_t*)dos)
+ { free(dos);
+ return -1;
+ }
+
+ return(0);
+}
diff --git a/src/lib/libast/disc/sfdcfilter.c b/src/lib/libast/disc/sfdcfilter.c
new file mode 100644
index 0000000..16a2219
--- /dev/null
+++ b/src/lib/libast/disc/sfdcfilter.c
@@ -0,0 +1,186 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfdchdr.h"
+
+/* Discipline to invoke UNIX processes as data filters.
+** These processes must be able to fit in pipelines.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998.
+*/
+
+typedef struct _filter_s
+{ Sfdisc_t disc; /* discipline structure */
+ Sfio_t* filter; /* the filter stream */
+ char* next; /* data unwritten */
+ char* endb; /* end of data */
+ char raw[4096]; /* raw data buffer */
+} Filter_t;
+
+/* read data from the filter */
+#if __STD_C
+static ssize_t filterread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc)
+#else
+static ssize_t filterread(f, buf, n, disc)
+Sfio_t* f; /* stream reading from */
+Void_t* buf; /* buffer to read into */
+size_t n; /* number of bytes requested */
+Sfdisc_t* disc; /* discipline */
+#endif
+{
+ Filter_t* fi;
+ ssize_t r, w;
+
+ fi = (Filter_t*)disc;
+ for(;;)
+ {
+ /* get some raw data to stuff down the pipe */
+ if(fi->next && fi->next >= fi->endb )
+ { if((r = sfrd(f,fi->raw,sizeof(fi->raw),disc)) > 0)
+ { fi->next = fi->raw;
+ fi->endb = fi->raw+r;
+ }
+ else
+ { /* eof, close write end of pipes */
+ sfset(fi->filter,SF_READ,0);
+ close(sffileno(fi->filter));
+ sfset(fi->filter,SF_READ,1);
+ fi->next = fi->endb = NIL(char*);
+ }
+ }
+
+ if(fi->next && (w = fi->endb - fi->next) > 0 )
+ { /* see if pipe is ready for write */
+ sfset(fi->filter, SF_READ, 0);
+ r = sfpoll(&fi->filter, 1, 1);
+ sfset(fi->filter, SF_READ, 1);
+
+ if(r == 1) /* non-blocking write */
+ { errno = 0;
+ if((w = sfwr(fi->filter, fi->next, w, 0)) > 0)
+ fi->next += w;
+ else if(errno != EAGAIN)
+ return 0;
+ }
+ }
+
+ /* see if pipe is ready for read */
+ sfset(fi->filter, SF_WRITE, 0);
+ w = sfpoll(&fi->filter, 1, fi->next ? 1 : -1);
+ sfset(fi->filter, SF_WRITE, 1);
+
+ if(!fi->next || w == 1) /* non-blocking read */
+ { errno = 0;
+ if((r = sfrd(fi->filter, buf, n, 0)) > 0)
+ return r;
+ if(errno != EAGAIN)
+ return 0;
+ }
+ }
+}
+
+#if __STD_C
+static ssize_t filterwrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc)
+#else
+static ssize_t filterwrite(f, buf, n, disc)
+Sfio_t* f; /* stream writing to */
+Void_t* buf; /* buffer to write into */
+size_t n; /* number of bytes requested */
+Sfdisc_t* disc; /* discipline */
+#endif
+{
+ return -1;
+}
+
+/* for the duration of this discipline, the stream is unseekable */
+#if __STD_C
+static Sfoff_t filterseek(Sfio_t* f, Sfoff_t addr, int offset, Sfdisc_t* disc)
+#else
+static Sfoff_t filterseek(f, addr, offset, disc)
+Sfio_t* f;
+Sfoff_t addr;
+int offset;
+Sfdisc_t* disc;
+#endif
+{ f = NIL(Sfio_t*);
+ addr = 0;
+ offset = 0;
+ disc = NIL(Sfdisc_t*);
+ return (Sfoff_t)(-1);
+}
+
+/* on close, remove the discipline */
+#if __STD_C
+static int filterexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc)
+#else
+static int filterexcept(f,type,data,disc)
+Sfio_t* f;
+int type;
+Void_t* data;
+Sfdisc_t* disc;
+#endif
+{
+ if(type == SF_FINAL || type == SF_DPOP)
+ { sfclose(((Filter_t*)disc)->filter);
+ free(disc);
+ }
+
+ return 0;
+}
+
+#if __STD_C
+int sfdcfilter(Sfio_t* f, const char* cmd)
+#else
+int sfdcfilter(f, cmd)
+Sfio_t* f; /* stream to filter data */
+char* cmd; /* program to run as a filter */
+#endif
+{
+ reg Filter_t* fi;
+ reg Sfio_t* filter;
+
+ /* open filter for read&write */
+ if(!(filter = sfpopen(NIL(Sfio_t*),cmd,"r+")) )
+ return -1;
+
+ /* unbuffered stream */
+ sfsetbuf(filter,NIL(Void_t*),0);
+
+ if(!(fi = (Filter_t*)malloc(sizeof(Filter_t))) )
+ { sfclose(filter);
+ return -1;
+ }
+
+ fi->disc.readf = filterread;
+ fi->disc.writef = filterwrite;
+ fi->disc.seekf = filterseek;
+ fi->disc.exceptf = filterexcept;
+ fi->filter = filter;
+ fi->next = fi->endb = fi->raw;
+
+ if(sfdisc(f,(Sfdisc_t*)fi) != (Sfdisc_t*)fi)
+ { sfclose(filter);
+ free(fi);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/lib/libast/disc/sfdchdr.h b/src/lib/libast/disc/sfdchdr.h
new file mode 100644
index 0000000..7e5bbca
--- /dev/null
+++ b/src/lib/libast/disc/sfdchdr.h
@@ -0,0 +1,28 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * common header for discipline functions
+ */
+
+#include "sfhdr.h"
+
+#include <sfdisc.h>
diff --git a/src/lib/libast/disc/sfdcmore.c b/src/lib/libast/disc/sfdcmore.c
new file mode 100644
index 0000000..900b55d
--- /dev/null
+++ b/src/lib/libast/disc/sfdcmore.c
@@ -0,0 +1,369 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfdchdr.h"
+
+#if _PACKAGE_ast
+#include <ast_tty.h>
+#include <signal.h>
+#endif
+
+/*
+ * a simple but fast more style pager discipline
+ * if on sfstdout then sfstdin ops reset the page state
+ *
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * @(#)$Id: sfdcmore (AT&T Research) 1998-06-25 $
+ */
+
+typedef struct
+{
+ Sfdisc_t disc; /* sfio discipline */
+ Sfio_t* input; /* tied with this input stream */
+ Sfio_t* error; /* tied with this error stream */
+ int rows; /* max rows */
+ int cols; /* max cols */
+ int row; /* current row */
+ int col; /* current col */
+ int match; /* match length, 0 if none */
+ char pattern[128]; /* match pattern */
+ char prompt[1]; /* prompt string */
+} More_t;
+
+/*
+ * more read
+ * we assume line-at-a-time input
+ */
+
+#if __STD_C
+static ssize_t moreread(Sfio_t* f, void* buf, size_t n, Sfdisc_t* dp)
+#else
+static ssize_t moreread(f, buf, n, dp)
+Sfio_t* f;
+void* buf;
+size_t n;
+Sfdisc_t* dp;
+#endif
+{
+ register More_t* more = (More_t*)dp;
+
+ more->match = 0;
+ more->row = 2;
+ more->col = 1;
+ return sfrd(f, buf, n, dp);
+}
+
+/*
+ * output label on wfd and return next char on rfd with no echo
+ * return < -1 is -(signal + 1)
+ */
+
+#if __STD_C
+static int ttyquery(Sfio_t* rp, Sfio_t* wp, const char* label, Sfdisc_t* dp)
+#else
+static int ttyquery(rp, wp, label, dp)
+Sfio_t* rp;
+Sfio_t* wp;
+char* label;
+Sfdisc_t* dp;
+#endif
+{
+ register int r;
+ int n;
+
+#ifdef TCSADRAIN
+ unsigned char c;
+ struct termios old;
+ struct termios tty;
+ int rfd = sffileno(rp);
+ int wfd = sffileno(rp);
+
+ if (!label)
+ n = 0;
+ else if (n = strlen(label))
+ write(wfd, label, n);
+ tcgetattr(rfd, &old);
+ tty = old;
+ tty.c_cc[VTIME] = 0;
+ tty.c_cc[VMIN] = 1;
+ tty.c_lflag &= ~(ICANON|ECHO|ECHOK|ISIG);
+ tcsetattr(rfd, TCSADRAIN, &tty);
+ if ((r = read(rfd, &c, 1)) == 1)
+ {
+ if (c == old.c_cc[VEOF])
+ r = -1;
+ else if (c == old.c_cc[VINTR])
+ r = -(SIGINT + 1);
+ else if (c == old.c_cc[VQUIT])
+ r = -(SIGQUIT + 1);
+ else if (c == '\r')
+ r = '\n';
+ else
+ r = c;
+ }
+ tcsetattr(rfd, TCSADRAIN, &old);
+ if (n)
+ {
+ write(wfd, "\r", 1);
+ while (n-- > 0)
+ write(wfd, " ", 1);
+ write(wfd, "\r", 1);
+ }
+#else
+ register char* s;
+
+ if (label && (n = strlen(label)))
+ sfwr(wp, label, n, dp);
+ r = (s = sfgetr(rp, '\n', 0)) ? *s : -1;
+#endif
+ return r;
+}
+
+/*
+ * more write
+ */
+
+#if __STD_C
+static ssize_t morewrite(Sfio_t* f, const Void_t* buf, register size_t n, Sfdisc_t* dp)
+#else
+static ssize_t morewrite(f, buf, n, dp)
+Sfio_t* f;
+Void_t* buf;
+register size_t n;
+Sfdisc_t* dp;
+#endif
+{
+ register More_t* more = (More_t*)dp;
+ register char* b;
+ register char* s;
+ register char* e;
+ register ssize_t w;
+ register int r;
+
+ if (!more->row)
+ return n;
+ if (!more->col)
+ return sfwr(f, buf, n, dp);
+ w = 0;
+ b = (char*)buf;
+ s = b;
+ e = s + n;
+ if (more->match)
+ {
+ match:
+ for (r = more->pattern[0];; s++)
+ {
+ if (s >= e)
+ return n;
+ if (*s == '\n')
+ b = s + 1;
+ else if (*s == r && (e - s) >= more->match && !strncmp(s, more->pattern, more->match))
+ break;
+ }
+ s = b;
+ w += b - (char*)buf;
+ more->match = 0;
+ }
+ while (s < e)
+ {
+ switch (*s++)
+ {
+ case '\t':
+ more->col = ((more->col + 8) & ~7) - 1;
+ /*FALLTHROUGH*/
+ default:
+ if (++more->col <= more->cols || s < e && *s == '\n')
+ continue;
+ /*FALLTHROUGH*/
+ case '\n':
+ more->col = 1;
+ if (++more->row < more->rows)
+ continue;
+ break;
+ case '\b':
+ if (more->col > 1)
+ more->col--;
+ continue;
+ case '\r':
+ more->col = 1;
+ continue;
+ }
+ w += sfwr(f, b, s - b, dp);
+ b = s;
+ r = ttyquery(sfstdin, f, more->prompt, dp);
+ if (r == '/' || r == 'n')
+ {
+ if (r == '/')
+ {
+ sfwr(f, "/", 1, dp);
+ if ((s = sfgetr(sfstdin, '\n', 1)) && (n = sfvalue(sfstdin) - 1) > 0)
+ {
+ if (n >= sizeof(more->pattern))
+ n = sizeof(more->pattern) - 1;
+ memcpy(more->pattern, s, n);
+ more->pattern[n] = 0;
+ }
+ }
+ if (more->match = strlen(more->pattern))
+ {
+ more->row = 1;
+ more->col = 1;
+ goto match;
+ }
+ }
+ switch (r)
+ {
+ case '\n':
+ case '\r':
+ more->row--;
+ more->col = 1;
+ break;
+ case ' ':
+ more->row = 2;
+ more->col = 1;
+ break;
+ default:
+ more->row = 0;
+ return n;
+ }
+ }
+ if (s > b)
+ w += sfwr(f, b, s - b, dp);
+ return w;
+}
+
+/*
+ * remove the discipline on close
+ */
+
+#if __STD_C
+static int moreexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* dp)
+#else
+static int moreexcept(f, type, data, dp)
+Sfio_t* f;
+int type;
+Void_t* data;
+Sfdisc_t* dp;
+#endif
+{
+ register More_t* more = (More_t*)dp;
+
+ if (type == SF_FINAL || type == SF_DPOP)
+ {
+ if (f = more->input)
+ {
+ more->input = 0;
+ sfdisc(f, SF_POPDISC);
+ }
+ else if (f = more->error)
+ {
+ more->error = 0;
+ sfdisc(f, SF_POPDISC);
+ }
+ else
+ free(dp);
+ }
+ else if (type == SF_SYNC)
+ {
+ more->match = 0;
+ more->row = 1;
+ more->col = 1;
+ }
+ return 0;
+}
+
+/*
+ * push the more discipline on f
+ * if prompt==0 then a default ansi prompt is used
+ * if rows==0 or cols==0 then they are deterimined from the tty
+ * if f==sfstdout then input on sfstdin also resets the state
+ */
+
+#if __STD_C
+int sfdcmore(Sfio_t* f, const char* prompt, int rows, int cols)
+#else
+int sfdcmore(f, prompt, rows, cols)
+Sfio_t* f;
+char* prompt;
+int rows;
+int cols;
+#endif
+{
+ register More_t* more;
+ size_t n;
+
+ /*
+ * this is a writeonly discipline for interactive io
+ */
+
+ if (!(sfset(f, 0, 0) & SF_WRITE) || !isatty(sffileno(sfstdin)) || !isatty(sffileno(sfstdout)))
+ return -1;
+ if (!prompt)
+ prompt = "\033[7m More\033[m";
+ n = strlen(prompt) + 1;
+ if (!(more = (More_t*)malloc(sizeof(More_t) + n)))
+ return -1;
+ memset(more, 0, sizeof(*more));
+
+ more->disc.readf = moreread;
+ more->disc.writef = morewrite;
+ more->disc.exceptf = moreexcept;
+ memcpy(more->prompt, prompt, n);
+ if (!rows || !cols)
+ {
+#if _PACKAGE_ast
+ astwinsize(sffileno(sfstdin), &rows, &cols);
+#endif
+ if (!rows)
+ rows = 24;
+ if (!cols)
+ cols = 80;
+ }
+ more->rows = rows;
+ more->cols = cols;
+ more->row = 1;
+ more->col = 1;
+
+ if (sfdisc(f, &more->disc) != &more->disc)
+ {
+ free(more);
+ return -1;
+ }
+ if (f == sfstdout)
+ {
+ if (sfdisc(sfstdin, &more->disc) != &more->disc)
+ {
+ sfdisc(f, SF_POPDISC);
+ return -1;
+ }
+ more->input = sfstdin;
+ if (sfdisc(sfstderr, &more->disc) != &more->disc)
+ {
+ sfdisc(f, SF_POPDISC);
+ return -1;
+ }
+ more->error = sfstdin;
+ }
+
+ return 0;
+}
diff --git a/src/lib/libast/disc/sfdcprefix.c b/src/lib/libast/disc/sfdcprefix.c
new file mode 100644
index 0000000..29f3fd4
--- /dev/null
+++ b/src/lib/libast/disc/sfdcprefix.c
@@ -0,0 +1,153 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfdchdr.h"
+
+/*
+ * a discipline that prepends a prefix string to each output line
+ *
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * @(#)$Id: sfdcprefix (AT&T Research) 1998-06-25 $
+ */
+
+typedef struct
+{
+ Sfdisc_t disc; /* sfio discipline */
+ size_t length; /* prefix length */
+ size_t empty; /* empty line prefix length */
+ int skip; /* this line already prefixed */
+ char prefix[1]; /* prefix string */
+} Prefix_t;
+
+/*
+ * prefix write
+ */
+
+#if __STD_C
+static ssize_t pfxwrite(Sfio_t* f, const Void_t* buf, register size_t n, Sfdisc_t* dp)
+#else
+static ssize_t pfxwrite(f, buf, n, dp)
+Sfio_t* f;
+Void_t* buf;
+register size_t n;
+Sfdisc_t* dp;
+#endif
+{
+ register Prefix_t* pfx = (Prefix_t*)dp;
+ register char* b;
+ register char* s;
+ register char* e;
+ register char* t;
+ register ssize_t w;
+ int skip;
+
+ skip = 0;
+ w = 0;
+ b = (char*)buf;
+ s = b;
+ e = s + n;
+ do
+ {
+ if (!(t = memchr(s, '\n', e - s)))
+ {
+ skip = 1;
+ t = e - 1;
+ }
+ n = t - s + 1;
+ if (pfx->skip)
+ pfx->skip = 0;
+ else
+ sfwr(f, pfx->prefix, n > 1 ? pfx->length : pfx->empty, dp);
+ w += sfwr(f, s, n, dp);
+ if ((s = t + 1) >= e)
+ return w;
+ } while ((s = t + 1) < e);
+ pfx->skip = skip;
+ return w;
+
+}
+
+/*
+ * remove the discipline on close
+ */
+
+#if __STD_C
+static int pfxexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* dp)
+#else
+static int pfxexcept(f, type, data, dp)
+Sfio_t* f;
+int type;
+Void_t* data;
+Sfdisc_t* dp;
+#endif
+{
+ if (type == SF_FINAL || type == SF_DPOP)
+ free(dp);
+ return 0;
+}
+
+/*
+ * push the prefix discipline on f
+ */
+
+#if __STD_C
+int sfdcprefix(Sfio_t* f, const char* prefix)
+#else
+int sfdcprefix(f, prefix)
+Sfio_t* f;
+char* prefix;
+#endif
+{
+ register Prefix_t* pfx;
+ register char* s;
+ size_t n;
+
+ /*
+ * this is a writeonly discipline
+ */
+
+ if (!prefix || !(n = strlen(prefix)) || !(sfset(f, 0, 0) & SF_WRITE))
+ return -1;
+ if (!(pfx = (Prefix_t*)malloc(sizeof(Prefix_t) + n)))
+ return -1;
+ memset(pfx, 0, sizeof(*pfx));
+
+ pfx->disc.writef = pfxwrite;
+ pfx->disc.exceptf = pfxexcept;
+ pfx->length = n;
+ memcpy(pfx->prefix, prefix, n);
+ s = (char*)prefix + n;
+ while (--s > (char*)prefix && (*s == ' ' || *s == '\t'));
+ n = s - (char*)prefix;
+ if (*s != ' ' || *s != '\t')
+ n++;
+ pfx->empty = n;
+
+ if (sfdisc(f, &pfx->disc) != &pfx->disc)
+ {
+ free(pfx);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/lib/libast/disc/sfdcseekable.c b/src/lib/libast/disc/sfdcseekable.c
new file mode 100644
index 0000000..23c5b93
--- /dev/null
+++ b/src/lib/libast/disc/sfdcseekable.c
@@ -0,0 +1,227 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfdchdr.h"
+
+/* Discipline to make an unseekable read stream seekable
+**
+** sfraise(f,SFSK_DISCARD,0) discards previous seek data
+** but seeks from current offset on still allowed
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998.
+*/
+
+typedef struct _skable_s
+{ Sfdisc_t disc; /* sfio discipline */
+ Sfio_t* shadow; /* to shadow data */
+ Sfoff_t discard;/* sfseek(f,-1,SEEK_SET) discarded data */
+ Sfoff_t extent; /* shadow extent */
+ int eof; /* if eof has been reached */
+} Seek_t;
+
+#if __STD_C
+static ssize_t skwrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc)
+#else
+static ssize_t skwrite(f, buf, n, disc)
+Sfio_t* f; /* stream involved */
+Void_t* buf; /* buffer to read into */
+size_t n; /* number of bytes to read */
+Sfdisc_t* disc; /* discipline */
+#endif
+{
+ return (ssize_t)(-1);
+}
+
+#if __STD_C
+static ssize_t skread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc)
+#else
+static ssize_t skread(f, buf, n, disc)
+Sfio_t* f; /* stream involved */
+Void_t* buf; /* buffer to read into */
+size_t n; /* number of bytes to read */
+Sfdisc_t* disc; /* discipline */
+#endif
+{
+ Seek_t* sk;
+ Sfio_t* sf;
+ Sfoff_t addr;
+ ssize_t r, w, p;
+
+ sk = (Seek_t*)disc;
+ sf = sk->shadow;
+ if(sk->eof)
+ return sfread(sf,buf,n);
+
+ addr = sfseek(sf,(Sfoff_t)0,SEEK_CUR);
+
+ if(addr+n <= sk->extent)
+ return sfread(sf,buf,n);
+
+ if((r = (ssize_t)(sk->extent-addr)) > 0)
+ { if((w = sfread(sf,buf,r)) != r)
+ return w;
+ buf = (char*)buf + r;
+ n -= r;
+ }
+
+ /* do a raw read */
+ if((w = sfrd(f,buf,n,disc)) <= 0)
+ { sk->eof = 1;
+ w = 0;
+ }
+ else
+ {
+ if((p = sfwrite(sf,buf,w)) != w)
+ sk->eof = 1;
+ if(p > 0)
+ sk->extent += p;
+ }
+
+ return r+w;
+}
+
+#if __STD_C
+static Sfoff_t skseek(Sfio_t* f, Sfoff_t addr, int type, Sfdisc_t* disc)
+#else
+static Sfoff_t skseek(f, addr, type, disc)
+Sfio_t* f;
+Sfoff_t addr;
+int type;
+Sfdisc_t* disc;
+#endif
+{
+ Seek_t* sk;
+ Sfio_t* sf;
+ char buf[SF_BUFSIZE];
+ ssize_t r, w;
+
+ sk = (Seek_t*)disc;
+ sf = sk->shadow;
+
+ switch (type)
+ {
+ case SEEK_SET:
+ addr -= sk->discard;
+ break;
+ case SEEK_CUR:
+ addr += sftell(sf);
+ break;
+ case SEEK_END:
+ addr += sk->extent;
+ break;
+ default:
+ return -1;
+ }
+
+ if(addr < 0)
+ return (Sfoff_t)(-1);
+ else if(addr > sk->extent)
+ { if(sk->eof)
+ return (Sfoff_t)(-1);
+
+ /* read enough to reach the seek point */
+ while(addr > sk->extent)
+ { if(addr > sk->extent+sizeof(buf) )
+ w = sizeof(buf);
+ else w = (int)(addr-sk->extent);
+ if((r = sfrd(f,buf,w,disc)) <= 0)
+ w = r-1;
+ else if((w = sfwrite(sf,buf,r)) > 0)
+ sk->extent += w;
+ if(w != r)
+ { sk->eof = 1;
+ break;
+ }
+ }
+
+ if(addr > sk->extent)
+ return (Sfoff_t)(-1);
+ }
+
+ return sfseek(sf,addr,SEEK_SET) + sk->discard;
+}
+
+/* on close, remove the discipline */
+#if __STD_C
+static int skexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc)
+#else
+static int skexcept(f,type,data,disc)
+Sfio_t* f;
+int type;
+Void_t* data;
+Sfdisc_t* disc;
+#endif
+{
+ Seek_t* sk;
+
+ sk = (Seek_t*)disc;
+
+ switch (type)
+ {
+ case SF_FINAL:
+ case SF_DPOP:
+ sfclose(sk->shadow);
+ free(disc);
+ break;
+ case SFSK_DISCARD:
+ sk->eof = 0;
+ sk->discard += sk->extent;
+ sk->extent = 0;
+ sfseek(sk->shadow,(Sfoff_t)0,SEEK_SET);
+ break;
+ }
+ return 0;
+}
+
+#if __STD_C
+int sfdcseekable(Sfio_t* f)
+#else
+int sfdcseekable(f)
+Sfio_t* f;
+#endif
+{
+ reg Seek_t* sk;
+
+ /* see if already seekable */
+ if(sfseek(f,(Sfoff_t)0,SEEK_CUR) >= 0)
+ return 0;
+
+ if(!(sk = (Seek_t*)malloc(sizeof(Seek_t))) )
+ return -1;
+ memset(sk, 0, sizeof(*sk));
+
+ sk->disc.readf = skread;
+ sk->disc.writef = skwrite;
+ sk->disc.seekf = skseek;
+ sk->disc.exceptf = skexcept;
+ sk->shadow = sftmp(SF_BUFSIZE);
+ sk->discard = 0;
+ sk->extent = 0;
+ sk->eof = 0;
+
+ if(sfdisc(f, (Sfdisc_t*)sk) != (Sfdisc_t*)sk)
+ { sfclose(sk->shadow);
+ free(sk);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/lib/libast/disc/sfdcslow.c b/src/lib/libast/disc/sfdcslow.c
new file mode 100644
index 0000000..e75f438
--- /dev/null
+++ b/src/lib/libast/disc/sfdcslow.c
@@ -0,0 +1,84 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfdchdr.h"
+
+/* Make a stream op return immediately on interrupts.
+** This is useful on slow streams (hence the name).
+**
+** Written by Glenn Fowler (03/18/1998).
+*/
+
+#if __STD_C
+static int slowexcept(Sfio_t* f, int type, Void_t* v, Sfdisc_t* disc)
+#else
+static int slowexcept(f, type, v, disc)
+Sfio_t* f;
+int type;
+Void_t* v;
+Sfdisc_t* disc;
+#endif
+{
+ NOTUSED(f);
+ NOTUSED(v);
+ NOTUSED(disc);
+
+ switch (type)
+ {
+ case SF_FINAL:
+ case SF_DPOP:
+ free(disc);
+ break;
+ case SF_READ:
+ case SF_WRITE:
+ if (errno == EINTR)
+ return(-1);
+ break;
+ }
+
+ return(0);
+}
+
+#if __STD_C
+int sfdcslow(Sfio_t* f)
+#else
+int sfdcslow(f)
+Sfio_t* f;
+#endif
+{
+ Sfdisc_t* disc;
+
+ if(!(disc = (Sfdisc_t*)malloc(sizeof(Sfdisc_t))) )
+ return(-1);
+
+ disc->readf = NIL(Sfread_f);
+ disc->writef = NIL(Sfwrite_f);
+ disc->seekf = NIL(Sfseek_f);
+ disc->exceptf = slowexcept;
+
+ if(sfdisc(f,disc) != disc)
+ { free(disc);
+ return(-1);
+ }
+ sfset(f,SF_IOINTR,1);
+
+ return(0);
+}
diff --git a/src/lib/libast/disc/sfdcsubstr.c b/src/lib/libast/disc/sfdcsubstr.c
new file mode 100644
index 0000000..c0fae9b
--- /dev/null
+++ b/src/lib/libast/disc/sfdcsubstr.c
@@ -0,0 +1,217 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfdchdr.h"
+
+
+/* Discipline to treat a contiguous segment of a stream as a stream
+** in its own right. The hard part in all this is to allow multiple
+** segments of the stream to be used as substreams at the same time.
+**
+** Written by David G. Korn and Kiem-Phong Vo (03/18/1998)
+*/
+
+typedef struct _subfile_s
+{
+ Sfdisc_t disc; /* sfio discipline */
+ Sfio_t* parent; /* parent stream */
+ Sfoff_t offset; /* starting offset */
+ Sfoff_t extent; /* size wanted */
+ Sfoff_t here; /* current seek location */
+} Subfile_t;
+
+#if __STD_C
+static ssize_t streamio(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc, int type)
+#else
+static ssize_t streamio(f, buf, n, disc, type)
+Sfio_t* f;
+Void_t* buf;
+size_t n;
+Sfdisc_t* disc;
+int type;
+#endif
+{
+ reg Subfile_t *su;
+ reg Sfoff_t here, parent;
+ reg ssize_t io;
+
+ su = (Subfile_t*)disc;
+
+ /* read just what we need */
+ if(su->extent >= 0 && (ssize_t)n > (io = (ssize_t)(su->extent - su->here)) )
+ n = io;
+ if(n <= 0)
+ return n;
+
+ /* save current location in parent stream */
+ parent = sfsk(f,(Sfoff_t)0,SEEK_CUR,disc);
+
+ /* read data */
+ here = su->here + su->offset;
+ if(sfsk(f,here,SEEK_SET,disc) != here)
+ io = 0;
+ else
+ { if(type == SF_WRITE)
+ io = sfwr(f,buf,n,disc);
+ else io = sfrd(f,buf,n,disc);
+ if(io > 0)
+ su->here += io;
+ }
+
+ /* restore parent current position */
+ sfsk(f,parent,SEEK_SET,disc);
+
+ return io;
+}
+
+#if __STD_C
+static ssize_t streamwrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc)
+#else
+static ssize_t streamwrite(f, buf, n, disc)
+Sfio_t* f;
+Void_t* buf;
+size_t n;
+Sfdisc_t* disc;
+#endif
+{
+ return streamio(f,(Void_t*)buf,n,disc,SF_WRITE);
+}
+
+#if __STD_C
+static ssize_t streamread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc)
+#else
+static ssize_t streamread(f, buf, n, disc)
+Sfio_t* f;
+Void_t* buf;
+size_t n;
+Sfdisc_t* disc;
+#endif
+{
+ return streamio(f,buf,n,disc,SF_READ);
+}
+
+#if __STD_C
+static Sfoff_t streamseek(Sfio_t* f, Sfoff_t pos, int type, Sfdisc_t* disc)
+#else
+static Sfoff_t streamseek(f, pos, type, disc)
+Sfio_t* f;
+Sfoff_t pos;
+int type;
+Sfdisc_t* disc;
+#endif
+{
+ reg Subfile_t* su;
+ reg Sfoff_t here, parent;
+
+ su = (Subfile_t*)disc;
+
+ switch(type)
+ {
+ case SEEK_SET:
+ here = 0;
+ break;
+ case SEEK_CUR:
+ here = su->here;
+ break;
+ case SEEK_END:
+ if(su->extent >= 0)
+ here = su->extent;
+ else
+ { parent = sfsk(f,(Sfoff_t)0,SEEK_CUR,disc);
+ if((here = sfsk(f,(Sfoff_t)0,SEEK_END,disc)) < 0)
+ return -1;
+ else here -= su->offset;
+ sfsk(f,parent,SEEK_SET,disc);
+ }
+ break;
+ default:
+ return -1;
+ }
+
+ pos += here;
+ if(pos < 0 || (su->extent >= 0 && pos >= su->extent))
+ return -1;
+
+ return (su->here = pos);
+}
+
+#if __STD_C
+static int streamexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc)
+#else
+static int streamexcept(f, type, data, disc)
+Sfio_t* f;
+int type;
+Void_t* data;
+Sfdisc_t* disc;
+#endif
+{
+ if(type == SF_FINAL || type == SF_DPOP)
+ free(disc);
+ return 0;
+}
+
+#if __STD_C
+Sfio_t* sfdcsubstream(Sfio_t* f, Sfio_t* parent, Sfoff_t offset, Sfoff_t extent)
+#else
+Sfio_t* sfdcsubstream(f, parent, offset, extent)
+Sfio_t* f; /* stream */
+Sfio_t* parent; /* parent stream */
+Sfoff_t offset; /* offset in f */
+Sfoff_t extent; /* desired size */
+#endif
+{
+ reg Sfio_t* sp;
+ reg Subfile_t* su;
+ reg Sfoff_t here;
+
+ /* establish that we can seek to offset */
+ if((here = sfseek(parent,(Sfoff_t)0,SEEK_CUR)) < 0 || sfseek(parent,offset,SEEK_SET) < 0)
+ return 0;
+ else sfseek(parent,here,SEEK_SET);
+ sfpurge(parent);
+
+ if (!(sp = f) && !(sp = sfnew(NIL(Sfio_t*), NIL(Void_t*), (size_t)SF_UNBOUND, dup(sffileno(parent)), parent->flags)))
+ return 0;
+
+ if(!(su = (Subfile_t*)malloc(sizeof(Subfile_t))))
+ { if(sp != f)
+ sfclose(sp);
+ return 0;
+ }
+ memset(su, 0, sizeof(*su));
+
+ su->disc.readf = streamread;
+ su->disc.writef = streamwrite;
+ su->disc.seekf = streamseek;
+ su->disc.exceptf = streamexcept;
+ su->parent = parent;
+ su->offset = offset;
+ su->extent = extent;
+
+ if(sfdisc(sp, (Sfdisc_t*)su) != (Sfdisc_t*)su)
+ { free(su);
+ if(sp != f)
+ sfclose(sp);
+ return 0;
+ }
+
+ return sp;
+}
diff --git a/src/lib/libast/disc/sfdctee.c b/src/lib/libast/disc/sfdctee.c
new file mode 100644
index 0000000..66bf71e
--- /dev/null
+++ b/src/lib/libast/disc/sfdctee.c
@@ -0,0 +1,102 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfdchdr.h"
+
+/* A discipline to tee the output to a stream to another stream.
+** This is similar to what the "tee" program does. As implemented
+** this discipline only works with file streams.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998.
+*/
+
+/* the discipline structure for tee-ing */
+typedef struct _tee_s
+{ Sfdisc_t disc; /* the sfio discipline structure */
+ Sfio_t* tee; /* the stream to tee to */
+ int status; /* if tee stream is still ok */
+} Tee_t;
+
+/* write to the teed stream. */
+#if __STD_C
+static ssize_t teewrite(Sfio_t* f, const Void_t* buf, size_t size, Sfdisc_t* disc)
+#else
+static ssize_t teewrite(f,buf,size,disc)
+Sfio_t* f; /* the stream being written to */
+Void_t* buf; /* the buffer of data being output */
+size_t size; /* the data size */
+Sfdisc_t* disc; /* the tee discipline */
+#endif
+{
+ reg Tee_t* te = (Tee_t*)disc;
+
+ /* tee data if still ok */
+ if(te->status == 0 && sfwrite(te->tee,buf,size) != (ssize_t)size)
+ te->status = -1;
+
+ /* do the actual write */
+ return sfwr(f,buf,size,disc);
+}
+
+/* on close, remove the discipline */
+#if __STD_C
+static int teeexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc)
+#else
+static int teeexcept(f,type,data,disc)
+Sfio_t* f;
+int type;
+Void_t* data;
+Sfdisc_t* disc;
+#endif
+{
+ if(type == SF_FINAL || type == SF_DPOP)
+ free(disc);
+
+ return 0;
+}
+
+#if __STD_C
+int sfdctee(Sfio_t* f, Sfio_t* tee)
+#else
+int sfdctee(f, tee)
+Sfio_t* f; /* stream to tee from */
+Sfio_t* tee; /* stream to tee to */
+#endif
+{
+ reg Tee_t* te;
+
+ if(!(te = (Tee_t*)malloc(sizeof(Tee_t))) )
+ return -1;
+
+ te->disc.readf = NIL(Sfread_f);
+ te->disc.seekf = NIL(Sfseek_f);
+ te->disc.writef = teewrite;
+ te->disc.exceptf = teeexcept;
+ te->tee = tee;
+ te->status = 0;
+
+ if(sfdisc(f,(Sfdisc_t*)te) != (Sfdisc_t*)te)
+ { free(te);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/lib/libast/disc/sfdcunion.c b/src/lib/libast/disc/sfdcunion.c
new file mode 100644
index 0000000..1f45909
--- /dev/null
+++ b/src/lib/libast/disc/sfdcunion.c
@@ -0,0 +1,203 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfdchdr.h"
+
+
+/* Make a sequence of streams act like a single stream.
+** This is for reading only.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 03/18/1998.
+*/
+
+#define UNSEEKABLE 1
+
+typedef struct _file_s
+{ Sfio_t* f; /* the stream */
+ Sfoff_t lower; /* its lowest end */
+} File_t;
+
+typedef struct _union_s
+{
+ Sfdisc_t disc; /* discipline structure */
+ short type; /* type of streams */
+ short c; /* current stream */
+ short n; /* number of streams */
+ Sfoff_t here; /* current location */
+ File_t f[1]; /* array of streams */
+} Union_t;
+
+#if __STD_C
+static ssize_t unwrite(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc)
+#else
+static ssize_t unwrite(f, buf, n, disc)
+Sfio_t* f; /* stream involved */
+Void_t* buf; /* buffer to read into */
+size_t n; /* number of bytes to read */
+Sfdisc_t* disc; /* discipline */
+#endif
+{
+ return -1;
+}
+
+#if __STD_C
+static ssize_t unread(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc)
+#else
+static ssize_t unread(f, buf, n, disc)
+Sfio_t* f; /* stream involved */
+Void_t* buf; /* buffer to read into */
+size_t n; /* number of bytes to read */
+Sfdisc_t* disc; /* discipline */
+#endif
+{
+ reg Union_t* un;
+ reg ssize_t r, m;
+
+ un = (Union_t*)disc;
+ m = n;
+ f = un->f[un->c].f;
+ while(1)
+ { if((r = sfread(f,buf,m)) < 0 || (r == 0 && un->c == un->n-1) )
+ break;
+
+ m -= r;
+ un->here += r;
+
+ if(m == 0)
+ break;
+
+ buf = (char*)buf + r;
+ if(sfeof(f) && un->c < un->n-1)
+ f = un->f[un->c += 1].f;
+ }
+ return n-m;
+}
+
+#if __STD_C
+static Sfoff_t unseek(Sfio_t* f, Sfoff_t addr, int type, Sfdisc_t* disc)
+#else
+static Sfoff_t unseek(f, addr, type, disc)
+Sfio_t* f;
+Sfoff_t addr;
+int type;
+Sfdisc_t* disc;
+#endif
+{
+ reg Union_t* un;
+ reg int i;
+ reg Sfoff_t extent, s;
+
+ un = (Union_t*)disc;
+ if(un->type&UNSEEKABLE)
+ return -1L;
+
+ if(type == 2)
+ { extent = 0;
+ for(i = 0; i < un->n; ++i)
+ extent += (sfsize(un->f[i].f) - un->f[i].lower);
+ addr += extent;
+ }
+ else if(type == 1)
+ addr += un->here;
+
+ if(addr < 0)
+ return -1;
+
+ /* find the stream where the addr could be in */
+ extent = 0;
+ for(i = 0; i < un->n-1; ++i)
+ { s = sfsize(un->f[i].f) - un->f[i].lower;
+ if(addr < extent + s)
+ break;
+ extent += s;
+ }
+
+ s = (addr-extent) + un->f[i].lower;
+ if(sfseek(un->f[i].f,s,0) != s)
+ return -1;
+
+ un->c = i;
+ un->here = addr;
+
+ for(i += 1; i < un->n; ++i)
+ sfseek(un->f[i].f,un->f[i].lower,0);
+
+ return addr;
+}
+
+/* on close, remove the discipline */
+#if __STD_C
+static int unexcept(Sfio_t* f, int type, Void_t* data, Sfdisc_t* disc)
+#else
+static int unexcept(f,type,data,disc)
+Sfio_t* f;
+int type;
+Void_t* data;
+Sfdisc_t* disc;
+#endif
+{
+ if(type == SF_FINAL || type == SF_DPOP)
+ free(disc);
+
+ return 0;
+}
+
+#if __STD_C
+int sfdcunion(Sfio_t* f, Sfio_t** array, int n)
+#else
+int sfdcunion(f, array, n)
+Sfio_t* f;
+Sfio_t** array;
+int n;
+#endif
+{
+ reg Union_t* un;
+ reg int i;
+
+ if(n <= 0)
+ return -1;
+
+ if(!(un = (Union_t*)malloc(sizeof(Union_t)+(n-1)*sizeof(File_t))) )
+ return -1;
+ memset(un, 0, sizeof(*un));
+
+ un->disc.readf = unread;
+ un->disc.writef = unwrite;
+ un->disc.seekf = unseek;
+ un->disc.exceptf = unexcept;
+ un->n = n;
+
+ for(i = 0; i < n; ++i)
+ { un->f[i].f = array[i];
+ if(!(un->type&UNSEEKABLE))
+ { un->f[i].lower = sfseek(array[i],(Sfoff_t)0,1);
+ if(un->f[i].lower < 0)
+ un->type |= UNSEEKABLE;
+ }
+ }
+
+ if(sfdisc(f,(Sfdisc_t*)un) != (Sfdisc_t*)un)
+ { free(un);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/src/lib/libast/disc/sfkeyprintf.c b/src/lib/libast/disc/sfkeyprintf.c
new file mode 100644
index 0000000..c63fe37
--- /dev/null
+++ b/src/lib/libast/disc/sfkeyprintf.c
@@ -0,0 +1,392 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * keyword printf support
+ */
+
+#define _AST_API_H 1
+
+#include <ast.h>
+#include <ccode.h>
+#include <ctype.h>
+#include <sfdisc.h>
+#include <regex.h>
+
+#define FMT_case 1
+#define FMT_edit 2
+
+typedef struct
+{
+ Sffmt_t fmt;
+ void* handle;
+ Sf_key_lookup_t lookup;
+ Sf_key_convert_t convert;
+ Sfio_t* tmp[2];
+ regex_t red[2];
+ regex_t* re[2];
+ int invisible;
+ int level;
+ int version;
+} Fmt_t;
+
+typedef struct
+{
+ char* next;
+ int delimiter;
+ int first;
+} Field_t;
+
+typedef union
+{
+ char** p;
+ char* s;
+ Sflong_t q;
+ long l;
+ int i;
+ short h;
+ char c;
+} Value_t;
+
+#define initfield(f,s) ((f)->first = (f)->delimiter = *((f)->next = (s)))
+
+static char*
+getfield(register Field_t* f, int restore)
+{
+ register char* s;
+ register int n;
+ register int c;
+ register int lp;
+ register int rp;
+ char* b;
+
+ if (!f->delimiter)
+ return 0;
+ s = f->next;
+ if (f->first)
+ f->first = 0;
+ else if (restore)
+ *s = f->delimiter;
+ b = ++s;
+ lp = rp = n = 0;
+ for (;;)
+ {
+ if (!(c = *s++))
+ {
+ f->delimiter = 0;
+ break;
+ }
+ else if (c == CC_esc || c == '\\')
+ {
+ if (*s)
+ s++;
+ }
+ else if (c == lp)
+ n++;
+ else if (c == rp)
+ n--;
+ else if (n <= 0)
+ {
+ if (c == '(' && restore)
+ {
+ lp = '(';
+ rp = ')';
+ n = 1;
+ }
+ else if (c == '[' && restore)
+ {
+ lp = '[';
+ rp = ']';
+ n = 1;
+ }
+ else if (c == f->delimiter)
+ {
+ *(f->next = --s) = 0;
+ break;
+ }
+ }
+ }
+ return b;
+}
+
+/*
+ * sfio %! extension function
+ */
+
+static int
+getfmt(Sfio_t* sp, void* vp, Sffmt_t* dp)
+{
+ register Fmt_t* fp = (Fmt_t*)dp;
+ Value_t* value = (Value_t*)vp;
+ register char* v;
+ char* t;
+ char* b;
+ char* a = 0;
+ char* s = 0;
+ Sflong_t n = 0;
+ int h = 0;
+ int i = 0;
+ int x = 0;
+ int d;
+ Field_t f;
+ regmatch_t match[10];
+
+ fp->level++;
+ if (fp->fmt.t_str && fp->fmt.n_str > 0 && (v = fmtbuf(fp->fmt.n_str + 1)))
+ {
+ memcpy(v, fp->fmt.t_str, fp->fmt.n_str);
+ v[fp->fmt.n_str] = 0;
+ b = v;
+ for (;;)
+ {
+ switch (*v++)
+ {
+ case 0:
+ break;
+ case '(':
+ h++;
+ continue;
+ case ')':
+ h--;
+ continue;
+ case '=':
+ case ':':
+ case ',':
+ if (h <= 0)
+ {
+ a = v;
+ break;
+ }
+ continue;
+ default:
+ continue;
+ }
+ if (i = *--v)
+ {
+ *v = 0;
+ if (i == ':' && fp->fmt.fmt == 's' && strlen(a) > 4 && !isalnum(*(a + 4)))
+ {
+ d = *(a + 4);
+ *(a + 4) = 0;
+ if (streq(a, "case"))
+ x = FMT_case;
+ else if (streq(a, "edit"))
+ x = FMT_edit;
+ *(a + 4) = d;
+ if (x)
+ a = 0;
+ }
+ }
+ break;
+ }
+ n = i;
+ t = fp->fmt.t_str;
+ fp->fmt.t_str = b;
+ h = (*fp->lookup)(fp->handle, &fp->fmt, a, &s, &n);
+ fp->fmt.t_str = t;
+ if (i)
+ *v++ = i;
+ }
+ else
+ {
+ h = (*fp->lookup)(fp->handle, &fp->fmt, a, &s, &n);
+ v = 0;
+ }
+ fp->fmt.flags |= SFFMT_VALUE;
+ switch (fp->fmt.fmt)
+ {
+ case 'c':
+ value->c = s ? *s : n;
+ break;
+ case 'd':
+ case 'i':
+ fp->fmt.size = sizeof(Sflong_t);
+ value->q = (Sflong_t)(s ? strtoll(s, NiL, 0) : n);
+ break;
+ case 'o':
+ case 'u':
+ case 'x':
+ fp->fmt.size = sizeof(Sflong_t);
+ value->q = s ? (Sflong_t)strtoull(s, NiL, 0) : n;
+ break;
+ case 'p':
+ if (s)
+ n = strtoll(s, NiL, 0);
+ value->p = pointerof(n);
+ break;
+ case 'q':
+ if (s)
+ {
+ fp->fmt.fmt = 's';
+ value->s = fmtquote(s, "$'", "'", strlen(s), 0);
+ }
+ else
+ {
+ fp->fmt.fmt = 'd';
+ value->q = n;
+ }
+ break;
+ case 's':
+ if (!s && (!h || !fp->tmp[1] && !(fp->tmp[1] = sfstropen()) || sfprintf(fp->tmp[1], "%I*d", sizeof(n), n) <= 0 || !(s = sfstruse(fp->tmp[1]))))
+ s = "";
+ if (x)
+ {
+ h = 0;
+ d = initfield(&f, v + 4);
+ switch (x)
+ {
+ case FMT_case:
+ while ((a = getfield(&f, 1)) && (v = getfield(&f, 0)))
+ {
+ if (strmatch(s, a))
+ {
+ Fmt_t fmt;
+
+ fmt = *fp;
+ fmt.fmt.form = v;
+ for (h = 0; h < elementsof(fmt.tmp); h++)
+ fmt.tmp[h] = 0;
+ if (!fp->tmp[0] && !(fp->tmp[0] = sfstropen()) || sfprintf(fp->tmp[0], "%!", &fmt) <= 0 || !(s = sfstruse(fp->tmp[0])))
+ s = "";
+ *(v - 1) = d;
+ if (f.delimiter)
+ *f.next = d;
+ for (h = 0; h < elementsof(fmt.tmp); h++)
+ if (fmt.tmp[h])
+ sfclose(fmt.tmp[h]);
+ h = 1;
+ break;
+ }
+ *(v - 1) = d;
+ }
+ break;
+ case FMT_edit:
+ for (x = 0; *f.next; x ^= 1)
+ {
+ if (fp->re[x])
+ regfree(fp->re[x]);
+ else
+ fp->re[x] = &fp->red[x];
+ if (regcomp(fp->re[x], f.next, REG_DELIMITED|REG_NULL))
+ break;
+ f.next += fp->re[x]->re_npat;
+ if (regsubcomp(fp->re[x], f.next, NiL, 0, 0))
+ break;
+ f.next += fp->re[x]->re_npat;
+ if (!regexec(fp->re[x], s, elementsof(match), match, 0) && !regsubexec(fp->re[x], s, elementsof(match), match))
+ {
+ s = fp->re[x]->re_sub->re_buf;
+ if (fp->re[x]->re_sub->re_flags & REG_SUB_STOP)
+ break;
+ }
+ }
+ h = 1;
+ break;
+ }
+ if (!h)
+ s = "";
+ }
+ value->s = s;
+ if (fp->level == 1)
+ while ((s = strchr(s, CC_esc)) && *(s + 1) == '[')
+ do fp->invisible++; while (*s && !islower(*s++));
+ break;
+ case 'Z':
+ fp->fmt.fmt = 'c';
+ value->c = 0;
+ break;
+ case '\n':
+ value->s = "\n";
+ break;
+ case '.':
+ value->i = n;
+ break;
+ default:
+ if ((!fp->convert || !(value->s = (*fp->convert)(fp->handle, &fp->fmt, a, s, n))) && (!fp->tmp[0] && !(fp->tmp[0] = sfstropen()) || sfprintf(fp->tmp[0], "%%%c", fp->fmt.fmt) <= 0 || !(value->s = sfstruse(fp->tmp[0]))))
+ value->s = "";
+ break;
+ }
+ fp->level--;
+ return 0;
+}
+
+/*
+ * this is the original interface
+ */
+
+int
+sfkeyprintf(Sfio_t* sp, void* handle, const char* format, Sf_key_lookup_t lookup, Sf_key_convert_t convert)
+{
+ register int i;
+ int r;
+ Fmt_t fmt;
+
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.fmt.version = SFIO_VERSION;
+ fmt.fmt.form = (char*)format;
+ fmt.fmt.extf = getfmt;
+ fmt.handle = handle;
+ fmt.lookup = lookup;
+ fmt.convert = convert;
+ r = sfprintf(sp, "%!", &fmt) - fmt.invisible;
+ for (i = 0; i < elementsof(fmt.tmp); i++)
+ if (fmt.tmp[i])
+ sfclose(fmt.tmp[i]);
+ for (i = 0; i < elementsof(fmt.re); i++)
+ if (fmt.re[i])
+ regfree(fmt.re[i]);
+ return r;
+}
+
+#undef _AST_API_H
+
+#include <ast_api.h>
+
+/*
+ * Sffmt_t* callback args
+ */
+
+int
+sfkeyprintf_20000308(Sfio_t* sp, void* handle, const char* format, Sf_key_lookup_t lookup, Sf_key_convert_t convert)
+{
+ register int i;
+ int r;
+ Fmt_t fmt;
+
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.version = 20030909;
+ fmt.fmt.version = SFIO_VERSION;
+ fmt.fmt.form = (char*)format;
+ fmt.fmt.extf = getfmt;
+ fmt.handle = handle;
+ fmt.lookup = lookup;
+ fmt.convert = convert;
+ r = sfprintf(sp, "%!", &fmt) - fmt.invisible;
+ for (i = 0; i < elementsof(fmt.tmp); i++)
+ if (fmt.tmp[i])
+ sfclose(fmt.tmp[i]);
+ return r;
+}
diff --git a/src/lib/libast/disc/sfstrtmp.c b/src/lib/libast/disc/sfstrtmp.c
new file mode 100644
index 0000000..beed91b
--- /dev/null
+++ b/src/lib/libast/disc/sfstrtmp.c
@@ -0,0 +1,62 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * sfio tmp string buffer support
+ */
+
+#include <sfio_t.h>
+#include <ast.h>
+
+#if __OBSOLETE__ >= 20070101 /* sfstr* macros now use sfsetbuf() */
+
+NoN(sfstrtmp)
+
+#else
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+/*
+ * replace buffer in string stream f for either SF_READ or SF_WRITE
+ */
+
+extern int
+sfstrtmp(register Sfio_t* f, int mode, void* buf, size_t siz)
+{
+ if (!(f->_flags & SF_STRING))
+ return -1;
+ if (f->_flags & SF_MALLOC)
+ free(f->_data);
+ f->_flags &= ~(SF_ERROR|SF_MALLOC);
+ f->mode = mode;
+ f->_next = f->_data = (unsigned char*)buf;
+ f->_endw = f->_endr = f->_endb = f->_data + siz;
+ f->_size = siz;
+ return 0;
+}
+
+#endif
diff --git a/src/lib/libast/features/align.c b/src/lib/libast/features/align.c
new file mode 100644
index 0000000..e2c97c8
--- /dev/null
+++ b/src/lib/libast/features/align.c
@@ -0,0 +1,188 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * generate align features
+ *
+ * NOTE: two's complement binary integral representation assumed
+ */
+
+#include "FEATURE/common"
+
+#include <setjmp.h>
+
+union _u_
+{
+ long u1;
+ char* u2;
+ double u3;
+ char u4[1024];
+ intmax_t u5;
+ uintmax_t u6;
+ _ast_fltmax_t u7;
+ void* u8;
+ char* (*u9)();
+ jmp_buf u10;
+};
+
+struct _s_
+{
+ char s1;
+ union _u_ s2;
+};
+
+#define roundof(x,y) (((x)+((y)-1))&~((y)-1))
+
+static union _u_ u;
+static union _u_ v;
+
+int
+main()
+{
+ register int i;
+ register int j;
+ register int k;
+
+ int align0;
+ int align1;
+ int align2;
+ unsigned long bit1;
+ unsigned long bit2;
+ unsigned long bits0;
+ unsigned long bits1;
+ unsigned long bits2;
+
+ u.u2 = u.u4;
+ v.u2 = u.u2 + 1;
+ bit1 = u.u1 ^ v.u1;
+ v.u2 = u.u2 + 2;
+ bit2 = u.u1 ^ v.u1;
+ align0 = sizeof(struct _s_) - sizeof(union _u_);
+ bits0 = 0;
+ k = 0;
+ for (j = 0; j < align0; j++)
+ {
+ u.u2 = u.u4 + j;
+ bits1 = 0;
+ for (i = 0; i < align0; i++)
+ {
+ v.u2 = u.u2 + i;
+ bits1 |= u.u1 ^ v.u1;
+ }
+ if (!bits0 || bits1 < bits0)
+ {
+ bits0 = bits1;
+ k = j;
+ }
+ }
+ align1 = roundof(align0, 2);
+ u.u2 = u.u4 + k;
+ for (bits1 = bits0; i < align1; i++)
+ {
+ v.u2 = u.u2 + i;
+ bits1 |= u.u1 ^ v.u1;
+ }
+ align2 = roundof(align0, 4);
+ for (bits2 = bits1; i < align2; i++)
+ {
+ v.u2 = u.u2 + i;
+ bits2 |= u.u1 ^ v.u1;
+ }
+ printf("\n");
+ printf("#define ALIGN_CHUNK %d\n", sizeof(char*) >= 4 ? 8192 : 1024);
+ printf("#define ALIGN_INTEGRAL uintptr_t\n");
+ printf("#define ALIGN_INTEGER(x) ((char*)(x)-(char*)0)\n");
+ printf("#define ALIGN_POINTER(x) ((char*)(x))\n");
+ if (bits2 == (align2 - 1))
+ printf("#define ALIGN_ROUND(x,y) ALIGN_POINTER(ALIGN_INTEGER((x)+(y)-1)&~((y)-1))\n");
+ else
+ printf("#define ALIGN_ROUND(x,y) ALIGN_POINTER(ALIGN_INTEGER(ALIGN_ALIGN(x)+(((y)+%d)/%d)-1)&~((((y)+%d)/%d)-1))\n", align0, align0, align0, align0);
+ printf("\n");
+ if (align0 == align2)
+ {
+ printf("#define ALIGN_BOUND ALIGN_BOUND2\n");
+ printf("#define ALIGN_ALIGN(x) ALIGN_ALIGN2(x)\n");
+ printf("#define ALIGN_TRUNC(x) ALIGN_TRUNC2(x)\n");
+ }
+ else if (align0 == align1)
+ {
+ printf("#define ALIGN_BOUND ALIGN_BOUND1\n");
+ printf("#define ALIGN_ALIGN(x) ALIGN_ALIGN1(x)\n");
+ printf("#define ALIGN_TRUNC(x) ALIGN_TRUNC1(x)\n");
+ }
+ else
+ {
+ printf("#define ALIGN_BOUND 1\n");
+ printf("#define ALIGN_ALIGN(x) ALIGN_POINTER(x)\n");
+ printf("#define ALIGN_TRUNC(x) ALIGN_POINTER(x)\n");
+ }
+ printf("\n");
+ printf("#define ALIGN_BIT1 0x%lx\n", bit1);
+ if (align1 == align2)
+ {
+ printf("#define ALIGN_BOUND1 ALIGN_BOUND2\n");
+ printf("#define ALIGN_ALIGN1(x) ALIGN_ALIGN2(x)\n");
+ printf("#define ALIGN_TRUNC1(x) ALIGN_TRUNC2(x)\n");
+ }
+ else
+ {
+ printf("#define ALIGN_BOUND1 %d\n", align1);
+ printf("#define ALIGN_ALIGN1(x) ALIGN_TRUNC1((x)+%d)\n", align1 - 1);
+ printf("#define ALIGN_TRUNC1(x) ALIGN_POINTER(ALIGN_INTEGER((x)+%d)&0x%lx)\n", align1 - 1, ~(bits0|bits1));
+ }
+#if _X86_ || _X64_
+ printf("#if _X64_\n");
+ printf("#define ALIGN_CLRBIT1(x) ALIGN_POINTER(ALIGN_INTEGER(x)&0xfffffffffffffffeULL)\n");
+ printf("#else\n");
+ printf("#define ALIGN_CLRBIT1(x) ALIGN_POINTER(ALIGN_INTEGER(x)&0xfffffffe)\n");
+ printf("#endif\n");
+#else
+ printf("#define ALIGN_CLRBIT1(x) ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", ~bit1);
+#endif
+ printf("#define ALIGN_SETBIT1(x) ALIGN_POINTER(ALIGN_INTEGER(x)|0x%lx)\n", bit1);
+ printf("#define ALIGN_TSTBIT1(x) ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", bit1);
+ printf("\n");
+ printf("#define ALIGN_BIT2 0x%lx\n", bit2);
+#if _X86_ || _X64_
+ printf("#if _X64_\n");
+ printf("#define ALIGN_BOUND2 16\n");
+ printf("#define ALIGN_ALIGN2(x) ALIGN_TRUNC2((x)+15)\n");
+ printf("#define ALIGN_TRUNC2(x) ALIGN_POINTER(ALIGN_INTEGER(x)&0xfffffffffffffffeULL)\n");
+ printf("#else\n");
+ printf("#define ALIGN_BOUND2 8\n");
+ printf("#define ALIGN_ALIGN2(x) ALIGN_TRUNC2((x)+7)\n");
+ printf("#define ALIGN_TRUNC2(x) ALIGN_POINTER(ALIGN_INTEGER(x)&0xfffffff8)\n");
+ printf("#endif\n");
+#else
+ printf("#define ALIGN_BOUND2 %d\n", align2);
+ printf("#define ALIGN_ALIGN2(x) ALIGN_TRUNC2((x)+%d)\n", align2 - 1);
+ printf("#define ALIGN_TRUNC2(x) ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", ~(bits0|bits1|bits2));
+#endif
+ printf("#define ALIGN_CLRBIT2(x) ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", ~bit2);
+ printf("#define ALIGN_SETBIT2(x) ALIGN_POINTER(ALIGN_INTEGER(x)|0x%lx)\n", bit2);
+ printf("#define ALIGN_TSTBIT2(x) ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", bit2);
+ printf("\n");
+ return 0;
+}
diff --git a/src/lib/libast/features/api b/src/lib/libast/features/api
new file mode 100644
index 0000000..acfcd71
--- /dev/null
+++ b/src/lib/libast/features/api
@@ -0,0 +1,11 @@
+iff AST_API
+
+ver ast 20110505
+
+api ast 20110505 cmdopen
+
+api ast 20100601 pathaccess pathcanon pathcat pathkey pathpath pathprobe pathrepl
+
+api ast 20000308 sfkeyprintf
+
+print #define _AST_VERSION AST_VERSION /* pre-20100601 compatibility */
diff --git a/src/lib/libast/features/aso b/src/lib/libast/features/aso
new file mode 100644
index 0000000..2b7f01a
--- /dev/null
+++ b/src/lib/libast/features/aso
@@ -0,0 +1,671 @@
+# ast atomic scalar operations feature tests
+
+if aso note{ gcc 4.1+ 64 bit memory atomic operations model }end link{
+ #include "FEATURE/common"
+ int main()
+ {
+ uint64_t i = 0;
+ return __sync_fetch_and_add(&i,7);
+ }
+ }end && {
+ #define _aso_cas8(p,o,n) __sync_val_compare_and_swap(p,o,n)
+ #define _aso_inc8(p) __sync_fetch_and_add(p,1)
+ #define _aso_dec8(p) __sync_fetch_and_sub(p,1)
+ #define _aso_cas16(p,o,n) __sync_val_compare_and_swap(p,o,n)
+ #define _aso_inc16(p) __sync_fetch_and_add(p,1)
+ #define _aso_dec16(p) __sync_fetch_and_sub(p,1)
+ #define _aso_cas32(p,o,n) __sync_val_compare_and_swap(p,o,n)
+ #define _aso_inc32(p) __sync_fetch_and_add(p,1)
+ #define _aso_dec32(p) __sync_fetch_and_sub(p,1)
+ #define _aso_cas64(p,o,n) __sync_val_compare_and_swap(p,o,n)
+ #define _aso_inc64(p) __sync_fetch_and_add(p,1)
+ #define _aso_dec64(p) __sync_fetch_and_sub(p,1)
+ #if _ast_sizeof_pointer == 8
+ #define _aso_casptr(p,o,n) ((void*)__sync_val_compare_and_swap(p,(uint64_t)o,(uint64_t)n))
+ #else
+ #define _aso_casptr(p,o,n) ((void*)__sync_val_compare_and_swap(p,(uint32_t)o,(uint32_t)n))
+ #endif
+ }
+elif aso note{ gcc 4.1+ 32 bit memory atomic operations model }end link{
+ #include "FEATURE/common"
+ int main()
+ {
+ uint32_t i = 0;
+ return __sync_fetch_and_add(&i,7);
+ }
+ }end && {
+ #define _aso_cas8(p,o,n) __sync_val_compare_and_swap(p,o,n)
+ #define _aso_inc8(p) __sync_fetch_and_add(p,1)
+ #define _aso_dec8(p) __sync_fetch_and_sub(p,1)
+ #define _aso_cas16(p,o,n) __sync_val_compare_and_swap(p,o,n)
+ #define _aso_inc16(p) __sync_fetch_and_add(p,1)
+ #define _aso_dec16(p) __sync_fetch_and_sub(p,1)
+ #define _aso_cas32(p,o,n) __sync_val_compare_and_swap(p,o,n)
+ #define _aso_inc32(p) __sync_fetch_and_add(p,1)
+ #define _aso_dec32(p) __sync_fetch_and_sub(p,1)
+ #define _aso_casptr(p,o,n) ((void*)__sync_val_compare_and_swap(p,(uint32_t)o,(uint32_t)n))
+ }
+elif aso note{ <atomic.h> atomic_cas_64 }end link{
+ #include "FEATURE/common"
+ #include <atomic.h>
+ int main()
+ {
+ uint64_t i = 0;
+ uint32_t j = 1;
+ return atomic_cas_64(&i, 0, 1) != 0 || atomic_add_32_nv(&j, 1) != 1;
+ }
+ }end && {
+ #include <atomic.h>
+ #define _aso_cas8(p,o,n) atomic_cas_8(p,o,n)
+ #define _aso_inc8(p) (atomic_add_8_nv(p,1)-1)
+ #define _aso_dec8(p) (atomic_add_8_nv(p,-1)+1)
+ #define _aso_cas16(p,o,n) atomic_cas_16(p,o,n)
+ #define _aso_inc16(p) (atomic_add_16_nv(p,1)-1)
+ #define _aso_dec16(p) (atomic_add_16_nv(p,-1)+1)
+ #define _aso_cas32(p,o,n) atomic_cas_32(p,o,n)
+ #define _aso_inc32(p) (atomic_add_32_nv(p,1)-1)
+ #define _aso_dec32(p) (atomic_add_32_nv(p,-1)+1)
+ #define _aso_cas64(p,o,n) atomic_cas_64(p,o,n)
+ #define _aso_inc64(p) (atomic_add_64_nv(p,1)-1)
+ #define _aso_dec64(p) (atomic_add_64_nv(p,-1)+1)
+ #if _ast_sizeof_pointer == 8
+ #define _aso_casptr(p,o,n) ((void*)atomic_cas_64((uint64_t*)p,(uint64_t)o,(uint64_t)n))
+ #else
+ #define _aso_casptr(p,o,n) ((void*)atomic_cas_32((uint32_t*)p,(uint32_t)o,(uint32_t)n))
+ #endif
+ }
+elif aso note{ <atomic.h> atomic_cas_32 }end link{
+ #include "FEATURE/common"
+ #include <atomic.h>
+ int main()
+ {
+ uint32_t i = 0;
+ return atomic_cas_32(&i, 0, 1) != 0 || (atomic_add_32_nv(&i, 1) - 1) != 1;
+ }
+ }end && {
+ #include <atomic.h>
+ #define _aso_cas8(p,o,n) atomic_cas_8(p,o,n)
+ #define _aso_inc8(p) (atomic_add_8_nv(p,1)-1)
+ #define _aso_dec8(p) (atomic_add_8_nv(p,-1)+1)
+ #define _aso_cas16(p,o,n) atomic_cas_16(p,o,n)
+ #define _aso_inc16(p) (atomic_add_16_nv(p,1)-1)
+ #define _aso_dec16(p) (atomic_add_16_nv(p,-1)+1)
+ #define _aso_cas32(p,o,n) atomic_cas_32(p,o,n)
+ #define _aso_inc32(p) (atomic_add_32_nv(p,1)-1)
+ #define _aso_dec32(p) (atomic_add_32_nv(p,-1)+1)
+ #define _aso_casptr(p,o,n) ((void*)atomic_cas_32((uint32_t*)p,(uint32_t)o,(uint32_t)n))
+ }
+elif aso -latomic note{ <atomic.h> atomic_cas_64 with -latomic }end link{
+ #include "FEATURE/common"
+ #include <atomic.h>
+ int main()
+ {
+ uint64_t i = 0;
+ uint32_t j = 1;
+ return atomic_cas_64(&i, 0, 1) != 0 || (atomic_add_32_nv(&j, 1) - 1) != 1;
+ }
+ }end && {
+ #include <atomic.h>
+ #define _REQ_atomic
+ #define _aso_cas8(p,o,n) atomic_cas_8(p,o,n)
+ #define _aso_inc8(p) (atomic_add_8_nv(p,1)-1)
+ #define _aso_dec8(p) (atomic_add_8_nv(p,-1)+1)
+ #define _aso_cas16(p,o,n) atomic_cas_16(p,o,n)
+ #define _aso_inc16(p) (atomic_add_16_nv(p,1)-1)
+ #define _aso_dec16(p) (atomic_add_16_nv(p,-1)+1)
+ #define _aso_cas32(p,o,n) atomic_cas_32(p,o,n)
+ #define _aso_inc32(p) (atomic_add_32_nv(p,1)-1)
+ #define _aso_dec32(p) (atomic_add_32_nv(p,-1)+1)
+ #define _aso_cas64(p,o,n) atomic_cas_64(p,o,n)
+ #define _aso_inc64(p) (atomic_add_64_nv(p,1)-1)
+ #define _aso_dec64(p) (atomic_add_64_nv(p,-1)+1)
+ #if _ast_sizeof_pointer == 8
+ #define _aso_casptr(p,o,n) ((void*)atomic_cas_64((uint64_t*)p,(uint64_t)o,(uint64_t)n))
+ #else
+ #define _aso_casptr(p,o,n) ((void*)atomic_cas_32((uint32_t*)p,(uint32_t)o,(uint32_t)n))
+ #endif
+ }
+elif aso note{ <atomic.h> atomic_cas_32 with -latomic }end link{
+ #include "FEATURE/common"
+ #include <atomic.h>
+ int main()
+ {
+ uint32_t i = 0;
+ return atomic_cas_32(&i, 0, 1) != 0 || (atomic_add_32_nv(&i, 1) - 1) != 1;
+ }
+ }end && {
+ #include <atomic.h>
+ #define _REQ_atomic
+ #define _aso_cas8(p,o,n) atomic_cas_8(p,o,n)
+ #define _aso_inc8(p) (atomic_add_8_nv(p,1)-1)
+ #define _aso_dec8(p) (atomic_add_8_nv(p,-1)+1)
+ #define _aso_cas16(p,o,n) atomic_cas_16(p,o,n)
+ #define _aso_inc16(p) (atomic_add_16_nv(p,1)-1)
+ #define _aso_dec16(p) (atomic_add_16_nv(p,-1)+1)
+ #define _aso_cas32(p,o,n) atomic_cas_32(p,o,n)
+ #define _aso_inc32(p) (atomic_add_32_nv(p,1)-1)
+ #define _aso_dec32(p) (atomic_add_32_nv(p,-1)+1)
+ #define _aso_casptr(p,o,n) ((void*)atomic_cas_32((uint32_t*)p,(uint32_t)o,(uint32_t)n))
+ }
+elif aso note{ <atomic.h> cas64 }end link{
+ #include "FEATURE/common"
+ #include <atomic.h>
+ int main()
+ {
+ uint64_t i = 0;
+ uint32_t j = 1;
+ return cas64(&i, 0, 1) != 0 || (atomic_add_32_nv(&j, 1) - 1) != 1;
+ }
+ }end && {
+ #include <atomic.h>
+ #define _aso_cas8(p,o,n) cas8(p,o,n)
+ #define _aso_inc8(p) (atomic_add_8_nv(p,1)-1)
+ #define _aso_dec8(p) (atomic_add_8_nv(p,-1)+1)
+ #define _aso_cas16(p,o,n) cas16(p,o,n)
+ #define _aso_inc16(p) (atomic_add_16_nv(p,1)-1)
+ #define _aso_dec16(p) (atomic_add_16_nv(p,-1)+1)
+ #define _aso_cas32(p,o,n) cas32(p,o,n)
+ #define _aso_inc32(p) (atomic_add_32_nv(p,1)-1)
+ #define _aso_dec32(p) (atomic_add_32_nv(p,-1)+1)
+ #define _aso_cas64(p,o,n) cas64(p,o,n)
+ #define _aso_inc64(p) (atomic_add_64_nv(p,1)-1)
+ #define _aso_dec64(p) (atomic_add_64_nv(p,-1)+1)
+ #if _ast_sizeof_pointer == 8
+ #define _aso_casptr(p,o,n) ((void*)cas64((uint64_t*)p,(uint64_t)o,(uint64_t)n))
+ #else
+ #define _aso_casptr(p,o,n) ((void*)cas32((uint32_t*)p,(uint32_t)o,(uint32_t)n))
+ #endif
+ }
+elif aso note{ <atomic.h> just cas64 }end link{
+ #include "FEATURE/common"
+ #include <atomic.h>
+ int main()
+ {
+ uint64_t i = 0;
+ uint32_t j = 1;
+ uint16_t k = 1;
+ uint8_t l = 1;
+ return cas64(&i, 0, 1) != 0 || cas32(&j, 0, 1) != 0 || cas16(&k, 0, 1) != 0 || cas8(&l, 0, 1) != 0;
+ }
+ }end && {
+ #include <atomic.h>
+ #define _aso_cas8(p,o,n) cas8(p,o,n)
+ #define _aso_cas16(p,o,n) cas16(p,o,n)
+ #define _aso_cas32(p,o,n) cas32(p,o,n)
+ #define _aso_cas64(p,o,n) cas64(p,o,n)
+ #if _ast_sizeof_pointer == 8
+ #define _aso_casptr(p,o,n) ((void*)cas64((uint64_t*)p,(uint64_t)o,(uint64_t)n))
+ #else
+ #define _aso_casptr(p,o,n) ((void*)cas32((uint32_t*)p,(uint32_t)o,(uint32_t)n))
+ #endif
+ }
+elif aso note{ <atomic.h> cas32 }end link{
+ #include "FEATURE/common"
+ #include <atomic.h>
+ int main()
+ {
+ uint32_t i = 0;
+ return cas32(&i, 0, 1) != 0 || (atomic_add_32_nv(&i, 1) - 1) != 1;
+ }
+ }end && {
+ #include <atomic.h>
+ #define _aso_cas8(p,o,n) cas8(p,o,n)
+ #define _aso_inc8(p) (atomic_add_8_nv(p,1)-1)
+ #define _aso_dec8(p) (atomic_add_8_nv(p,-1)+1)
+ #define _aso_cas16(p,o,n) cas16(p,o,n)
+ #define _aso_inc16(p) (atomic_add_16_nv(p,1)-1)
+ #define _aso_dec16(p) (atomic_add_16_nv(p,-1)+1)
+ #define _aso_cas32(p,o,n) cas32(p,o,n)
+ #define _aso_inc32(p) (atomic_add_32_nv(p,1)-1)
+ #define _aso_dec32(p) (atomic_add_32_nv(p,-1)+1)
+ #define _aso_casptr(p,o,n) ((void*)cas32((uint32_t*)p,(uint32_t)o,(uint32_t)n))
+ }
+elif aso note{ <atomic.h> just cas32 }end link{
+ #include "FEATURE/common"
+ #include <atomic.h>
+ int main()
+ {
+ uint32_t j = 1;
+ uint16_t k = 1;
+ uint8_t l = 1;
+ return cas32(&j, 0, 1) != 0 || cas16(&k, 0, 1) != 0 || cas8(&l, 0, 1) != 0;
+ }
+ }end && {
+ #include <atomic.h>
+ #define _aso_cas8(p,o,n) cas8(p,o,n)
+ #define _aso_cas16(p,o,n) cas16(p,o,n)
+ #define _aso_cas32(p,o,n) cas32(p,o,n)
+ #define _aso_casptr(p,o,n) ((void*)cas32((uint32_t*)p,(uint32_t)o,(uint32_t)n))
+ }
+elif aso note{ winix Interlocked }end link{
+ #include <windows.h>
+ int main()
+ {
+ LONG i = 0;
+ LONGLONG j = 0;
+ return InterlockedCompareExchange(&i, 1, 0) != 0 ||
+ InterlockedIncrement(&i) != 1 ||
+ InterlockedDecrement(&i) != 2;
+ }
+ }end && {
+ #include <ast_windows.h>
+ #define _aso_cas32(p,o,n) InterlockedCompareExchange((LONG volatile*)p,n,o)
+ #define _aso_inc32(p) (InterlockedIncrement((LONG volatile*)p)-1)
+ #define _aso_dec32(p) (InterlockedDecrement((LONG volatile*)p)+1)
+ #if _X64
+ #define _aso_cas64(p,o,n) InterlockedCompareExchange64((LONGLONG volatile*)p,n,o)
+ #define _aso_inc64(p) (InterlockedIncrement64((LONGLONG volatile*)p)-1)
+ #define _aso_dec64(p) (InterlockedDecrement64((LONGLONG volatile*)p)+1)
+ #define _aso_casptr(p,o,n) ((void*)InterlockedCompareExchange64((LONGLONG volatile*)p,(LONGLONG)n,(LONGLONG)o))
+ #else
+ #if _BLD_posix
+ #include "dl.h"
+ typedef struct LL_s
+ {
+ LONG a;
+ LONG b;
+ } LL_t;
+ typedef union
+ {
+ LONGLONG i;
+ LL_t ll;
+ } LL_u;
+
+ #define _aso_cas64(p,o,n) _aso_InterlockedCompareExchange64((LONGLONG volatile*)p,n,o)
+ static LONGLONG _aso_InterlockedCompareExchange64_init(LONGLONG volatile*, LONGLONG, LONGLONG);
+ typedef LONGLONG (*_aso_InterlockedCompareExchange64_f)(LONGLONG volatile*, LONGLONG, LONGLONG);
+ static _aso_InterlockedCompareExchange64_f _aso_InterlockedCompareExchange64 = _aso_InterlockedCompareExchange64_init;
+ static LONGLONG _aso_InterlockedCompareExchange64_32(LONGLONG volatile* p, LONGLONG o, LONGLONG n)
+ {
+ LL_t* lp = (LL_t*)p;
+ LL_t* op = (LL_t*)&o;
+ LL_t* np = (LL_t*)&n;
+ LONGLONG r;
+
+ r = *p;
+ if (_aso_cas32(&lp->a, op->a, np->a) == op->a)
+ {
+ if (_aso_cas32(&lp->b, op->b, np->b) == op->b)
+ return o;
+ _aso_cas32(&lp->a, np->a, op->a);
+ }
+ return r;
+ }
+ static LONGLONG _aso_InterlockedCompareExchange64_init(LONGLONG volatile* p, LONGLONG o, LONGLONG n)
+ {
+ if (!(_aso_InterlockedCompareExchange64 = (_aso_InterlockedCompareExchange64_f)getsymbol(MODULE_kernel, "InterlockedCompareExchange64")))
+ _aso_InterlockedCompareExchange64 = _aso_InterlockedCompareExchange64_32;
+ return _aso_InterlockedCompareExchange64(p, o, n);
+ }
+
+ #define _aso_inc64(p) (_aso_InterlockedIncrement64((LONGLONG volatile*)p)-1)
+ typedef LONGLONG (*_aso_InterlockedIncrement64_f)(LONGLONG volatile*);
+ static LONGLONG _aso_InterlockedIncrement64_init(LONGLONG volatile*);
+ static _aso_InterlockedIncrement64_f _aso_InterlockedIncrement64 = _aso_InterlockedIncrement64_init;
+ static LONGLONG _aso_InterlockedIncrement64_32(LONGLONG volatile* p)
+ {
+ LONGLONG o;
+
+ do
+ {
+ o = *p;
+ } while (_aso_InterlockedCompareExchange64_32(p, o, o + 1) != o);
+ return o;
+ }
+ static LONGLONG _aso_InterlockedIncrement64_init(LONGLONG volatile* p)
+ {
+ if (!(_aso_InterlockedIncrement64 = (_aso_InterlockedIncrement64_f)getsymbol(MODULE_kernel, "InterlockedIncrement64")))
+ _aso_InterlockedIncrement64 = _aso_InterlockedIncrement64_32;
+ return _aso_InterlockedIncrement64(p);
+ }
+
+ #define _aso_dec64(p) (_aso_InterlockedDecrement64((LONGLONG volatile*)p)+1)
+ typedef LONGLONG (*_aso_InterlockedDecrement64_f)(LONGLONG volatile*);
+ static LONGLONG _aso_InterlockedDecrement64_init(LONGLONG volatile*);
+ static _aso_InterlockedDecrement64_f _aso_InterlockedDecrement64 = _aso_InterlockedDecrement64_init;
+ static LONGLONG _aso_InterlockedDecrement64_32(LONGLONG volatile* p)
+ {
+ LONGLONG o;
+
+ do
+ {
+ o = *p;
+ } while (_aso_InterlockedCompareExchange64_32(p, o, o - 1) != o);
+ return o;
+ }
+ static LONGLONG _aso_InterlockedDecrement64_init(LONGLONG volatile* p)
+ {
+ if (!(_aso_InterlockedDecrement64 = (_aso_InterlockedDecrement64_f)getsymbol(MODULE_kernel, "InterlockedDecrement64")))
+ _aso_InterlockedDecrement64 = _aso_InterlockedDecrement64_32;
+ return _aso_InterlockedDecrement64(p);
+ }
+ #endif
+ #define _aso_casptr(p,o,n) ((void*)InterlockedCompareExchange((LONG volatile*)p,(LONG)n,(LONG)o))
+ #endif
+ }
+elif aso note{ aix fetch and add }end link{
+ #include <sys/atomic_op.h>
+ int main()
+ {
+ int i = 0;
+ return fetch_and_add((atomic_p)&i,1);
+ }
+ }end && {
+ #include <sys/atomic_op.h>
+ #define _aso_incint(p) fetch_and_add((atomic_p)p,1)
+ #define _aso_decint(p) fetch_and_add((atomic_p)p,-1)
+ #define _aso_casint(p,o,n) (compare_and_swap((atomic_p)p,(int*)&o,(int)n) ? o : *p)
+ #if _ast_sizeof_pointer == 8
+ #define _aso_casptr(p,o,n) (compare_and_swaplp((atomic_l)p,(long*)&o,(long)n) ? o : *(void**)p)
+ #else
+ #define _aso_casptr(p,o,n) (compare_and_swap((atomic_p)p,(int*)&o,(int)n) ? o : *(void**)p)
+ #endif
+ }
+elif aso note{ mips compare and swap }end link{
+ int main()
+ {
+ int i = 1;
+ return __compare_and_swap(&i, 0, 1) != 1;
+ }
+ }end && {
+ #define _aso_cas32(p,o,n) (__compare_and_swap(p,o,n) ? o : *p)
+ #define _aso_casptr(p,o,n) (__compare_and_swap((long*)p,(long)o,(long)n) ? o : *(void**)p)
+ }
+elif aso note{ i386|i386-64 asm compare and swap }end link{
+ #include "FEATURE/common"
+
+ static uint32_t
+ cas32(uint32_t volatile* p, uint32_t o, uint32_t n)
+ {
+ uint32_t r;
+
+ __asm__ __volatile__ (
+ "lock ; cmpxchg %3,%4"
+ : "=a"(r), "=m"(*p)
+ : "0"(o), "q"(n), "m"(*p)
+ : "memory", "cc"
+ );
+ return r;
+ }
+
+ #if _ast_sizeof_pointer == 8
+
+ static uint64_t
+ cas64(uint64_t volatile* p, uint64_t o, uint64_t n)
+ {
+ uint64_t r;
+
+ __asm__ __volatile__ (
+ "lock ; cmpxchg %3,%4"
+ : "=a"(r), "=m"(*p)
+ : "0"(o), "q"(n), "m"(*p)
+ : "memory", "cc"
+ );
+ return r;
+ }
+
+ #else
+
+ #define cas64(p,o,n) (*(p))
+
+ #endif
+
+ int main()
+ {
+ uint32_t i = 0;
+ uint64_t j = 0;
+ return cas32(&i, 0, 1) || cas64(&j, 0, 1);
+ }
+ }end && {
+ static uint32_t
+ cas32(uint32_t volatile* p, uint32_t o, uint32_t n)
+ {
+ uint32_t r;
+
+ __asm__ __volatile__ (
+ "lock ; cmpxchg %3,%4"
+ : "=a"(r), "=m"(*p)
+ : "0"(o), "q"(n), "m"(*p)
+ : "memory", "cc"
+ );
+ return r;
+ }
+
+ #if _ast_sizeof_pointer == 8
+
+ static uint64_t
+ cas64(uint64_t volatile* p, uint64_t o, uint64_t n)
+ {
+ uint64_t r;
+
+ __asm__ __volatile__ (
+ "lock ; cmpxchg %3,%4"
+ : "=a"(r), "=m"(*p)
+ : "0"(o), "q"(n), "m"(*p)
+ : "memory", "cc"
+ );
+ return r;
+ }
+
+ #endif
+
+ #define _aso_cas32(p,o,n) cas32(p,o,n)
+ #if _ast_sizeof_pointer == 8
+ #define _aso_cas64(p,o,n) cas64(p,o,n)
+ #define _aso_casptr(p,o,n) ((void*)cas64((uint64_t*)p,(uint64_t)o,(uint64_t)n))
+ #else
+ #define _aso_casptr(p,o,n) ((void*)cas32((uint32_t*)p,(uint32_t)o,(uint32_t)n))
+ #endif
+ }
+elif aso note{ ia64 asm compare and swap }end link{
+ #include "FEATURE/common"
+
+ static uint32_t
+ cas32(uint32_t volatile* p, uint32_t o, uint32_t n)
+ {
+ uint32_t r;
+
+ __asm__ __volatile__ (
+ "zxt4 %3=%3 ;; mov ar.ccv=%3 ;; cmpxchg4.acq %0=%1,%2,ar.ccv"
+ : "=r"(r), "+S"(*p)
+ : "r"(n), "r"(o) : "memory"
+ );
+ return r;
+ }
+
+ static uint64_t
+ cas64(uint64_t volatile* p, uint64_t o, uint64_t n)
+ {
+ uint64_t r;
+
+ __asm__ __volatile__ (
+ "mov ar.ccv=%3 ;; cmpxchg8.acq %0=%1,%2,ar.ccv"
+ : "=r"(r), "+S"(*p)
+ : "r"(n), "r"(o) : "memory"
+ );
+ return r;
+ }
+
+ int main()
+ {
+ uint32_t i = 0;
+ uint64_t j = 0;
+ return cas32(&i, 0, 1) || cas64(&j, 0, 1);
+ }
+ }end && {
+ static uint32_t
+ cas32(uint32_t volatile* p, uint32_t o, uint32_t n)
+ {
+ uint32_t r;
+
+ __asm__ __volatile__ (
+ "zxt4 %3=%3 ;; mov ar.ccv=%3 ;; cmpxchg4.acq %0=%1,%2,ar.ccv"
+ : "=r"(r), "+S"(*p)
+ : "r"(n), "r"(o) : "memory"
+ );
+ return r;
+ }
+
+ static uint64_t
+ cas64(uint64_t volatile* p, uint64_t o, uint64_t n)
+ {
+ uint64_t r;
+
+ __asm__ __volatile__ (
+ "mov ar.ccv=%3 ;; cmpxchg8.acq %0=%1,%2,ar.ccv"
+ : "=r"(r), "+S"(*p)
+ : "r"(n), "r"(o) : "memory"
+ );
+ return r;
+ }
+
+ #define _aso_cas32(p,o,n) cas32(p,o,n)
+ #define _aso_cas64(p,o,n) cas64(p,o,n)
+ #if _ast_sizeof_pointer == 8
+ #define _aso_casptr(p,o,n) ((void*)cas64((uint64_t*)p,(uint64_t)o,(uint64_t)n))
+ #else
+ #define _aso_casptr(p,o,n) ((void*)cas32((uint32_t*)p,(uint32_t)o,(uint32_t)n))
+ #endif
+ }
+elif aso note{ ppc asm compare and swap }end link{
+ #include "FEATURE/common"
+
+ static uint32_t
+ cas32(uint32_t volatile* p, uint32_t o, uint32_t n)
+ {
+ int r;
+
+ __asm__ __volatile__ (
+ "0: lwarx %0,0,%1 ;"
+ " xor. %0,%3,%0;"
+ " bne 1f;"
+ " stwcx. %2,0,%1;"
+ " bne- 0b;"
+ "1:"
+ : "=&r"(r)
+ : "r"(p), "r"(n), "r"(o)
+ : "cr0", "memory"
+ );
+ __asm__ __volatile__ ("isync" : : : "memory");
+ return r ? *p : o;
+ }
+
+ static uint64_t
+ cas64(uint64_t volatile* p, uint64_t o, uint64_t n)
+ {
+ long r;
+
+ __asm__ __volatile__ (
+ "0: ldarx %0,0,%1 ;"
+ " xor. %0,%3,%0;"
+ " bne 1f;"
+ " stdcx. %2,0,%1;"
+ " bne- 0b;"
+ "1:"
+ : "=&r"(r)
+ : "r"(p), "r"(n), "r"(o)
+ : "cr0", "memory"
+ );
+ __asm__ __volatile__ ("isync" : : : "memory");
+ return r ? *p : o;
+ }
+
+ int main()
+ {
+ uint32_t i = 0;
+ uint64_t j = 0;
+ return cas32(&i, 0, 1) || cas64(&j, 0, 1);
+ }
+ }end && {
+ static uint32_t
+ cas32(uint32_t volatile* p, uint32_t o, uint32_t n)
+ {
+ int r;
+
+ __asm__ __volatile__ (
+ "0: lwarx %0,0,%1 ;"
+ " xor. %0,%3,%0;"
+ " bne 1f;"
+ " stwcx. %2,0,%1;"
+ " bne- 0b;"
+ "1:"
+ : "=&r"(r)
+ : "r"(p), "r"(n), "r"(o)
+ : "cr0", "memory"
+ );
+ __asm__ __volatile__ ("isync" : : : "memory");
+ return r ? *p : o;
+ }
+
+ static uint64_t
+ cas64(uint64_t volatile* p, uint64_t o, uint64_t n)
+ {
+ long r;
+
+ __asm__ __volatile__ (
+ "0: ldarx %0,0,%1 ;"
+ " xor. %0,%3,%0;"
+ " bne 1f;"
+ " stdcx. %2,0,%1;"
+ " bne- 0b;"
+ "1:"
+ : "=&r"(r)
+ : "r"(p), "r"(n), "r"(o)
+ : "cr0", "memory"
+ );
+ __asm__ __volatile__ ("isync" : : : "memory");
+ return r ? *p : o;
+ }
+
+ #define _aso_cas32(p,o,n) cas32(p,o,n)
+ #define _aso_cas64(p,o,n) cas64(p,o,n)
+ #if _ast_sizeof_pointer == 8
+ #define _aso_casptr(p,o,n) ((void*)cas64((uint64_t*)p,(uint64_t)o,(uint64_t)n))
+ #else
+ #define _aso_casptr(p,o,n) ((void*)cas32((uint32_t*)p,(uint32_t)o,(uint32_t)n))
+ #endif
+ }
+endif
+
+aso fcntl note{ fcntl(F_SETLCK[W]) work }end link{
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+
+ int main()
+ {
+ struct flock lock;
+
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 1;
+ return fcntl(1, F_SETLKW, &lock) < 0;
+ }
+}end
+
+aso semaphore note{ semget semop semctl work }end link{
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/ipc.h>
+ #include <sys/sem.h>
+
+ int main()
+ {
+ int id;
+ struct sembuf sem;
+
+ if ((id = semget(IPC_PRIVATE, 16, IPC_CREAT|IPC_EXCL|S_IRUSR|S_IWUSR)) < 0)
+ return 1;
+ sem.sem_num = 0;
+ sem.sem_op = 1;
+ sem.sem_flg = 0;
+ if (semop(id, &sem, 1) < 0)
+ return 1;
+ if (semctl(id, 0, IPC_RMID) < 0)
+ return 1;
+ return 0;
+ }
+}end
diff --git a/src/lib/libast/features/botch.c b/src/lib/libast/features/botch.c
new file mode 100644
index 0000000..d30547d
--- /dev/null
+++ b/src/lib/libast/features/botch.c
@@ -0,0 +1,72 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * generate ast traps for botched standard prototypes
+ */
+
+#include <sys/types.h>
+
+#include "FEATURE/lib"
+#include "FEATURE/sys"
+
+#if _lib_getgroups
+extern int getgroups(int, gid_t*);
+#endif
+
+int
+main()
+{
+#if _lib_getgroups
+ if (sizeof(int) > sizeof(gid_t))
+ {
+ int n;
+ int i;
+ int r;
+ gid_t groups[32 * sizeof(int) / sizeof(gid_t)];
+
+ r = sizeof(int) / sizeof(gid_t);
+ if ((n = getgroups((sizeof(groups) / sizeof(groups[0])) / r, groups)) > 0)
+ for (i = 1; i <= n; i++)
+ {
+ groups[i] = ((gid_t)0);
+ if (getgroups(i, groups) != i)
+ goto botched;
+ if (groups[i] != ((gid_t)0))
+ goto botched;
+ groups[i] = ((gid_t)-1);
+ if (getgroups(i, groups) != i)
+ goto botched;
+ if (groups[i] != ((gid_t)-1))
+ goto botched;
+ }
+ }
+ return 0;
+ botched:
+ printf("#undef getgroups\n");
+ printf("#define getgroups _ast_getgroups /* implementation botches gid_t* arg */\n");
+#endif
+ return 0;
+}
diff --git a/src/lib/libast/features/ccode b/src/lib/libast/features/ccode
new file mode 100644
index 0000000..0175763
--- /dev/null
+++ b/src/lib/libast/features/ccode
@@ -0,0 +1,81 @@
+tst output{
+ int main()
+ {
+ printf("\n");
+ printf("#define CC_ASCII 1 /* ISO-8859-1 */\n");
+ printf("#define CC_EBCDIC_E 2 /* Xopen dd(1) EBCDIC */\n");
+ printf("#define CC_EBCDIC_I 3 /* Xopen dd(1) IBM */\n");
+ printf("#define CC_EBCDIC_O 4 /* IBM-1047 mvs OpenEdition */\n");
+ printf("#define CC_EBCDIC_S 5 /* Siemens posix-bc */\n");
+ printf("#define CC_EBCDIC_H 6 /* IBM-37 AS/400 */\n");
+ printf("#define CC_EBCDIC_M 7 /* IBM mvs cobol */\n");
+ printf("#define CC_EBCDIC_U 8 /* microfocus cobol */\n");
+ printf("\n");
+ printf("#define CC_MAPS 8 /* number of code maps */\n");
+ printf("\n");
+ printf("#define CC_EBCDIC CC_EBCDIC_E\n");
+ printf("#define CC_EBCDIC1 CC_EBCDIC_E\n");
+ printf("#define CC_EBCDIC2 CC_EBCDIC_I\n");
+ printf("#define CC_EBCDIC3 CC_EBCDIC_O\n");
+ printf("\n");
+ switch ('~')
+ {
+ case 0137:
+ printf("#define CC_NATIVE CC_EBCDIC_E /* native character code */\n");
+ break;
+ case 0176:
+ printf("#define CC_NATIVE CC_ASCII /* native character code */\n");
+ break;
+ case 0241:
+ switch ('\n')
+ {
+ case 0025:
+ printf("#define CC_NATIVE CC_EBCDIC_O /* native character code */\n");
+ break;
+ default:
+ switch ('[')
+ {
+ case 0272:
+ printf("#define CC_NATIVE CC_EBCDIC_H /* native character code */\n");
+ break;
+ default:
+ printf("#define CC_NATIVE CC_EBCDIC_I /* native character code */\n");
+ break;
+ }
+ break;
+ }
+ break;
+ case 0377:
+ printf("#define CC_NATIVE CC_EBCDIC_S /* native character code */\n");
+ break;
+ default:
+ switch ('A')
+ {
+ case 0301:
+ printf("#define CC_NATIVE CC_EBCDIC_O /* native character code */\n");
+ break;
+ default:
+ printf("#define CC_NATIVE CC_ASCII /* native character code */\n");
+ break;
+ }
+ break;
+ }
+ if ('A' == 0101)
+ {
+ printf("#define CC_ALIEN CC_EBCDIC /* alien character code */\n\n");
+ printf("#define CC_bel 0007 /* bel character */\n");
+ printf("#define CC_esc 0033 /* esc character */\n");
+ printf("#define CC_sub 0032 /* sub character */\n");
+ printf("#define CC_vt 0013 /* vt character */\n");
+ }
+ else
+ {
+ printf("#define CC_ALIEN CC_ASCII /* alien character code */\n\n");
+ printf("#define CC_bel 0057 /* bel character */\n");
+ printf("#define CC_esc 0047 /* esc character */\n");
+ printf("#define CC_sub 0077 /* sub character */\n");
+ printf("#define CC_vt 0013 /* vt character */\n");
+ }
+ return 0;
+ }
+}end
diff --git a/src/lib/libast/features/common b/src/lib/libast/features/common
new file mode 100644
index 0000000..500ce87
--- /dev/null
+++ b/src/lib/libast/features/common
@@ -0,0 +1,624 @@
+iff AST_COMMON
+hdr pthread,stdarg,stddef,stdint,inttypes,types,unistd
+sys types
+typ long.double,size_t,ssize_t
+typ __va_list stdio.h
+
+mac SF_APPEND,SF_CLOSE sys/stat.h sys/socket.h
+
+dll import note{ Microsoft import/export nonsense }end execute{
+ __declspec(dllimport) int foo;
+ int main() { return foo == 5 ? 0 : 1; }
+ int bar = 5;
+ int* _imp__foo = &bar;
+}end
+
+std proto note{ standard C prototypes ok }end compile{
+ extern int foo(int, int);
+ bar() { foo(1, 1); }
+}end
+
+tst ptr_void note{ standard C void* ok }end compile{
+ extern void* foo();
+ void* bar() { return foo(); }
+}end
+
+cat{
+ /* disable non-standard linux/gnu inlines */
+ #ifdef __GNUC__
+ # undef __OPTIMIZE_SIZE__
+ # define __OPTIMIZE_SIZE__ 1
+ #endif
+
+ /* __STD_C indicates that the language is ANSI-C or C++ */
+ #if !defined(__STD_C) && __STDC__
+ # define __STD_C 1
+ #endif
+ #if !defined(__STD_C) && (__cplusplus || c_plusplus)
+ # define __STD_C 1
+ #endif
+ #if !defined(__STD_C) && _std_proto
+ # define __STD_C 1
+ #endif
+ #if !defined(__STD_C)
+ # define __STD_C 0
+ #endif
+
+ /* extern symbols must be protected against C++ name mangling */
+ #ifndef _BEGIN_EXTERNS_
+ # if __cplusplus || c_plusplus
+ # define _BEGIN_EXTERNS_ extern "C" {
+ # define _END_EXTERNS_ }
+ # else
+ # define _BEGIN_EXTERNS_
+ # define _END_EXTERNS_
+ # endif
+ #endif
+
+ /* _ARG_ simplifies function prototyping among flavors of C */
+ #ifndef _ARG_
+ # if __STD_C
+ # define _ARG_(x) x
+ # else
+ # define _ARG_(x) ()
+ # endif
+ #endif
+
+ /* _NIL_ simplifies defining nil pointers to a given type */
+ #ifndef _NIL_
+ # define _NIL_(x) ((x)0)
+ #endif
+
+ /* __INLINE__, if defined, is the inline keyword */
+ #if !defined(__INLINE__) && defined(__cplusplus)
+ # define __INLINE__ inline
+ #endif
+ #if !defined(__INLINE__) && defined(_WIN32) && !defined(__GNUC__)
+ # define __INLINE__ __inline
+ #endif
+
+ /* Void_t is defined so that Void_t* can address any type */
+ #ifndef Void_t
+ # if __STD_C
+ # define Void_t void
+ # else
+ # define Void_t char
+ # endif
+ #endif
+
+ /* windows variants and veneers */
+ #if !defined(_WINIX) && (_UWIN || __CYGWIN__ || __EMX__)
+ # define _WINIX 1
+ #endif
+
+ /* dynamic linked library external scope handling */
+ #ifdef __DYNAMIC__
+ # undef __DYNAMIC__
+ # ifndef _DLL
+ # define _DLL 1
+ # endif
+ #endif
+ #if _dll_import
+ # if _BLD_STATIC && !_BLD_DLL
+ # undef _DLL
+ # else
+ # if !_UWIN && !defined(_DLL)
+ # define _DLL 1
+ # endif
+ # endif
+ # if !defined(__EXPORT__) && _BLD_DLL
+ # define __EXPORT__ __declspec(dllexport)
+ # endif
+ # if !defined(__IMPORT__) && ( _BLD_DLL || defined(_DLL) )
+ # define __IMPORT__ __declspec(dllimport)
+ # endif
+ # if _BLD_DLL && _UWIN
+ # define __DYNAMIC__(v) (_ast_getdll()->_ast_ ## v)
+ # endif
+ #endif
+ #if !defined(_astimport)
+ # if defined(__IMPORT__) && defined(_DLL)
+ # define _astimport __IMPORT__
+ # else
+ # define _astimport extern
+ # endif
+ #endif
+ #if _dll_import && ( !_BLD_DLL || _WINIX && !_UWIN )
+ # ifdef __STDC__
+ # define __EXTERN__(T,obj) extern T obj; T* _imp__ ## obj = &obj
+ # define __DEFINE__(T,obj,val) T obj = val; T* _imp__ ## obj = &obj
+ # else
+ # define __EXTERN__(T,obj) extern T obj; T* _imp__/**/obj = &obj
+ # define __DEFINE__(T,obj,val) T obj = val; T* _imp__/**/obj = &obj
+ # endif
+ #else
+ # define __EXTERN__(T,obj) extern T obj
+ # define __DEFINE__(T,obj,val) T obj = val
+ #endif
+}end
+
+if tst - note{ <stdarg.h>+<wchar.h> works }end compile{
+ /*<NOSTDIO>*/
+ #include <stdarg.h>
+ #include <wchar.h>
+ }end
+elif tst - note{ explicit <sys/va_list.h> before <stdarg.h>+<wchar.h> }end compile{
+ /*<NOSTDIO>*/
+ #include <sys/va_list.h>
+ #include <stdarg.h>
+ #include <wchar.h>
+ }end {
+ #include <sys/va_list.h>
+ }
+endif
+
+tst ast_LL note{ LL numeric suffix supported }end compile{
+ int i = 1LL;
+ unsigned int u = 1ULL; /* NOTE: some compilers choke on 1LLU */
+}end
+
+tst - -DN=1 - -DN=2 - -DN=3 - -DN=4 - -DN=5 - -DN=6 - -DN=7 - -DN=8 - -DN=0 output{
+ #define _BYTESEX_H
+
+ #include <string.h>
+ #include <sys/types.h>
+
+ #if _STD_
+ #if N == 1
+ #define _ast_int8_t long
+ #define _ast_int8_str "long"
+ #endif
+ #if N == 2
+ #define _ast_int8_t long long
+ #define _ast_int8_str "long long"
+ #endif
+ #if N == 3
+ #define _ast_int8_t __int64
+ #define _ast_int8_str "__int64"
+ #endif
+ #if N == 4
+ #define _ast_int8_t __int64_t
+ #define _ast_int8_str "__int64_t"
+ #endif
+ #if N == 5
+ #define _ast_int8_t _int64_t
+ #define _ast_int8_str "_int64_t"
+ #endif
+ #if N == 6
+ #define _ast_int8_t int64_t
+ #define _ast_int8_str "int64_t"
+ #endif
+ #if N == 7
+ #define _ast_int8_t _int64
+ #define _ast_int8_str "_int64"
+ #endif
+ #if N == 8
+ #define _ast_int8_t int64
+ #define _ast_int8_str "int64"
+ #endif
+ #endif
+
+ #define elementsof(x) (sizeof(x)/sizeof(x[0]))
+
+ static char i_char = 1;
+ static short i_short = 1;
+ static int i_int = 1;
+ static long i_long = 1L;
+ #ifdef _ast_int8_t
+ #if _ast_LL
+ static _ast_int8_t i_long_long = 1LL;
+ static unsigned _ast_int8_t u_long_long = 18446744073709551615ULL;
+ #else
+ static _ast_int8_t i_long_long = 1;
+ static unsigned _ast_int8_t u_long_long = 18446744073709551615;
+ #endif
+ #endif
+
+ static struct
+ {
+ char* name;
+ int size;
+ char* swap;
+ } int_type[] =
+ {
+ "char", sizeof(char), (char*)&i_char,
+ "short", sizeof(short), (char*)&i_short,
+ "int", sizeof(int), (char*)&i_int,
+ "long", sizeof(long), (char*)&i_long,
+ #ifdef _ast_int8_t
+ _ast_int8_str, sizeof(_ast_int8_t), (char*)&i_long_long,
+ #endif
+ };
+
+ static int int_size[] = { 1, 2, 4, 8 };
+
+ int
+ main()
+ {
+ register int t;
+ register int s;
+ register int m = 1;
+ register int b = 1;
+ register int w = 0;
+
+ #ifdef _ast_int8_t
+ unsigned _ast_int8_t p;
+ char buf[64];
+
+ if (int_type[elementsof(int_type)-1].size <= 4)
+ return 1;
+ p = 0x12345678;
+ p <<= 32;
+ p |= 0x9abcdef0;
+ sprintf(buf, "0x%016llx", p);
+ if (strcmp(buf, "0x123456789abcdef0"))
+ return 1;
+ #endif
+ for (s = 0; s < elementsof(int_size); s++)
+ {
+ for (t = 0; t < elementsof(int_type) && int_type[t].size < int_size[s]; t++);
+ if (t < elementsof(int_type))
+ {
+ m = int_size[s];
+ #if __INTERIX
+ if (m == 8)
+ {
+ printf("#ifdef _MSC_VER\n");
+ printf("#define _ast_int8_t __int64\n");
+ printf("#else\n");
+ printf("#define _ast_int8_t long long\n");
+ printf("#endif\n");
+ }
+ else
+ #endif
+ printf("#define _ast_int%d_t %s\n", m, int_type[t].name);
+ if (m > 1)
+ {
+ if (*int_type[t].swap)
+ w |= b;
+ b <<= 1;
+ }
+ }
+ }
+ printf("#define _ast_intmax_t _ast_int%d_t\n", m);
+ if (m == sizeof(long))
+ printf("#define _ast_intmax_long 1\n");
+ printf("#define _ast_intswap %d\n", w);
+ printf("\n");
+ return 0;
+ }
+}end
+
+tst - output{
+ #include <string.h>
+ #include <sys/types.h>
+
+ #if _X86_ || _X64_
+ #define COND 1
+ #define CONDNAME "_X64_"
+ #else
+ #define COND 0
+ #endif
+
+ #define elementsof(x) (sizeof(x)/sizeof(x[0]))
+
+ static struct
+ {
+ char* name;
+ int size;
+ int cond;
+ } types[] =
+ {
+ "short", sizeof(short), 0,
+ "int", sizeof(int), 0,
+ "long", sizeof(long), 0,
+ "size_t", sizeof(size_t), 0,
+ "pointer", sizeof(void*), COND * 4,
+ "float", sizeof(float), 0,
+ "double", sizeof(double), 0,
+ #ifdef _typ_long_double
+ "long_double", sizeof(long double), 0,
+ #endif
+ };
+
+ int
+ main()
+ {
+ register int t;
+
+ for (t = 0; t < elementsof(types); t++)
+ #if COND
+ if (types[t].cond)
+ {
+ printf("#if %s\n", CONDNAME);
+ printf("#define _ast_sizeof_%s%s %d /* sizeof(%s) */\n", types[t].name, strlen(types[t].name) < 4 ? "\t" : "", types[t].cond * 2, types[t].name);
+ printf("#else\n");
+ printf("#define _ast_sizeof_%s%s %d /* sizeof(%s) */\n", types[t].name, strlen(types[t].name) < 4 ? "\t" : "", types[t].cond, types[t].name);
+ printf("#endif\n");
+ }
+ else
+ #endif
+ printf("#define _ast_sizeof_%s%s %d /* sizeof(%s) */\n", types[t].name, strlen(types[t].name) < 4 ? "\t" : "", types[t].size, types[t].name);
+ printf("\n");
+ return 0;
+ }
+}end
+
+tst - -DN=1 - -DN=0 output{
+ #define _BYTESEX_H
+
+ #include <string.h>
+ #include <sys/types.h>
+
+ #if !N || !_STD_
+ #undef _typ_long_double
+ #endif
+
+ #define elementsof(x) (sizeof(x)/sizeof(x[0]))
+
+ static struct
+ {
+ char* name;
+ int size;
+ } flt_type[] =
+ {
+ "float", sizeof(float),
+ "double", sizeof(double),
+ #ifdef _typ_long_double
+ "long double", sizeof(long double),
+ #endif
+ };
+
+ int
+ main()
+ {
+ register int t;
+ register int m = 1;
+
+ #ifdef _typ_long_double
+ long double p;
+ char buf[64];
+
+ if (flt_type[elementsof(flt_type)-1].size <= sizeof(double))
+ return 1;
+ p = 1.12345E-55;
+ sprintf(buf, "%1.5LE", p);
+ if (strcmp(buf, "1.12345E-55"))
+ return 1;
+ #endif
+ for (t = 0; t < elementsof(flt_type); t++)
+ {
+ while (t < (elementsof(flt_type) - 1) && flt_type[t].size == flt_type[t + 1].size)
+ t++;
+ m = flt_type[t].size;
+ printf("#define _ast_flt%d_t %s\n", flt_type[t].size, flt_type[t].name);
+ }
+ printf("#define _ast_fltmax_t _ast_flt%d_t\n", m);
+ if (m == sizeof(double))
+ printf("#define _ast_fltmax_double 1\n");
+ return 0;
+ }
+}end
+
+typ int8_t stdint.h inttypes.h no{
+ #undef _typ_int8_t
+ #define _typ_int8_t 1
+ typedef _ast_int1_t int8_t;
+}end
+typ uint8_t stdint.h inttypes.h no{
+ #undef _typ_uint8_t
+ #define _typ_uint8_t 1
+ typedef unsigned _ast_int1_t uint8_t;
+}end
+typ int16_t stdint.h inttypes.h no{
+ #undef _typ_int16_t
+ #define _typ_int16_t 1
+ typedef _ast_int2_t int16_t;
+}end
+typ uint16_t stdint.h inttypes.h no{
+ #undef _typ_uint16_t
+ #define _typ_uint16_t 1
+ typedef unsigned _ast_int2_t uint16_t;
+}end
+typ int32_t stdint.h inttypes.h no{
+ #undef _typ_int32_t
+ #define _typ_int32_t 1
+ typedef _ast_int4_t int32_t;
+}end
+typ uint32_t stdint.h inttypes.h no{
+ #undef _typ_uint32_t
+ #define _typ_uint32_t 1
+ typedef unsigned _ast_int4_t uint32_t;
+}end
+typ int64_t stdint.h inttypes.h no{
+ #ifdef _ast_int8_t
+ #undef _typ_int64_t
+ #define _typ_int64_t 1
+ typedef _ast_int8_t int64_t;
+ #endif
+}end
+typ uint64_t stdint.h inttypes.h no{
+ #ifdef _ast_int8_t
+ #undef _typ_uint64_t
+ #define _typ_uint64_t 1
+ typedef unsigned _ast_int8_t uint64_t;
+ #endif
+}end
+typ intmax_t stdint.h inttypes.h no{
+ #undef _typ_intmax_t
+ #define _typ_intmax_t 1
+ typedef _ast_intmax_t intmax_t;
+}end
+typ uintmax_t stdint.h inttypes.h no{
+ #undef _typ_uintmax_t
+ #define _typ_uintmax_t 1
+ typedef unsigned _ast_intmax_t uintmax_t;
+}end
+typ uintptr_t stdint.h inttypes.h no{
+ #undef _typ_uintptr_t
+ #define _typ_uintptr_t 1
+ #if _ast_sizeof_pointer == 8 && defined(_ast_int8_t)
+ typedef unsigned _ast_int8_t uintptr_t;
+ #else
+ typedef unsigned _ast_int4_t uintptr_t;
+ #endif
+}end
+
+tst - -DTRY=1 - -DTRY=1 -Dvoid=char - -DTRY=2 - -DTRY=3 - -DTRY=4 output{
+ #if _STD_ && _hdr_stdarg
+ #include <stdarg.h>
+ static void
+ varyfunny(int* p, ...)
+ {
+ va_list ap;
+ va_start(ap, p);
+ #if TRY == 1
+ *p = *ap++ != 0;
+ #endif /*TRY == 1*/
+ #if TRY == 2
+ *p = *ap != 0;
+ #endif /*TRY == 2*/
+ #if TRY == 3
+ *p = ap++ != 0;
+ #endif /*TRY == 3*/
+ va_end(ap);
+ }
+ #else
+ #include <varargs.h>
+ static void
+ varyfunny(va_alist)
+ va_dcl
+ {
+ va_list ap;
+ int* p;
+ va_start(ap);
+ p = va_arg(ap, int*);
+ #if TRY == 1
+ *p = *ap++ != 0;
+ #endif /*TRY == 1*/
+ #if TRY == 2
+ *p = *ap != 0;
+ #endif /*TRY == 2*/
+ #if TRY == 3
+ *p = ap++ != 0;
+ #endif /*TRY == 3*/
+ va_end(ap);
+ }
+ #endif
+ int
+ main()
+ {
+ int r;
+
+ printf("\n#ifndef va_listref\n");
+ printf("#ifndef va_start\n");
+ printf("#if __STD_C\n");
+ printf("#include <stdarg.h>\n");
+ printf("#else\n");
+ printf("#include <varargs.h>\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ #if TRY == 4
+ printf("#define va_listref(p) (&(p))\t");
+ printf("/* pass va_list to varargs function */\n");
+ printf("#define va_listval(p) (*(p))\t");
+ printf("/* retrieve va_list from va_arg(ap,va_listarg) */\n");
+ printf("#define va_listarg va_list*\t");
+ printf("/* va_arg() va_list type */\n");
+ #else
+ varyfunny(&r);
+ printf("#define va_listref(p) (p)\t");
+ printf("/* pass va_list to varargs function */\n");
+ if (sizeof(va_list) > sizeof(void*))
+ printf("#define va_listval(p) (*(p))\t");
+ else
+ printf("#define va_listval(p) (p)\t");
+ printf("/* retrieve va_list from va_arg(ap,va_listarg) */\n");
+ #if TRY == 2
+ printf("#define va_listarg va_list*\t");
+ #else
+ printf("#define va_listarg va_list\t");
+ #endif /*TRY == 2*/
+ printf("/* va_arg() va_list type */\n");
+ #endif /*TRY == 4*/
+
+ #if _UWIN
+ printf("#ifndef va_copy\n");
+ printf("#define va_copy(to,fr) ((to)=(fr))\t");
+ printf("/* copy va_list fr -> to */\n");
+ printf("#endif\n");
+ #else
+ #if !defined(va_copy)
+ #if defined(__va_copy)
+ printf("#ifndef va_copy\n");
+ printf("#define va_copy(to,fr) __va_copy(to,fr)\t");
+ printf("/* copy va_list fr -> to */\n");
+ printf("#endif\n");
+ #else
+ #if TRY == 2
+ printf("#ifndef va_copy\n");
+ printf("#define va_copy(to,fr) memcpy(to,fr,sizeof(va_list))\t");
+ printf("/* copy va_list fr -> to */\n");
+ printf("#endif\n");
+ #else
+ printf("#ifndef va_copy\n");
+ printf("#define va_copy(to,fr) ((to)=(fr))\t");
+ printf("/* copy va_list fr -> to */\n");
+ printf("#endif\n");
+ #endif
+ #endif
+ #endif
+ #endif
+
+ printf("#endif\n");
+ return 0;
+ }
+}end
+
+cat{
+ #ifndef _AST_STD_H
+ # if __STD_C && _hdr_stddef
+ # include <stddef.h>
+ # endif
+ # if _sys_types
+ # include <sys/types.h>
+ # endif
+ # if _hdr_stdint
+ # include <stdint.h>
+ # else
+ # if _hdr_inttypes
+ # include <inttypes.h>
+ # endif
+ # endif
+ #endif
+ #if !_typ_size_t
+ # define _typ_size_t 1
+ typedef int size_t;
+ #endif
+ #if !_typ_ssize_t
+ # define _typ_ssize_t 1
+ typedef int ssize_t;
+ #endif
+ #ifndef _AST_STD_H
+ # define _def_map_ast 1
+ # if !_def_map_ast
+ # include <ast_map.h>
+ # endif
+ #endif
+}end
+
+run{
+ grep __NO_INCLUDE_WARN__ /usr/include/stat.h >/dev/null 2>&1 &&
+ grep '<name.h>' /usr/include/sys/stat.h >/dev/null 2>&1 &&
+ grep __name_h /usr/include/name.h >/dev/null 2>&1 &&
+ cat <<!
+ /* disable ${HOSTTYPE} <sys/foo.h> vs. <foo.h> clash warnings */
+ #ifndef __NO_INCLUDE_WARN__
+ #define __NO_INCLUDE_WARN__ 1
+ #endif
+ /* disable ${HOSTTYPE} <sys/stat.h> <name.h> hijack */
+ #ifndef __name_h
+ #define __name_h 1
+ #endif
+ !
+}end
diff --git a/src/lib/libast/features/dirent b/src/lib/libast/features/dirent
new file mode 100644
index 0000000..a36d35a
--- /dev/null
+++ b/src/lib/libast/features/dirent
@@ -0,0 +1,275 @@
+set prototyped
+
+set nodefine
+lib stat64 -D_LARGEFILE64_SOURCE
+typ off64_t -D_LARGEFILE64_SOURCE
+set define
+
+lib opendir
+hdr dirent,ndir
+sys dir
+nxt dirent
+
+tst botch_d_ino_dirent64 -D_LARGEFILE64_SOURCE note{ dirent64.d_ino vs. readdir64 mismatch }end compile{
+ #if !__arm__
+ )
+ #endif
+ #include <dirent.h>
+ int
+ main()
+ {
+ struct dirent64 ent;
+ char aha[5-((int)sizeof(ent.d_ino))];
+ return sizeof(aha);
+ }
+}end
+
+if ( ! _lib_opendir ) {
+ /*
+ * <dirent.h> for systems with no opendir()
+ */
+
+ #ifndef _DIRENT_H
+ #define _DIRENT_H
+
+ typedef struct
+ {
+ int dd_fd; /* file descriptor */
+ #ifdef _DIR_PRIVATE_
+ _DIR_PRIVATE_
+ #endif
+ } DIR;
+
+ struct dirent
+ {
+ long d_fileno; /* entry serial number */
+ int d_reclen; /* entry length */
+ int d_namlen; /* entry name length */
+ char d_name[1]; /* entry name */
+ };
+
+ #ifndef _DIR_PRIVATE_
+
+ #ifdef rewinddir
+ #undef rewinddir
+ #define rewinddir(p) seekdir(p,0L)
+ #endif
+
+ extern DIR* opendir(const char*);
+ extern void closedir(DIR*);
+ extern struct dirent* readdir(DIR*);
+ extern void seekdir(DIR*, long);
+ extern long telldir(DIR*);
+
+ #endif
+
+ #endif
+}
+elif ( _nxt_dirent && _lib_stat64 && _typ_off64_t && _botch_d_ino_dirent64 ) pass{
+cat <<!
+ /*
+ * <dirent.h> for [fl]stat64 and off64_t with sizeof(ino64_t)==4
+ */
+
+ #ifndef _AST_STD_H
+
+ #include ${_nxt_dirent-_nxt_dirent} /* the native <dirent.h> */
+
+ #else
+
+ #ifndef _DIR64_H
+ #define _DIR64_H
+
+ #include <ast_std.h>
+
+ #if _typ_off64_t
+ #undef off_t
+ #endif
+
+ #undef __ino64_t
+ #define __ino64_t int64_t
+
+ #include ${_nxt_dirent-_nxt_dirent} /* the native <dirent.h> */
+
+ #undef __ino64_t
+ #define __ino64_t __ino64_t
+
+ #if _typ_off64_t
+ #define off_t off64_t
+ #endif
+
+ #if _lib_readdir64 && _typ_struct_dirent64
+ #ifndef dirent
+ #define dirent dirent64
+ #endif
+ #ifndef readdir
+ #define readdir readdir64
+ #endif
+ #endif
+
+ #endif
+
+ #endif
+!
+}end
+elif ( _nxt_dirent && _lib_stat64 && _typ_off64_t ) pass{
+cat <<!
+ /*
+ * <dirent.h> for [fl]stat64 and off64_t
+ */
+
+ #ifndef _AST_STD_H
+
+ #include ${_nxt_dirent-_nxt_dirent} /* the native <dirent.h> */
+
+ #else
+
+ #ifndef _DIR64_H
+ #define _DIR64_H
+
+ #include <ast_std.h>
+
+ #if _typ_off64_t
+ #undef off_t
+ #endif
+
+ #include ${_nxt_dirent-_nxt_dirent} /* the native <dirent.h> */
+
+ #if _typ_off64_t
+ #define off_t off64_t
+ #endif
+
+ #if _lib_readdir64 && _typ_struct_dirent64
+ #ifndef dirent
+ #define dirent dirent64
+ #endif
+ #ifndef readdir
+ #define readdir readdir64
+ #endif
+ #endif
+
+ #endif
+
+ #endif
+!
+}end
+elif ( _nxt_dirent && _hdr_dirent ) pass{
+cat <<!
+ /*
+ * <dirent.h> for systems with ok <dirent.h>
+ */
+
+ #ifndef _DIRENT_H
+
+ #include ${_nxt_dirent-_nxt_dirent} /* the native <dirent.h> */
+
+ #ifndef _DIRENT_H
+ #define _DIRENT_H
+ #endif
+
+ #endif
+!
+}end
+elif ( _hdr_ndir ) {
+ /*
+ * <dirent.h> for systems with opendir() and <ndir.h>
+ */
+
+ #ifndef _DIRENT_H
+ #define _DIRENT_H
+
+ #if defined(__STDPP__directive) && defined(__STDPP__hide)
+ __STDPP__directive pragma pp:hide closedir opendir readdir seekdir telldir
+ #else
+ #define closedir ______closedir
+ #define opendir ______opendir
+ #define readdir ______readdir
+ #define seekdir ______seekdir
+ #define telldir ______telldir
+ #endif
+
+ #include <ndir.h>
+
+ #if defined(__STDPP__directive) && defined(__STDPP__hide)
+ __STDPP__directive pragma pp:nohide closedir opendir readdir seekdir telldir
+ #else
+ #undef closedir
+ #undef opendir
+ #undef readdir
+ #undef seekdir
+ #undef telldir
+ #endif
+
+ #ifndef dirent
+ #define dirent direct
+ #endif
+
+ #if !defined(d_fileno) && !defined(d_ino)
+ #define d_fileno d_ino
+ #endif
+
+ #ifdef rewinddir
+ #undef rewinddir
+ #define rewinddir(p) seekdir(p,0L)
+ #endif
+
+ extern DIR* opendir(const char*);
+ extern void closedir(DIR*);
+ extern struct dirent* readdir(DIR*);
+ extern void seekdir(DIR*, long);
+ extern long telldir(DIR*);
+
+ #endif
+}
+elif ( _sys_dir ) {
+ /*
+ * <dirent.h> for systems with opendir() and no <ndir.h>
+ */
+
+ #ifndef _DIRENT_H
+ #define _DIRENT_H
+
+ #if defined(__STDPP__directive) && defined(__STDPP__hide)
+ __STDPP__directive pragma pp:hide closedir opendir readdir seekdir telldir
+ #else
+ #define closedir ______closedir
+ #define opendir ______opendir
+ #define readdir ______readdir
+ #define seekdir ______seekdir
+ #define telldir ______telldir
+ #endif
+
+ #include <sys/dir.h>
+
+ #if defined(__STDPP__directive) && defined(__STDPP__hide)
+ __STDPP__directive pragma pp:nohide closedir opendir readdir seekdir telldir
+ #else
+ #undef closedir
+ #undef opendir
+ #undef readdir
+ #undef seekdir
+ #undef telldir
+ #endif
+
+ #ifndef dirent
+ #define dirent direct
+ #endif
+
+ #if !defined(d_fileno) && !defined(d_ino)
+ #define d_fileno d_ino
+ #endif
+
+ #ifdef rewinddir
+ #undef rewinddir
+ #define rewinddir(p) seekdir(p,0L)
+ #endif
+
+ extern DIR* opendir(const char*);
+ extern void closedir(DIR*);
+ extern struct dirent* readdir(DIR*);
+ extern void seekdir(DIR*, long);
+ extern long telldir(DIR*);
+
+ #endif
+}
+endif
diff --git a/src/lib/libast/features/eaccess b/src/lib/libast/features/eaccess
new file mode 100644
index 0000000..bf9710a
--- /dev/null
+++ b/src/lib/libast/features/eaccess
@@ -0,0 +1,11 @@
+lib eaccess,euidaccess
+macro{
+ #include <sys/types.h>
+ #include <unistd.h>
+ #ifdef EFF_ONLY_OK
+ <<"#define EFF_ONLY_OK">> EFF_ONLY_OK
+ #endif
+ #ifdef EX_OK
+ <<"#define EX_OK">> EX_OK
+ #endif
+}end
diff --git a/src/lib/libast/features/errno b/src/lib/libast/features/errno
new file mode 100644
index 0000000..271fe6d
--- /dev/null
+++ b/src/lib/libast/features/errno
@@ -0,0 +1,31 @@
+tst dat_sys_nerr note{ sys_nerr in default libs }end compile{
+ extern int sys_nerr;
+ int f()
+ {
+ return sys_nerr > 0;
+ }
+}end
+
+tst def_errno_sys_nerr note{ sys_nerr declared in errno.h }end compile{
+ #include <errno.h>
+ int f()
+ {
+ return sys_nerr > 0;
+ }
+}end
+
+tst dat_sys_errlist note{ sys_errlist in default libs }end compile{
+ extern char* sys_errlist[];
+ int f()
+ {
+ return *sys_errlist[1] != 0;
+ }
+}end
+
+tst def_errno_sys_errlist note{ sys_errlist declared in errno.h }end compile{
+ #include <errno.h>
+ int f()
+ {
+ return *sys_errlist[1] != 0;
+ }
+}end
diff --git a/src/lib/libast/features/fcntl.c b/src/lib/libast/features/fcntl.c
new file mode 100644
index 0000000..0868f06
--- /dev/null
+++ b/src/lib/libast/features/fcntl.c
@@ -0,0 +1,360 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * generate POSIX fcntl.h
+ */
+
+#include <sys/types.h>
+
+#include "FEATURE/lib"
+
+#define getdtablesize ______getdtablesize
+#define getpagesize ______getpagesize
+#define ioctl ______ioctl
+
+#if _typ_off64_t
+#undef off_t
+#ifdef __STDC__
+#define off_t off_t
+#endif
+#endif
+
+#if _hdr_fcntl
+#include <fcntl.h>
+#endif
+#if _hdr_unistd
+#include <unistd.h>
+#endif
+
+#include <sys/stat.h>
+
+#include "FEATURE/fs"
+
+#undef getdtablesize
+#undef getpagesize
+#undef ioctl
+
+#include "FEATURE/tty"
+
+#if _typ_off64_t
+#undef off_t
+#define off_t off64_t
+#endif
+
+int
+main()
+{
+ int f_local = 0;
+ int f_lck = 0;
+ int o_local = 2;
+
+ printf("#pragma prototyped\n");
+ printf("\n");
+ printf("#if _typ_off64_t\n");
+ printf("#undef off_t\n");
+ printf("#ifdef __STDC__\n");
+ printf("#define off_t off_t\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n");
+ printf("#include <ast_fs.h>\n");
+ printf("\n");
+ printf("#if _typ_off64_t\n");
+ printf("#undef off_t\n");
+ printf("#ifdef __STDC__\n");
+ printf("#define off_t off_t\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n");
+ printf("#include <fcntl.h>\n");
+#if _hdr_mman
+ printf("#include <mman.h>\n");
+#else
+#if _sys_mman
+ printf("#include <sys/mman.h>\n");
+#endif
+#endif
+ printf("\n");
+#ifndef FD_CLOEXEC
+ printf("#define FD_CLOEXEC 1\n");
+ printf("\n");
+#endif
+
+#ifndef F_DUPFD
+#define NEED_F 1
+#else
+ if (F_DUPFD > f_local) f_local = F_DUPFD;
+#endif
+#ifndef F_GETFD
+#define NEED_F 1
+#else
+ if (F_GETFD > f_local) f_local = F_GETFD;
+#endif
+#ifndef F_GETFL
+#define NEED_F 1
+#else
+ if (F_GETFL > f_local) f_local = F_GETFL;
+#endif
+#ifndef F_GETLK
+#define NEED_F 1
+#else
+ if (F_GETLK > f_local) f_local = F_GETLK;
+#endif
+#ifndef F_RDLCK
+#define NEED_F 1
+#define NEED_LCK 1
+#else
+ if (F_RDLCK > f_lck) f_lck = F_RDLCK;
+#endif
+#ifndef F_SETFD
+#define NEED_F 1
+#else
+ if (F_SETFD > f_local) f_local = F_SETFD;
+#endif
+#ifndef F_SETFL
+#define NEED_F 1
+#else
+ if (F_SETFL > f_local) f_local = F_SETFL;
+#endif
+#ifndef F_SETLK
+#define NEED_F 1
+#else
+ if (F_SETLK > f_local) f_local = F_SETLK;
+#endif
+#ifndef F_SETLKW
+#define NEED_F 1
+#else
+ if (F_SETLKW > f_local) f_local = F_SETLKW;
+#endif
+#ifndef F_UNLCK
+#define NEED_F 1
+#define NEED_LCK 1
+#else
+ if (F_UNLCK > f_lck) f_lck = F_UNLCK;
+#endif
+#ifndef F_WRLCK
+#define NEED_F 1
+#define NEED_LCK 1
+#else
+ if (F_WRLCK > f_lck) f_lck = F_WRLCK;
+#endif
+
+#if NEED_F
+ printf("#define fcntl _ast_fcntl\n");
+#if _lib_fcntl
+ printf("#define _lib_fcntl 1\n");
+#endif
+ printf("#define _ast_F_LOCAL %d\n", f_local + 1);
+#ifndef F_DUPFD
+ printf("#define F_DUPFD %d\n", ++f_local);
+#endif
+#ifndef F_GETFD
+ printf("#define F_GETFD %d\n", ++f_local);
+#endif
+#ifndef F_GETFL
+ printf("#define F_GETFL %d\n", ++f_local);
+#endif
+#ifndef F_GETLK
+ printf("#define F_GETLK %d\n", ++f_local);
+#endif
+#ifndef F_SETFD
+ printf("#define F_SETFD %d\n", ++f_local);
+#endif
+#ifndef F_SETFL
+ printf("#define F_SETFL %d\n", ++f_local);
+#endif
+#ifndef F_SETLK
+ printf("#define F_SETLK %d\n", ++f_local);
+#endif
+#ifndef F_SETLKW
+ printf("#define F_SETLKW %d\n", ++f_local);
+#endif
+#if NEED_LCK
+ printf("\n");
+#ifndef F_RDLCK
+ printf("#define F_RDLCK %d\n", f_lck++);
+#endif
+#ifndef F_WRLCK
+ printf("#define F_WRLCK %d\n", f_lck++);
+#endif
+#ifndef F_UNLCK
+ printf("#define F_UNLCK %d\n", f_lck++);
+#endif
+#endif
+ printf("\n");
+ if (f_lck == 3)
+ {
+ printf("struct flock\n");
+ printf("{\n");
+ printf(" short l_type;\n");
+ printf(" short l_whence;\n");
+ printf(" off_t l_start;\n");
+ printf(" off_t l_len;\n");
+ printf(" short l_pid;\n");
+ printf("};\n");
+ printf("\n");
+ }
+ printf("\n");
+#endif
+
+#ifndef O_APPEND
+#define NEED_O 1
+#else
+ if (O_APPEND > o_local) o_local = O_APPEND;
+#endif
+#ifndef O_CREAT
+#define NEED_O 1
+#else
+ if (O_CREAT > o_local) o_local = O_CREAT;
+#endif
+#ifndef O_EXCL
+#define NEED_O 1
+#else
+ if (O_EXCL > o_local) o_local = O_EXCL;
+#endif
+#ifndef O_NOCTTY
+#ifdef TIOCNOTTY
+#define NEED_O 1
+#endif
+#else
+ if (O_NOCTTY > o_local) o_local = O_NOCTTY;
+#endif
+#ifndef O_NONBLOCK
+#ifndef O_NDELAY
+#define NEED_O 1
+#endif
+#else
+ if (O_NONBLOCK > o_local) o_local = O_NONBLOCK;
+#endif
+#ifndef O_RDONLY
+#define NEED_O 1
+#endif
+#ifndef O_RDWR
+#define NEED_O 1
+#endif
+#ifndef O_TRUNC
+#define NEED_O 1
+#else
+ if (O_TRUNC > o_local) o_local = O_TRUNC;
+#endif
+#ifndef O_WRONLY
+#define NEED_O 1
+#endif
+
+#if NEED_O
+ printf("#define open _ast_open\n");
+ printf("#define _ast_O_LOCAL 0%o\n", o_local<<1);
+#ifndef O_RDONLY
+ printf("#define O_RDONLY 0\n");
+#endif
+#ifndef O_WRONLY
+ printf("#define O_WRONLY 1\n");
+#endif
+#ifndef O_RDWR
+ printf("#define O_RDWR 2\n");
+#endif
+#ifndef O_APPEND
+ printf("#define O_APPEND 0%o\n", o_local <<= 1);
+#endif
+#ifndef O_CREAT
+ printf("#define O_CREAT 0%o\n", o_local <<= 1);
+#endif
+#ifndef O_EXCL
+ printf("#define O_EXCL 0%o\n", o_local <<= 1);
+#endif
+#ifndef O_NOCTTY
+#ifdef TIOCNOTTY
+ printf("#define O_NOCTTY 0%o\n", o_local <<= 1);
+#endif
+#endif
+#ifndef O_NONBLOCK
+#ifndef O_NDELAY
+ printf("#define O_NONBLOCK 0%o\n", o_local <<= 1);
+#endif
+#endif
+#ifndef O_TRUNC
+ printf("#define O_TRUNC 0%o\n", o_local <<= 1);
+#endif
+#endif
+#ifndef O_ACCMODE
+ printf("#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)\n");
+#endif
+#ifndef O_NOCTTY
+#ifndef TIOCNOTTY
+ printf("#define O_NOCTTY 0\n");
+#endif
+#endif
+#ifndef O_NONBLOCK
+#ifdef O_NDELAY
+ printf("#define O_NONBLOCK O_NDELAY\n");
+#endif
+#endif
+#ifndef O_BINARY
+ printf("#define O_BINARY 0\n");
+#endif
+#ifndef O_TEMPORARY
+ printf("#define O_TEMPORARY 0\n");
+#endif
+#ifndef O_TEXT
+ printf("#define O_TEXT 0\n");
+#endif
+#if NEED_F || NEED_O
+ printf("\n");
+#if NEED_F
+ printf("extern int fcntl(int, int, ...);\n");
+#endif
+#if NEED_O
+ printf("extern int open(const char*, int, ...);\n");
+#endif
+#endif
+ printf("\n");
+ printf("#include <ast_fs.h>\n");
+ printf("#if _typ_off64_t\n");
+ printf("#undef off_t\n");
+ printf("#define off_t off64_t\n");
+ printf("#endif\n");
+ printf("#if _lib_fstat64\n");
+ printf("#define fstat fstat64\n");
+ printf("#endif\n");
+ printf("#if _lib_lstat64\n");
+ printf("#define lstat lstat64\n");
+ printf("#endif\n");
+ printf("#if _lib_stat64\n");
+ printf("#define stat stat64\n");
+ printf("#endif\n");
+ printf("#if _lib_creat64\n");
+ printf("#define creat creat64\n");
+ printf("#endif\n");
+ printf("#if _lib_mmap64\n");
+ printf("#define mmap mmap64\n");
+ printf("#endif\n");
+ printf("#if _lib_open64\n");
+ printf("#undef open\n");
+ printf("#define open open64\n");
+ printf("#endif\n");
+
+ return 0;
+}
diff --git a/src/lib/libast/features/float b/src/lib/libast/features/float
new file mode 100644
index 0000000..de27bb2
--- /dev/null
+++ b/src/lib/libast/features/float
@@ -0,0 +1,1191 @@
+set prototyped
+set nooptimize
+set stdio FEATURE/isoc99
+hdr float,limits,math,values
+lib fpclassify,frexp,frexpl,ldexp,ldexpl,finite,finitel,isinf,isinfl,isnan,isnanl,signbit,copysign,copysignl FEATURE/isoc99 math.h -lm
+
+tst ast_no_um2fm note{ no unsigned intmax => floatmax cast }end nolink{
+ #include "FEATURE/common"
+ int
+ main()
+ {
+ _ast_fltmax_t f = 0;
+ unsigned _ast_intmax_t i = 0;
+ f = i;
+ i = f;
+ return f == i;
+ }
+}end
+
+tst ast_mpy_overflow_fpe note{ fpe on mpy overflow }end noexecute{
+ int
+ main()
+ {
+ float f;
+ float p;
+ int i;
+
+ i = 0;
+ p = f = 1.0;
+ do
+ {
+ p = f;
+ f *= 2.0;
+ } while (f != p && ++i < 1024);
+ return 0;
+ }
+}end
+
+tst ast_div_underflow_fpe note{ fpe on div underflow }end noexecute{
+ int
+ main()
+ {
+ float f;
+ float p;
+ int i;
+
+ i = 0;
+ p = f = 1.0;
+ do
+ {
+ p = f;
+ f /= 2.0;
+ } while (f != p && ++i < 1024);
+ return 0;
+ }
+}end
+
+macro{
+ #if _hdr_float
+ #include <float.h>
+ #endif
+ #if _hdr_limits
+ #include <limits.h>
+ #endif
+ #if _hdr_math
+ #include <math.h>
+ #endif
+ #if _hdr_values
+ #include <values.h>
+ #endif
+
+ #if !defined(FLT_MIN_EXP) && defined(FMINEXP)
+ #define FLT_MIN_EXP FMINEXP
+ #endif
+ #if !defined(FLT_MIN) && defined(MINFLOAT)
+ #define FLT_MIN MINFLOAT
+ #endif
+ #if !defined(FLT_MAX_EXP) && defined(FMAXEXP)
+ #define FLT_MAX_EXP FMAXEXP
+ #endif
+ #if !defined(FLT_MAX) && defined(MAXFLOAT)
+ #define FLT_MAX MAXFLOAT
+ #endif
+
+ #if !defined(DBL_MIN_EXP) && defined(DMINEXP)
+ #define DBL_MIN_EXP DMINEXP
+ #endif
+ #if !defined(DBL_MIN) && defined(MINDOUBLE)
+ #define DBL_MIN MINDOUBLE
+ #endif
+ #if !defined(DBL_MAX_EXP) && defined(DMAXEXP)
+ #define DBL_MAX_EXP DMAXEXP
+ #endif
+ #if !defined(DBL_MAX) && defined(MAXDOUBLE)
+ #define DBL_MAX MAXDOUBLE
+ #endif
+
+ <<"#include <ast_common.h>">>
+ #if _hdr_float
+ <<"#include <float.h>">>
+ #endif
+ #if _hdr_math
+ <<"#include <math.h>">>
+ #endif
+ #ifdef FLT_DIG
+ <<"#ifndef FLT_DIG">>
+ <<"#define FLT_DIG">> FLT_DIG
+ <<"#endif">>
+ #endif
+ #ifdef FLT_MAX
+ <<"#ifndef FLT_MAX">>
+ <<"#define FLT_MAX">> FLT_MAX
+ <<"#endif">>
+ #endif
+ #ifdef FLT_MAX_10_EXP
+ <<"#ifndef FLT_MAX_10_EXP">>
+ <<"#define FLT_MAX_10_EXP">> FLT_MAX_10_EXP
+ <<"#endif">>
+ #endif
+ #ifdef FLT_MAX_EXP
+ <<"#ifndef FLT_MAX_EXP">>
+ <<"#define FLT_MAX_EXP">> FLT_MAX_EXP
+ <<"#endif">>
+ #endif
+ #ifdef FLT_MIN
+ <<"#ifndef FLT_MIN">>
+ <<"#define FLT_MIN">> FLT_MIN
+ <<"#endif">>
+ #endif
+ #ifdef FLT_MIN_10_EXP
+ <<"#ifndef FLT_MIN_10_EXP">>
+ <<"#define FLT_MIN_10_EXP">> FLT_MIN_10_EXP
+ <<"#endif">>
+ #endif
+ #ifdef FLT_MIN_EXP
+ <<"#ifndef FLT_MIN_EXP">>
+ <<"#define FLT_MIN_EXP">> FLT_MIN_EXP
+ <<"#endif">>
+ #endif
+
+ #ifdef DBL_DIG
+ <<"#ifndef DBL_DIG">>
+ <<"#define DBL_DIG">> DBL_DIG
+ <<"#endif">>
+ #endif
+ #ifdef DBL_MAX
+ <<"#ifndef DBL_MAX">>
+ <<"#define DBL_MAX">> DBL_MAX
+ <<"#endif">>
+ #endif
+ #ifdef DBL_MAX_10_EXP
+ <<"#ifndef DBL_MAX_10_EXP">>
+ <<"#define DBL_MAX_10_EXP">> DBL_MAX_10_EXP
+ <<"#endif">>
+ #endif
+ #ifdef DBL_MAX_EXP
+ <<"#ifndef DBL_MAX_EXP">>
+ <<"#define DBL_MAX_EXP">> DBL_MAX_EXP
+ <<"#endif">>
+ #endif
+ #ifdef DBL_MIN
+ <<"#ifndef DBL_MIN">>
+ <<"#define DBL_MIN">> DBL_MIN
+ <<"#endif">>
+ #endif
+ #ifdef DBL_MIN_10_EXP
+ <<"#ifndef DBL_MIN_10_EXP">>
+ <<"#define DBL_MIN_10_EXP">> DBL_MIN_10_EXP
+ <<"#endif">>
+ #endif
+ #ifdef DBL_MIN_EXP
+ <<"#ifndef DBL_MIN_EXP">>
+ <<"#define DBL_MIN_EXP">> DBL_MIN_EXP
+ <<"#endif">>
+ #endif
+
+ #ifdef LDBL_DIG
+ <<"#ifndef LDBL_DIG">>
+ <<"#define LDBL_DIG">> LDBL_DIG
+ <<"#endif">>
+ #endif
+ #ifdef LDBL_MAX
+ <<"#ifndef LDBL_MAX">>
+ <<"#define LDBL_MAX">> LDBL_MAX
+ <<"#endif">>
+ #endif
+ #ifdef LDBL_MAX_10_EXP
+ <<"#ifndef LDBL_MAX_10_EXP">>
+ <<"#define LDBL_MAX_10_EXP">> LDBL_MAX_10_EXP
+ <<"#endif">>
+ #endif
+ #ifdef LDBL_MAX_EXP
+ <<"#ifndef LDBL_MAX_EXP">>
+ <<"#define LDBL_MAX_EXP">> LDBL_MAX_EXP
+ <<"#endif">>
+ #endif
+ #ifdef LDBL_MIN
+ <<"#ifndef LDBL_MIN">>
+ <<"#define LDBL_MIN">> LDBL_MIN
+ <<"#endif">>
+ #endif
+ #ifdef LDBL_MIN_10_EXP
+ <<"#ifndef LDBL_MIN_10_EXP">>
+ <<"#define LDBL_MIN_10_EXP">> LDBL_MIN_10_EXP
+ <<"#endif">>
+ #endif
+ #ifdef LDBL_MIN_EXP
+ <<"#ifndef LDBL_MIN_EXP">>
+ <<"#define LDBL_MIN_EXP">> LDBL_MIN_EXP
+ <<"#endif">>
+ #endif
+}end
+
+tst - note{ missing floating point limits }end output{
+ #include "FEATURE/common"
+ #include <stdio.h>
+ #if _hdr_float
+ #include <float.h>
+ #endif
+ #if _hdr_limits
+ #include <limits.h>
+ #endif
+ #if _hdr_math
+ #include <math.h>
+ #endif
+ #if _hdr_values
+ #include <values.h>
+ #endif
+ #include <signal.h>
+ #ifdef SIGFPE
+ static int caught = 0;
+ #if _STD_
+ static void catch(int sig)
+ #else
+ static void catch(sig) int sig;
+ #endif
+ {
+ signal(sig, SIG_IGN);
+ caught++;
+ }
+ #endif
+ int
+ main()
+ {
+ register int i;
+ register int s;
+ float f;
+ float pf;
+ float mf;
+ float xf;
+ double d;
+ double pd;
+ double md;
+ char* fp;
+ #if _ast_fltmax_double
+ char* fs = "";
+ char* ds = "";
+ #else
+ _ast_fltmax_t l;
+ _ast_fltmax_t pl;
+ _ast_fltmax_t ml;
+ char* fs = "F";
+ char* ds = "";
+ char* ls = "L";
+ #endif
+ unsigned long u;
+ unsigned _ast_intmax_t w;
+ unsigned _ast_intmax_t pw;
+ unsigned _ast_intmax_t x;
+ unsigned short us;
+ unsigned int ui;
+ unsigned long ul;
+ unsigned _ast_intmax_t uq;
+
+ #ifdef SIGFPE
+ signal(SIGFPE, catch);
+ #endif
+ printf("\n");
+ printf("\n");
+ us = 0;
+ us = ~us;
+ i = 0;
+ while (us /= 10)
+ i++;
+ printf("#define USHRT_DIG %d\n", i);
+ ui = 0;
+ ui = ~ui;
+ i = 0;
+ while (ui /= 10)
+ i++;
+ printf("#define UINT_DIG %d\n", i);
+ ul = 0;
+ ul = ~ul;
+ i = 0;
+ while (ul /= 10)
+ i++;
+ printf("#define ULONG_DIG %d\n", i);
+ if (sizeof(uq) > sizeof(ul))
+ {
+ uq = 0;
+ uq = ~uq;
+ i = 0;
+ while (uq /= 10)
+ i++;
+ printf("#define ULLONG_DIG %d\n", i);
+ printf("#define UINTMAX_DIG ULLONG_DIG\n");
+ }
+ else
+ printf("#define UINTMAX_DIG ULONG_DIG\n");
+ printf("\n");
+ w = 1;
+ do
+ {
+ pw = w;
+ w *= 2;
+ f = (_ast_intmax_t)w;
+ x = (_ast_intmax_t)f;
+ } while (w > pw && w == x);
+ w = (pw - 1) + pw;
+ u = ~0;
+ if (u > w)
+ u = w;
+ printf("#define FLT_ULONG_MAX %lu.0F\n", u);
+ if (sizeof(w) > sizeof(u))
+ {
+ printf("#define FLT_ULLONG_MAX %llu.0F\n", w);
+ printf("#define FLT_UINTMAX_MAX FLT_ULLONG_MAX\n");
+ }
+ else
+ {
+ printf("#define FLT_ULLONG_MAX FLT_ULONG_MAX\n");
+ printf("#define FLT_UINTMAX_MAX FLT_ULONG_MAX\n");
+ }
+ u /= 2;
+ w /= 2;
+ printf("#define FLT_LONG_MAX %lu.0F\n", u);
+ if (sizeof(w) > sizeof(u))
+ {
+ printf("#define FLT_LLONG_MAX %llu.0F\n", w);
+ printf("#define FLT_INTMAX_MAX FLT_LLONG_MAX\n");
+ }
+ else
+ {
+ printf("#define FLT_LLONG_MAX FLT_LONG_MAX\n");
+ printf("#define FLT_INTMAX_MAX FLT_LONG_MAX\n");
+ }
+ u++;
+ w++;
+ printf("#define FLT_LONG_MIN (-%lu.0F)\n", u);
+ if (sizeof(w) > sizeof(u))
+ {
+ printf("#define FLT_LLONG_MIN (-%llu.0F)\n", w);
+ printf("#define FLT_INTMAX_MIN FLT_LLONG_MIN\n");
+ }
+ else
+ {
+ printf("#define FLT_LLONG_MIN FLT_LONG_MIN\n");
+ printf("#define FLT_INTMAX_MIN FLT_LONG_MIN\n");
+ }
+ #ifdef FLT_DIG
+ s = FLT_DIG;
+ #else
+ f = pf = 1.0;
+ s = -1;
+ do
+ {
+ s++;
+ f *= 10.0;
+ } while (f != (f + pf));
+ #endif
+ #if defined(FLT_MIN) && defined(FLT_MIN_EXP)
+ i = FLT_MIN_EXP;
+ mf = FLT_MIN;
+ #else
+ i = 3;
+ f = pf = 1.0;
+ do
+ {
+ i--;
+ mf = pf;
+ pf = f;
+ f /= 2.0;
+ } while (f < pf);
+ #ifdef FLT_MIN_EXP
+ i = FLT_MIN_EXP;
+ #endif
+ #ifdef FLT_MIN
+ mf = FLT_MIN;
+ #endif
+ #endif
+ #ifndef FLT_DIG
+ printf("#ifndef FLT_DIG\n");
+ printf("#define FLT_DIG %d\n", s);
+ printf("#endif\n");
+ #endif
+ #ifndef FLT_MIN
+ printf("#ifndef FLT_MIN\n");
+ printf("#define FLT_MIN %.*E%s\n", s + 1, mf, fs);
+ printf("#endif\n");
+ #endif
+ #ifndef FLT_MIN_EXP
+ printf("#ifndef FLT_MIN_EXP\n");
+ printf("#define FLT_MIN_EXP (%d)\n", i);
+ printf("#endif\n");
+ #endif
+
+ #if defined(FLT_MAX) && defined(FLT_MAX_EXP)
+ i = FLT_MAX_EXP;
+ f = FLT_MAX;
+ #else
+ i = -1;
+ f = pf = 1.0;
+ do
+ {
+ i++;
+ mf = pf;
+ pf = f;
+ f *= 2.0;
+ } while (f > pf);
+ #ifdef FLT_MAX_EXP
+ i = FLT_MAX_EXP;
+ #endif
+ #ifdef FLT_MAX
+ f = FLT_MAX;
+ #endif
+ #endif
+ #ifdef FLT_MAX_EXP
+ i = FLT_MAX_EXP;
+ #else
+ f = 1;
+ do
+ {
+ f *= 2.0;
+ } while (mf == (mf + f));
+ f = (mf - f) * 2.0 + f;
+ #endif
+ xf = f;
+ #ifndef FLT_MAX
+ printf("#ifndef FLT_MAX\n");
+ printf("#define FLT_MAX %.*E%s\n", s + 1, f, fs);
+ printf("#endif\n");
+ #endif
+ #ifndef FLT_MAX_EXP
+ printf("#ifndef FLT_MAX_EXP\n");
+ printf("#define FLT_MAX_EXP %d\n", i);
+ printf("#endif\n");
+ #endif
+
+ #ifdef FLT_MIN_10_EXP
+ i = FLT_MIN_10_EXP;
+ #else
+ i = 2;
+ f = 1.0;
+ do
+ {
+ i--;
+ pf = f;
+ f /= 10.0;
+ } while (f < pf);
+ #endif
+ #ifndef FLT_MIN_10_EXP
+ printf("#ifndef FLT_MIN_10_EXP\n");
+ printf("#define FLT_MIN_10_EXP (%d)\n", i);
+ printf("#endif\n");
+ #endif
+
+ #ifdef FLT_MAX_10_EXP
+ i = FLT_MAX_10_EXP;
+ #else
+ i = -2;
+ f = 1.0;
+ do
+ {
+ i++;
+ pf = f;
+ f *= 10.0;
+ } while (f > pf);
+ #endif
+ #ifndef FLT_MAX_10_EXP
+ printf("#ifndef FLT_MAX_10_EXP\n");
+ printf("#define FLT_MAX_10_EXP %d\n", i);
+ printf("#endif\n");
+ #endif
+
+ printf("\n");
+ w = 1;
+ do
+ {
+ pw = w;
+ w *= 2;
+ d = (_ast_intmax_t)w;
+ x = (_ast_intmax_t)d;
+ } while (w > pw && w == x);
+ w = (pw - 1) + pw;
+ u = ~0;
+ if (u > w)
+ u = w;
+ printf("#define DBL_ULONG_MAX %lu.0\n", u);
+ if (sizeof(w) > sizeof(u))
+ {
+ printf("#define DBL_ULLONG_MAX %llu.0\n", w);
+ printf("#define DBL_UINTMAX_MAX DBL_ULLONG_MAX\n");
+ }
+ else
+ {
+ printf("#define DBL_ULLONG_MAX DBL_ULONG_MAX\n");
+ printf("#define DBL_UINTMAX_MAX DBL_ULONG_MAX\n");
+ }
+ u /= 2;
+ w /= 2;
+ printf("#define DBL_LONG_MAX %lu.0\n", u);
+ if (sizeof(w) > sizeof(u))
+ {
+ printf("#define DBL_LLONG_MAX %llu.0\n", w);
+ printf("#define DBL_INTMAX_MAX DBL_LLONG_MAX\n");
+ }
+ else
+ {
+ printf("#define DBL_LLONG_MAX DBL_LONG_MAX\n");
+ printf("#define DBL_INTMAX_MAX DBL_LONG_MAX\n");
+ }
+ u++;
+ w++;
+ printf("#define DBL_LONG_MIN (-%lu.0)\n", u);
+ if (sizeof(w) > sizeof(u))
+ {
+ printf("#define DBL_LLONG_MIN (-%llu.0)\n", w);
+ printf("#define DBL_INTMAX_MIN DBL_LLONG_MIN\n");
+ }
+ else
+ {
+ printf("#define DBL_LLONG_MIN DBL_LONG_MIN\n");
+ printf("#define DBL_INTMAX_MIN DBL_LONG_MIN\n");
+ }
+ #ifdef DBL_DIG
+ s = DBL_DIG;
+ #else
+ d = pd = 1.0;
+ s = -1;
+ do
+ {
+ s++;
+ d *= 10.0;
+ } while (d != (d + pd));
+ #endif
+ #if defined(DBL_MIN) && defined(DBL_MIN_EXP)
+ i = DBL_MIN_EXP;
+ md = DBL_MIN;
+ #else
+ i = 3;
+ d = pd = 1.0;
+ do
+ {
+ i--;
+ md = pd;
+ pd = d;
+ d /= 2.0;
+ } while (d < pd);
+ #ifdef DBL_MIN_EXP
+ i = DBL_MIN_EXP;
+ #endif
+ #ifdef DBL_MIN
+ md = DBL_MIN;
+ #endif
+ #endif
+ #ifndef DBL_DIG
+ printf("#ifndef DBL_DIG\n");
+ printf("#define DBL_DIG %d\n", s);
+ printf("#endif\n");
+ #endif
+ #ifndef DBL_MIN
+ printf("#ifndef DBL_MIN\n");
+ printf("#define DBL_MIN %.*E%s\n", s + 1, md, ds);
+ printf("#endif\n");
+ #endif
+ #ifndef DBL_MIN_EXP
+ printf("#ifndef DBL_MIN_EXP\n");
+ printf("#define DBL_MIN_EXP (%d)\n", i);
+ printf("#endif\n");
+ #endif
+
+ #if defined(DBL_MAX) && defined(DBL_MAX_EXP)
+ i = DBL_MAX_EXP;
+ d = DBL_MAX;
+ #else
+ i = -1;
+ d = pd = 1.0;
+ do
+ {
+ i++;
+ md = pd;
+ pd = d;
+ d *= 2.0;
+ } while (d > pd);
+ d = 1.0;
+ do
+ {
+ d *= 2.0;
+ } while (md == (md + d));
+ d = (md - d) * 2.0 + d;
+ #ifdef DBL_MAX_EXP
+ i = DBL_MAX_EXP;
+ #endif
+ #ifdef DBL_MAX
+ d = DBL_MAX;
+ #endif
+ #endif
+ #ifndef DBL_MAX
+ printf("#ifndef DBL_MAX\n");
+ printf("#define DBL_MAX %.*E%s\n", s + 1, d, ds);
+ printf("#endif\n");
+ #endif
+ #ifndef DBL_MAX_EXP
+ printf("#ifndef DBL_MAX_EXP\n");
+ printf("#define DBL_MAX_EXP %d\n", i);
+ printf("#endif\n");
+ #endif
+
+ #ifdef DBL_MIN_10_EXP
+ i = DBL_MIN_10_EXP;
+ #else
+ i = 2;
+ d = 1.0;
+ do
+ {
+ i--;
+ pd = d;
+ d /= 10.0;
+ } while (d < pd);
+ #endif
+ #ifndef DBL_MIN_10_EXP
+ printf("#ifndef DBL_MIN_10_EXP\n");
+ printf("#define DBL_MIN_10_EXP (%d)\n", i);
+ printf("#endif\n");
+ #endif
+
+ #ifdef DBL_MAX_10_EXP
+ i = DBL_MAX_10_EXP;
+ #else
+ i = -2;
+ d = 1.0;
+ do
+ {
+ i++;
+ pd = d;
+ d *= 10.0;
+ } while (d > pd);
+ #endif
+ #ifndef DBL_MAX_10_EXP
+ printf("#ifndef DBL_MAX_10_EXP\n");
+ printf("#define DBL_MAX_10_EXP %d\n", i);
+ printf("#endif\n");
+ #endif
+
+ #if !_ast_fltmax_double
+ printf("\n");
+ w = 1;
+ do
+ {
+ pw = w;
+ w *= 2;
+ l = (_ast_intmax_t)w;
+ x = (_ast_intmax_t)l;
+ } while (w > pw && w == x);
+ w = (pw - 1) + pw;
+ u = ~0;
+ if (u > w)
+ u = w;
+ printf("#define LDBL_ULONG_MAX %lu.0L\n", u);
+ if (sizeof(w) > sizeof(u))
+ {
+ printf("#define LDBL_ULLONG_MAX %llu.0L\n", w);
+ printf("#define LDBL_UINTMAX_MAX LDBL_ULLONG_MAX\n");
+ }
+ else
+ {
+ printf("#define LDBL_ULLONG_MAX LDBL_ULONG_MAX\n");
+ printf("#define LDBL_UINTMAX_MAX LDBL_ULONG_MAX\n");
+ }
+ u /= 2;
+ w /= 2;
+ printf("#define LDBL_LONG_MAX %lu.0L\n", u);
+ if (sizeof(w) > sizeof(u))
+ {
+ printf("#define LDBL_LLONG_MAX %llu.0L\n", w);
+ printf("#define LDBL_INTMAX_MAX LDBL_LLONG_MAX\n");
+ }
+ else
+ {
+ printf("#define LDBL_LLONG_MAX LDBL_LONG_MAX\n");
+ printf("#define LDBL_INTMAX_MAX LDBL_LONG_MAX\n");
+ }
+ u++;
+ w++;
+ printf("#define LDBL_LONG_MIN (-%lu.0L)\n", u);
+ if (sizeof(w) > sizeof(u))
+ {
+ printf("#define LDBL_LLONG_MIN (-%llu.0L)\n", w);
+ printf("#define LDBL_INTMAX_MIN LDBL_LLONG_MIN\n");
+ }
+ else
+ {
+ printf("#define LDBL_LLONG_MIN LDBL_LONG_MIN\n");
+ printf("#define LDBL_INTMAX_MIN LDBL_LONG_MIN\n");
+ }
+ #ifdef LDBL_DIG
+ s = LDBL_DIG;
+ #else
+ l = pl = 1.0L;
+ s = -1;
+ do
+ {
+ s++;
+ l *= 10.0L;
+ } while (l != (l + pl));
+ #endif
+ #if defined(LDBL_MIN) && defined(LDBL_MIN_EXP)
+ i = LDBL_MIN_EXP;
+ ml = LDBL_MIN;
+ #else
+ i = 3;
+ l = pl = 1.0L;
+ do
+ {
+ i--;
+ ml = pl;
+ pl = l;
+ l /= 2.0L;
+ } while (l < pl);
+ #ifdef LDBL_MIN_EXP
+ i = LDBL_MIN_EXP;
+ #endif
+ #ifdef LDBL_MIN
+ ml = LDBL_MIN;
+ #endif
+ #endif
+ #ifndef LDBL_DIG
+ printf("#ifndef LDBL_DIG\n");
+ printf("#define LDBL_DIG %d\n", s);
+ printf("#endif\n");
+ #endif
+ #ifndef LDBL_MIN
+ printf("#ifndef LDBL_MIN\n");
+ printf("#define LDBL_MIN %.*LE%s\n", s + 1, ml, ls);
+ printf("#endif\n");
+ #endif
+ #ifndef LDBL_MIN_EXP
+ printf("#ifndef LDBL_MIN_EXP\n");
+ printf("#define LDBL_MIN_EXP (%d)\n", i);
+ printf("#endif\n");
+ #endif
+
+ #if defined(LDBL_MAX) && defined(LDBL_MAX_EXP)
+ i = LDBL_MAX_EXP;
+ l = LDBL_MAX;
+ #else
+ i = -1;
+ l = pl = 1.0L;
+ do
+ {
+ i++;
+ ml = pl;
+ pl = l;
+ l *= 2.0L;
+ } while (l > pl);
+ l = 1.0L;
+ do
+ {
+ l *= 2.0L;
+ } while (ml == (ml + l));
+ l = (ml - l) * 2.0L + l;
+ #ifdef LDBL_MAX_EXP
+ i = LDBL_MAX_EXP;
+ #endif
+ #ifdef LDBL_MAX
+ l = LDBL_MAX;
+ #endif
+ #endif
+ #ifndef LDBL_MAX
+ printf("#ifndef LDBL_MAX\n");
+ printf("#define LDBL_MAX %.*LE%s\n", s + 1, l, ls);
+ printf("#endif\n");
+ #endif
+ #ifndef LDBL_MAX_EXP
+ printf("#ifndef LDBL_MAX_EXP\n");
+ printf("#define LDBL_MAX_EXP %d\n", i);
+ printf("#endif\n");
+ #endif
+
+ #ifdef LDBL_MIN_10_EXP
+ i = LDBL_MIN_10_EXP;
+ #else
+ i = 2;
+ l = 1.0L;
+ do
+ {
+ i--;
+ pl = l;
+ l /= 10.0L;
+ } while (l < pl);
+ #endif
+ #ifndef LDBL_MIN_10_EXP
+ printf("#ifndef LDBL_MIN_10_EXP\n");
+ printf("#define LDBL_MIN_10_EXP (%d)\n", i);
+ printf("#endif\n");
+ #endif
+
+ #ifdef LDBL_MAX_10_EXP
+ i = LDBL_MAX_10_EXP;
+ #else
+ i = -2;
+ l = 1.0L;
+ do
+ {
+ i++;
+ pl = l;
+ l *= 10.0L;
+ } while (l > pl);
+ #endif
+ #ifndef LDBL_MAX_10_EXP
+ printf("#ifndef LDBL_MAX_10_EXP\n");
+ printf("#define LDBL_MAX_10_EXP %d\n", i);
+ printf("#endif\n");
+ #endif
+ fp = "LDBL";
+ #else
+ fp = "DBL";
+ #endif
+
+ printf("\n");
+ printf("#define FLTMAX_UINTMAX_MAX %s_UINTMAX_MAX\n", fp);
+ printf("#define FLTMAX_INTMAX_MAX %s_INTMAX_MAX\n", fp);
+ printf("#define FLTMAX_INTMAX_MIN %s_INTMAX_MIN\n", fp);
+
+ #ifdef SIGFPE
+ if (!caught)
+ {
+ #if !__MVS__
+ f = xf;
+ f *= 2;
+ if (!f)
+ #endif
+ caught = 1;
+ }
+ if (caught)
+ printf("\n#define _ast_fltsig %d\n", SIGFPE);
+ #endif
+
+ printf("\n");
+ #if !_lib_frexp
+ printf("extern double frexp(double, int*);\n");
+ #endif
+ #if !_lib_frexpl
+ printf("extern _ast_fltmax_t frexpl(_ast_fltmax_t, int*);\n");
+ #endif
+ #if !_lib_ldexp
+ printf("extern double ldexp(double, int);\n");
+ #endif
+ #if !_lib_ldexpl
+ printf("extern _ast_fltmax_t ldexpl(_ast_fltmax_t, int);\n");
+ #endif
+
+ return 0;
+ }
+}end
+
+tst - note{ double exponent bitfoolery }end output{
+ #include "FEATURE/common"
+ #include <stdio.h>
+ typedef union _dbl_exp_u
+ {
+ unsigned _ast_int4_t e[sizeof(double) / 4];
+ double f;
+ } _ast_dbl_exp_t;
+ int
+ main()
+ {
+ int i;
+ int j;
+ unsigned _ast_int4_t e;
+ _ast_dbl_exp_t a;
+ _ast_dbl_exp_t b;
+ a.f = 1;
+ b.f = 2;
+ for (i = 0; i < sizeof(a.e) / sizeof(a.e[0]); i++)
+ if (e = a.e[i] ^ b.e[i])
+ {
+ for (j = i + 1; j < sizeof(a.e) / sizeof(a.e[0]); j++)
+ if (a.e[j] ^ b.e[j])
+ return 0;
+ printf("typedef union _ast_dbl_exp_u\n{\n\tuint32_t\t\te[sizeof(double)/4];\n\tdouble\t\t\tf;\n} _ast_dbl_exp_t;\n\n");
+ printf("#define _ast_dbl_exp_index %d\n", i);
+ for (i = 0; !(e & 1); e >>= 1, i++);
+ printf("#define _ast_dbl_exp_shift %d\n\n", i);
+ return 0;
+ }
+ return 0;
+ }
+}end
+
+tst - note{ long double exponent bitfoolery }end output{
+ #include "FEATURE/common"
+ #include <stdio.h>
+ typedef union _ast_fltmax_exp_u
+ {
+ unsigned _ast_int4_t e[sizeof(_ast_fltmax_t) / 4];
+ _ast_fltmax_t f;
+ } _ast_fltmax_exp_t;
+ int
+ main()
+ {
+ int i;
+ int j;
+ unsigned _ast_int4_t e;
+ _ast_fltmax_exp_t a;
+ _ast_fltmax_exp_t b;
+ a.f = 1;
+ b.f = 2;
+ for (i = 0; i < sizeof(a.e) / sizeof(a.e[0]); i++)
+ if (e = a.e[i] ^ b.e[i])
+ {
+ for (j = i + 1; j < sizeof(a.e) / sizeof(a.e[0]); j++)
+ if (a.e[j] ^ b.e[j])
+ return 0;
+ printf("typedef union _fltmax_exp_u\n{\n\tuint32_t\t\te[sizeof(_ast_fltmax_t)/4];\n\t_ast_fltmax_t\t\tf;\n} _ast_fltmax_exp_t;\n\n");
+ printf("#define _ast_fltmax_exp_index\t%d\n", i);
+ for (i = 0; !(e & 1); e >>= 1, i++);
+ printf("#define _ast_fltmax_exp_shift\t%d\n\n", i);
+ return 0;
+ }
+ return 0;
+ }
+}end
+
+tst - -DN=1 - -DN=2 note{ _ast_fltmax_t maximum integral type }end output{
+ #include <stdio.h>
+ int
+ main()
+ {
+ #if N == 1
+ unsigned long long m;
+ long double f = 123.456;
+
+ m = f;
+ if (!m || f == m)
+ return 1;
+ printf("#define _ast_flt_unsigned_max_t unsigned long long\n");
+ #else
+ printf("#define _ast_flt_unsigned_max_t unsigned long\n");
+ #endif
+ return 0;
+ }
+}end
+
+tst - -DSCAN=1 - -lm -DSTRTO=1 - -DMAC=1 - -DDIV=1 - -DEXP=1 - -DADD=1 - -DMPY=1 note{ INF and NAN memory representations }end output{
+ #if MAC
+ #define _AIX_COMPATIBILITY 1
+ #define _FP_MODE_VARIABLE 1
+ #endif
+ #include "FEATURE/common"
+ #include <stdio.h>
+ #include <sys/types.h>
+ #include <signal.h>
+ #if _hdr_float
+ #include <float.h>
+ #endif
+ #if _hdr_limits
+ #include <limits.h>
+ #endif
+ #if _hdr_math
+ #include <math.h>
+ #endif
+ #if _hdr_values
+ #include <values.h>
+ #endif
+ #if STRTO && _hdr_stdlib
+ #include <stdlib.h>
+ #endif
+ #if !defined(FLT_MAX) && defined(MAXFLOAT)
+ #define FLT_MAX MAXFLOAT
+ #endif
+ #if !defined(DBL_MAX) && defined(MAXDOUBLE)
+ #define DBL_MAX MAXDOUBLE
+ #endif
+ #if _ast_fltmax_double
+ #undef LDBL_MAX
+ #endif
+ static void
+ #if _STD_
+ list(const char* typ, const char* var, void* val, int siz)
+ #else
+ list(typ, var, val, siz)
+ char* typ;
+ char* var;
+ void* val;
+ int siz;
+ #endif
+ {
+ register unsigned char* u = (unsigned char*)val;
+ register unsigned char* e = u + siz;
+
+ printf("#define _ast_%s_%s_init\t0x%02x", typ, var, *u);
+ while (++u < e)
+ printf(",0x%02x", *u);
+ printf("\n");
+ }
+ int
+ main()
+ {
+ #if SCAN || STRTO
+ #undef NAN
+ #define NAN "NaN"
+ #undef INF
+ #define INF "INF"
+ {
+ float f;
+
+ #if SCAN
+ if (sscanf(NAN, "%g", &f) != 1)
+ return 1;
+ #else
+ f = atof(NAN);
+ #endif
+ list("flt", "nan", &f, sizeof(f));
+ #if SCAN
+ if (sscanf(INF, "%g", &f) != 1)
+ return 1;
+ #else
+ f = atof(INF);
+ #endif
+ list("flt", "inf", &f, sizeof(f));
+ }
+ {
+ double f;
+ #if STRTO
+ char* e;
+ #endif
+
+ #if SCAN
+ if (sscanf(NAN, "%lg", &f) != 1)
+ return 1;
+ #else
+ f = strtod(NAN, &e);
+ if (*e)
+ return 1;
+ #endif
+ list("dbl", "nan", &f, sizeof(f));
+ #if SCAN
+ if (sscanf(INF, "%lg", &f) != 1)
+ return 1;
+ #else
+ f = strtod(INF, &e);
+ if (*e)
+ return 1;
+ #endif
+ list("dbl", "inf", &f, sizeof(f));
+ }
+ #ifdef LDBL_MAX
+ {
+ long double f;
+ #if STRTO
+ char* e;
+ #endif
+
+ #if SCAN
+ if (sscanf(NAN, "%Lg", &f) != 1)
+ return 1;
+ #else
+ f = strtold(NAN, &e);
+ if (*e)
+ return 1;
+ #endif
+ list("ldbl", "nan", &f, sizeof(f));
+ #if SCAN
+ if (sscanf(INF, "%Lg", &f) != 1)
+ return 1;
+ #else
+ f = strtold(INF, &e);
+ if (*e)
+ return 1;
+ #endif
+ list("ldbl", "inf", &f, sizeof(f));
+ }
+ #endif
+ #else
+ #ifdef SIGFPE
+ signal(SIGFPE, SIG_IGN);
+ #endif
+ #ifdef FLT_MAX
+ {
+ float f = FLT_MAX;
+ #if DIV
+ float z = 0;
+
+ f = 0.0 / z;
+ if (!f)
+ return 1;
+ list("flt", "nan", &f, sizeof(f));
+ f = 1.0 / z;
+ list("flt", "inf", &f, sizeof(f));
+ #else
+ #if ADD
+ f += f;
+ #endif
+ #if EXP
+ f = exp(f);
+ #endif
+ #if MPY
+ f *= 2;
+ #endif
+ #if MAC
+ f = FLT_QNAN;
+ #endif
+ list("flt", "nan", &f, sizeof(f));
+ #if MAC
+ f = FLT_INFINITY;
+ #endif
+ list("flt", "inf", &f, sizeof(f));
+ #endif
+ }
+ #endif
+ #ifdef DBL_MAX
+ {
+ double f = DBL_MAX;
+ #if DIV
+ double z = 0;
+
+ f = 0.0 / z;
+ if (!f)
+ return 1;
+ list("dbl", "nan", &f, sizeof(f));
+ f = 1.0 / z;
+ list("dbl", "inf", &f, sizeof(f));
+ #else
+ #if ADD
+ f += f;
+ #endif
+ #if EXP
+ f = exp(f);
+ #endif
+ #if MPY
+ f *= 2;
+ #endif
+ #if MAC
+ f = DBL_QNAN;
+ #endif
+ list("dbl", "nan", &f, sizeof(f));
+ #if MAC
+ f = DBL_INFINITY;
+ #endif
+ list("dbl", "inf", &f, sizeof(f));
+ #endif
+ }
+ #endif
+ #ifdef LDBL_MAX
+ {
+ long double f = LDBL_MAX;
+ #if DIV
+ long double z = 0;
+
+ f = 0.0 / z;
+ if (!f)
+ return 1;
+ list("ldbl", "nan", &f, sizeof(f));
+ f = 1.0 / z;
+ list("ldbl", "inf", &f, sizeof(f));
+ #else
+ #if ADD
+ f += f;
+ #endif
+ #if EXP
+ f = exp(f);
+ #endif
+ #if MPY
+ f *= 2;
+ #endif
+ #if MAC
+ f = LDBL_QNAN;
+ #endif
+ list("ldbl", "nan", &f, sizeof(f));
+ #if MAC
+ f = LDBL_INFINITY;
+ #endif
+ list("ldbl", "inf", &f, sizeof(f));
+ #endif
+ }
+ #endif
+ #endif
+ return 0;
+ }
+}end
diff --git a/src/lib/libast/features/fs b/src/lib/libast/features/fs
new file mode 100644
index 0000000..3caeedb
--- /dev/null
+++ b/src/lib/libast/features/fs
@@ -0,0 +1,251 @@
+set prototyped
+lib _fxstat,__fxstat,_lxstat,__lxstat,_xmknod,__xmknod,_xstat,__xstat,lstat,mknod,sync sys/types.h sys/stat.h
+lib _fxstat64,__fxstat64,_lxstat64,__lxstat64,_xstat64,__xstat64 -D_LARGEFILE64_SOURCE sys/types.h sys/stat.h
+mac fstat,lstat,stat,mknod sys/types.h sys/stat.h
+
+lcl xstat -D_LARGEFILE64_SOURCE link{
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ struct stat64 { int xxx; }; /* disable if stat64 available */
+ #if _STD_
+ extern int stat(const char* path, struct stat* st)
+ #else
+ int stat(path, st)
+ char* path;
+ struct stat* st;
+ #endif
+ {
+ #if _lib___xstat
+ return __xstat(_STAT_VER, path, st);
+ #else
+ return _xstat(_STAT_VER, path, st);
+ #endif
+ }
+ int
+ main()
+ {
+ struct stat st;
+ return stat(".",&st) < 0;
+ }
+}end
+
+lcl xstat64 -D_LARGEFILE64_SOURCE link{
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #if _STD_
+ extern int stat64(const char* path, struct stat64* st)
+ #else
+ int stat64(path, st)
+ char* path;
+ #endif
+ {
+ #if _lib___xstat64
+ return __xstat64(_STAT_VER, path, st);
+ #else
+ return _xstat64(_STAT_VER, path, st);
+ #endif
+ }
+ int
+ main()
+ {
+ struct stat64 st;
+ return stat64(".",&st) < 0;
+ }
+}end
+
+header sys/stat.h
+header sys/mkdev.h
+
+extern chmod int (const char*, mode_t)
+extern fstat int (int, struct stat*)
+extern lstat int (const char*, struct stat*)
+extern mkdir int (const char*, mode_t)
+extern mkfifo int (const char*, mode_t)
+extern mknod int (const char*, mode_t, dev_t)
+extern stat int (const char*, struct stat*)
+
+define FS_default "ufs"
+
+macro{
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #ifndef major
+ #include <sys/param.h>
+ #ifndef major
+ #include <sys/sysmacros.h>
+ #endif
+ <<"#if defined(__STDPP__directive) && defined(__STDPP__initial)">>
+ <<"__STDPP__directive pragma pp:initial">>
+ <<"#endif">>
+ <<"#ifndef major">>
+ #ifdef major
+ <<"#define major(x)">> major((x))
+ #else
+ #ifndef L_BITSMAJOR
+ #define L_BITSMAJOR 8
+ #endif
+ #ifndef L_BITSMINOR
+ #define L_BITSMINOR 8
+ #endif
+ #ifndef L_MAXMAJ
+ #define L_MAXMAJ ((1<<L_BITSMAJOR)-1)
+ #endif
+ #ifndef L_MAXMIN
+ #define L_MAXMIN ((1<<L_BITSMINOR)-1)
+ #endif
+ <<"#define major(x)">> ((int)(((unsigned)(x)>>L_BITSMINOR)&L_MAXMAJ))
+ #endif
+ <<"#endif">>
+ <<"#ifndef minor">>
+ #ifdef minor
+ <<"#define minor(x)">> minor((x))
+ #else
+ <<"#define minor(x)">> ((int)((x)&L_MAXMIN))
+ #endif
+ <<"#endif">>
+ <<"#ifndef makedev">>
+ #ifdef makedev
+ <<"#define makedev(x,y)">> makedev((x),(y))
+ #else
+ <<"#define makedev(x,y)">> ((dev_t)((((x)&0377)<<8)|((y)&0377)))
+ #endif
+ <<"#endif">>
+ #endif
+ <<"#if defined(__STDPP__directive) && defined(__STDPP__initial)">>
+ <<"__STDPP__directive pragma pp:noinitial">>
+ <<"#endif">>
+}end fail{
+ cat <<!
+ #ifndef major
+ #define major(x) ((int)(((unsigned)(x)>>8)&0377))
+ #endif
+ #ifndef minor
+ #define minor(x) ((int)((x)&0377))
+ #endif
+ #ifndef makedev
+ #define makedev(x,y) ((dev_t)((((x)&0377)<<8)|((y)&0377)))
+ #endif
+ !
+}end
+
+hdr mntent,mnttab stdio.h
+sys mntent,mnttab stdio.h
+sys fs_types,mount,statfs,statvfs,vfs,vmount sys/param.h sys/ucred.h
+
+mem mnttab.mt_dev,mnttab.mt_filsys,mnttab.mt_fstyp sys/types.h mnttab.h
+mem mntent.mnt_opts,w_mntent.mnt_opts,mnttab.mnt_opts sys/types.h stdio.h mntent.h sys/mntent.h
+mem mntent.mnt_opts,mnttab.mnt_opts stdio.h sys/types.h mnttab.h sys/mnttab.h
+mem stat.st_blocks,stat.st_blksize,stat.st_rdev sys/types.h sys/stat.h
+mem statfs.f_files,statfs.f_bavail sys/types.h - sys/statfs.h - sys/vfs.h - sys/param.h sys/mount.h
+mem statvfs.f_basetype,statvfs.f_frsize sys/types.h sys/statvfs.h
+
+ary f_reserved7 sys/types.h sys/statvfs.h note{ statvfs.f_reserved7 can double for statvfs.f_basetype }end compile{
+ int f(vp)struct statvfs* vp;{return vp->f_reserved7[0] = 1;}
+}end
+
+lib getfsstat,getmntent,getmntinfo,mntctl,mntopen,mntread,mntclose,setmntent
+lib w_getmntent
+lib statfs,statvfs
+
+lib statfs4 sys/types.h - sys/statfs.h - sys/vfs.h - sys/mount.h compile{
+ int f()
+ {
+ struct statfs fs;
+ return statfs("/",&fs,sizeof(fs),0);
+ }
+}end
+
+lib getmntinfo_statvfs note{ getmntinfo uses statvfs -- since when? }end compile{
+ #include <sys/types.h>
+ #include <sys/mount.h>
+ int
+ gmi(struct statvfs* fs)
+ {
+ fs->f_flag = 0;
+ return getmntinfo(fs, 0);
+ }
+}end
+
+lib getfsstat_statvfs note{ getfsstat uses statvfs -- just in case it is confused like getmntinfo }end compile{
+ #include <sys/types.h>
+ #include <sys/mount.h>
+ int
+ gfs(struct statvfs* fs)
+ {
+ fs->f_flag = 0;
+ return getfsstat(fs, sizeof(struct statvfs), MNT_WAIT);
+ }
+}end
+
+cat{
+ #if _sys_statvfs
+ #include <sys/statvfs.h>
+ #if !_mem_statvfs_f_basetype
+ #if _ary_f_reserved7
+ #define f_basetype f_reserved7
+ #endif
+ #endif
+ #else
+ #define _mem_f_basetype_statvfs 1
+ #define _mem_f_frsize_statvfs 1
+ struct statvfs
+ {
+ unsigned long f_bsize; /* fundamental file system block size */
+ unsigned long f_frsize; /* fragment size */
+ unsigned long f_blocks; /* total # of blocks of f_frsize on fs */
+ unsigned long f_bfree; /* total # of free blocks of f_frsize */
+ unsigned long f_bavail; /* # of free blocks avail to non-superuser */
+ unsigned long f_files; /* total # of file nodes (inodes) */
+ unsigned long f_ffree; /* total # of free file nodes */
+ unsigned long f_favail; /* # of free nodes avail to non-superuser */
+ unsigned long f_fsid; /* file system id (dev for now) */
+ char f_basetype[16]; /* target fs type name, null-terminated */
+ unsigned long f_flag; /* bit-mask of flags */
+ unsigned long f_namemax; /* maximum file name length */
+ char f_fstr[32]; /* filesystem-specific string */
+ unsigned long f_filler[16]; /* reserved for future expansion */
+ };
+ extern int fstatvfs(int, struct statvfs*);
+ extern int statvfs(const char*, struct statvfs*);
+ #endif
+ #if _typ_off64_t
+ #undef off_t
+ #define off_t off64_t
+ #endif
+ #if _lib_statvfs64 && !defined(statvfs)
+ #define statvfs statvfs64
+ #if !defined(__USE_LARGEFILE64)
+ extern int statvfs64(const char*, struct statvfs64*);
+ #endif
+ #endif
+ #if _lib_fstatvfs64 && !defined(fstatvfs)
+ #define fstatvfs fstatvfs64
+ #if !defined(__USE_LARGEFILE64)
+ extern int fstatvfs64(int, struct statvfs64*);
+ #endif
+ #endif
+}end
+
+str st_fstype sys/types.h sys/stat.h note{ stat.st_fstype is a string }end compile{
+ int f(st)struct stat* st;{return st->st_fstype[0];}
+}end
+
+int st_fstype sys/types.h sys/stat.h note{ stat.st_fstype is an int }end compile{
+ int f(st)struct stat* st;{return st->st_fstype = 1;}
+}end
+
+int st_spare1 sys/types.h sys/stat.h note{ stat.st_spare1 is an int }end compile{
+ int f(st)struct stat* st;{return st->st_spare1 = 1;}
+}end
+
+ary st_spare4 sys/types.h sys/stat.h note{ stat.st_spare4 is an array }end compile{
+ int f(st)struct stat* st;{return st->st_spare4[0] = 1;}
+}end
+
+ary st_extra sys/types.h sys/stat.h note{ stat.st_extra is an array }end compile{
+ int f(st)struct stat* st;{return st->st_extra[0] = 1;}
+}end
+
+ary st_pad4 sys/types.h sys/stat.h note{ stat.st_pad4 is an array }end compile{
+ int f(st)struct stat* st;{return st->st_pad4[0] = 1;}
+}end
diff --git a/src/lib/libast/features/hack b/src/lib/libast/features/hack
new file mode 100644
index 0000000..2be7af9
--- /dev/null
+++ b/src/lib/libast/features/hack
@@ -0,0 +1 @@
+hdr locale_attr
diff --git a/src/lib/libast/features/iconv b/src/lib/libast/features/iconv
new file mode 100644
index 0000000..92fd62f
--- /dev/null
+++ b/src/lib/libast/features/iconv
@@ -0,0 +1,116 @@
+set prototyped
+hdr iconv
+lib iconv_open,iconv_close,iconv iconv.h -liconv
+nxt iconv
+
+tst output{
+ #if !_lib_iconv_open
+ #define _undef_hdr_iconv 1
+ #undef _hdr_iconv
+ #endif
+ #if !_hdr_iconv
+ #define _undef_lib_iconv_open 1
+ #undef _lib_iconv_open
+ #endif
+ #if _hdr_iconv
+ #include <sys/types.h>
+ #include <iconv.h>
+ #endif
+
+ int
+ main()
+ {
+ char* lib;
+
+ printf("#include <ast_common.h>\n");
+ printf("#include <ccode.h>\n");
+ #if _undef_hdr_iconv
+ printf("#undef _hdr_iconv\n");
+ #endif
+ #if _undef_lib_iconv_open
+ printf("#undef _lib_iconv_open\n");
+ #endif
+ #if _hdr_iconv && defined(_nxt_iconv_str)
+ printf("#include <%s> /* the native iconv.h */\n", _nxt_iconv_str);
+ #endif
+ printf("\n");
+ printf("#define ICONV_VERSION 20110111L\n");
+ printf("\n");
+ printf("#define ICONV_FATAL 0x02\n");
+ printf("#define ICONV_OMIT 0x04\n");
+ printf("\n");
+ printf("#define CC_ICONV (-1)\n");
+ printf("#define CC_UCS (-2)\n");
+ printf("#define CC_SCU (-3)\n");
+ printf("#define CC_UTF (-4)\n");
+ printf("#define CC_UME (-5)\n");
+ printf("\n");
+ #if _lib_iconv_open
+ lib = "_ast_";
+ printf("#ifndef _ICONV_LIST_PRIVATE_\n");
+ printf("#undef iconv_t\n");
+ printf("#define iconv_t %siconv_t\n", lib);
+ printf("#undef iconv_f\n");
+ printf("#define iconv_f %siconv_f\n", lib);
+ printf("#undef iconv_list_t\n");
+ printf("#define iconv_list_t %siconv_list_t\n", lib);
+ printf("#undef iconv_open\n");
+ printf("#define iconv_open %siconv_open\n", lib);
+ printf("#undef iconv\n");
+ printf("#define iconv %siconv\n", lib);
+ printf("#undef iconv_close\n");
+ printf("#define iconv_close %siconv_close\n", lib);
+ printf("#undef iconv_list\n");
+ printf("#define iconv_list %siconv_list\n", lib);
+ printf("#undef iconv_move\n");
+ printf("#define iconv_move %siconv_move\n", lib);
+ printf("#undef iconv_name\n");
+ printf("#define iconv_name %siconv_name\n", lib);
+ printf("#undef iconv_write\n");
+ printf("#define iconv_write %siconv_write\n", lib);
+ printf("#endif\n");
+ #else
+ lib = "";
+ #endif
+ printf("\n");
+ printf("typedef int (*Iconv_error_f)(void*, void*, int, ...);\n");
+ printf("\n");
+ printf("typedef struct Iconv_disc_s\n");
+ printf("{\n");
+ printf(" uint32_t version;\n");
+ printf(" Iconv_error_f errorf;\n");
+ printf(" size_t errors;\n");
+ printf(" uint32_t flags;\n");
+ printf(" int fill;\n");
+ printf("} Iconv_disc_t;\n");
+ printf("\n");
+ printf("typedef Ccmap_t %siconv_list_t;\n", lib);
+ printf("typedef void* %siconv_t;\n", lib);
+ printf("typedef size_t (*%siconv_f)(%siconv_t, char**, size_t*, char**, size_t*);\n", lib, lib);
+ printf("\n");
+ printf("#define iconv_init(d,e) (memset(d,0,sizeof(*(d))),(d)->version=ICONV_VERSION,(d)->errorf=(Iconv_error_f)(e),(d)->fill=(-1))\n");
+ printf("\n");
+ printf("#if _BLD_ast && defined(__EXPORT__)\n");
+ printf("#define extern __EXPORT__\n");
+ printf("#endif\n");
+ printf("\n");
+ printf("extern %siconv_t %siconv_open(const char*, const char*);\n", lib, lib);
+ printf("extern size_t %siconv(%siconv_t, char**, size_t*, char**, size_t*);\n", lib, lib);
+ printf("extern int %siconv_close(%siconv_t);\n", lib, lib);
+ printf("extern %siconv_list_t* %siconv_list(%siconv_list_t*);\n", lib, lib, lib);
+ printf("extern int %siconv_name(const char*, char*, size_t);\n", lib);
+ printf("#if _SFIO_H\n");
+ printf("extern ssize_t %siconv_move(%siconv_t, Sfio_t*, Sfio_t*, size_t, Iconv_disc_t*);\n", lib, lib);
+ printf("extern ssize_t %siconv_write(%siconv_t, Sfio_t*, char**, size_t*, Iconv_disc_t*);\n", lib, lib);
+ printf("#else\n");
+ printf("#if _SFSTDIO_H\n");
+ printf("extern ssize_t %siconv_move(%siconv_t, FILE*, FILE*, size_t, Iconv_disc_t*);\n", lib, lib);
+ printf("extern ssize_t %siconv_write(%siconv_t, FILE*, char**, size_t*, Iconv_disc_t*);\n", lib, lib);
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n");
+ printf("#undef extern\n");
+ printf("\n");
+ return 0;
+ }
+}end
diff --git a/src/lib/libast/features/isoc99 b/src/lib/libast/features/isoc99
new file mode 100644
index 0000000..e85c9f5
--- /dev/null
+++ b/src/lib/libast/features/isoc99
@@ -0,0 +1,13 @@
+if tst -D_ISOC99_SOURCE -lm note{ _ISOC99_SOURCE plays nice }end link{
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ #include <math.h>
+ int main() { return signbit(-0.0); }
+ }end {
+ #ifndef _ISOC99_SOURCE
+ #define _ISOC99_SOURCE 1
+ #endif
+ }
+endif
diff --git a/src/lib/libast/features/lib b/src/lib/libast/features/lib
new file mode 100644
index 0000000..763c91d
--- /dev/null
+++ b/src/lib/libast/features/lib
@@ -0,0 +1,664 @@
+ref -D_def_map_ast=1
+
+cmd universe
+
+hdr dirent,direntry,filio,fmtmsg,fnmatch,jioctl,libgen,limits
+hdr locale,ndir,nl_types,process,spawn,syslog,utime,vfork
+hdr wchar note{ <wchar.h> and isw*() really work }end execute{
+ #include <wchar.h>
+ int
+ main()
+ {
+ wchar_t w = 'a';
+ return iswalnum(w) == 0;
+ }
+}end
+hdr wctype wchar.h
+
+dat _tzname,tzname
+
+lib BSDsetpgrp
+lib _cleanup
+lib atexit,bcopy,bzero,catclose,catgets,catopen,confstr,dirread,dup2
+lib execlp,execve,execvp,execvpe
+lib fchmod,fcntl,fmtmsg,fnmatch,fork,fsync
+lib getconf,getdents,getdirentries,getdtablesize,getdate
+lib getgroups,gethostname,getlogin,getpagesize,getrlimit,getuniverse
+lib getopt,getsubopt,getopt_long,getopt_long_only
+lib glob,index,iswblank,iswctype,killpg,link,localeconv,madvise
+lib mbtowc,mbrtowc,memalign,memchr,memcpy,memdup,memmove,memset
+lib mkdir,mkfifo,mktemp,mktime
+lib mount,on_exit,onexit,opendir,pathconf
+lib readlink,remove,rename,rewinddir,rindex,rmdir,setlocale
+lib setpgid,setpgrp,setpgrp2,setreuid,setsid,setuid,sigaction
+lib sigprocmask,sigsetmask,sigunblock,sigvec,socketpair
+lib spawn,spawnve,spawnveg
+lib strchr,strcoll,strdup,strerror,strcasecmp,strncasecmp,strrchr,strstr
+lib strmode,strxfrm,strftime,swab,symlink,sysconf,sysinfo,syslog
+lib telldir,tmpnam,tzset,universe,unlink,utime,wctype
+lib ftruncate,truncate
+lib creat64,fstat64,fstatvfs64,ftruncate64 -D_LARGEFILE64_SOURCE
+lib lseek64,lstat64 -D_LARGEFILE64_SOURCE
+lib open64,readdir64,stat64,statvfs64,truncate64 -D_LARGEFILE64_SOURCE
+
+lib,npt strtod,strtold,strtol,strtoll,strtoul,strtoull stdlib.h
+lib,npt sigflag signal.h
+
+mem direct.d_reclen sys/types.h sys/dir.h
+mem dirent.d_fileno,dirent.d_ino,dirent.d_namlen,dirent.d_off,dirent.d_reclen,dirent.d_type sys/types.h dirent.h
+mem DIR sys/types.h - dirent.h - sys/dir.h
+mem DIR.dd_fd sys/types.h - dirent.h - sys/dir.h
+mem inheritance.pgroup spawn.h
+
+sys dir,filio,jioctl,localedef,ptem,resource
+sys socket,stream,systeminfo,universe,vfork
+
+typ off64_t -D_LARGEFILE64_SOURCE
+typ struct.dirent64 -D_LARGEFILE64_SOURCE dirent.h
+
+tst tst_errno note{ errno can be assigned }end link{
+ _BEGIN_EXTERNS_
+ #define error ______error
+ #define strerror ______strerror
+ #include <errno.h>
+ #undef error
+ #undef strerror
+ #ifndef errno
+ extern int errno;
+ #endif
+ error() { }
+ strerror() { }
+ _END_EXTERNS_
+ int main() { errno = 0; error(); strerror(); return 0; }
+}end
+
+tst lib_poll_fd_1 note{ fd is first arg to poll() }end execute{
+ #include <poll.h>
+ _BEGIN_EXTERNS_
+ extern int pipe _ARG_((int*));
+ _END_EXTERNS_
+ int
+ main()
+ { int rw[2];
+ struct pollfd fd;
+ if (pipe(rw) < 0) return 1;
+ fd.fd = rw[0];
+ fd.events = POLLIN;
+ fd.revents = 0;
+ if (poll(&fd, 1, 0) < 0 || fd.revents != 0) return 1;
+ if (write(rw[1], "x", 1) != 1) return 1;
+ if (poll(&fd, 1, 0) < 0 || fd.revents == 0) return 1;
+ return 0;
+ }
+}end
+
+tst lib_poll_fd_2 note{ fd is second arg to poll() }end execute{
+ #include <poll.h>
+ _BEGIN_EXTERNS_
+ extern int pipe _ARG_((int*));
+ _END_EXTERNS_
+ int
+ main()
+ { int rw[2];
+ struct pollfd fd;
+ if (pipe(rw) < 0) return 1;
+ fd.fd = rw[0];
+ fd.events = POLLIN;
+ fd.revents = 0;
+ return poll(1, &fd, 0) < 0;
+ if (poll(1, &fd, 0) < 0 || fd.revents != 0) return 1;
+ if (write(rw[1], "x", 1) != 1) return 1;
+ if (poll(1, &fd, 0) < 0 || fd.revents == 0) return 1;
+ return 0;
+ }
+}end
+
+exp _lib_poll _lib_poll_fd_1||_lib_poll_fd_2
+
+tst lib_poll_notimer note{ poll with no fds ignores timeout }end execute{
+ #include <sys/types.h>
+ #include <poll.h>
+ _BEGIN_EXTERNS_
+ extern time_t time _ARG_((time_t*));
+ _END_EXTERNS_
+ #define TIMEOUT 4
+ int
+ main()
+ {
+ unsigned long start;
+ unsigned long finish;
+ struct pollfd fd;
+ start = time((time_t*)0);
+ if (poll(&fd, 0, TIMEOUT * 1000) < 0)
+ return 0;
+ finish = time((time_t*)0);
+ return (finish - start) > (TIMEOUT / 2);
+ }
+}end
+
+tst lib_select note{ select() has standard 5 arg interface }end link{
+ #include <sys/types.h>
+ #include <sys/time.h>
+ #include <sys/socket.h>
+ int
+ main()
+ { struct timeval tmb;
+ fd_set rd;
+ FD_ZERO(&rd);
+ FD_SET(0,&rd);
+ tmb.tv_sec = 0;
+ tmb.tv_usec = 0;
+ select(1,&rd,(fd_set*)0,(fd_set*)0,&tmb);
+ return 0;
+ }
+}end
+
+tst pipe_rw note{ full duplex pipes }end execute{
+ _BEGIN_EXTERNS_
+ extern int pipe _ARG_((int*));
+ extern int read _ARG_((int, void*, int));
+ extern int strcmp _ARG_((const char*, const char*));
+ extern int write _ARG_((int, void*, int));
+ _END_EXTERNS_
+ int
+ main()
+ {
+ #if defined(__sgi) || defined(_sgi) || defined(sgi)
+ /* boot tuneable pipes force one way for bin compatibility */
+ return 1;
+ #else
+ static char test[] = "test\n";
+ int io[2];
+ char buf[sizeof(test)];
+ if (pipe(io)) return 1;
+ if (write(io[1], test, sizeof(test)) != sizeof(test)) return 1;
+ if (read(io[0], buf, sizeof(test)) != sizeof(test)) return 1;
+ if (strcmp(test, buf)) return 1;
+ if (write(io[0], test, sizeof(test)) != sizeof(test)) return 1;
+ if (read(io[1], buf, sizeof(test)) != sizeof(test)) return 1;
+ if (strcmp(test, buf)) return 1;
+ return 0;
+ #endif
+ }
+}end
+
+tst lib_vfork unistd.h stdlib.h vfork.h note{ vfork exists and it works }end execute{
+ #include <signal.h>
+ int
+ main(argc, argv)
+ int argc;
+ char** argv;
+ {
+ int status;
+ char* cmd[3];
+ if (argv[1])
+ _exit(signal(SIGHUP, SIG_DFL) != SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+ switch (vfork())
+ {
+ case -1:
+ _exit(1);
+ case 0:
+ cmd[0] = argv[0];
+ cmd[1] = "test";
+ cmd[2] = 0;
+ execv(cmd[0], cmd);
+ _exit(2);
+ }
+ status = 1;
+ _exit(wait(&status) < 0 || status != 0);
+ }
+}end
+
+tst real_vfork note{ vfork child shares data with parent }end execute{
+ _BEGIN_EXTERNS_
+ extern int _exit _ARG_((int));
+ extern int vfork _ARG_((void));
+ _END_EXTERNS_
+ int code;
+ int
+ main()
+ {
+ code = 1;
+ if (!vfork())
+ code = 0;
+ _exit(code);
+ }
+}end
+
+tst lib_posix_spawn unistd.h stdlib.h spawn.h -Dfork=______fork note{ posix_spawn exists and it works and its worth using }end status{
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <sys/wait.h>
+ #include <spawn.h>
+ #include <signal.h>
+ #include <fcntl.h>
+ #include <string.h>
+ #undef fork
+ /* if it uses fork() why bother? */
+ pid_t fork _ARG_((void)) { return -1; }
+ pid_t _fork _ARG_((void)) { return -1; }
+ pid_t __fork _ARG_((void)) { return -1; }
+ int
+ main(argc, argv)
+ int argc;
+ char** argv;
+ {
+ char* s;
+ pid_t pid;
+ posix_spawnattr_t attr;
+ int n;
+ int status;
+ char* cmd[3];
+ char tmp[1024];
+ if (argv[1])
+ _exit(signal(SIGHUP, SIG_DFL) != SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+ if (posix_spawnattr_init(&attr))
+ _exit(0);
+ if (posix_spawnattr_setpgroup(&attr, 0))
+ _exit(0);
+ if (posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETPGROUP))
+ _exit(0);
+ /* first try an a.out and verify that SIGHUP is ignored */
+ cmd[0] = argv[0];
+ cmd[1] = "test";
+ cmd[2] = 0;
+ if (posix_spawn(&pid, cmd[0], 0, &attr, cmd, 0))
+ _exit(0);
+ status = 1;
+ if (wait(&status) < 0 || status != 0)
+ _exit(0);
+ /* passing ENOEXEC to the shell is bogus */
+ n = strlen(cmd[0]);
+ if (n >= (sizeof(tmp) - 3))
+ _exit(0);
+ strcpy(tmp, cmd[0]);
+ tmp[n] = '.';
+ tmp[n+1] = 's';
+ tmp[n+2] = 'h';
+ tmp[n+3] = 0;
+ if (close(open(tmp, O_CREAT, S_IRWXU|S_IRWXG|S_IRWXO)) < 0 || chmod(tmp, S_IRWXU|S_IRWXG|S_IRWXO) < 0)
+ _exit(0);
+ cmd[0] = tmp;
+ n = 0;
+ pid = -1;
+ if (posix_spawn(&pid, cmd[0], 0, &attr, cmd, 0))
+ n = 2;
+ else
+ {
+ n = pid != -1 && waitpid(pid, &status, WNOHANG|WNOWAIT) == pid && ((status>>8)&0x7f) == 127;
+ wait(&status);
+ }
+ _exit(n);
+ }
+}end
+
+tst lib_spawn_mode unistd.h stdlib.h note{ first spawn arg is mode and it works }end execute{
+ #include <signal.h>
+ #include <process.h>
+ #ifndef P_NOWAIT
+ #define P_NOWAIT _P_NOWAIT
+ #endif
+ int
+ main(argc, argv)
+ int argc;
+ char** argv;
+ {
+ int status;
+ char* cmd[3];
+ if (argv[1])
+ _exit(signal(SIGHUP, SIG_DFL) != SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+ cmd[0] = argv[0];
+ cmd[1] = "test";
+ cmd[2] = 0;
+ if (spawnv(P_NOWAIT, cmd[0], cmd) < 0)
+ _exit(1);
+ status = 1;
+ _exit(wait(&status) < 0 || status != 0);
+ }
+}end
+
+tst stream_peek note{ ioctl(I_PEEK) works on pipe() }end execute{
+ #include <sys/types.h>
+ #include <unistd.h>
+ #include <stropts.h>
+ int
+ main()
+ { struct strpeek peek;
+ int fds[2];
+ char ctlbuf[32];
+ char databuf[32];
+ peek.flags = 0;
+ peek.ctlbuf.maxlen = peek.ctlbuf.len = sizeof(ctlbuf);
+ peek.ctlbuf.buf = ctlbuf;
+ peek.databuf.maxlen = peek.databuf.len = sizeof(databuf);
+ peek.databuf.buf = databuf;
+ pipe(fds);
+ return ioctl(fds[0],I_PEEK,&peek) < 0;
+ }
+}end
+
+tst socket_peek note{ recv(MSG_PEEK) works on socketpair() }end execute{
+ #include <unistd.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ int
+ main()
+ {
+ int i;
+ int fds[2];
+ char buf[128];
+
+ static char msg[] = "abcd";
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
+ return 1;
+ if (write(fds[1], msg, sizeof(msg)) != sizeof(msg))
+ return 1;
+ if (recv(fds[0], buf, sizeof(buf), MSG_PEEK) != sizeof(msg))
+ return 1;
+ for (i = 0; i < sizeof(msg); i++)
+ if (buf[i] != msg[i])
+ return 1;
+ if (read(fds[0], buf, sizeof(msg)) != sizeof(msg))
+ return 1;
+ for (i = 0; i < sizeof(msg); i++)
+ if (buf[i] != msg[i])
+ return 1;
+ return 0;
+ }
+}end
+
+tst lib_memcmp string.h note{ standard memcmp interface that works }end execute{
+ /* sgi again -- we're sick of being their regression test */
+ #define L 8
+ char a[L] = { '0' };
+ char b[L] = { '1' };
+ int
+ main()
+ {
+ return memcmp(a, b, L) >= 0;
+ }
+}end
+
+tst lib_memccpy string.h unistd.h stdlib.h fcntl.h signal.h sys/types.h sys/stat.h sys/mman.h fcntl.h note{ standard memccpy interface that works }end execute{
+ #if _STD_
+ static void gotcha(int sig)
+ #else
+ static int gotcha(sig) int sig;
+ #endif
+ {
+ exit(1);
+ }
+ #ifdef MAP_PRIVATE
+ static const char x[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxN";
+ #if _STD_
+ static int indict_sgi_ia64_4Q_2004(int n)
+ #else
+ static int indict_sgi_ia64_4Q_2004(n) int n;
+ #endif
+ {
+ char* b;
+ char* s;
+ char* e;
+ char* t;
+ long m;
+ int d;
+ char u[1024];
+
+ static char p[32] = {'/','t','m','p','/','m','m'};
+
+ for (d = 7; d < 13; d++)
+ p[d] = 'X';
+ p[d] = 0;
+ if ((d = mkstemp(p)) < 0)
+ return 1;
+ remove(p);
+ for (m = 0; m < n; m++)
+ if (write(d, x, sizeof(x)-1) != sizeof(x)-1)
+ {
+ close(d);
+ return 1;
+ }
+ if (lseek(d, (off_t)0, SEEK_SET))
+ {
+ close(d);
+ return 1;
+ }
+ m = n * (sizeof(x)-1);
+ if (!(b = mmap((void*)0, m, PROT_READ|PROT_WRITE, MAP_PRIVATE, d, (off_t)0)))
+ {
+ close(d);
+ return 1;
+ }
+ for (e = (s = b) + m; s < e && (t = memccpy(u, s, 'N', (e-s) > sizeof(u) ? sizeof(u) : (e-s))); s += (t-u))
+ if ((t-u) != (sizeof(x)-1) || memcmp(u, s, t-u))
+ {
+ close(d);
+ return 1;
+ }
+ if (s < e)
+ {
+ close(d);
+ return 1;
+ }
+ close(d);
+ return 0;
+ }
+ #endif
+
+ int
+ main ()
+ {
+ char buf[1024];
+ #ifdef MAP_PRIVATE
+ char* srcbuf;
+ char* dstbuf;
+ int fd;
+ size_t siz;
+ int i;
+ #endif
+
+ #if defined(__ia64) || defined(__ia64__) || defined(__itanium__)
+ /*
+ * 0 faith that the itanium coders will ever get this right
+ * prove me wrong
+ */
+
+ return 1;
+ #endif
+
+ /*
+ * early mac osx failed here -- fixed 3Q 2001
+ */
+
+ if (memccpy(buf, "abc", 0, sizeof(buf)) != (buf + 4))
+ return 1;
+ #ifdef MAP_PRIVATE
+ siz = 64 * 1024;
+ if (!(dstbuf = malloc(2 * siz)))
+ return 0;
+ if ((fd = open("/dev/zero", O_RDWR)) < 0)
+ return 0;
+ if (!(srcbuf = (char*)mmap(NULL, siz, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0)))
+ return 0;
+ if (!mmap(srcbuf + siz, siz, PROT_NONE, MAP_PRIVATE, fd, 0))
+ return 0;
+ for (i = 0; i < siz; i++)
+ srcbuf[i] = 'x';
+ srcbuf[siz - 1] = 0;
+ alarm(10);
+ signal(SIGSEGV, gotcha);
+ signal(SIGBUS, gotcha);
+ signal(SIGALRM, gotcha);
+ /*
+ * sgi ia64 dumps here as of 3Q 2001
+ * bug acknowleged 1Q 2003
+ */
+ memccpy(dstbuf, srcbuf, 0, siz + 10);
+ alarm(0);
+ if (strcmp(srcbuf, dstbuf))
+ return 1;
+ if (indict_sgi_ia64_4Q_2004(1))
+ return 1;
+ if (indict_sgi_ia64_4Q_2004(257))
+ return 1;
+ #endif
+ return 0;
+ }
+}end
+
+tst lib_utime_now note{ utime works with 0 time vector }end execute{
+ #include <sys/types.h>
+ _BEGIN_EXTERNS_
+ extern int utime _ARG_((const char*, void*));
+ _END_EXTERNS_
+ int
+ main()
+ {
+ return utime(".", (void*)0) == -1;
+ }
+}end
+
+tst cross{
+ u=att
+ case `/bin/cat -s /dev/null/foo 2>&1` in
+ '') ;;
+ *) case `/bin/echo '\\t'` in
+ '\t') u=ucb ;;
+ esac
+ ;;
+ esac
+ echo "#define _UNIV_DEFAULT \"$u\" /* default universe name */"
+}end
+
+std cleanup note{ stuck with standard _cleanup }end noexecute{
+ _BEGIN_EXTERNS_
+ extern void exit _ARG_((int));
+ extern void _exit _ARG_((int));
+ extern void _cleanup();
+ void _cleanup() { _exit(0); }
+ _END_EXTERNS_
+ int main() { printf("cleanup\n"); exit(1); }
+}end
+
+std remove note{ stuck with standard remove() }end nostatic{
+ _BEGIN_EXTERNS_
+ extern int unlink _ARG_((const char*));
+ _END_EXTERNS_
+ #if _STD_
+ int remove(const char* path) { return 0; }
+ #else
+ int remove(path) char* path; { return 0; }
+ #endif
+ int main() { return unlink("foo"); }
+}end
+
+std signal note{ stuck with standard signal }end nolink{
+ _BEGIN_EXTERNS_
+ extern int abort();
+ int signal() { return 0; }
+ _END_EXTERNS_
+ int main() { signal(); abort(); return 0; }
+}end
+
+std strcoll note{ standard strcoll works }end execute{
+ #include <string.h>
+ #define S "hello world"
+ int
+ main()
+ {
+ char s[] = S;
+ char t[] = S;
+ return strcoll(s, t) || strcmp(s, t);
+ }
+}end
+
+std strtod stdlib.h note{ stuck with standard strtod }end nostatic{
+ _BEGIN_EXTERNS_
+ #if _STD_
+ double strtod(const char* s, char** e) { return 0.0; }
+ #else
+ double strtod(s, e) char* s; char** e; { return 0.0; }
+ #endif
+ _END_EXTERNS_
+ int main() { printf(""); return strtod("1",0) != 0; }
+}end
+
+std strtold stdlib.h note{ stuck with standard strtold }end nostatic{
+ _BEGIN_EXTERNS_
+ #if _STD_
+ long double strtold(const char* s, char** e) { return 0.0; }
+ #else
+ long double strtold(s, e) char* s; char** e; { return 0.0; }
+ #endif
+ _END_EXTERNS_
+ int main() { printf(""); return strtold("1",0) != 0; }
+}end
+
+std strtol note{ stuck with standard strtol }end nostatic{
+ _BEGIN_EXTERNS_
+ #if _STD_
+ extern long atol(const char*);
+ long strtol(const char* s, char** e, int b) { return 0; }
+ #else
+ extern long atol();
+ long strtol(s, e, b) char* s; char** e; int b; { return 0; }
+ #endif
+ _END_EXTERNS_
+ int main() { printf(""); return (atol("1") + strtol("1",(char**)0,0)) != 0; }
+}end
+
+tst - output{
+ int
+ main()
+ {
+ #if _UWIN
+ printf("\n");
+ printf("/* override some uwin feature tests */\n");
+ printf("#undef _lib_execlp\n");
+ printf("#undef _lib_execvp\n");
+ printf("#undef _lib_execvpe\n");
+ printf("#undef _lib_fork\n");
+ printf("#undef _std_string\n");
+ printf("#define _std_string 1\n");
+ printf("#undef _stream_peek\n");
+ printf("\n");
+ #endif
+
+ #if _lib_spawnveg || _lib_posix_spawn || _lib_spawn_mode || _lib_spawn && _hdr_spawn && _mem_pgroup_inheritance || _lib_vfork && _real_vfork
+ printf("#if !_AST_no_spawnveg\n");
+ printf("#define _use_spawnveg 1\n");
+ printf("#endif\n");
+ printf("\n");
+ #endif
+
+ return 0;
+ }
+
+}end
+
+tst no64 -D_LARGEFILE64_SOURCE note{ largefile 64 broken }end execute{
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ int
+ main()
+ {
+ struct stat64 st;
+ return !stat64(".", &st) && st.st_mode && st.st_mtime;
+ }
+}end pass{
+ echo "/* can we at least agree that a successful return means success? */"
+ echo "#undef _lib_creat64"
+ echo "#undef _lib_fstat64"
+ echo "#undef _lib_fstatvfs64"
+ echo "#undef _lib_ftruncate64"
+ echo "#undef _lib_lseek64"
+ echo "#undef _lib_lstat64"
+ echo "#undef _lib_mmap64"
+ echo "#undef _lib_stat64"
+ echo "#undef _lib_statvfs64"
+ echo "#undef _lib_truncate64"
+}end
diff --git a/src/lib/libast/features/libpath.sh b/src/lib/libast/features/libpath.sh
new file mode 100644
index 0000000..b3809fd
--- /dev/null
+++ b/src/lib/libast/features/libpath.sh
@@ -0,0 +1,73 @@
+########################################################################
+# #
+# This software is part of the ast package #
+# Copyright (c) 1985-2011 AT&T Intellectual Property #
+# and is licensed under the #
+# Eclipse Public License, Version 1.0 #
+# by AT&T Intellectual Property #
+# #
+# A copy of the License is available at #
+# http://www.eclipse.org/org/documents/epl-v10.html #
+# (with md5 checksum b35adb5213ca9657e911e9befb180842) #
+# #
+# Information and Software Systems Research #
+# AT&T Research #
+# Florham Park NJ #
+# #
+# Glenn Fowler <gsf@research.att.com> #
+# David Korn <dgk@research.att.com> #
+# Phong Vo <kpv@research.att.com> #
+# #
+########################################################################
+ok=0
+for i in \
+ -x /lib/ld.so /lib/ld-*.so /usr/lib/ld.so /lib/rld \
+ -f /usr/shlib/libc.so /shlib/libc.so /usr/lib/libc.so \
+ -r /usr/shlib/libc.so /shlib/libc.so
+do case $i in
+ -*) op=$i; continue ;;
+ esac
+ if test $op $i
+ then ok=1
+ break
+ fi
+ set x $i.[0-9]*
+ if test $op $2
+ then ok=1
+ break
+ fi
+done
+if test "0" != "$ok"
+then libpath=lib:LD_LIBRARY_PATH
+ case `package` in
+ sgi.*) if test -d /lib32
+ then libpath="lib32:LD_LIBRARYN32_PATH:sgi.mips3|sgi.*-n32,$libpath"
+ fi
+ if test -d /lib64
+ then libpath="lib64:LD_LIBRARY64_PATH:sgi.mips[4-9]|sgi.*-64,$libpath"
+ fi
+ ;;
+ sol*.*) if test -d /lib/32
+ then libpath="lib/32:LD_LIBRARY_PATH_32,$libpath"
+ fi
+ if test -d /lib/64
+ then libpath="lib/64:LD_LIBRARY_PATH_64:sol.*64*,$libpath"
+ fi
+ ;;
+ esac
+elif test -x /lib/dld.sl
+then libpath=lib:SHLIB_PATH
+elif test -x /usr/lib/dyld
+then libpath=lib:DYLD_LIBRARY_PATH
+else case `package` in
+ ibm.*|mvs.*)
+ libpath=lib:LIBPATH
+ ;;
+ *) libpath=
+ ;;
+ esac
+fi
+case $libpath in
+'') libpath=bin ;;
+esac
+echo "#define CONF_LIBPATH \"$libpath\""
diff --git a/src/lib/libast/features/limits.c b/src/lib/libast/features/limits.c
new file mode 100644
index 0000000..c6e82df
--- /dev/null
+++ b/src/lib/libast/features/limits.c
@@ -0,0 +1,339 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * generate limits features
+ *
+ * FOPEN_MAX POSIX says ANSI defines it but it's not in ANSI
+ *
+ * NOTE: two's complement binary integral representation assumed
+ */
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide getpagesize getdtablesize
+#else
+#define getpagesize ______getpagesize
+#define getdtablesize ______getdtablesize
+#endif
+
+/*
+ * we'd like as many symbols as possible defined
+ * the standards push the vendors the other way
+ * but don't provide guard that lets everything through
+ * so each vendor adds their own guard
+ * many now include something like <standards.h> to
+ * get it straight in one place -- <sys/types.h> should
+ * kick that in
+ */
+
+#include "FEATURE/standards"
+#include "FEATURE/lib"
+
+#ifdef __sun
+#define _timespec timespec
+#endif
+
+#include <sys/types.h>
+
+#undef _SGIAPI
+#define _SGIAPI 1
+
+#if _hdr_limits
+#include <limits.h>
+#endif
+
+#undef _SGIAPI
+#define _SGIAPI 0
+
+#include "FEATURE/lib"
+#include "FEATURE/common"
+
+#if _hdr_unistd
+#include <unistd.h>
+#endif
+
+#include "FEATURE/param"
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide getpagesize getdtablesize
+#else
+#undef getpagesize
+#undef getdtablesize
+#endif
+
+int main()
+{
+ char c;
+ unsigned char uc;
+ unsigned short us;
+ unsigned int ui;
+ unsigned long ul;
+ unsigned long val;
+#if _typ_uint64_t
+ uint64_t ull;
+ uint64_t vll;
+#endif
+
+ /*
+ * <limits.h> with *constant* valued macros
+ */
+
+ printf("\n");
+#ifndef CHAR_BIT
+ uc = 0;
+ uc = ~uc;
+ val = 1;
+ while (uc >>= 1) val++;
+ printf("#define CHAR_BIT %lu\n", val);
+#endif
+#ifndef MB_LEN_MAX
+ val = 1;
+ printf("#define MB_LEN_MAX %lu\n", val);
+#endif
+
+ c = 0;
+ c = ~c;
+ uc = 0;
+ uc = ~uc;
+ us = 0;
+ us = ~us;
+ ui = 0;
+ ui = ~ui;
+ ul = 0;
+ ul = ~ul;
+#if _typ_uint64_t
+ ull = 0;
+ ull = ~ull;
+#endif
+
+#ifndef UCHAR_MAX
+ val = uc;
+ printf("#if defined(__STDC__)\n");
+ printf("#define UCHAR_MAX %luU\n", val);
+ printf("#else\n");
+ printf("#define UCHAR_MAX %lu\n", val);
+ printf("#endif\n");
+#endif
+
+#ifndef SCHAR_MIN
+ val = (unsigned char)(uc >> 1) + 1;
+ printf("#define SCHAR_MIN (-%lu)\n", val);
+#endif
+
+#ifndef SCHAR_MAX
+ val = (unsigned char)(uc >> 1);
+ printf("#define SCHAR_MAX %lu\n", val);
+#endif
+
+ if (c < 0)
+ {
+#ifndef CHAR_MIN
+ printf("#define CHAR_MIN SCHAR_MIN\n");
+#endif
+
+#ifndef CHAR_MAX
+ printf("#define CHAR_MAX SCHAR_MAX\n");
+#endif
+ }
+ else
+ {
+#ifndef CHAR_MIN
+ printf("#define CHAR_MIN 0\n");
+#endif
+
+#ifndef CHAR_MAX
+ printf("#define CHAR_MAX UCHAR_MAX\n");
+#endif
+ }
+
+#ifndef USHRT_MAX
+ val = us;
+ printf("#if defined(__STDC__)\n");
+ printf("#define USHRT_MAX %luU\n", val);
+ printf("#else\n");
+ printf("#define USHRT_MAX %lu\n", val);
+ printf("#endif\n");
+#endif
+
+#ifndef SHRT_MIN
+ val = (unsigned short)(us >> 1) + 1;
+ printf("#define SHRT_MIN (-%lu)\n", val);
+#endif
+
+#ifndef SHRT_MAX
+ val = (unsigned short)(us >> 1);
+ printf("#define SHRT_MAX %lu\n", val);
+#endif
+
+ if (ui == us)
+ {
+#ifndef UINT_MAX
+ printf("#define UINT_MAX USHRT_MAX\n");
+#endif
+
+#ifndef INT_MIN
+ printf("#define INT_MIN SHRT_MIN\n");
+#endif
+
+#ifndef INT_MAX
+ printf("#define INT_MAX SHRT_MAX\n");
+#endif
+ }
+ else
+ {
+#ifndef UINT_MAX
+ val = ui;
+ printf("#if defined(__STDC__)\n");
+ printf("#define UINT_MAX %luU\n", val);
+ printf("#else\n");
+ printf("#define UINT_MAX %lu\n", val);
+ printf("#endif\n");
+#endif
+
+#ifndef INT_MIN
+ val = (unsigned int)(ui >> 1) + 1;
+ if (ui == ul) printf("#define INT_MIN (-%lu-1)\n", val - 1);
+ else printf("#define INT_MIN (-%lu)\n", val);
+#endif
+
+#ifndef INT_MAX
+ val = (unsigned int)(ui >> 1);
+ printf("#define INT_MAX %lu\n", val);
+#endif
+ }
+
+ if (ul == ui)
+ {
+#ifndef ULONG_MAX
+ printf("#define ULONG_MAX UINT_MAX\n");
+#endif
+
+#ifndef LONG_MIN
+ printf("#define LONG_MIN INT_MIN\n");
+#endif
+
+#ifndef LONG_MAX
+ printf("#define LONG_MAX INT_MAX\n");
+#endif
+ }
+ else
+ {
+#ifndef ULONG_MAX
+ val = ul;
+ printf("#if defined(__STDC__)\n");
+ printf("#define ULONG_MAX %luLU\n", val);
+ printf("#else\n");
+ printf("#define ULONG_MAX %lu\n", val);
+ printf("#endif\n");
+#endif
+
+#ifndef LONG_MIN
+ val = (unsigned long)(ul >> 1) + 1;
+ printf("#define LONG_MIN (-%luL-1L)\n", val - 1);
+#endif
+
+#ifndef LONG_MAX
+ val = (unsigned long)(ul >> 1);
+ printf("#define LONG_MAX %luL\n", val);
+#endif
+ }
+
+#if _typ_uint64_t && !_ast_intmax_long
+ if (ull == ul)
+ {
+#ifndef ULLONG_MAX
+ printf("#define ULLONG_MAX ULONG_MAX\n");
+#endif
+
+#ifndef LLONG_MIN
+ printf("#define LLONG_MIN LONG_MIN\n");
+#endif
+
+#ifndef LLONG_MAX
+ printf("#define LLONG_MAX LONG_MAX\n");
+#endif
+ }
+ else
+ {
+#ifndef ULLONG_MAX
+ vll = ull;
+ printf("#ifndef ULLONG_MAX\n");
+ printf("#if defined(__STDC__) && _ast_LL\n");
+ printf("#define ULLONG_MAX %lluULL\n", vll);
+ printf("#else\n");
+ printf("#define ULLONG_MAX %llu\n", vll);
+ printf("#endif\n");
+ printf("#endif\n");
+#endif
+
+#ifndef LLONG_MIN
+ vll = (uint64_t)(ull >> 1) + 1;
+ printf("#ifndef LLONG_MIN\n");
+ printf("#if defined(__STDC__) && _ast_LL\n");
+ printf("#define LLONG_MIN (-%lluLL-1LL)\n", vll - 1);
+ printf("#else\n");
+ printf("#define LLONG_MIN (-%llu-1)\n", vll - 1);
+ printf("#endif\n");
+ printf("#endif\n");
+#endif
+
+#ifndef LLONG_MAX
+ vll = (uint64_t)(ull >> 1);
+ printf("#ifndef LLONG_MAX\n");
+ printf("#if defined(__STDC__) && _ast_LL\n");
+ printf("#define LLONG_MAX %lluLL\n", vll);
+ printf("#else\n");
+ printf("#define LLONG_MAX %llu\n", vll);
+ printf("#endif\n");
+ printf("#endif\n");
+#endif
+ }
+#endif
+
+ printf("\n");
+#ifdef _UWIN
+ printf("#ifdef _UWIN\n");
+ printf("#ifndef DBL_DIG\n");
+ printf("#define DBL_DIG 15\n");
+ printf("#endif\n");
+ printf("#ifndef DBL_MAX\n");
+ printf("#define DBL_MAX 1.7976931348623158e+308\n");
+ printf("#endif\n");
+ printf("#ifndef FLT_DIG\n");
+ printf("#define FLT_DIG 6\n");
+ printf("#endif\n");
+ printf("#ifndef FLT_MAX\n");
+ printf("#define FLT_MAX 3.402823466e+38F\n");
+ printf("#endif\n");
+ printf("#endif\n");
+ printf("\n");
+#endif
+
+#include "conflim.h"
+
+ printf("\n");
+
+ return 0;
+}
diff --git a/src/lib/libast/features/locale b/src/lib/libast/features/locale
new file mode 100644
index 0000000..ffd1988
--- /dev/null
+++ b/src/lib/libast/features/locale
@@ -0,0 +1,28 @@
+tst - note{ canonical UTF-8 name }end run{
+ ifs=$IFS
+ str=
+ sys=
+ for i in `PATH=/bin:/usr/bin:$PATH locale -a | grep -i '^[^C].*\.UTF[-8]*$'`
+ do IFS=.
+ set '' $i
+ IFS=$ifs
+ case $3 in
+ UTF-8) str=$3
+ break
+ ;;
+ *) if $SHELL -c "LC_CTYPE=$2.UTF-8 PATH=/bin:/usr/bin:$PATH locale LC_CTYPE | grep -i utf.*8" >/dev/null 2>&1
+ then str=UTF-8
+ break
+ fi
+ ;;
+ esac
+ sys=$3
+ done
+ case $str in
+ '') str=$sys ;;
+ esac
+ case $str in
+ '') echo "#define _locale_utf8_str 0" ;;
+ *) echo "#define _locale_utf8_str \"$str\"" ;;
+ esac
+}end
diff --git a/src/lib/libast/features/map.c b/src/lib/libast/features/map.c
new file mode 100644
index 0000000..52c35aa
--- /dev/null
+++ b/src/lib/libast/features/map.c
@@ -0,0 +1,565 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * some systems may pull in <ast_common.h> and its <ast_map.h>
+ * which we are in the process of generating ... this prevents it
+ */
+
+#define _def_map_ast 1
+
+#include "FEATURE/lib"
+#include "FEATURE/mmap"
+#include "FEATURE/options"
+#include "FEATURE/vmalloc"
+#include "FEATURE/eaccess"
+#include "FEATURE/api"
+
+#if _opt_map_libc && !defined(_map_libc)
+#define _map_libc 1
+#endif
+
+int
+main()
+{
+ printf("#pragma prototyped\n");
+ printf("\n");
+ printf("/*\n");
+ printf(" * prototypes provided for standard interfaces hijacked\n");
+ printf(" * by ast and mapped to _ast_* but already prototyped\n");
+ printf(" * unmapped in native headers included by <ast_std.h>\n");
+ printf(" */\n");
+ printf("\n");
+ printf("#if _BLD_ast && defined(__EXPORT__)\n");
+ printf("#define extern __EXPORT__\n");
+ printf("#endif\n");
+ printf("\n");
+#if __MVS__
+#undef _map_libc
+#define _map_libc 1
+ printf("\n");
+ printf("/* mvs.390 libc.dll routines can't be intercepted by user dlls */\n");
+ printf("#undef _mem_dd_fd_DIR\n");
+ printf("#undef _typ_long_double\n");
+#endif
+#if _map_libc
+#undef _map_malloc
+#define _map_malloc 1
+ printf("\n");
+ printf("#define _map_libc 1\n");
+ printf("#undef basename\n");
+ printf("#define basename _ast_basename\n");
+ printf("#undef dirname\n");
+ printf("#define dirname _ast_dirname\n");
+#if !_lib_eaccess
+ printf("#undef eaccess\n");
+ printf("#define eaccess _ast_eaccess\n");
+#endif
+#if !_lib_execvpe
+ printf("#undef execvpe\n");
+ printf("#define execvpe _ast_execvpe\n");
+ printf("extern int execvpe(const char*, char* const[], char* const[]);\n");
+#endif
+ printf("#undef fnmatch\n");
+ printf("#define fnmatch _ast_fnmatch\n");
+ printf("#undef fts_children\n");
+ printf("#define fts_children _ast_fts_children\n");
+ printf("#undef fts_close\n");
+ printf("#define fts_close _ast_fts_close\n");
+ printf("#undef fts_flags\n");
+ printf("#define fts_flags _ast_fts_flags\n");
+ printf("#undef fts_notify\n");
+ printf("#define fts_notify _ast_fts_notify\n");
+ printf("#undef fts_open\n");
+ printf("#define fts_open _ast_fts_open\n");
+ printf("#undef fts_read\n");
+ printf("#define fts_read _ast_fts_read\n");
+ printf("#undef fts_set\n");
+ printf("#define fts_set _ast_fts_set\n");
+ printf("#undef ftw\n");
+ printf("#define ftw _ast_ftw\n");
+ printf("#undef ftwalk\n");
+ printf("#define ftwalk _ast_ftwalk\n");
+ printf("#undef ftwflags\n");
+ printf("#define ftwflags _ast_ftwflags\n");
+#if !_WINIX
+ printf("#undef getcwd\n");
+ printf("#define getcwd _ast_getcwd\n");
+ printf("extern char* getcwd(char*, size_t);\n");
+#endif
+ printf("#undef getdate\n");
+ printf("#define getdate _ast_getdate\n");
+#if _lib_getopt || _lib_getsubopt || _lib_getopt_long || _lib_getopt_long_only
+ printf("#undef getopt\n");
+ printf("#define getopt _ast_getopt\n");
+ printf("#undef getsubopt\n");
+ printf("#define getsubopt _ast_getsubopt\n");
+ printf("#undef getopt_long\n");
+ printf("#define getopt_long _ast_getopt_long\n");
+ printf("#undef getopt_long_only\n");
+ printf("#define getopt_long_only _ast_getopt_long_only\n");
+ printf("#undef optopt\n");
+ printf("#define optopt _ast_optopt\n");
+ printf("#undef optarg\n");
+ printf("#define optarg _ast_optarg\n");
+ printf("#undef optind\n");
+ printf("#define optind _ast_optind\n");
+ printf("#undef opterr\n");
+ printf("#define opterr _ast_opterr\n");
+#endif
+ printf("#undef getwd\n");
+ printf("#define getwd _ast_getwd\n");
+ printf("extern char* getwd(char*);\n");
+ printf("#undef glob\n");
+ printf("#define glob _ast_glob\n");
+ printf("#undef globfree\n");
+ printf("#define globfree _ast_globfree\n");
+ printf("#undef memdup\n");
+ printf("#define memdup _ast_memdup\n");
+ printf("#undef memfatal\n");
+ printf("#define memfatal _ast_memfatal\n");
+ printf("#undef memhash\n");
+ printf("#define memhash _ast_memhash\n");
+ printf("#undef memsum\n");
+ printf("#define memsum _ast_memsum\n");
+ printf("#undef mkstemp\n");
+ printf("#define mkstemp _ast_mkstemp\n");
+ printf("extern int mkstemp(char*);\n");
+ printf("#undef mktemp\n");
+ printf("#define mktemp _ast_mktemp\n");
+ printf("extern char* mktemp(char*);\n");
+ printf("#undef mktime\n");
+ printf("#define mktime _ast_mktime\n");
+ printf("#undef nftw\n");
+ printf("#define nftw _ast_nftw\n");
+ printf("#undef optctx\n");
+ printf("#define optctx _ast_optctx\n");
+ printf("#undef optesc\n");
+ printf("#define optesc _ast_optesc\n");
+ printf("#undef optget\n");
+ printf("#define optget _ast_optget\n");
+ printf("#undef opthelp\n");
+ printf("#define opthelp _ast_opthelp\n");
+ printf("#undef optjoin\n");
+ printf("#define optjoin _ast_optjoin\n");
+ printf("#undef optstr\n");
+ printf("#define optstr _ast_optstr\n");
+ printf("#undef optusage\n");
+ printf("#define optusage _ast_optusage\n");
+ printf("#undef pathaccess\n");
+ printf("#define pathaccess _ast_pathaccess\n");
+ printf("#undef pathbin\n");
+ printf("#define pathbin _ast_pathbin\n");
+ printf("#undef pathcanon\n");
+ printf("#define pathcanon _ast_pathcanon\n");
+ printf("#undef pathcat\n");
+ printf("#define pathcat _ast_pathcat\n");
+ printf("#undef pathcd\n");
+ printf("#define pathcd _ast_pathcd\n");
+ printf("#undef pathcheck\n");
+ printf("#define pathcheck _ast_pathcheck\n");
+ printf("#undef pathexists\n");
+ printf("#define pathexists _ast_pathexists\n");
+ printf("#undef pathfind\n");
+ printf("#define pathfind _ast_pathfind\n");
+ printf("#undef pathgetlink\n");
+ printf("#define pathgetlink _ast_pathgetlink\n");
+ printf("#undef pathinclude\n");
+ printf("#define pathinclude _ast_pathinclude\n");
+ printf("#undef pathkey\n");
+ printf("#define pathkey _ast_pathkey\n");
+ printf("#undef pathnative\n");
+ printf("#define pathnative _ast_pathnative\n");
+ printf("#undef pathpath\n");
+ printf("#define pathpath _ast_pathpath\n");
+ printf("#undef pathposix\n");
+ printf("#define pathposix _ast_pathposix\n");
+ printf("#undef pathprobe\n");
+ printf("#define pathprobe _ast_pathprobe\n");
+ printf("#undef pathprog\n");
+ printf("#define pathprog _ast_pathprog\n");
+ printf("#undef pathrepl\n");
+ printf("#define pathrepl _ast_pathrepl\n");
+ printf("#undef pathsetlink\n");
+ printf("#define pathsetlink _ast_pathsetlink\n");
+ printf("#undef pathshell\n");
+ printf("#define pathshell _ast_pathshell\n");
+ printf("#undef pathstat\n");
+ printf("#define pathstat _ast_pathstat\n");
+ printf("#undef pathtemp\n");
+ printf("#define pathtemp _ast_pathtemp\n");
+ printf("#undef pathtmp\n");
+ printf("#define pathtmp _ast_pathtmp\n");
+ printf("#undef procclose\n");
+ printf("#define procclose _ast_procclose\n");
+ printf("#undef procfree\n");
+ printf("#define procfree _ast_procfree\n");
+ printf("#undef procopen\n");
+ printf("#define procopen _ast_procopen\n");
+ printf("#undef procrun\n");
+ printf("#define procrun _ast_procrun\n");
+ printf("#undef putenv\n");
+ printf("#define putenv _ast_putenv\n");
+ printf("#undef re_comp\n");
+ printf("#define re_comp _ast_re_comp\n");
+ printf("#undef re_exec\n");
+ printf("#define re_exec _ast_re_exec\n");
+ printf("#undef realpath\n");
+ printf("#define realpath _ast_realpath\n");
+ printf("extern char* realpath(const char*, char*);\n");
+ printf("#undef regaddclass\n");
+ printf("#define regaddclass _ast_regaddclass\n");
+ printf("#undef regalloc\n");
+ printf("#define regalloc _ast_regalloc\n");
+ printf("#undef regcache\n");
+ printf("#define regcache _ast_regcache\n");
+ printf("#undef regclass\n");
+ printf("#define regclass _ast_regclass\n");
+ printf("#undef regcmp\n");
+ printf("#define regcmp _ast_regcmp\n");
+ printf("#undef regcollate\n");
+ printf("#define regcollate _ast_regcollate\n");
+ printf("#undef regcomb\n");
+ printf("#define regcomb _ast_regcomb\n");
+ printf("#undef regcomp\n");
+ printf("#define regcomp _ast_regcomp\n");
+ printf("#undef regdecomp\n");
+ printf("#define regdecomp _ast_regdecomp\n");
+ printf("#undef regdup\n");
+ printf("#define regdup _ast_regdup\n");
+ printf("#undef regerror\n");
+ printf("#define regerror _ast_regerror\n");
+ printf("#undef regex\n");
+ printf("#define regex _ast_regex\n");
+ printf("#undef regexec\n");
+ printf("#define regexec _ast_regexec\n");
+ printf("#undef regfatal\n");
+ printf("#define regfatal _ast_regfatal\n");
+ printf("#undef regfatalpat\n");
+ printf("#define regfatalpat _ast_regfatalpat\n");
+ printf("#undef regfree\n");
+ printf("#define regfree _ast_regfree\n");
+ printf("#undef regncomp\n");
+ printf("#define regncomp _ast_regncomp\n");
+ printf("#undef regnexec\n");
+ printf("#define regnexec _ast_regnexec\n");
+ printf("#undef regrecord\n");
+ printf("#define regrecord _ast_regrecord\n");
+ printf("#undef regrexec\n");
+ printf("#define regrexec _ast_regrexec\n");
+ printf("#undef regstat\n");
+ printf("#define regstat _ast_regstat\n");
+ printf("#undef regsub\n");
+ printf("#define regsub _ast_regsub\n");
+ printf("#undef regsubcomp\n");
+ printf("#define regsubcomp _ast_regsubcomp\n");
+ printf("#undef regsubexec\n");
+ printf("#define regsubexec _ast_regsubexec\n");
+ printf("#undef regsubflags\n");
+ printf("#define regsubflags _ast_regsubflags\n");
+ printf("#undef regsubfree\n");
+ printf("#define regsubfree _ast_regsubfree\n");
+ printf("#undef remove\n");
+ printf("#define remove _ast_remove\n");
+ printf("extern int remove(const char*);\n");
+ printf("#undef resolvepath\n");
+ printf("#define resolvepath _ast_resolvepath\n");
+ printf("extern int resolvepath(const char*, char*, size_t);\n");
+ printf("#undef setenv\n");
+ printf("#define setenv _ast_setenv\n");
+ printf("extern int setenv(const char*, const char*, int);\n");
+ printf("#undef setenviron\n");
+ printf("#define setenviron _ast_setenviron\n");
+ printf("#undef sigcritical\n");
+ printf("#define sigcritical _ast_sigcritical\n");
+ printf("#undef signal\n");
+ printf("#define signal _ast_signal\n");
+ printf("#undef sigunblock\n");
+ printf("#define sigunblock _ast_sigunblock\n");
+ printf("#undef stracmp\n");
+ printf("#define stracmp _ast_stracmp\n");
+ printf("#undef strcopy\n");
+ printf("#define strcopy _ast_strcopy\n");
+ printf("#undef strelapsed\n");
+ printf("#define strelapsed _ast_strelapsed\n");
+ printf("#undef stresc\n");
+ printf("#define stresc _ast_stresc\n");
+ printf("#undef streval\n");
+ printf("#define streval _ast_streval\n");
+ printf("#undef strexpr\n");
+ printf("#define strexpr _ast_strexpr\n");
+ printf("#undef strftime\n");
+ printf("#define strftime _ast_strftime\n");
+ printf("#undef strgid\n");
+ printf("#define strgid _ast_strgid\n");
+ printf("#undef strgrpmatch\n");
+ printf("#define strgrpmatch _ast_strgrpmatch\n");
+ printf("#undef strhash\n");
+ printf("#define strhash _ast_strhash\n");
+ printf("#undef strkey\n");
+ printf("#define strkey _ast_strkey\n");
+ printf("#undef strlcat\n");
+ printf("#define strlcat _ast_strlcat\n");
+ printf("extern size_t strlcat(char*, const char*, size_t);\n");
+ printf("#undef strlcpy\n");
+ printf("#define strlcpy _ast_strlcpy\n");
+ printf("extern size_t strlcpy(char*, const char*, size_t);\n");
+ printf("#undef strlook\n");
+ printf("#define strlook _ast_strlook\n");
+ printf("#undef strmatch\n");
+ printf("#define strmatch _ast_strmatch\n");
+#endif
+#if _map_libc || _lib_strmode
+ printf("#undef strmode\n");
+ printf("#define strmode _ast_strmode\n");
+#endif
+#if _map_libc
+ printf("#undef strnacmp\n");
+ printf("#define strnacmp _ast_strnacmp\n");
+ printf("#undef strncopy\n");
+ printf("#define strncopy _ast_strncopy\n");
+ printf("#undef strntod\n");
+ printf("#define strntod _ast_strntod\n");
+ printf("#undef strntol\n");
+ printf("#define strntol _ast_strntol\n");
+ printf("#undef strntold\n");
+ printf("#define strntold _ast_strntold\n");
+ printf("#undef strntoll\n");
+ printf("#define strntoll _ast_strntoll\n");
+ printf("#undef strntoul\n");
+ printf("#define strntoul _ast_strntoul\n");
+ printf("#undef strntoull\n");
+ printf("#define strntoull _ast_strntoull\n");
+ printf("#undef stropt\n");
+ printf("#define stropt _ast_stropt\n");
+ printf("#undef strperm\n");
+ printf("#define strperm _ast_strperm\n");
+ printf("#undef strpsearch\n");
+ printf("#define strpsearch _ast_strpsearch\n");
+#if !_lib_strptime
+ printf("#undef strptime\n");
+ printf("#define strptime _ast_strptime\n");
+#endif
+ printf("#undef strsearch\n");
+ printf("#define strsearch _ast_strsearch\n");
+ printf("#undef strsort\n");
+ printf("#define strsort _ast_strsort\n");
+ printf("#undef strsubmatch\n");
+ printf("#define strsubmatch _ast_strsubmatch\n");
+ printf("#undef strsum\n");
+ printf("#define strsum _ast_strsum\n");
+ printf("#undef strtape\n");
+ printf("#define strtape _ast_strtape\n");
+ printf("#undef strtoip4\n");
+ printf("#define strtoip4 _ast_strtoip4\n");
+ printf("#undef strton\n");
+ printf("#define strton _ast_strton\n");
+ printf("#undef strtonll\n");
+ printf("#define strtonll _ast_strtonll\n");
+ printf("#undef struid\n");
+ printf("#define struid _ast_struid\n");
+ printf("#undef struniq\n");
+ printf("#define struniq _ast_struniq\n");
+ printf("#undef system\n");
+ printf("#define system _ast_system\n");
+ printf("extern int system(const char*);\n");
+ printf("#undef tempnam\n");
+ printf("#define tempnam _ast_tempnam\n");
+ printf("extern char* tempnam(const char*, const char*);\n");
+ printf("#undef tmpnam\n");
+ printf("#define tmpnam _ast_tmpnam\n");
+ printf("extern char* tmpnam(char*);\n");
+ printf("#undef touch\n");
+ printf("#define touch _ast_touch\n");
+ printf("#undef wordexp\n");
+ printf("#define wordexp _ast_wordexp\n");
+ printf("#undef wordfree\n");
+ printf("#define wordfree _ast_wordfree\n");
+ printf("#undef unsetenv\n");
+ printf("#define unsetenv _ast_unsetenv\n");
+#endif
+#if _std_malloc
+ printf("\n");
+ printf("/* no local malloc override */\n");
+ printf("#define _std_malloc 1\n");
+#else
+#if _map_malloc
+ printf("\n");
+ printf("/* cannot override local malloc */\n");
+ printf("#define _map_malloc 1\n");
+ printf("#undef calloc\n");
+ printf("#define calloc _ast_calloc\n");
+ printf("extern void* calloc(size_t, size_t);\n");
+ printf("#undef cfree\n");
+ printf("#define cfree _ast_cfree\n");
+ printf("extern void cfree(void*);\n");
+ printf("#undef free\n");
+ printf("#define free _ast_free\n");
+ printf("extern void free(void*);\n");
+#if _lib_mallinfo
+ printf("#undef mallinfo\n");
+ printf("#define mallinfo _ast_mallinfo\n");
+#endif
+ printf("#undef malloc\n");
+ printf("#define malloc _ast_malloc\n");
+ printf("extern void* malloc(size_t);\n");
+#if _lib_mallopt
+ printf("#undef mallopt\n");
+ printf("#define mallopt _ast_mallopt\n");
+#endif
+#if _lib_memalign
+ printf("#undef memalign\n");
+ printf("#define memalign _ast_memalign\n");
+ printf("extern void* memalign(size_t, size_t);\n");
+#endif
+#if _lib_mstats
+ printf("#undef mstats\n");
+ printf("#define mstats _ast_mstats\n");
+#endif
+#if _lib_pvalloc
+ printf("#undef pvalloc\n");
+ printf("#define pvalloc _ast_pvalloc\n");
+#endif
+ printf("#undef realloc\n");
+ printf("#define realloc _ast_realloc\n");
+ printf("extern void* realloc(void*, size_t);\n");
+ printf("#undef strdup\n");
+ printf("#define strdup _ast_strdup\n");
+ printf("extern char* strdup(const char*);\n");
+#if _lib_valloc
+ printf("#undef valloc\n");
+ printf("#define valloc _ast_valloc\n");
+ printf("extern void* valloc(size_t);\n");
+#endif
+#endif
+#endif
+
+ /*
+ * overriding <stdlib.h> strto*() is problematic to say the least
+ */
+
+#if _map_libc || _std_strtol
+#if !__CYGWIN__
+ printf("#undef strtol\n");
+ printf("#define strtol _ast_strtol\n");
+ printf("#undef strtoul\n");
+ printf("#define strtoul _ast_strtoul\n");
+#endif
+ printf("#undef strtoll\n");
+ printf("#define strtoll _ast_strtoll\n");
+ printf("#undef strtoull\n");
+ printf("#define strtoull _ast_strtoull\n");
+#endif
+#if _map_libc || _std_strtod
+ printf("#undef strtod\n");
+ printf("#define strtod _ast_strtod\n");
+#endif
+#if _map_libc || _std_strtold
+ printf("#undef strtold\n");
+ printf("#define strtold _ast_strtold\n");
+#endif
+#if !__CYGWIN__
+#if _npt_strtol || _map_libc || _std_strtol
+#if _npt_strtol && !_map_libc && !_std_strtol
+ printf("#ifndef _ISOC99_SOURCE\n");
+#endif
+ printf("extern long strtol(const char*, char**, int);\n");
+#if _npt_strtol && !_map_libc && !_std_strtol
+ printf("#endif\n");
+#endif
+#endif
+#if _npt_strtoul || _map_libc || _std_strtol
+#if _npt_strtoul && !_map_libc && !_std_strtol
+ printf("#ifndef _ISOC99_SOURCE\n");
+#endif
+ printf("extern unsigned long strtoul(const char*, char**, int);\n");
+#if _npt_strtoul && !_map_libc && !_std_strtol
+ printf("#endif\n");
+#endif
+#endif
+#endif
+#if _npt_strtod || _map_libc || _std_strtod
+#if _npt_strtod && !_map_libc && !_std_strtod
+ printf("#ifndef _ISOC99_SOURCE\n");
+#endif
+ printf("extern double strtod(const char*, char**);\n");
+#if _npt_strtod && !_map_libc && !_std_strtod
+ printf("#endif\n");
+#endif
+#endif
+ printf("#if !_UWIN\n");
+ printf("#undef extern\n");
+ printf("#endif\n");
+#if _npt_strtold || _map_libc || _std_strtold
+#if _npt_strtold && !_map_libc && !_std_strtold
+ printf("#ifndef _ISOC99_SOURCE\n");
+#endif
+ printf("extern _ast_fltmax_t strtold(const char*, char**);\n");
+#if _npt_strtold && !_map_libc && !_std_strtold
+ printf("#endif\n");
+#endif
+#endif
+ printf("#undef extern\n");
+#if _npt_strtoll || _map_libc || _std_strtol
+#if _npt_strtoll && !_map_libc && !_std_strtol
+ printf("#ifndef _ISOC99_SOURCE\n");
+#endif
+ printf("extern _ast_intmax_t strtoll(const char*, char**, int);\n");
+#if _npt_strtoll && !_map_libc && !_std_strtol
+ printf("#endif\n");
+#endif
+#endif
+#if _npt_strtoull || _map_libc || _std_strtol
+#if _npt_strtoull && !_map_libc && !_std_strtol
+ printf("#ifndef _ISOC99_SOURCE\n");
+#endif
+ printf("extern unsigned _ast_intmax_t strtoull(const char*, char**, int);\n");
+#if _npt_strtoull && !_map_libc && !_std_strtoul
+ printf("#endif\n");
+#endif
+#endif
+
+ /*
+ * finally some features/api mediation
+ */
+
+#if defined(_API_ast_MAP) && _map_libc
+ {
+ register const char* s;
+ register const char* t;
+
+ static const char map[] = _API_ast_MAP;
+
+ printf("\n");
+ t = map;
+ do
+ {
+ for (s = t; *t && *t != ' '; t++);
+ printf("#define %-.*s _ast_%-.*s\n", t - s, s, t - s, s);
+ } while (*t++);
+ }
+#endif
+ printf("\n");
+ printf("#undef extern\n");
+ return 0;
+}
diff --git a/src/lib/libast/features/mmap b/src/lib/libast/features/mmap
new file mode 100644
index 0000000..41ac44e
--- /dev/null
+++ b/src/lib/libast/features/mmap
@@ -0,0 +1,342 @@
+ref -D_def_map_ast=1
+
+sys mman
+
+tst lib_mmap note{ standard mmap interface that works }end execute{
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <sys/times.h>
+
+ #define MAPSIZE (64*1024)
+ #define BUFSIZE (8*1024)
+ #define WRITE (64)
+
+ #define Failed(file) (remove(file),1)
+
+ int
+ #if _STD_
+ main(int argc, char** argv)
+ #else
+ main(argc,argv)
+ int argc;
+ char** argv;
+ #endif
+ {
+ caddr_t mm;
+ char *t, *u, *f;
+ int i, fd, okfixed;
+ char file[1024], buf[MAPSIZE];
+ struct tms stm, etm;
+ clock_t rdtm, mmtm;
+
+ /* create data file in a local fs if possible */
+ t = file;
+ if (access(f = "/tmp", 0) == 0 ||
+ access(f = "/usr/tmp", 0) == 0)
+ {
+ while (*t = *f++)
+ t++;
+ *t++ = '/';
+ }
+ u = t;
+ f = argv[0];
+ while (*t = *f++)
+ if (*t == '/')
+ t = u;
+ else if (*t != '.')
+ t++;
+ *t++ = '.'; *t++ = 'D'; *t = 0;
+ if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0666)) < 0)
+ return 1;
+
+ for (i = 0; i < sizeof(buf); ++i)
+ buf[i] = '0' + (i%10);
+ for (i = 0; i < WRITE; ++i)
+ if (write(fd,buf,sizeof(buf)) != sizeof(buf))
+ return Failed(file);
+ close(fd);
+
+ /* see if can overwrite fixed map */
+ #ifndef MAP_VARIABLE
+ #define MAP_VARIABLE 0
+ #endif
+ if ((fd = open(file, O_RDWR)) < 0)
+ return Failed(file);
+
+ mm = mmap((caddr_t)0, sizeof(buf), (PROT_READ|PROT_WRITE),
+ (MAP_PRIVATE|MAP_VARIABLE), fd, 0);
+ if(mm == (caddr_t)0 || mm == (caddr_t)(-1))
+ return Failed(file);
+ mm = mmap(mm, sizeof(buf), (PROT_READ|PROT_WRITE),
+ (MAP_PRIVATE|MAP_FIXED), fd, 0);
+ okfixed = (mm == (caddr_t)0 || mm == (caddr_t)(-1)) ? 0 : 1;
+ munmap(mm, sizeof(buf));
+ close(fd);
+
+ /* read time */
+ if((fd = open(file, O_RDWR)) < 0)
+ return Failed(file);
+ times(&stm);
+ for (i = 0; i < WRITE; ++i)
+ if (read(fd,buf,BUFSIZE) != BUFSIZE)
+ return Failed(file);
+ times(&etm);
+ close(fd);
+ rdtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime);
+
+ /* mmap time */
+ if ((fd = open(file, O_RDWR)) < 0)
+ return Failed(file);
+ times(&stm);
+ for(i = 0, mm = (caddr_t)0; i < WRITE; ++i)
+ { if(okfixed)
+ { mm = (caddr_t)mmap(mm, MAPSIZE,
+ (PROT_READ|PROT_WRITE),
+ (MAP_PRIVATE | (mm ? MAP_FIXED : MAP_VARIABLE)),
+ fd, i*MAPSIZE );
+ }
+ else
+ { if(mm)
+ munmap(mm, MAPSIZE);
+ mm = (caddr_t)mmap((caddr_t)0, MAPSIZE,
+ (PROT_READ|PROT_WRITE),
+ (MAP_PRIVATE|MAP_VARIABLE),
+ fd, i*MAPSIZE );
+ }
+ if(mm == (caddr_t)(-1) || mm == (caddr_t)0)
+ return Failed(file);
+ }
+ times(&etm);
+ close(fd);
+ remove(file);
+ mmtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime);
+
+ return rdtm+60 < mmtm ? 1 : 0;
+ }
+}end
+
+tst lib_mmap64 -D_LARGEFILE64_SOURCE note{ mmap64 interface and implementation work }end execute{
+ #if !_lib_mmap
+ (
+ #endif
+
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+
+ int
+ main()
+ {
+ off64_t off;
+ int fd;
+ int n;
+ char* s;
+ struct stat64 st;
+ char file[32] = {'/','t','m','p','/','m','m','X','X','X','X','X','X'};
+
+ /* hey, stubs are supposed to fail! */
+ if (stat64(".", &st) || !st.st_mode || !st.st_mtime)
+ return 1;
+ if (!mktemp(file) || (fd = open64(file, O_CREAT|O_WRONLY, 0600)) < 0)
+ {
+ remove(file);
+ return 1;
+ }
+ off = (1<<8);
+ off *= off;
+ if (lseek64(fd, off, SEEK_SET) != off)
+ {
+ remove(file);
+ return 1;
+ }
+ n = strlen(file) + 1;
+ if (write(fd, file, n) != n)
+ {
+ remove(file);
+ return 1;
+ }
+ if (close(fd) < 0 || (fd = open64(file, O_RDWR)) < 0)
+ {
+ remove(file);
+ return 1;
+ }
+ if (!(s = mmap64((caddr_t)0, (size_t)n, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, off)))
+ {
+ remove(file);
+ return 1;
+ }
+ if (strcmp(s, file))
+ {
+ remove(file);
+ return 1;
+ }
+ close(fd);
+ remove(file);
+ return 0;
+ }
+}end
+
+tst mmap_anon note{ use mmap MAP_ANON to get raw memory }end execute{
+ #if !_lib_mmap
+ (
+ #endif
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/mman.h>
+ #if defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
+ #define MAP_ANON MAP_ANONYMOUS
+ #endif
+ int
+ main()
+ { void *addr;
+ addr = mmap(0,1024*1024,PROT_READ|PROT_WRITE,MAP_ANON|MAP_PRIVATE,-1,0);
+ return (addr && addr != (void*)(-1)) ? 0 : 1;
+ }
+}end
+
+tst mmap_devzero note{ use mmap on /dev/zero to get raw memory }end execute{
+ #if !_lib_mmap
+ (
+ #endif
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/mman.h>
+ int
+ main()
+ { int fd;
+ void *addr;
+ if((fd = open("/dev/zero", O_RDWR)) < 0)
+ return 1;
+ addr = mmap(0,1024*1024,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0);
+ return (addr && addr != (void*)(-1)) ? 0 : 1;
+ }
+}end
+
+tst note{ mmap is worth using }end output{
+ #if !_lib_mmap
+ (
+ #endif
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <sys/times.h>
+
+ #define MAPSIZE (64*1024)
+ #define BUFSIZE (MAPSIZE/8)
+ #define WRITE (64)
+ #define RUN (64)
+
+ #define Failed(file) (remove(file),1)
+
+ int
+ #if _STD_
+ main(int argc, char** argv)
+ #else
+ main(argc,argv)
+ int argc;
+ char** argv;
+ #endif
+ {
+ caddr_t mm;
+ char *t, *f;
+ int i, fd, k, run;
+ char file[1024], buf[MAPSIZE];
+ struct tms stm, etm;
+ clock_t rdtm, mmtm;
+
+ /* create data file */
+ f = argv[0]; t = file;
+ while (*t = *f++)
+ t++;
+ *t++ = '.'; *t++ = 'D'; *t = 0;
+ if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0666)) < 0)
+ return 1;
+
+ for (i = 0; i < sizeof(buf); ++i)
+ buf[i] = '0' + (i%10);
+ for (i = 0; i < WRITE; ++i)
+ if (write(fd,buf,sizeof(buf)) != sizeof(buf))
+ return Failed(file);
+ close(fd);
+
+ /* read time */
+ times(&stm);
+ for(run = 0; run < RUN; ++run)
+ { if((fd = open(file, O_RDWR)) < 0)
+ return Failed(file);
+ for (i = 0; i < WRITE; ++i)
+ { for(k = 0; k < MAPSIZE; k += BUFSIZE)
+ if (read(fd,buf,BUFSIZE) != BUFSIZE)
+ return Failed(file);
+ }
+ close(fd);
+ }
+ times(&etm);
+ rdtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime);
+
+ /* mmap time */
+ times(&stm);
+ for(run = 0; run < RUN; ++run)
+ { if ((fd = open(file, O_RDWR)) < 0)
+ return Failed(file);
+ for(i = 0, mm = (caddr_t)0; i < WRITE; ++i)
+ { if(mm)
+ munmap(mm, MAPSIZE);
+ mm = (caddr_t)mmap((caddr_t)0, MAPSIZE,
+ (PROT_READ|PROT_WRITE),
+ MAP_PRIVATE, fd, i*MAPSIZE );
+ if(mm == (caddr_t)(-1) || mm == (caddr_t)0)
+ return Failed(file);
+
+ /* the memcpy is < BUFSIZE to simulate the
+ fact that functions like sfreserve/sfgetr do
+ not do buffer copying.
+ */
+ t = (char*)mm;
+ for(k = 0; k < MAPSIZE; k += BUFSIZE, t += BUFSIZE)
+ memcpy(buf,t,(3*BUFSIZE)/4);
+ }
+ close(fd);
+ }
+ times(&etm);
+ mmtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime);
+
+ remove(file);
+
+ if(4*mmtm <= 3*rdtm)
+ printf("#define _mmap_worthy 2 /* mmap is great */\n");
+ else if(4*mmtm <= 5*rdtm)
+ printf("#define _mmap_worthy 1 /* mmap is good */\n");
+
+ else
+ return 1;
+ return 0;
+ }
+}end
+
+cat{
+
+ /* some systems get it wrong but escape concise detection */
+ #ifndef _NO_MMAP
+ #if __CYGWIN__
+ #define _NO_MMAP 1
+ #endif
+ #endif
+
+ #if _NO_MMAP
+ #undef _lib_mmap
+ #undef _lib_mmap64
+ #undef _mmap_anon
+ #undef _mmap_devzero
+ #undef _mmap_worthy
+ #endif
+}end
diff --git a/src/lib/libast/features/mode.c b/src/lib/libast/features/mode.c
new file mode 100644
index 0000000..68b5e68
--- /dev/null
+++ b/src/lib/libast/features/mode.c
@@ -0,0 +1,218 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * generate mode features
+ */
+
+#include "limits.h"
+
+#include "FEATURE/param"
+
+#include <modecanon.h>
+
+int
+main()
+{
+ int n;
+ int idperm;
+ int idtype;
+
+ idperm = idtype = 1;
+#ifndef S_ITYPE
+#ifdef S_IFMT
+ printf("#define S_ITYPE(m) ((m)&S_IFMT)\n");
+#else
+ printf("#define S_ITYPE(m) ((m)&~S_IPERM)\n");
+#endif
+#endif
+#ifdef S_ISBLK
+ if (!S_ISBLK(X_IFBLK)) idtype = 0;
+#else
+#ifdef S_IFBLK
+ printf("#define S_ISBLK(m) (S_ITYPE(m)==S_IFBLK)\n");
+#else
+ printf("#define S_ISBLK(m) 0\n");
+#endif
+#endif
+#ifdef S_ISCHR
+ if (!S_ISCHR(X_IFCHR)) idtype = 0;
+#else
+#ifdef S_IFCHR
+ printf("#define S_ISCHR(m) (S_ITYPE(m)==S_IFCHR)\n");
+#else
+ printf("#define S_ISCHR(m) 0\n");
+#endif
+#endif
+#ifdef S_ISCTG
+ if (!S_ISCTG(X_IFCTG)) idtype = 0;
+#else
+#ifdef S_IFCTG
+ printf("#define S_ISCTG(m) (S_ITYPE(m)==S_IFCTG)\n");
+#endif
+#endif
+#ifdef S_ISDIR
+ if (!S_ISDIR(X_IFDIR)) idtype = 0;
+#else
+#ifdef S_IFDIR
+ printf("#define S_ISDIR(m) (S_ITYPE(m)==S_IFDIR)\n");
+#else
+ printf("#define S_ISDIR(m) 0\n");
+#endif
+#endif
+#ifdef S_ISFIFO
+ if (!S_ISFIFO(X_IFIFO)) idtype = 0;
+#else
+#ifdef S_IFIFO
+ printf("#define S_ISFIFO(m) (S_ITYPE(m)==S_IFIFO)\n");
+#else
+ printf("#define S_ISFIFO(m) 0\n");
+#endif
+#endif
+#ifdef S_ISLNK
+ if (!S_ISLNK(X_IFLNK)) idtype = 0;
+#else
+#ifdef S_IFLNK
+ printf("#define S_ISLNK(m) (S_ITYPE(m)==S_IFLNK)\n");
+#else
+ printf("#define S_ISLNK(m) 0\n");
+#endif
+#endif
+#ifdef S_ISREG
+ if (!S_ISREG(X_IFREG)) idtype = 0;
+#else
+#ifdef S_IFREG
+ printf("#define S_ISREG(m) (S_ITYPE(m)==S_IFREG)\n");
+#else
+ printf("#define S_ISREG(m) 0\n");
+#endif
+#endif
+#ifdef S_ISSOCK
+ if (!S_ISSOCK(X_IFSOCK)) idtype = 0;
+#else
+#ifdef S_IFSOCK
+ printf("#define S_ISSOCK(m) (S_ITYPE(m)==S_IFSOCK)\n");
+#endif
+#endif
+ printf("\n");
+#ifndef S_IPERM
+ printf("#define S_IPERM (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)\n");
+#endif
+#ifndef S_ISUID
+ printf("#define S_ISUID 0%04o\n", X_ISUID);
+#else
+ if (S_ISUID != X_ISUID) idperm = 0;
+#endif
+#ifndef S_ISGID
+ printf("#define S_ISGID 0%04o\n", X_ISGID);
+#else
+ if (S_ISGID != X_ISGID) idperm = 0;
+#endif
+#ifndef S_ISVTX
+ printf("#define S_ISVTX 0%04o\n", X_ISVTX);
+#else
+ if (S_ISVTX != X_ISVTX) idperm = 0;
+#endif
+#ifndef S_IRUSR
+ printf("#define S_IRUSR 0%04o\n", X_IRUSR);
+#else
+ if (S_IRUSR != X_IRUSR) idperm = 0;
+#endif
+#ifndef S_IWUSR
+ printf("#define S_IWUSR 0%04o\n", X_IWUSR);
+#else
+ if (S_IWUSR != X_IWUSR) idperm = 0;
+#endif
+#ifndef S_IXUSR
+ printf("#define S_IXUSR 0%04o\n", X_IXUSR);
+#else
+ if (S_IXUSR != X_IXUSR) idperm = 0;
+#endif
+#ifndef S_IRGRP
+ printf("#define S_IRGRP 0%04o\n", X_IRGRP);
+#else
+ if (S_IRGRP != X_IRGRP) idperm = 0;
+#endif
+#ifndef S_IWGRP
+ printf("#define S_IWGRP 0%04o\n", X_IWGRP);
+#else
+ if (S_IWGRP != X_IWGRP) idperm = 0;
+#endif
+#ifndef S_IXGRP
+ printf("#define S_IXGRP 0%04o\n", X_IXGRP);
+#else
+ if (S_IXGRP != X_IXGRP) idperm = 0;
+#endif
+#ifndef S_IROTH
+ printf("#define S_IROTH 0%04o\n", X_IROTH);
+#else
+ if (S_IROTH != X_IROTH) idperm = 0;
+#endif
+#ifndef S_IWOTH
+ printf("#define S_IWOTH 0%04o\n", X_IWOTH);
+#else
+ if (S_IWOTH != X_IWOTH) idperm = 0;
+#endif
+#ifndef S_IXOTH
+ printf("#define S_IXOTH 0%04o\n", X_IXOTH);
+#else
+ if (S_IXOTH != X_IXOTH) idperm = 0;
+#endif
+#ifndef S_IRWXU
+ printf("#define S_IRWXU (S_IRUSR|S_IWUSR|S_IXUSR)\n");
+#endif
+#ifndef S_IRWXG
+ printf("#define S_IRWXG (S_IRGRP|S_IWGRP|S_IXGRP)\n");
+#endif
+#ifndef S_IRWXO
+ printf("#define S_IRWXO (S_IROTH|S_IWOTH|S_IXOTH)\n");
+#endif
+ printf("\n");
+ if (idperm) printf("#define _S_IDPERM 1\n");
+ if (idtype) printf("#define _S_IDTYPE 1\n");
+ printf("\n");
+#ifdef BUFFERSIZE
+ n = BUFFERSIZE;
+#else
+#ifdef MAXBSIZE
+ n = MAXBSIZE;
+#else
+#ifdef SBUFSIZE
+ n = SBUFSIZE;
+#else
+#ifdef BUFSIZ
+ n = BUFSIZ;
+#else
+ if (sizeof(char*) > 4) n = 8192;
+ else if (sizeof(char*) < 4) n = 512;
+ else n = 4096;
+#endif
+#endif
+#endif
+#endif
+ printf("#define BUFFERSIZE %u\n", n);
+ printf("\n");
+ return 0;
+}
diff --git a/src/lib/libast/features/ndbm b/src/lib/libast/features/ndbm
new file mode 100644
index 0000000..d12d15c
--- /dev/null
+++ b/src/lib/libast/features/ndbm
@@ -0,0 +1,29 @@
+if tst -ldb note{ sleepycat ndbm compatibility }end link{
+ #define DB_DBM_HSEARCH 1
+ #include <db.h>
+ int main()
+ {
+ DBM* dbm = 0;
+ dbm_close(dbm);
+ return 0;
+ }
+ }end {
+ #ifndef DB_DBM_HSEARCH
+ #define DB_DBM_HSEARCH 1
+ #include <db.h>
+ #endif
+ #define _use_ndbm 1
+ }
+elif hdr gdbm-ndbm {
+ #include <gdbm-ndbm.h>
+ #define _use_ndbm 1
+}
+elif hdr gdbm/ndbm {
+ #include <gdbm/ndbm.h>
+ #define _use_ndbm 1
+}
+elif hdr ndbm {
+ #include <ndbm.h>
+ #define _use_ndbm 1
+}
+endif
diff --git a/src/lib/libast/features/nl_types b/src/lib/libast/features/nl_types
new file mode 100644
index 0000000..02cae3e
--- /dev/null
+++ b/src/lib/libast/features/nl_types
@@ -0,0 +1,64 @@
+set prototyped
+lib catopen,nl_langinfo
+hdr nl_types,langinfo
+nxt nl_types
+
+tst output{
+ #if !_lib_catopen
+ #undef _hdr_nl_types
+ #endif
+ #include "FEATURE/limits"
+ #if _hdr_nl_types
+ #include <nl_types.h>
+ #endif
+
+ int
+ main()
+ {
+ printf("#include <limits.h>\n");
+ #if _hdr_nl_types && defined(_nxt_nl_types_str)
+ printf("#include <%s> /* the native nl_types.h */\n", _nxt_nl_types_str);
+ #endif
+ printf("\n");
+ #ifndef NL_SETMAX
+ printf("#undef NL_SETMAX\n");
+ printf("#define NL_SETMAX 1023\n");
+ #endif
+ #ifndef NL_MSGMAX
+ printf("#undef NL_MSGMAX\n");
+ printf("#define NL_MSGMAX 32767\n");
+ #endif
+ #ifndef NL_SETD
+ printf("#undef NL_SETD\n");
+ printf("#define NL_SETD 1\n");
+ #endif
+ #ifndef NL_CAT_LOCALE
+ printf("#undef NL_CAT_LOCALE\n");
+ printf("#define NL_CAT_LOCALE 1\n");
+ #endif
+ #if _lib_catopen
+ printf("#undef nl_catd\n");
+ printf("#define nl_catd _ast_nl_catd\n");
+ printf("#undef catopen\n");
+ printf("#define catopen _ast_catopen\n");
+ printf("#undef catgets\n");
+ printf("#define catgets _ast_catgets\n");
+ printf("#undef catclose\n");
+ printf("#define catclose _ast_catclose\n");
+ #endif
+ printf("\n");
+ printf("typedef void* nl_catd;\n");
+ printf("\n");
+ printf("#if _BLD_ast && defined(__EXPORT__)\n");
+ printf("#define extern __EXPORT__\n");
+ printf("#endif\n");
+ printf("\n");
+ printf("extern nl_catd catopen(const char*, int);\n");
+ printf("extern char* catgets(nl_catd, int, int, const char*);\n");
+ printf("extern int catclose(nl_catd);\n");
+ printf("\n");
+ printf("#undef extern\n");
+ printf("\n");
+ return 0;
+ }
+}end
diff --git a/src/lib/libast/features/omitted b/src/lib/libast/features/omitted
new file mode 100644
index 0000000..1e4eca4
--- /dev/null
+++ b/src/lib/libast/features/omitted
@@ -0,0 +1,110 @@
+tst note{ check for win32 .exe botches }end output{
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ static int
+ cp(const char* from, const char* to)
+ {
+ ssize_t n;
+ int fd;
+ int td;
+ struct stat fs;
+ char buf[1024];
+
+ if ((fd = _open(from, O_RDONLY|O_BINARY)) < 0)
+ return -1;
+ if (_fstat(fd, &fs) || (td = _open(to, O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, fs.st_mode & 0777)) < 0)
+ {
+ _close(fd);
+ return -1;
+ }
+ while ((n = _read(fd, buf, sizeof(buf))) > 0 && _write(td, buf, n) == n);
+ _close(fd);
+ _close(td);
+ return n ? -1 : 0;
+ }
+ int
+ main(int argc, char** argv)
+ {
+ int fd;
+ int fix;
+ struct stat st;
+ char buf[256];
+
+ snprintf(buf, sizeof(buf), "rm -rf /tmp/iff-%d", getpid());
+ if (_mkdir(buf+7, 0755))
+ return 1;
+ if (_chdir(buf+7))
+ return 1;
+ if (cp("/bin/cat.exe", "foo.exe"))
+ return 1;
+ fix = 0;
+ if (_access("foo", X_OK))
+ fix++,printf("#define _win32_botch_access 1\n");
+ if (_chmod("foo", 0755))
+ fix++,printf("#define _win32_botch_chmod 1\n");
+ if (cp("/bin/cat", "bam") || _access("bam.exe", X_OK))
+ fix++,printf("#define _win32_botch_copy 1\n");
+ if (_getpagesize() != 64 * 1024)
+ fix++,printf("#define _win32_botch_getpagesize 1\n");
+ #if !__EMX__
+ if (_link("foo", "bar") || _access("bar.exe", X_OK))
+ fix++,printf("#define _win32_botch_link 1\n");
+ else
+ #endif
+ cp("foo.exe", "bar.exe");
+ if ((fd = _open("foo", O_RDONLY)) < 0)
+ fix++,printf("#define _win32_botch_open 1\n");
+ else
+ _close(fd);
+ if (_pathconf("huh", _PC_NAME_MAX) >= 0)
+ fix++,printf("#define _win32_botch_pathconf 1\n");
+ if (_rename("foo", "aha") || _access("aha.exe", X_OK))
+ fix++,printf("#define _win32_botch_rename 1\n");
+ else
+ _rename("foo.exe", "aha.exe");
+ if (_stat("bar", &st))
+ {
+ fix++,printf("#define _win32_botch_stat 1\n");
+ if (sizeof(st.st_ino) == 8)
+ printf("#define _stat _stat64\n");
+ }
+ if (_truncate("aha", 0))
+ fix++,printf("#define _win32_botch_truncate 1\n");
+ if (_unlink("bar"))
+ fix++,printf("#define _win32_botch_unlink 1\n");
+ if (_utime("aha", 0))
+ fix++,printf("#define _win32_botch_utime 1\n");
+ if (fix)
+ {
+ printf("#define _win32_botch_execve 1\n");
+ printf("#define _win32_botch 1\n");
+ }
+ _chdir("/tmp");
+ system(buf);
+ return 0;
+ }
+}end
+
+tst win32_botch_alarm note{ win32 alarm(2) return botched }end noexecute{
+ #include <signal.h>
+ #include <unistd.h>
+ #include <time.h>
+
+ static int sigalrm = 0;
+
+ static void
+ handler(int sig)
+ {
+ sigalrm++;
+ }
+ int
+ main(int argc, char** argv)
+ {
+ signal(SIGALRM, handler);
+ alarm(2);
+ pause();
+ return sigalrm != 1 || alarm(0) != 0;
+ }
+}end
diff --git a/src/lib/libast/features/options b/src/lib/libast/features/options
new file mode 100644
index 0000000..500bd63
--- /dev/null
+++ b/src/lib/libast/features/options
@@ -0,0 +1 @@
+opt map-libc
diff --git a/src/lib/libast/features/param.sh b/src/lib/libast/features/param.sh
new file mode 100644
index 0000000..7d4a856
--- /dev/null
+++ b/src/lib/libast/features/param.sh
@@ -0,0 +1,47 @@
+########################################################################
+# #
+# This software is part of the ast package #
+# Copyright (c) 1985-2011 AT&T Intellectual Property #
+# and is licensed under the #
+# Eclipse Public License, Version 1.0 #
+# by AT&T Intellectual Property #
+# #
+# A copy of the License is available at #
+# http://www.eclipse.org/org/documents/epl-v10.html #
+# (with md5 checksum b35adb5213ca9657e911e9befb180842) #
+# #
+# Information and Software Systems Research #
+# AT&T Research #
+# Florham Park NJ #
+# #
+# Glenn Fowler <gsf@research.att.com> #
+# David Korn <dgk@research.att.com> #
+# Phong Vo <kpv@research.att.com> #
+# #
+########################################################################
+: generate "<sys/param.h> + <sys/types.h> + <sys/stat.h>" include sequence
+case $# in
+0) ;;
+*) eval $1
+ shift
+ ;;
+esac
+for i in "#include <sys/param.h>" "#include <sys/param.h>
+#ifndef S_IFDIR
+#include <sys/stat.h>
+#endif" "#include <sys/param.h>
+#ifndef S_IFDIR
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif" "#ifndef S_IFDIR
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif"
+do echo "$i
+struct stat V_stat_V;
+F_stat_F() { V_stat_V.st_mode = 0; }" > $tmp.c
+ if $cc -c $tmp.c >/dev/null
+ then echo "$i"
+ break
+ fi
+done
diff --git a/src/lib/libast/features/preroot.sh b/src/lib/libast/features/preroot.sh
new file mode 100644
index 0000000..40ac2fc
--- /dev/null
+++ b/src/lib/libast/features/preroot.sh
@@ -0,0 +1,46 @@
+########################################################################
+# #
+# This software is part of the ast package #
+# Copyright (c) 1985-2011 AT&T Intellectual Property #
+# and is licensed under the #
+# Eclipse Public License, Version 1.0 #
+# by AT&T Intellectual Property #
+# #
+# A copy of the License is available at #
+# http://www.eclipse.org/org/documents/epl-v10.html #
+# (with md5 checksum b35adb5213ca9657e911e9befb180842) #
+# #
+# Information and Software Systems Research #
+# AT&T Research #
+# Florham Park NJ #
+# #
+# Glenn Fowler <gsf@research.att.com> #
+# David Korn <dgk@research.att.com> #
+# Phong Vo <kpv@research.att.com> #
+# #
+########################################################################
+: generate preroot features
+case $# in
+0) ;;
+*) eval $1
+ shift
+ ;;
+esac
+if /etc/preroot / /bin/echo >/dev/null
+then cat <<!
+#pragma prototyped
+
+#define FS_PREROOT 1 /* preroot enabled */
+#define PR_BASE "CCS" /* preroot base env var */
+#define PR_COMMAND "/etc/preroot" /* the preroot command */
+#define PR_REAL "/dev/.." /* real root pathname */
+#define PR_SILENT "CCSQUIET" /* no command trace */
+
+extern char* getpreroot(char*, const char*);
+extern int ispreroot(const char*);
+extern int realopen(const char*, int, int);
+extern void setpreroot(char**, const char*);
+
+!
+else echo "/* preroot not enabled */"
+fi
diff --git a/src/lib/libast/features/prog b/src/lib/libast/features/prog
new file mode 100644
index 0000000..365ce88
--- /dev/null
+++ b/src/lib/libast/features/prog
@@ -0,0 +1,12 @@
+lib getexecname,_NSGetExecutablePath
+
+tst run{
+ for p in /proc/self/exe /proc/self/path/a.out
+ do if test -e $p
+ then echo "#define _PROC_PROG \"$p\""
+ break
+ fi
+ done
+}end
+
+_hdr_macho_o_dyld = hdr mach-o/dyld
diff --git a/src/lib/libast/features/sfinit.c b/src/lib/libast/features/sfinit.c
new file mode 100644
index 0000000..ccd0527
--- /dev/null
+++ b/src/lib/libast/features/sfinit.c
@@ -0,0 +1,94 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * generate sfio _Sftable static initializers
+ */
+
+#include "FEATURE/common"
+#include "FEATURE/float"
+
+int
+main()
+{
+ register int i;
+#if _ast_fltmax_double
+ char* fs = "";
+ char* ds = "";
+ char* ls = "";
+#else
+ char* fs = "F";
+ char* ds = "";
+ char* ls = "L";
+#endif
+
+ printf("\nstatic const float sf_flt_pow10[] =\n{\n");
+ for (i = 0; i <= FLT_MAX_10_EXP; i++)
+ printf("\t1E%d%s,\n", i, fs);
+ printf("};\n");
+ printf("\nstatic const double sf_dbl_pow10[] =\n{\n");
+ for (i = 0; i <= DBL_MAX_10_EXP; i++)
+ printf("\t1E%d%s,\n", i, ds);
+ printf("};\n");
+#if !_ast_fltmax_double
+ printf("\nstatic const _ast_fltmax_t sf_ldbl_pow10[] =\n{\n");
+ for (i = 0; i <= LDBL_MAX_10_EXP; i++)
+ printf("\t1E%d%s,\n", i, ls);
+ printf("};\n");
+#endif
+ printf("\nSftab_t _Sftable =\n{\n");
+ printf("\t{ 1E1%s, 1E2%s, 1E4%s, 1E8%s, 1E16%s, 1E32%s },\n", ls, ls, ls, ls, ls, ls);
+ printf("\t{ 1E-1%s, 1E-2%s, 1E-4%s, 1E-8%s, 1E-16%s, 1E-32%s },\n", ls, ls, ls, ls, ls, ls);
+ printf("\t{ '0','0', '0','1', '0','2', '0','3', '0','4',\n");
+ printf("\t '0','5', '0','6', '0','7', '0','8', '0','9',\n");
+ printf("\t '1','0', '1','1', '1','2', '1','3', '1','4',\n");
+ printf("\t '1','5', '1','6', '1','7', '1','8', '1','9',\n");
+ printf("\t '2','0', '2','1', '2','2', '2','3', '2','4',\n");
+ printf("\t '2','5', '2','6', '2','7', '2','8', '2','9',\n");
+ printf("\t '3','0', '3','1', '3','2', '3','3', '3','4',\n");
+ printf("\t '3','5', '3','6', '3','7', '3','8', '3','9',\n");
+ printf("\t '4','0', '4','1', '4','2', '4','3', '4','4',\n");
+ printf("\t '4','5', '4','6', '4','7', '4','8', '4','9',\n");
+ printf("\t '5','0', '5','1', '5','2', '5','3', '5','4',\n");
+ printf("\t '5','5', '5','6', '5','7', '5','8', '5','9',\n");
+ printf("\t '6','0', '6','1', '6','2', '6','3', '6','4',\n");
+ printf("\t '6','5', '6','6', '6','7', '6','8', '6','9',\n");
+ printf("\t '7','0', '7','1', '7','2', '7','3', '7','4',\n");
+ printf("\t '7','5', '7','6', '7','7', '7','8', '7','9',\n");
+ printf("\t '8','0', '8','1', '8','2', '8','3', '8','4',\n");
+ printf("\t '8','5', '8','6', '8','7', '8','8', '8','9',\n");
+ printf("\t '9','0', '9','1', '9','2', '9','3', '9','4',\n");
+ printf("\t '9','5', '9','6', '9','7', '9','8', '9','9',\n");
+ printf("\t},\n");
+ printf("\t\"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@_\",\n");
+ printf("\tsfcvinit, 0,\n");
+ printf("\tsffmtpos,\n");
+ printf("\tsffmtint,\n");
+ printf("\t(float*)&sf_flt_pow10[0],\n");
+ printf("\t(double*)&sf_dbl_pow10[0],\n");
+#if _ast_fltmax_double
+ printf("\t0,\n");
+#else
+ printf("\t(_ast_fltmax_t*)&sf_ldbl_pow10[0],\n");
+#endif
+ printf("};\n");
+ return 0;
+}
diff --git a/src/lib/libast/features/sfio b/src/lib/libast/features/sfio
new file mode 100644
index 0000000..901935a
--- /dev/null
+++ b/src/lib/libast/features/sfio
@@ -0,0 +1,170 @@
+ref -D_def_map_ast=1
+hdr float,floatingpoint,math,values
+sys filio,ioctl
+lib qfrexp,qldexp
+key signed
+
+tst - note{ number of bits in pointer }end output{
+ #include <stdio.h>
+ int
+ main()
+ {
+ printf("#define _ptr_bits %d\n", sizeof(char*) * 8);
+ return 0;
+ }
+}end
+
+tst tmp_rmfail note{ open files cannot be removed }end execute{
+ #include <string.h>
+ #include <time.h>
+ int
+ main()
+ {
+ #if !_UWIN
+ int n;
+ char* s;
+ FILE* fr;
+ FILE* fw;
+ char file[16];
+ static char data[] = "0123456789";
+ s = file;
+ *s++ = '1';
+ *s++ = 'F';
+ *s++ = 'F';
+ *s++ = '3';
+ n = (int)time(0);
+ *s++ = (n & 0xF) + 'A';
+ *s++ = ((n >> 4) & 0xF) + 'A';
+ *s++ = ((n >> 8) & 0xF) + 'A';
+ *s++ = ((n >> 12) & 0xF) + 'A';
+ *s++ = '.';
+ *s++ = 'T';
+ *s++ = 'M';
+ *s++ = 'P';
+ *s = 0;
+ remove(file);
+ if (!(fw = fopen(file, "w")))
+ return 0;
+ if (!(fr = fopen(file, "r")))
+ {
+ fclose(fw);
+ remove(file);
+ return 0;
+ }
+ if (remove(file) < 0)
+ {
+ fclose(fr);
+ fclose(fw);
+ remove(file);
+ return 0;
+ }
+ if (fwrite(data, sizeof(data), 1, fw) != 1)
+ return 0;
+ fclose(fw);
+ if (fread(file, sizeof(data), 1, fr) != 1)
+ return 0;
+ fclose(fr);
+ if (strcmp(file, data) != 0)
+ return 0;
+ #endif
+ return 1;
+ }
+}end
+
+more void_int note{ voidptr is larger than int }end execute{
+ int
+ main()
+ {
+ return sizeof(char*) > sizeof(int) ? 0 : 1;
+ }
+}end
+
+more long_int note{ long is larger than int }end execute{
+ int
+ main()
+ {
+ return sizeof(long) > sizeof(int) ? 0 : 1;
+ }
+}end
+
+tst vax_asm note{ register layout ok for vax string operations }end execute{
+ int
+ main()
+ {
+ #ifndef vax
+ return absurd = -1;
+ #else
+ register int r11, r10, r9, r8, r7, r6;
+ r11 = r10 = r9 = r8 = r7 = r6 = -1;
+ asm("clrw r11");
+ asm("clrw r10");
+ asm("clrw r9");
+ asm("clrw r8");
+ asm("clrw r7");
+ asm("clrw r6");
+ if(sizeof(int) != sizeof(char*) || r11 || r10 || r9 || r8 || r7 || r6 )
+ return -1;
+ return 0;
+ #endif
+ }
+}end
+
+tst lib_cvt note{ native floating point conversions ok }end link{
+ _BEGIN_EXTERNS_
+ extern char* ecvt _ARG_((double, int, int*, int*));
+ extern char* fcvt _ARG_((double, int, int*, int*));
+ extern double strtod _ARG_((const char*, char**));
+ _END_EXTERNS_
+ int
+ main()
+ {
+ ecvt(0.0, 0, 0, 0);
+ fcvt(0.0, 0, 0, 0);
+ strtod(0, 0);
+ return 0;
+ }
+}end
+
+tst xopen_stdio note{ Stdio fseek/fflush are X/Open-compliant }end execute{
+ #define Failed(file) (unlink(file),1)
+ int
+ main(argc, argv)
+ int argc;
+ char** argv;
+ { FILE *f1, *f2;
+ char file[1024], buf[1024], *f, *t;
+ int i, fd;
+
+ /* create file */
+ for(f = argv[0], t = file; (*t = *f++) != 0; )
+ t++;
+ *t++ = '.'; *t++ = 'D'; *t++ = 0;
+ if((fd = creat(file,0666)) < 0)
+ return 1;
+
+ for (i = 0; i < sizeof(buf); ++i)
+ buf[i] = '0' + (i%10);
+ for (i = 0; i < 16; ++i)
+ if (write(fd,buf,sizeof(buf)) != sizeof(buf))
+ return Failed(file);
+ close(fd);
+
+ if(!(f1 = fopen(file,"r+")) ||
+ (fd = dup(fileno(f1))) < 0 ||
+ !(f2 = fdopen(fd,"r+")) )
+ return Failed(file);
+
+ if(fread(buf, 1, 7, f2) != 7 || ftell(f2) != 7)
+ return Failed(file);
+
+ if(fseek(f1, 1010, 0) < 0 || ftell(f1) != 1010)
+ return Failed(file);
+
+ fflush(f2); /* this should set the seek location to 1010 */
+ if(ftell(f2) != 1010)
+ return Failed(file);
+
+ unlink(file);
+ return 0;
+ }
+}end
diff --git a/src/lib/libast/features/sig.sh b/src/lib/libast/features/sig.sh
new file mode 100644
index 0000000..706372b
--- /dev/null
+++ b/src/lib/libast/features/sig.sh
@@ -0,0 +1,132 @@
+########################################################################
+# #
+# This software is part of the ast package #
+# Copyright (c) 1985-2011 AT&T Intellectual Property #
+# and is licensed under the #
+# Eclipse Public License, Version 1.0 #
+# by AT&T Intellectual Property #
+# #
+# A copy of the License is available at #
+# http://www.eclipse.org/org/documents/epl-v10.html #
+# (with md5 checksum b35adb5213ca9657e911e9befb180842) #
+# #
+# Information and Software Systems Research #
+# AT&T Research #
+# Florham Park NJ #
+# #
+# Glenn Fowler <gsf@research.att.com> #
+# David Korn <dgk@research.att.com> #
+# Phong Vo <kpv@research.att.com> #
+# #
+########################################################################
+: generate sig features
+case $# in
+0) ;;
+*) eval $1
+ shift
+ ;;
+esac
+echo "#include <signal.h>
+int xxx;" > $tmp.c
+$cc -c $tmp.c >/dev/null 2>$tmp.e
+echo "#pragma prototyped
+#define sig_info _sig_info_
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide kill killpg
+#else
+#define kill ______kill
+#define killpg ______killpg
+#endif
+#include <signal.h>
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide kill killpg
+#else
+#undef kill
+#undef killpg
+#endif
+#ifndef sigmask
+#define sigmask(s) (1<<((s)-1))
+#endif"
+echo "#include <signal.h>
+#ifdef TYPE
+#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
+typedef TYPE (*Sig_handler_t)(ARG);
+#else
+typedef TYPE (*Sig_handler_t)();
+#endif
+#endif
+Sig_handler_t f()
+{
+ Sig_handler_t handler;
+ handler = signal(1, SIG_IGN);
+ return(handler);
+}" > $tmp.c
+if $cc -c $tmp.c >/dev/null
+then :
+else e=`wc -l $tmp.e`
+ i1= j1=
+ for i in void int
+ do for j in int,... ... int
+ do $cc -c -DTYPE=$i -DARG=$j $tmp.c >/dev/null 2>$tmp.e || continue
+ case `wc -l $tmp.e` in
+ $e) i1= j1=; break 2 ;;
+ esac
+ case $i1 in
+ "") i1=$i j1=$j ;;
+ esac
+ done
+ done
+ case $i1 in
+ ?*) i=$i1 j=$j1 ;;
+ esac
+ echo "typedef $i (*Sig_handler_t)($j);"
+fi
+echo '
+
+#define Handler_t Sig_handler_t
+
+#define SIG_REG_PENDING (-1)
+#define SIG_REG_POP 0
+#define SIG_REG_EXEC 00001
+#define SIG_REG_PROC 00002
+#define SIG_REG_TERM 00004
+#define SIG_REG_ALL 00777
+#define SIG_REG_SET 01000
+
+typedef struct
+{
+ char** name;
+ char** text;
+ int sigmax;
+} Sig_info_t;
+
+extern int kill(pid_t, int);
+extern int killpg(pid_t, int);
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+#if !_BLD_ast && defined(__IMPORT__)
+#define extern extern __IMPORT__
+#endif
+
+extern Sig_info_t sig_info;
+
+#undef extern
+
+#if _lib_sigflag && _npt_sigflag
+extern int sigflag(int, int, int);
+#endif
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#if !_lib_sigflag
+extern int sigflag(int, int, int);
+#endif
+extern int sigcritical(int);
+extern int sigunblock(int);
+
+#undef extern'
diff --git a/src/lib/libast/features/siglist b/src/lib/libast/features/siglist
new file mode 100644
index 0000000..37d1bf0
--- /dev/null
+++ b/src/lib/libast/features/siglist
@@ -0,0 +1,14 @@
+lib strsignal string.h signal.h
+
+tst - run{
+ for sig in `/bin/kill -l 2>/dev/null`
+ do case $sig in
+ *[!A-Za-z0-9_]*|*MIN|*MAX)
+ ;;
+ *) echo "#if defined(SIG$sig) && !defined(HAD_SIG$sig)"
+ echo "0,\"$sig\",SIG$sig,"
+ echo "#endif"
+ ;;
+ esac
+ done
+}end
diff --git a/src/lib/libast/features/signal.c b/src/lib/libast/features/signal.c
new file mode 100644
index 0000000..07c9b4b
--- /dev/null
+++ b/src/lib/libast/features/signal.c
@@ -0,0 +1,371 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * generate signal features
+ */
+
+#include "FEATURE/standards"
+
+#define strsignal ______strsignal
+
+#include <signal.h>
+
+#undef strsignal
+
+struct _m_
+{
+ char* text;
+ char* name;
+ int value;
+};
+
+#define elementsof(x) (sizeof(x)/sizeof(x[0]))
+
+static struct _m_ map[] =
+{
+#ifdef SIGABRT
+#define HAD_SIGABRT 1
+"Abort", "ABRT", SIGABRT,
+#endif
+#ifdef SIGAIO
+#define HAD_SIGAIO 1
+"Asynchronous I/O", "AIO", SIGAIO,
+#endif
+#ifdef SIGALRM
+#define HAD_SIGALRM 1
+"Alarm call", "ALRM", SIGALRM,
+#endif
+#ifdef SIGAPOLLO
+#define HAD_SIGAPOLLO 1
+"Apollo", "APOLLO", SIGAPOLLO,
+#endif
+#ifdef SIGBUS
+#define HAD_SIGBUS 1
+"Bus error", "BUS", SIGBUS,
+#endif
+#ifdef SIGCHLD
+#define HAD_SIGCHLD 1
+"Child status change", "CHLD", SIGCHLD,
+#endif
+#ifdef SIGCLD
+#define HAD_SIGCLD 1
+"Death of child", "CLD", SIGCLD,
+#endif
+#ifdef SIGCONT
+#define HAD_SIGCONT 1
+"Stopped process continued", "CONT", SIGCONT,
+#endif
+#ifdef SIGDANGER
+#define HAD_SIGDANGER 1
+"System crash soon", "DANGER", SIGDANGER,
+#endif
+#ifdef SIGDEBUG
+#define HAD_SIGDEBUG 1
+"Debug trap", "DEBUG", SIGDEBUG,
+#endif
+#ifdef SIGDIL
+#define HAD_SIGDIL 1
+"DIL trap", "DIL", SIGDIL,
+#endif
+#ifdef SIGEMT
+#define HAD_SIGEMT 1
+"EMT trap", "EMT", SIGEMT,
+#endif
+#ifdef SIGERR
+#define HAD_SIGERR 1
+"ERR trap", "ERR", SIGERR,
+#endif
+#ifdef SIGEXIT
+#define HAD_SIGEXIT 1
+"Exit", "EXIT", SIGEXIT,
+#endif
+#ifdef SIGFPE
+#define HAD_SIGFPE 1
+"Floating exception", "FPE", SIGFPE,
+#endif
+#ifdef SIGFREEZE
+#define HAD_SIGFREEZE 1
+"CPR freeze", "FREEZE", SIGFREEZE,
+#endif
+#ifdef SIGHUP
+#define HAD_SIGHUP 1
+"Hangup", "HUP", SIGHUP,
+#endif
+#ifdef SIGILL
+#define HAD_SIGILL 1
+"Illegal instruction", "ILL", SIGILL,
+#endif
+#ifdef SIGINT
+#define HAD_SIGINT 1
+"Interrupt", "INT", SIGINT,
+#endif
+#ifdef SIGIO
+#define HAD_SIGIO 1
+"IO possible", "IO", SIGIO,
+#endif
+#ifdef SIGIOT
+#define HAD_SIGIOT 1
+"IOT trap", "IOT", SIGIOT,
+#endif
+#ifdef SIGKILL
+#define HAD_SIGKILL 1
+"Killed", "KILL", SIGKILL,
+#endif
+#ifdef SIGLAB
+#define HAD_SIGLAB 1
+"Security label changed", "LAB", SIGLAB,
+#endif
+#ifdef SIGLOST
+#define HAD_SIGLOST 1
+"Resources lost", "LOST", SIGLOST,
+#endif
+#ifdef SIGLWP
+#define HAD_SIGLWP 1
+"Thread event", "LWP", SIGLWP,
+#endif
+#ifdef SIGMIGRATE
+#define HAD_SIGMIGRATE 1
+"Migrate process", "MIGRATE", SIGMIGRATE,
+#endif
+#ifdef SIGPHONE
+#define HAD_SIGPHONE 1
+"Phone status change", "PHONE", SIGPHONE,
+#endif
+#ifdef SIGPIPE
+#define HAD_SIGPIPE 1
+"Broken pipe", "PIPE", SIGPIPE,
+#endif
+#ifdef SIGPOLL
+#define HAD_SIGPOLL 1
+"Poll event", "POLL", SIGPOLL,
+#endif
+#ifdef SIGPROF
+#define HAD_SIGPROF 1
+"Profile timer alarm", "PROF", SIGPROF,
+#endif
+#ifdef SIGPWR
+#define HAD_SIGPWR 1
+"Power fail", "PWR", SIGPWR,
+#endif
+#ifdef SIGQUIT
+#define HAD_SIGQUIT 1
+"Quit", "QUIT", SIGQUIT,
+#endif
+#ifdef SIGSEGV
+#define HAD_SIGSEGV 1
+"Memory fault", "SEGV", SIGSEGV,
+#endif
+#ifdef SIGSOUND
+#define HAD_SIGSOUND 1
+"Sound completed", "SOUND", SIGSOUND,
+#endif
+#ifdef SIGSSTOP
+#define HAD_SIGSSTOP 1
+"Sendable stop", "SSTOP", SIGSSTOP,
+#endif
+#ifdef gould
+#define HAD_gould 1
+"Stack overflow", "STKOV", 28,
+#endif
+#ifdef SIGSTOP
+#define HAD_SIGSTOP 1
+"Stopped (signal)", "STOP", SIGSTOP,
+#endif
+#ifdef SIGSYS
+#define HAD_SIGSYS 1
+"Bad system call", "SYS", SIGSYS,
+#endif
+#ifdef SIGTERM
+#define HAD_SIGTERM 1
+"Terminated", "TERM", SIGTERM,
+#endif
+#ifdef SIGTHAW
+#define HAD_SIGTHAW 1
+"CPR thaw", "THAW", SIGTHAW,
+#endif
+#ifdef SIGTINT
+#define HAD_SIGTINT 1
+"Interrupt (terminal)", "TINT", SIGTINT,
+#endif
+#ifdef SIGTRAP
+#define HAD_SIGTRAP 1
+"Trace trap", "TRAP", SIGTRAP,
+#endif
+#ifdef SIGTSTP
+#define HAD_SIGTSTP 1
+"Stopped", "TSTP", SIGTSTP,
+#endif
+#ifdef SIGTTIN
+#define HAD_SIGTTIN 1
+"Stopped (tty input)", "TTIN", SIGTTIN,
+#endif
+#ifdef SIGTTOU
+#define HAD_SIGTTOU 1
+"Stopped (tty output)", "TTOU", SIGTTOU,
+#endif
+#ifdef SIGURG
+#define HAD_SIGURG 1
+"Urgent IO", "URG", SIGURG,
+#endif
+#ifdef SIGUSR1
+#define HAD_SIGUSR1 1
+"User signal 1", "USR1", SIGUSR1,
+#endif
+#ifdef SIGUSR2
+#define HAD_SIGUSR2 1
+"User signal 2", "USR2", SIGUSR2,
+#endif
+#ifdef SIGVTALRM
+#define HAD_SIGVTALRM 1
+"Virtual timer alarm", "VTALRM", SIGVTALRM,
+#endif
+#ifdef SIGWAITING
+#define HAD_SIGWAITING 1
+"All threads blocked", "WAITING", SIGWAITING,
+#endif
+#ifdef SIGWINCH
+#define HAD_SIGWINCH 1
+"Window change", "WINCH", SIGWINCH,
+#endif
+#ifdef SIGWIND
+#define HAD_SIGWIND 1
+"Window change", "WIND", SIGWIND,
+#endif
+#ifdef SIGWINDOW
+#define HAD_SIGWINDOW 1
+"Window change", "WINDOW", SIGWINDOW,
+#endif
+#ifdef SIGXCPU
+#define HAD_SIGXCPU 1
+"CPU time limit", "XCPU", SIGXCPU,
+#endif
+#ifdef SIGXFSZ
+#define HAD_SIGXFSZ 1
+"File size limit", "XFSZ", SIGXFSZ,
+#endif
+#include "FEATURE/siglist"
+0
+};
+
+#define RANGE_MIN (1<<14)
+#define RANGE_MAX (1<<13)
+#define RANGE_RT (1<<12)
+
+#define RANGE_SIG (~(RANGE_MIN|RANGE_MAX|RANGE_RT))
+
+static int mapindex[1024];
+
+#if _lib_strsignal
+extern char* strsignal(int);
+#endif
+
+int
+main()
+{
+ register int i;
+ register int j;
+ register int k;
+ int m;
+ int n;
+#if _lib_strsignal
+ char* s;
+#endif
+
+ k = 0;
+ for (i = 0; map[i].name; i++)
+ if ((j = map[i].value) > 0 && j < elementsof(mapindex) && !mapindex[j])
+ {
+ if (j > k)
+ k = j;
+ mapindex[j] = i;
+ }
+#ifdef SIGRTMIN
+ i = SIGRTMIN;
+#ifdef SIGRTMAX
+ j = SIGRTMAX;
+#else
+ j = i;
+#endif
+ if (j >= elementsof(mapindex))
+ j = elementsof(mapindex) - 1;
+ if (i <= j && i > 0 && i < elementsof(mapindex) && j > 0 && j < elementsof(mapindex))
+ {
+ if (j > k)
+ k = j;
+ mapindex[i] = RANGE_MIN | RANGE_RT;
+ n = 1;
+ while (++i < j)
+ mapindex[i] = RANGE_RT | n++;
+ mapindex[j] = RANGE_MAX | RANGE_RT | n;
+ }
+#endif
+ printf("#pragma prototyped\n");
+ printf("#define SIG_MAX %d\n", k);
+ printf("\n");
+ printf("static const char* const sig_name[] =\n");
+ printf("{\n");
+ for (i = 0; i <= k; i++)
+ if (!(j = mapindex[i]))
+ printf(" \"%d\",\n", i);
+ else if (j & RANGE_RT)
+ {
+ if (j & RANGE_MIN)
+ printf(" \"RTMIN\",\n");
+ else if (j & RANGE_MAX)
+ printf(" \"RTMAX\",\n");
+ else
+ {
+ m = j & RANGE_SIG;
+ if (m > n / 2)
+ printf(" \"RTMAX-%d\",\n", n - m);
+ else
+ printf(" \"RTMIN+%d\",\n", m);
+ }
+ }
+ else
+ printf(" \"%s\",\n", map[j].name);
+ printf(" 0\n");
+ printf("};\n");
+ printf("\n");
+ printf("static const char* const sig_text[] =\n");
+ printf("{\n");
+ for (i = 0; i <= k; i++)
+ if (!(j = mapindex[i]))
+ printf(" \"Signal %d\",\n", i);
+ else if (j & RANGE_RT)
+ printf(" \"Realtime priority %d%s\",\n", j & RANGE_SIG, (j & RANGE_MIN) ? " (lo)" : (j & RANGE_MAX) ? " (hi)" : "");
+ else if (map[j].text)
+ printf(" \"%s\",\n", map[j].text);
+#if _lib_strsignal
+ else if (s = strsignal(i))
+ printf(" \"%s\",\n", s);
+#endif
+ else
+ printf(" \"Signal %d\",\n", i);
+ printf(" 0\n");
+ printf("};\n");
+ return 0;
+}
diff --git a/src/lib/libast/features/sizeof b/src/lib/libast/features/sizeof
new file mode 100644
index 0000000..06c8707
--- /dev/null
+++ b/src/lib/libast/features/sizeof
@@ -0,0 +1,13 @@
+tst - note{ sizeof(integral-type) }end output{
+ #include "FEATURE/common"
+ int
+ main()
+ {
+ printf("#define _ast_sizeof_char %d\n", sizeof(char));
+ printf("#define _ast_sizeof_short %d\n", sizeof(short));
+ printf("#define _ast_sizeof_int %d\n", sizeof(int));
+ printf("#define _ast_sizeof_long %d\n", sizeof(long));
+ printf("#define _ast_sizeof_intmax_t %d\n", sizeof(_ast_intmax_t));
+ return 0;
+ }
+}end
diff --git a/src/lib/libast/features/standards b/src/lib/libast/features/standards
new file mode 100644
index 0000000..adee277
--- /dev/null
+++ b/src/lib/libast/features/standards
@@ -0,0 +1,153 @@
+set stdio
+if tst note{ _ALL_SOURCE & _ISOC99_SOURCE & _POSIX_SOURCE & _POSIX_C_SOURCE & _XOPEN_SOURCE & __EXTENSIONS__ works }end compile{
+ #define _ALL_SOURCE 1
+ #define _ISOC99_SOURCE 1
+ #define _POSIX_SOURCE 1
+ #define _POSIX_C_SOURCE 21000101L
+ #define _XOPEN_SOURCE 9900
+ #define _GNU_SOURCE 1
+ #define __EXTENSIONS__ 1
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ }end {
+ #ifndef _ALL_SOURCE
+ #define _ALL_SOURCE 1
+ #endif
+ #ifndef _ISOC99_SOURCE
+ #define _ISOC99_SOURCE 1
+ #endif
+ #ifndef _POSIX_SOURCE
+ #define _POSIX_SOURCE 1
+ #endif
+ #ifndef _POSIX_C_SOURCE
+ #define _POSIX_C_SOURCE 21000101L
+ #endif
+ #ifndef _XOPEN_SOURCE
+ #define _XOPEN_SOURCE 9900
+ #endif
+ #ifndef _GNU_SOURCE
+ #define _GNU_SOURCE 1
+ #endif
+ #ifndef __EXTENSIONS__
+ #define __EXTENSIONS__ 1
+ #endif
+ }
+elif tst note{ _ALL_SOURCE & _ISOC99_SOURCE & _POSIX_SOURCE & _XOPEN_SOURCE & __EXTENSIONS__ works }end compile{
+ #define _ALL_SOURCE 1
+ #define _ISOC99_SOURCE 1
+ #define _POSIX_SOURCE 1
+ #define _XOPEN_SOURCE 9900
+ #define _GNU_SOURCE 1
+ #define __EXTENSIONS__ 1
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ }end {
+ #ifndef _ALL_SOURCE
+ #define _ALL_SOURCE 1
+ #endif
+ #ifndef _ISOC99_SOURCE
+ #define _ISOC99_SOURCE 1
+ #endif
+ #ifndef _POSIX_SOURCE
+ #define _POSIX_SOURCE 1
+ #endif
+ #ifndef _XOPEN_SOURCE
+ #define _XOPEN_SOURCE 9900
+ #endif
+ #ifndef _GNU_SOURCE
+ #define _GNU_SOURCE 1
+ #endif
+ #ifndef __EXTENSIONS__
+ #define __EXTENSIONS__ 1
+ #endif
+ }
+elif tst note{ _ISOC99_SOURCE & _POSIX_SOURCE & _POSIX_C_SOURCE & _XOPEN_SOURCE & __EXTENSIONS__ works }end compile{
+ #define _ISOC99_SOURCE 1
+ #define _POSIX_SOURCE 1
+ #define _POSIX_C_SOURCE 21000101L
+ #define _XOPEN_SOURCE 9900
+ #define _GNU_SOURCE 1
+ #define __EXTENSIONS__ 1
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ }end {
+ #ifndef _ISOC99_SOURCE
+ #define _ISOC99_SOURCE 1
+ #endif
+ #ifndef _POSIX_SOURCE
+ #define _POSIX_SOURCE 1
+ #endif
+ #ifndef _POSIX_C_SOURCE
+ #define _POSIX_C_SOURCE 21000101L
+ #endif
+ #ifndef _XOPEN_SOURCE
+ #define _XOPEN_SOURCE 9900
+ #endif
+ #ifndef _GNU_SOURCE
+ #define _GNU_SOURCE 1
+ #endif
+ #ifndef __EXTENSIONS__
+ #define __EXTENSIONS__ 1
+ #endif
+ }
+elif tst note{ _POSIX_SOURCE & _XOPEN_SOURCE & __EXTENSIONS__ works }end compile{
+ #define _POSIX_SOURCE 1
+ #define _XOPEN_SOURCE 1
+ #define __EXTENSIONS__ 1
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ }end {
+ #ifndef _POSIX_SOURCE
+ #define _POSIX_SOURCE 1
+ #endif
+ #ifndef _XOPEN_SOURCE
+ #define _XOPEN_SOURCE 1
+ #endif
+ #ifndef __EXTENSIONS__
+ #define __EXTENSIONS__ 1
+ #endif
+ }
+elif tst note{ _XOPEN_SOURCE & __EXTENSIONS__ works }end compile{
+ #define _XOPEN_SOURCE 1
+ #define __EXTENSIONS__ 1
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ }end {
+ #ifndef _XOPEN_SOURCE
+ #define _XOPEN_SOURCE 1
+ #endif
+ #ifndef __EXTENSIONS__
+ #define __EXTENSIONS__ 1
+ #endif
+ }
+elif tst note{ _XOPEN_SOURCE works }end compile{
+ #define _XOPEN_SOURCE 1
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+ }end {
+ #ifndef _XOPEN_SOURCE
+ #define _XOPEN_SOURCE 1
+ #endif
+ }
+else tst note{ __EXTENSIONS__ works }end compile{
+ #define __EXTENSIONS__ 1
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ }end {
+ #ifndef __EXTENSIONS__
+ #define __EXTENSIONS__ 1
+ #endif
+ }
+endif
diff --git a/src/lib/libast/features/stdio b/src/lib/libast/features/stdio
new file mode 100644
index 0000000..b323893
--- /dev/null
+++ b/src/lib/libast/features/stdio
@@ -0,0 +1,568 @@
+set prototyped
+ref -D_def_map_ast=1
+iff SFSTDIO
+cat{
+ #define __FILE_typedef 1
+ #define _FILE_DEFINED 1
+ #define _FILE_defined 1
+ #define _FILEDEFED 1
+
+ #ifndef __FILE_TAG
+ #define __FILE_TAG _sfio_s
+ #endif
+
+ #undef FILE
+ #undef _FILE
+ #undef fpos_t
+ #undef fpos64_t
+
+ typedef struct _sfio_s _sfio_FILE;
+
+ #define FILE _sfio_FILE
+ #define _FILE FILE
+
+ #if !defined(__FILE) && !__CYGWIN__
+ #undef __FILE
+ #define __FILE FILE
+ #endif
+
+ #if defined(_AST_H) || defined(_SFIO_H)
+
+ #define BUFSIZ SF_BUFSIZE
+
+ #else
+
+ #ifndef BUFSIZ
+ #define BUFSIZ 8192
+ #endif
+
+ #ifndef EOF
+ #define EOF (-1)
+ #endif
+
+ #ifndef NULL
+ #define NULL 0
+ #endif
+
+ #ifndef SEEK_SET
+ #define SEEK_SET 0
+ #define SEEK_CUR 1
+ #define SEEK_END 2
+ #endif
+
+ #include <ast_std.h>
+
+ #include <sfio_s.h>
+
+ #if __cplusplus
+ #define _sf_(f) (f)
+ #else
+ #define _sf_(f) ((struct _sfio_s*)(f))
+ #endif
+
+ #define _SF_EOF 0000200
+ #define _SF_ERROR 0000400
+
+ #endif
+
+ #ifdef _NO_LARGEFILE64_SOURCE
+ #undef _LARGEFILE64_SOURCE
+ #endif
+
+ #ifdef _LARGEFILE64_SOURCE
+ #undef off_t
+ #endif
+
+ #define fpos_t _ast_fpos_t
+ #if _typ_int64_t
+ #define fpos64_t _ast_fpos_t
+ #endif
+
+ typedef struct _ast_fpos_s
+ {
+ intmax_t _sf_offset;
+ unsigned char _sf_state[64 - sizeof(intmax_t)];
+ } _ast_fpos_t;
+
+ #define _base _data
+ #define _ptr _next
+ #define _IOFBF 0
+ #define _IONBF 1
+ #define _IOLBF 2
+
+ #if defined(__cplusplus) && defined(__THROW) && !defined(_UWIN)
+
+ #undef FILE
+ #define FILE FILE
+ typedef struct _sfio_s FILE;
+
+ #undef strerror
+ extern char* strerror(int) __THROW;
+
+ extern int _doprnt(const char*, va_list, FILE*);
+ extern int _doscan(FILE*, const char*, va_list);
+ extern int asprintf(char**, const char*, ...);
+ extern int clearerr(FILE*);
+ extern int fclose(FILE*);
+ extern FILE* fdopen(int, const char*);
+ extern int feof(FILE*);
+ extern int ferror(FILE*);
+ extern int fflush(FILE*);
+ extern int fgetc(FILE*);
+ extern int fgetpos(FILE*, fpos_t*);
+ extern char* fgets(char*, int, FILE*);
+ extern int fileno(FILE*);
+ extern FILE* fopen(const char*, const char*);
+ extern int fprintf(FILE*, const char*, ...);
+ extern int fpurge(FILE*);
+ extern int fputc(int, FILE*);
+ extern int fputs(const char*, FILE*);
+ extern size_t fread(void*, size_t, size_t, FILE*);
+ extern FILE* freopen(const char*, const char*, FILE*);
+ extern int fscanf(FILE*, const char*, ...);
+ extern int fseek(FILE*, long, int);
+ extern int fseeko(FILE*, off_t, int);
+ extern int fsetpos(FILE*, const fpos_t*);
+ extern long ftell(FILE*);
+ extern off_t ftello(FILE*);
+ extern size_t fwrite(const void*, size_t, size_t, FILE*);
+ extern int getc(FILE*);
+ extern int getchar(void);
+ extern char* gets(char*);
+ extern int getw(FILE*);
+ extern int pclose(FILE*);
+ extern FILE* popen(const char*, const char*);
+ extern int printf(const char*, ...);
+ extern int putc(int, FILE*);
+ extern int putchar(int);
+ extern int puts(const char*);
+ extern int putw(int, FILE*);
+ extern void rewind(FILE*);
+ extern int scanf(const char*, ...);
+ extern void setbuf(FILE*, char*);
+ extern int setbuffer(FILE*, char*, int);
+ extern int setlinebuf(FILE*);
+ extern int setvbuf(FILE*, char*, int, size_t);
+ extern int snprintf(char*, int, const char*, ...);
+ extern int sprintf(char*, const char*, ...);
+ extern int sscanf(const char*, const char*, ...);
+ extern FILE* tmpfile(void);
+ extern int ungetc(int, FILE*);
+ extern int vasprintf(char**, const char*, va_list);
+ extern int vfprintf(FILE*, const char*, va_list);
+ extern int vfscanf(FILE*, const char*, va_list);
+ extern int vprintf(const char*, va_list);
+ extern int vscanf(const char*, va_list);
+ extern int vsnprintf(char*, int, const char*, va_list);
+ extern int vsprintf(char*, const char*, va_list);
+ extern int vsscanf(const char*, const char*, va_list);
+
+ #if _typ_int64_t
+
+ extern int fgetpos64(FILE*, fpos64_t*);
+ extern int fsetpos64(FILE*, const fpos64_t*);
+ extern int fseek64(FILE*, int64_t, int);
+ extern int fseeko64(FILE*, int64_t, int);
+ extern int64_t ftell64(FILE*);
+ extern int64_t ftello64(FILE*);
+
+ #endif
+
+ extern void clearerr_unlocked(FILE*);
+ extern int feof_unlocked(FILE*);
+ extern int ferror_unlocked(FILE*);
+ extern int fflush_unlocked(FILE*);
+ extern int fgetc_unlocked(FILE*);
+ extern char* fgets_unlocked(char*, int, FILE*);
+ extern int fileno_unlocked(FILE*);
+ extern int fputc_unlocked(int, FILE*);
+ extern int fputs_unlocked(char*, FILE*);
+ extern size_t fread_unlocked(void*, size_t, size_t, FILE*);
+ extern size_t fwrite_unlocked(void*, size_t, size_t, FILE*);
+ extern int getc_unlocked(FILE*);
+ extern int getchar_unlocked(void);
+ extern int putc_unlocked(int, FILE*);
+ extern int putchar_unlocked(int);
+
+ extern void flockfile(FILE*);
+ extern int ftrylockfile(FILE*);
+ extern void funlockfile(FILE*);
+
+ #ifdef _USE_GNU
+
+ extern int fcloseall(void);
+ extern FILE* fmemopen(void*, size_t, const char*);
+ extern ssize_t __getdelim(char**, size_t*, int, FILE*);
+ extern ssize_t getdelim(char**, size_t*, int, FILE*);
+ extern ssize_t getline(char**, size_t*, FILE*);
+
+ #endif
+
+ #endif
+}end
+output{
+ #include <stdio.h>
+ #ifndef FILENAME_MAX
+ #ifndef NAME_MAX
+ #ifndef _POSIX_NAME_MAX
+ #define _POSIX_NAME_MAX 14
+ #endif
+ #define NAME_MAX _POSIX_NAME_MAX
+ #endif
+ #define FILENAME_MAX NAME_MAX
+ #endif
+ #ifndef FOPEN_MAX
+ #ifdef STREAM_MAX
+ #define FOPEN_MAX STREAM_MAX
+ #else
+ #ifndef OPEN_MAX
+ #ifndef _POSIX_OPEN_MAX
+ #define _POSIX_OPEN_MAX 20
+ #endif
+ #define OPEN_MAX _POSIX_OPEN_MAX
+ #endif
+ #define FOPEN_MAX OPEN_MAX
+ #endif
+ #endif
+ #ifndef TMP_MAX
+ #define TMP_MAX 33520641
+ #endif
+ int
+ main()
+ {
+ printf("#ifndef FILENAME_MAX\n");
+ printf("#define FILENAME_MAX %d\n", FILENAME_MAX);
+ printf("#endif\n");
+ printf("#ifndef FOPEN_MAX\n");
+ printf("#define FOPEN_MAX %d\n", FOPEN_MAX);
+ printf("#endif\n");
+ printf("#ifndef TMP_MAX\n");
+ printf("#define TMP_MAX %d\n", TMP_MAX);
+ printf("#endif\n");
+ #if !_UWIN
+ printf("\n");
+ printf("#define _doprnt _ast_doprnt\n");
+ printf("#define _doscan _ast_doscan\n");
+ printf("#define asprintf _ast_asprintf\n");
+ printf("#define clearerr _ast_clearerr\n");
+ printf("#define fclose _ast_fclose\n");
+ printf("#define fdopen _ast_fdopen\n");
+ printf("#define fflush _ast_fflush\n");
+ printf("#define fgetc _ast_fgetc\n");
+ printf("#define fgetpos _ast_fgetpos\n");
+ printf("#define fgetpos64 _ast_fgetpos64\n");
+ printf("#define fgets _ast_fgets\n");
+ printf("#define fopen _ast_fopen\n");
+ printf("#define fprintf _ast_fprintf\n");
+ printf("#define fpurge _ast_fpurge\n");
+ printf("#define fputs _ast_fputs\n");
+ printf("#define fread _ast_fread\n");
+ printf("#define freopen _ast_freopen\n");
+ printf("#define fscanf _ast_fscanf\n");
+ printf("#define fseek _ast_fseek\n");
+ printf("#define fseek64 _ast_fseek64\n");
+ printf("#define fseeko _ast_fseeko\n");
+ printf("#define fseeko64 _ast_fseeko64\n");
+ printf("#define fsetpos _ast_fsetpos\n");
+ printf("#define fsetpos64 _ast_fsetpos64\n");
+ printf("#define ftell _ast_ftell\n");
+ printf("#define ftell64 _ast_ftell64\n");
+ printf("#define ftello _ast_ftello\n");
+ printf("#define ftello64 _ast_ftello64\n");
+ printf("#define fwrite _ast_fwrite\n");
+ printf("#define gets _ast_gets\n");
+ printf("#define getw _ast_getw\n");
+ printf("#define pclose _ast_pclose\n");
+ printf("#define popen _ast_popen\n");
+ printf("#define printf _ast_printf\n");
+ printf("#define puts _ast_puts\n");
+ printf("#define putw _ast_putw\n");
+ printf("#define rewind _ast_rewind\n");
+ printf("#define scanf _ast_scanf\n");
+ printf("#define setbuf _ast_setbuf\n");
+ printf("#undef setbuffer\n");
+ printf("#define setbuffer _ast_setbuffer\n");
+ printf("#define setlinebuf _ast_setlinebuf\n");
+ printf("#define setvbuf _ast_setvbuf\n");
+ printf("#define snprintf _ast_snprintf\n");
+ printf("#define sprintf _ast_sprintf\n");
+ printf("#define sscanf _ast_sscanf\n");
+ printf("#define tmpfile _ast_tmpfile\n");
+ printf("#define ungetc _ast_ungetc\n");
+ printf("#define vasprintf _ast_vasprintf\n");
+ printf("#define vfprintf _ast_vfprintf\n");
+ printf("#define vfscanf _ast_vfscanf\n");
+ printf("#define vprintf _ast_vprintf\n");
+ printf("#define vscanf _ast_vscanf\n");
+ printf("#define vsnprintf _ast_vsnprintf\n");
+ printf("#define vsprintf _ast_vsprintf\n");
+ printf("#define vsscanf _ast_vsscanf\n");
+
+ printf("#define fcloseall _ast_fcloseall\n");
+ printf("#define _filbuf _ast__filbuf\n");
+ printf("#define fmemopen _ast_fmemopen\n");
+ printf("#define __getdelim _ast___getdelim\n");
+ printf("#define getdelim _ast_getdelim\n");
+ printf("#define getline _ast_getline\n");
+
+ printf("#define clearerr_unlocked _ast_clearerr_unlocked\n");
+ printf("#define feof_unlocked _ast_feof_unlocked\n");
+ printf("#define ferror_unlocked _ast_ferror_unlocked\n");
+ printf("#define fflush_unlocked _ast_fflush_unlocked\n");
+ printf("#define fgetc_unlocked _ast_fgetc_unlocked\n");
+ printf("#define fgets_unlocked _ast_fgets_unlocked\n");
+ printf("#define fileno_unlocked _ast_fileno_unlocked\n");
+ printf("#define fputc_unlocked _ast_fputc_unlocked\n");
+ printf("#define fputs_unlocked _ast_fputs_unlocked\n");
+ printf("#define fread_unlocked _ast_fread_unlocked\n");
+ printf("#define fwrite_unlocked _ast_fwrite_unlocked\n");
+ printf("#define getc_unlocked _ast_getc_unlocked\n");
+ printf("#define getchar_unlocked _ast_getchar_unlocked\n");
+ printf("#define putc_unlocked _ast_putc_unlocked\n");
+ printf("#define putchar_unlocked _ast_putchar_unlocked\n");
+
+ printf("#define flockfile _ast_flockfile\n");
+ printf("#define ftrylockfile _ast_ftrylockfile\n");
+ printf("#define funlockfile _ast_funlockfile\n");
+
+ printf("\n");
+ #endif
+ return 0;
+ }
+}end
+macro{
+ <<"#if defined(__STDPP__directive) && defined(__STDPP__initial)">>
+ <<"__STDPP__directive pragma pp:initial">>
+ <<"#endif">>
+ <<"#ifndef P_tmpdir">>
+ #ifndef P_tmpdir
+ #define P_tmpdir "/usr/tmp/"
+ #endif
+ <<"#define P_tmpdir">> P_tmpdir <<"/*NOCATLITERAL*/">>
+ <<"#endif">>
+ <<"#ifndef L_ctermid">>
+ #ifndef L_ctermid
+ #define L_ctermid 9
+ #endif
+ <<"#define L_ctermid">> L_ctermid
+ <<"#endif">>
+ <<"#ifndef L_tmpnam">>
+ #ifndef L_tmpnam
+ #define L_tmpnam (sizeof(P_tmpdir)+15)
+ #endif
+ <<"#define L_tmpnam">> L_tmpnam
+ <<"#endif">>
+ <<"#if defined(__STDPP__directive) && defined(__STDPP__initial)">>
+ <<"__STDPP__directive pragma pp:noinitial">>
+ <<"#endif">>
+}end
+cat{
+ #if defined(__cplusplus) && defined(__THROW)
+ extern char* ctermid(char*) __THROW;
+ #else
+ extern char* ctermid(char*);
+ #endif
+ extern char* tmpnam(char*);
+ extern char* tempnam(const char*, const char*);
+ extern void perror(const char*);
+ #ifndef _AST_STD_H
+ #ifndef remove
+ extern int remove(const char*);
+ #endif
+ #ifndef rename
+ extern int rename(const char*, const char*);
+ #endif
+ #endif
+
+ #undef extern
+
+ #if _BLD_ast && defined(__EXPORT__)
+ #define extern __EXPORT__
+ #endif
+
+ extern int _doprnt(const char*, va_list, FILE*);
+ extern int _doscan(FILE*, const char*, va_list);
+ extern int asprintf(char**, const char*, ...);
+ extern int clearerr(FILE*);
+ extern int fclose(FILE*);
+ extern FILE* fdopen(int, const char*);
+ extern int feof(FILE*);
+ extern int ferror(FILE*);
+ extern int fflush(FILE*);
+ extern int fgetc(FILE*);
+ extern int fgetpos(FILE*, fpos_t*);
+ extern char* fgets(char*, int, FILE*);
+ extern int fileno(FILE*);
+ extern FILE* fopen(const char*, const char*);
+ extern int fprintf(FILE*, const char*, ...);
+ extern int fpurge(FILE*);
+ extern int fputc(int, FILE*);
+ extern int fputs(const char*, FILE*);
+ extern size_t fread(void*, size_t, size_t, FILE*);
+ extern FILE* freopen(const char*, const char*, FILE*);
+ extern int fscanf(FILE*, const char*, ...);
+ extern int fseek(FILE*, long, int);
+ extern int fseeko(FILE*, off_t, int);
+ extern int fsetpos(FILE*, const fpos_t*);
+ extern long ftell(FILE*);
+ extern off_t ftello(FILE*);
+ extern size_t fwrite(const void*, size_t, size_t, FILE*);
+ extern int getc(FILE*);
+ extern int getchar(void);
+ extern char* gets(char*);
+ extern int getw(FILE*);
+ extern int pclose(FILE*);
+ extern FILE* popen(const char*, const char*);
+ extern int printf(const char*, ...);
+ extern int putc(int, FILE*);
+ extern int putchar(int);
+ extern int puts(const char*);
+ extern int putw(int, FILE*);
+ extern void rewind(FILE*);
+ extern int scanf(const char*, ...);
+ extern void setbuf(FILE*, char*);
+ extern int setbuffer(FILE*, char*, int);
+ extern int setlinebuf(FILE*);
+ extern int setvbuf(FILE*, char*, int, size_t);
+ extern int snprintf(char*, int, const char*, ...);
+ extern int sprintf(char*, const char*, ...);
+ extern int sscanf(const char*, const char*, ...);
+ extern FILE* tmpfile(void);
+ extern int ungetc(int, FILE*);
+ extern int vasprintf(char**, const char*, va_list);
+ extern int vfprintf(FILE*, const char*, va_list);
+ extern int vfscanf(FILE*, const char*, va_list);
+ extern int vprintf(const char*, va_list);
+ extern int vscanf(const char*, va_list);
+ extern int vsnprintf(char*, int, const char*, va_list);
+ extern int vsprintf(char*, const char*, va_list);
+ extern int vsscanf(const char*, const char*, va_list);
+
+ #if _typ_int64_t
+
+ extern int fgetpos64(FILE*, fpos64_t*);
+ extern int fsetpos64(FILE*, const fpos64_t*);
+ extern int fseek64(FILE*, int64_t, int);
+ extern int fseeko64(FILE*, int64_t, int);
+ extern int64_t ftell64(FILE*);
+ extern int64_t ftello64(FILE*);
+
+ #ifdef _LARGEFILE64_SOURCE
+
+ #undef fpos_t
+ #undef off_t
+ #undef fgetpos
+ #undef fsetpos
+ #undef fseek
+ #undef fseeko
+ #undef ftell
+ #undef ftello
+
+ #define fpos_t fpos64_t
+ #if _typ_off64_t
+ #define off_t off64_t
+ #else
+ #define off_t int64_t
+ #endif
+
+ #define fgetpos fgetpos64
+ #define fsetpos fsetpos64
+ #define fseek fseek64
+ #define fseeko fseeko64
+ #define ftell ftell64
+ #define ftello ftello64
+
+ #endif
+
+ #endif
+
+ extern void clearerr_unlocked(FILE*);
+ extern int feof_unlocked(FILE*);
+ extern int ferror_unlocked(FILE*);
+ extern int fflush_unlocked(FILE*);
+ extern int fgetc_unlocked(FILE*);
+ extern char* fgets_unlocked(char*, int, FILE*);
+ extern int fileno_unlocked(FILE*);
+ extern int fputc_unlocked(int, FILE*);
+ extern int fputs_unlocked(char*, FILE*);
+ extern size_t fread_unlocked(void*, size_t, size_t, FILE*);
+ extern size_t fwrite_unlocked(void*, size_t, size_t, FILE*);
+ extern int getc_unlocked(FILE*);
+ extern int getchar_unlocked(void);
+ extern int putc_unlocked(int, FILE*);
+ extern int putchar_unlocked(int);
+
+ #ifdef _USE_GNU
+
+ extern int fcloseall(void);
+ extern FILE* fmemopen(void*, size_t, const char*);
+ extern ssize_t __getdelim(char**, size_t*, int, FILE*);
+ extern ssize_t getdelim(char**, size_t*, int, FILE*);
+ extern ssize_t getline(char**, size_t*, FILE*);
+
+ #endif
+
+ #undef extern
+
+ #if _BLD_DLL && _DLL_INDIRECT_DATA
+
+ #define stdin ((FILE*)_ast_dll->_ast_stdin)
+ #define stdout ((FILE*)_ast_dll->_ast_stdout)
+ #define stderr ((FILE*)_ast_dll->_ast_stderr)
+
+ #else
+
+ #define stdin (&_Sfstdin)
+ #define stdout (&_Sfstdout)
+ #define stderr (&_Sfstderr)
+
+ #endif
+
+ #if defined(_AST_H) || defined(_SFIO_H)
+
+ #define feof(f) sfeof(f)
+ #define ferror(f) sferror(f)
+ #define fileno(f) sffileno(f)
+ #define fputc(c,f) sfputc(f,c)
+ #define getc(f) sfgetc(f)
+ #define getchar() sfgetc(sfstdin)
+ #define putc(c,f) sfputc(f,c)
+ #define putchar(c) sfputc(sfstdout,c)
+
+ #else
+
+ #if !_UWIN
+ #if _BLD_ast && defined(__EXPORT__)
+ #define extern extern __EXPORT__
+ #endif
+ #if !_BLD_ast && defined(__IMPORT__)
+ #define extern extern __IMPORT__
+ #endif
+ #endif
+
+ extern FILE _Sfstdin;
+ extern FILE _Sfstdout;
+ extern FILE _Sfstderr;
+
+ #undef extern
+
+ #define feof(f) (_sf_(f)->_flags&_SF_EOF)
+ #define ferror(f) (_sf_(f)->_flags&_SF_ERROR)
+ #define fileno(f) (_sf_(f)->_file)
+ #define fputc(c,f) (_sf_(f)->_next>=_sf_(f)->_endw?_sfflsbuf(_sf_(f),(int)((unsigned char)(c))):(int)(*_sf_(f)->_next++=(unsigned char)(c)))
+ #define getc(f) (_sf_(f)->_next>=_sf_(f)->_endr?_sffilbuf(_sf_(f),0):(int)(*_sf_(f)->_next++))
+ #define getchar() getc(stdin)
+ #define putc(c,f) fputc(c,f)
+ #define putchar(c) fputc(c,stdout)
+
+ #if _BLD_ast && defined(__EXPORT__)
+ #define extern __EXPORT__
+ #endif
+
+ extern int _sffilbuf(FILE*, int);
+ extern int _sfflsbuf(FILE*, int);
+
+ #undef extern
+
+ #endif
+}end
diff --git a/src/lib/libast/features/sys b/src/lib/libast/features/sys
new file mode 100644
index 0000000..87ad1e5
--- /dev/null
+++ b/src/lib/libast/features/sys
@@ -0,0 +1,272 @@
+set prototyped
+iff AST_SYS
+ref -D_def_map_ast
+
+print #if __mips == 2 && !defined(_NO_LARGEFILE64_SOURCE)
+print #define _NO_LARGEFILE64_SOURCE 1
+print #endif
+print #if !defined(_NO_LARGEFILE64_SOURCE) && _typ_off64_t && _lib_lseek64 && _lib_stat64
+print #if !defined(_LARGEFILE64_SOURCE)
+print #define _LARGEFILE64_SOURCE 1
+print #endif
+print #if !defined(_LARGEFILE_SOURCE)
+print #define _LARGEFILE_SOURCE 1
+print #endif
+print #else
+print #undef _LARGEFILE64_SOURCE
+print #undef _LARGEFILE_SOURCE
+print #undef _typ_off64_t
+print #undef _typ_struct_dirent64
+print #undef _lib_creat64
+print #undef _lib_fstat64
+print #undef _lib_fstatvfs64
+print #undef _lib_ftruncate64
+print #undef _lib_lseek64
+print #undef _lib_lstat64
+print #undef _lib_mmap64
+print #undef _lib_open64
+print #undef _lib_readdir64
+print #undef _lib_stat64
+print #undef _lib_statvfs64
+print #undef _lib_truncate64
+print #endif
+
+print #if defined(__STDC__) && !defined(__USE_FIXED_PROTOTYPES__)
+print #define __USE_FIXED_PROTOTYPES__ 1 /* kick gcc out of the past */
+print #endif
+
+header stdlib.h
+header stddef.h
+header sys/types.h
+header stdint.h
+header inttypes.h
+header string.h
+header unistd.h
+header limits.h
+header fcntl.h
+header locale.h
+
+typ dev_t,nlink_t fail{
+ echo "#ifndef $m"
+ echo "#define $m 1"
+ echo "typedef short $v;"
+ echo "#endif"
+}end
+typ gid_t,mode_t,uid_t fail{
+ echo "#ifndef $m"
+ echo "#define $m 1"
+ echo "typedef unsigned short $v;"
+ echo "#endif"
+}end
+typ wchar_t stdio.h wchar.h fail{
+ echo "#ifndef $m"
+ echo "#define $m 1"
+ echo "typedef unsigned short $v;"
+ echo "#endif"
+}end
+typ pid_t,ssize_t fail{
+ echo "#ifndef $m"
+ echo "#define $m 1"
+ echo "typedef int $v;"
+ echo "#endif"
+}end
+typ wint_t stdio.h wchar.h fail{
+ echo "#ifndef $m"
+ echo "#define $m 1"
+ echo "typedef int $v;"
+ echo "#endif"
+}end
+typ socklen_t sys/socket.h fail{
+ echo "#ifndef $m"
+ echo "#define $m 1"
+ echo "typedef int $v;"
+ echo "#endif"
+}end
+typ size_t fail{
+ echo "#ifndef $m"
+ echo "#define $m 1"
+ echo "typedef unsigned int $v;"
+ echo "#endif"
+}end
+typ clock_t,ino_t,off_t,ptrdiff_t fail{
+ echo "#ifndef $m"
+ echo "#define $m 1"
+ echo "typedef long $v;"
+ echo "#endif"
+}end
+typ time_t fail{
+ echo "#ifndef $m"
+ echo "#define $m 1"
+ echo "typedef unsigned long $v;"
+ echo "#endif"
+}end
+typ div_t fail{
+ echo "#ifndef $m"
+ echo "#define $m 1"
+ echo "typedef struct { int quot; int rem; } $v;"
+ echo "#endif"
+}end
+typ ldiv_t fail{
+ echo "#ifndef $m"
+ echo "#define $m 1"
+ echo "typedef struct { long quot; long rem; } $v;"
+ echo "#endif"
+}end
+tst typ_signed_size_t output{
+ #include <sys/types.h>
+ int
+ main()
+ {
+ unsigned long u = ~0;
+ size_t s = ~0;
+ if (s >= 0)
+ return 1;
+ printf("#if !defined(__cplusplus) && !defined(c_plusplus) && !defined(_typ_signed_size_t)\n/* what dipsticks made size_t signed? sun. */\ntypedef unsigned %s _ast_size_t;\n#undef\tsize_t\n#define size_t\t_ast_size_t\n#endif\n", u == (unsigned long)s ? "long" : "int");
+ return 0;
+ }
+}end
+
+define offsetof (type,member) ((size_t)&(((type*)0)->member))
+define EXIT_FAILURE 1
+define EXIT_SUCCESS 0
+define MB_CUR_MAX 1
+define RAND_MAX 32767
+
+define STDIN_FILENO 0
+define STDOUT_FILENO 1
+define STDERR_FILENO 2
+
+define NULL 0
+
+define SEEK_SET 0
+define SEEK_CUR 1
+define SEEK_END 2
+
+define F_OK 0
+define X_OK 1
+define W_OK 2
+define R_OK 4
+
+print #if _BLD_ast && defined(__EXPORT__)
+print #define extern __EXPORT__
+print #endif
+
+extern _exit void (int)
+extern abort void (void)
+extern abs int (int)
+extern access int (const char*, int)
+extern alarm unsigned (unsigned)
+extern atexit int (void(*)(void))
+extern atof double (const char*)
+extern atoi int (const char*)
+extern atol long (const char*)
+extern bsearch void* (const void*, const void*, size_t, size_t, int(*)(const void*, const void*))
+extern calloc void* (size_t, size_t)
+extern cfree void (void*)
+extern chdir int (const char*)
+extern chown int (const char*, uid_t, gid_t)
+extern close int (int)
+extern confstr size_t (int, char*, size_t)
+extern div div_t (int, int)
+extern dup int (int)
+extern dup2 int (int, int)
+extern eaccess int (const char*, int)
+extern execl int (const char*, const char*, ...)
+extern execle int (const char*, const char*, ...)
+extern execlp int (const char*, const char*, ...)
+extern execv int (const char*, char* const[])
+extern execve int (const char*, char* const[], char* const[])
+extern execve int (const char*, char* const[], char* const[])
+extern execvp int (const char*, char* const[])
+extern execvpe int (const char*, char* const[], char* const[])
+extern exit void (int)
+extern fork pid_t (void)
+extern fpathconf long (int, int)
+extern free void (void*)
+extern fsync int (int)
+extern ftruncate int (int, off_t)
+extern getcwd char* (char*, size_t)
+extern getegid gid_t (void)
+extern getenv char* (const char*)
+extern geteuid uid_t (void)
+extern getgid gid_t (void)
+extern getgroups int (int, gid_t[])
+extern getlogin char* (void)
+extern getpgrp pid_t (void)
+extern getpid pid_t (void)
+extern getppid pid_t (void)
+extern gettxt char* (const char*, const char*)
+extern getuid uid_t (void)
+extern isatty int (int)
+extern labs long (long)
+extern ldiv ldiv_t (long, long)
+extern link int (const char*, const char*)
+extern lseek off_t (int, off_t, int)
+extern malloc void* (size_t)
+extern mblen int (const char*, size_t)
+extern mbstowcs size_t (wchar_t*, const char*, size_t)
+extern mbtowc int (wchar_t*, const char*, size_t)
+extern memalign void* (size_t, size_t)
+extern memccpy void* (void*, const void*, int, size_t)
+extern memchr void* (const void*, int, size_t)
+extern memcmp int (const void*, const void*, size_t)
+extern memcpy void* (void*, const void*, size_t)
+extern memmove void* (void*, const void*, size_t)
+extern memset void* (void*, int, size_t)
+extern pathconf long (const char*, int)
+extern pause int (void)
+extern pipe int (int[])
+extern pvalloc void* (size_t)
+extern qsort void (void*, size_t, size_t, int(*)(const void*, const void*))
+extern rand int (void)
+extern read ssize_t (int, void*, size_t)
+extern realloc void* (void*, size_t)
+extern realpath char* (const char*, char*)
+extern resolvepath char* (const char*, char*, size_t)
+extern rmdir int (const char*)
+extern setgid int (gid_t)
+extern setpgid int (pid_t, pid_t)
+extern setsid pid_t (void)
+extern setuid int (uid_t)
+extern sleep unsigned (unsigned int)
+extern spawnveg pid_t (const char*, char* const[], char* const[], pid_t)
+extern srand void (unsigned int)
+extern strcasecmp int (const char*, const char*)
+extern strcat char* (char*, const char*)
+extern strchr char* (const char*, int)
+extern strcmp int (const char*, const char*)
+extern strcoll int (const char*, const char*)
+extern strcpy char* (char*, const char*)
+extern strcspn size_t (const char*, const char*)
+extern strdup char* (const char*)
+extern strlcat size_t (char*, const char*, size_t)
+extern strlcpy size_t (char*, const char*, size_t)
+extern strlen size_t (const char*)
+extern strncasecmp int (const char*, const char*, size_t)
+extern strncat char* (char*, const char*, size_t)
+extern strncmp int (const char*, const char*, size_t)
+extern strncpy char* (char*, const char*, size_t)
+extern strpbrk char* (const char*, const char*)
+extern strrchr char* (const char*, int)
+extern strspn size_t (const char*, const char*)
+extern strstr char* (const char*, const char*)
+extern strtok char* (char*, const char*)
+extern strxfrm size_t (char*, const char*, size_t)
+extern swab void (const void*, void*, ssize_t)
+extern sysconf long (int)
+extern system int (const char*)
+extern tcgetpgrp pid_t (int)
+extern tcsetpgrp int (int, pid_t)
+extern truncate int (const char*, off_t)
+extern ttyname char* (int)
+extern unlink int (const char*)
+extern valloc void* (size_t)
+extern wcstombs size_t (char*, const wchar_t*, size_t)
+extern wctomb int (char*, wchar_t)
+extern write ssize_t (int, const void*, size_t)
+
+print #undef extern
+
+# <stdarg.h> is handled by proto so this must be after the last test
+
+print #include <stdarg.h>
diff --git a/src/lib/libast/features/syscall b/src/lib/libast/features/syscall
new file mode 100644
index 0000000..9788b9b
--- /dev/null
+++ b/src/lib/libast/features/syscall
@@ -0,0 +1,18 @@
+lib sysgetcwd note{ syscall(SYS_getcwd,buf,len) implemented }end link{
+ #include <sys/syscall.h>
+ int main()
+ {
+ char buf[256];
+ return syscall(SYS_getcwd, buf, sizeof(buf)) < 0;
+ }
+}end
+
+if ( _lib_sysgetcwd ) {
+ #include <sys/syscall.h>
+}
+endif
+
+if ( _lib_sysgetcwd ) {
+ #define SYSGETCWD(a,b) syscall(SYS_getcwd,a,b)
+}
+endif
diff --git a/src/lib/libast/features/time b/src/lib/libast/features/time
new file mode 100644
index 0000000..6c15113
--- /dev/null
+++ b/src/lib/libast/features/time
@@ -0,0 +1,46 @@
+set prototyped
+lib nanosleep,usleep,_strftime
+typ clock_t = uint32_t
+typ time_t = uint32_t
+
+if sys time {
+ #include <sys/time.h>
+}
+endif
+
+if ! mem tm.tm_sec sys/time.h
+ if hdr time {
+ #include <time.h>
+ }
+ endif
+endif
+
+if sys times {
+ #include <sys/times.h>
+}
+else {
+ struct tms
+ {
+ clock_t tms_utime;
+ clock_t tms_stime;
+ clock_t tms_cutime;
+ clock_t tms_cstime;
+ };
+ extern clock_t times(struct tms*);
+}
+endif
+
+if ! mem timeval.tv_sec sys/time.h {
+ struct timeval
+ {
+ time_t tv_sec;
+ time_t tv_usec;
+ };
+}
+endif
+
+cat{
+#if !defined(CLOCKS_PER_SEC) && defined(CLK_TCK)
+#define CLOCKS_PER_SEC CLK_TCK
+#endif
+}end
diff --git a/src/lib/libast/features/tmlib b/src/lib/libast/features/tmlib
new file mode 100644
index 0000000..221079c
--- /dev/null
+++ b/src/lib/libast/features/tmlib
@@ -0,0 +1,45 @@
+set prototyped
+
+_cc_export_dynamic = note{ probe CC.EXPORT.DYNAMIC supported }end run{
+ case `{ probe -l C make cc | grep '^CC.EXPORT.DYNAMIC = .'; } 2>/dev/null` in
+ '') exit 1 ;;
+ esac
+}end
+
+tst tzset_environ note{ tzset() bypasses user getenv() }end execute{
+ #if _UWIN || !_cc_export_dynamic
+ int main()
+ {
+ return 0;
+ }
+ #else
+ #include <time.h>
+ extern char** environ;
+ extern char* tzname[2];
+ #if _STD_
+ extern char* getenv(char* s)
+ #else
+ extern char* getenv(s)
+ char* s;
+ #endif
+ {
+ return "foo0bar";
+ }
+ int main()
+ {
+ tzset();
+ return tzname[0] && !strcmp(tzname[0], "foo") &&
+ tzname[1] && !strcmp(tzname[1], "bar");
+ }
+ #endif
+}end
+
+if ( _tzset_environ ) {
+ #define tmlocaltime(p) _tm_localtime(p)
+
+ extern struct tm* _tm_localtime(const time_t*);
+}
+else {
+ #define tmlocaltime(p) localtime(p)
+}
+endif
diff --git a/src/lib/libast/features/tmx b/src/lib/libast/features/tmx
new file mode 100644
index 0000000..ebf5c0f
--- /dev/null
+++ b/src/lib/libast/features/tmx
@@ -0,0 +1,106 @@
+set prototyped
+set explicit
+iff TMX
+
+cat{
+ /*
+ * AT&T Research
+ *
+ * high resolution Time_t support
+ */
+
+ #include <tm.h>
+ #include <tv.h>
+}end
+
+inc FEATURE/common
+
+if ( _ast_int8_t ) {
+ #define TMX_MAXDATE "2554-07-21+23:34:33.709551614 UTC"
+ #define TMX_MAXYEAR 2554
+ #define TMX_MAXSEC ((Time_t)18446744073)
+ #define TMX_MAXNSEC 709551614
+ #define TMX_RESOLUTION 1000000000
+
+ typedef uint64_t Time_t;
+ typedef uint64_t Tmxsec_t;
+ typedef uint32_t Tmxnsec_t;
+
+ #define tmxsec(t) ((Tmxsec_t)((t)/1000000000))
+ #define tmxnsec(t) ((Tmxnsec_t)((t)%1000000000))
+ #define tmxsns(s,n) (((((Time_t)(s))*1000000000))+((Time_t)(n)))
+}
+elif ( _ast_flt8_t ) {
+ #define TMX_FLOAT 1
+ #define TMX_MAXDATE "2106-02-07+06:28:15.999 UTC"
+ #define TMX_MAXYEAR 2106
+ #define TMX_MAXSEC 0xffffffffL
+ #define TMX_MAXNSEC 999000000L
+ #define TMX_RESOLUTION 1000
+
+ typedef _ast_flt8_t Time_t;
+ typedef uint32_t Tmxsec_t;
+ typedef uint32_t Tmxnsec_t;
+
+ #define tmxsec(t) ((Tmxsec_t)(t))
+ #define tmxnsec(t) (((Tmxnsec_t)(((t)-((uint32_t)(t))+0.0000005)*1000L))*1000000L)
+ #define tmxsns(s,n) (((Time_t)(s))+((((uint32_t)(n))/1000L)/1e6))
+}
+else {
+ #define TMX_MAXDATE "2106-02-07+06:28:14 UTC"
+ #define TMX_MAXYEAR 2106
+ #define TMX_MAXSEC 0xfffffffeL
+ #define TMX_MAXNSEC 0L
+ #define TMX_RESOLUTION 1
+
+ typedef uint32_t Time_t;
+ typedef uint32_t Tmxsec_t;
+ typedef uint32_t Tmxnsec_t;
+
+ #define tmxsec(t) ((Tmxsec_t)(t))
+ #define tmxnsec(t) (0)
+ #define tmxsns(s,n) ((Time_t)(s))
+}
+endif
+
+cat{
+ #define TMX_NOTIME ((Time_t)(-1))
+ #define TMX_NOW tmxgettime()
+ #define TMX_MAXTIME tmxsns(TMX_MAXSEC,TMX_MAXNSEC)
+
+ #define tmx2tv(t,v) ((v)->tv_nsec=tmxnsec(t),(v)->tv_sec=tmxsec(t))
+ #define tv2tmx(v) tmxsns((v)->tv_sec,(v)->tv_nsec)
+
+ #define tmxclock(p) tmxsns(((p)?*(p):time(NiL)),0)
+
+ #define tmxgetatime(s) tmxsns((s)->st_atime,ST_ATIME_NSEC_GET(s))
+ #define tmxgetctime(s) tmxsns((s)->st_ctime,ST_CTIME_NSEC_GET(s))
+ #define tmxgetmtime(s) tmxsns((s)->st_mtime,ST_MTIME_NSEC_GET(s))
+
+ #define tmxsetatime(s,t) ((s)->st_atime=tmxsec(t),ST_ATIME_NSEC_SET(s,tmxnsec(t)))
+ #define tmxsetctime(s,t) ((s)->st_ctime=tmxsec(t),ST_CTIME_NSEC_SET(s,tmxnsec(t)))
+ #define tmxsetmtime(s,t) ((s)->st_mtime=tmxsec(t),ST_MTIME_NSEC_SET(s,tmxnsec(t)))
+
+ #if _BLD_ast && defined(__EXPORT__)
+ #define extern __EXPORT__
+ #endif
+
+ extern Time_t tmxdate(const char*, char**, Time_t);
+ extern Time_t tmxduration(const char*, char**);
+ extern char* tmxfmt(char*, size_t, const char*, Time_t);
+ extern Time_t tmxleap(Time_t);
+ extern Tm_t* tmxmake(Time_t);
+ extern Time_t tmxscan(const char*, char**, const char*, char**, Time_t, long);
+ extern int tmxsleep(Time_t);
+ extern Time_t tmxtime(Tm_t*, int);
+ extern Tm_t* tmxtm(Tm_t*, Time_t, Tm_zone_t*);
+
+ extern Time_t tmxgettime(void);
+ extern int tmxsettime(Time_t);
+
+ extern int tmxtouch(const char*, Time_t, Time_t, Time_t, int);
+
+ extern char* fmttmx(const char*, Time_t);
+
+ #undef extern
+}end
diff --git a/src/lib/libast/features/tty b/src/lib/libast/features/tty
new file mode 100644
index 0000000..a75edeb
--- /dev/null
+++ b/src/lib/libast/features/tty
@@ -0,0 +1,127 @@
+hdr termios,termio,sgtty
+sys termios,termio,ioctl,bsdtty,nttyio,ttyio
+lib tcgetattr,tcgetpgrp termios.h
+mac _POSIX_VDISABLE termios.h
+mem termios.c_line termios.h
+
+cat{
+
+#ifdef _hdr_termios
+# if _mac__POSIX_VDISABLE
+# undef _POSIX_VDISABLE
+# endif
+# include <termios.h>
+#else
+# if defined(_sys_termios) && defined(_lib_tcgetattr)
+# include <sys/termios.h>
+# define _hdr_termios 1
+# else
+# undef _sys_termios
+# endif /* _sys_termios */
+#endif /* _hdr_termios */
+
+#ifdef _hdr_termios
+# undef _hdr_sgtty
+# undef tcgetattr
+# undef tcsetattr
+# undef tcgetpgrp
+# undef tcsetpgrp
+# undef cfgetospeed
+# ifndef TCSANOW
+# define TCSANOW TCSETS
+# define TCSADRAIN TCSETSW
+# define TCSAFLUSH TCSETSF
+# endif /* TCSANOW */
+ /* The following corrects bugs in some implementations */
+# if defined(TCSADFLUSH) && !defined(TCSAFLUSH)
+# define TCSAFLUSH TCSADFLUSH
+# endif /* TCSADFLUSH */
+# ifndef _lib_tcgetattr
+# undef tcgetattr
+# define tcgetattr(fd,tty) ioctl(fd, TCGETS, tty)
+# undef tcsetattr
+# define tcsetattr(fd,action,tty) ioctl(fd, action, tty)
+# undef cfgetospeed
+# define cfgetospeed(tp) ((tp)->c_cflag & CBAUD)
+# endif /* _lib_tcgetattr */
+# undef TIOCGETC
+#else
+# define cfgetospeed(tp) ((tp)->c_cflag & CBAUD)
+# define cfgetispeed(tp) ((tp)->c_cflag & CBAUD)
+# define cfsetispeed(tp,val) ((tp)->c_cflag &=~ CBAUD,(tp)->c_cflag|=(val))
+# define cfsetospeed(tp,val) ((tp)->c_cflag &=~ CBAUD,(tp)->c_cflag|=(val))
+# ifdef _hdr_termio
+# include <termio.h>
+# else
+# ifdef _sys_termio
+# include <sys/termio.h>
+# define _hdr_termio 1
+# endif /* _sys_termio */
+# endif /* _hdr_termio */
+# ifdef _hdr_termio
+# define termios termio
+# undef TIOCGETC
+# define tcgetattr(fd,tty) ioctl(fd, TCGETA, tty)
+# define tcsetattr(fd,action,tty) ioctl(fd, action, tty)
+
+# ifdef _sys_bsdtty
+# include <sys/bsdtty.h>
+# endif /* _sys_bsdtty */
+# else
+# ifdef _hdr_sgtty
+# include <sgtty.h>
+# ifndef LPENDIN
+# ifdef _sys_nttyio
+# include <sys/nttyio.h>
+# endif /* _sys_nttyio */
+# endif /* LPENDIN */
+# define termios sgttyb
+# ifdef TIOCSETN
+# undef TCSETAW
+# endif /* TIOCSETN */
+# ifdef TIOCGETP
+# define tcgetattr(fd,tty) ioctl(fd, TIOCGETP, tty)
+# define tcsetattr(fd,action,tty) ioctl(fd, action, tty)
+# else
+# define tcgetattr(fd,tty) gtty(fd, tty)
+# define tcsetattr(fd,action,tty) stty(fd, tty)
+# endif /* TIOCGETP */
+# else
+# ifdef _sys_ttyio
+# include <sys/ttyio.h>
+# endif
+# endif /* _hdr_sgtty */
+# endif /* hdr_termio */
+
+# ifndef TCSANOW
+# ifdef TCSETAW
+# define TCSANOW TCSETA
+# define TCSAFLUSH TCSETAF
+# else
+# ifdef TIOCSETN
+# define TCSANOW TIOCSETN
+# define TCSADRAIN TIOCSETN
+# define TCSAFLUSH TIOCSETP
+# endif /* TIOCSETN */
+# endif /* TCSETAW */
+# endif /* TCSANOW */
+#endif /* _hdr_termios */
+
+/* set ECHOCTL if driver can echo control charaters as ^c */
+#ifdef LCTLECH
+# ifndef ECHOCTL
+# define ECHOCTL LCTLECH
+# endif /* !ECHOCTL */
+#endif /* LCTLECH */
+#ifdef LNEW_CTLECH
+# ifndef ECHOCTL
+# define ECHOCTL LNEW_CTLECH
+# endif /* !ECHOCTL */
+#endif /* LNEW_CTLECH */
+#ifdef LNEW_PENDIN
+# ifndef PENDIN
+# define PENDIN LNEW_PENDIN
+# endif /* !PENDIN */
+#endif /* LNEW_PENDIN */
+
+}end
diff --git a/src/lib/libast/features/tv b/src/lib/libast/features/tv
new file mode 100644
index 0000000..ae15682
--- /dev/null
+++ b/src/lib/libast/features/tv
@@ -0,0 +1,81 @@
+set prototyped
+set explicit
+iff TV
+
+cat{
+ /*
+ * AT&T Research
+ *
+ * high resolution Tv_t interface definitions
+ */
+
+ #include <ast.h>
+
+ #define TV_NSEC_IGNORE (1000000000L)
+ #define TV_TOUCH_RETAIN ((Tv_t*)1)
+
+ typedef struct Tv_s
+ {
+ uint32_t tv_sec;
+ uint32_t tv_nsec;
+ } Tv_t;
+}end
+
+if mem stat.st_mtimespec.tv_nsec sys/stat.h {
+ #define ST_ATIME_NSEC_GET(st) ((st)->st_atimespec.tv_nsec)
+ #define ST_CTIME_NSEC_GET(st) ((st)->st_ctimespec.tv_nsec)
+ #define ST_MTIME_NSEC_GET(st) ((st)->st_mtimespec.tv_nsec)
+}
+elif mem stat.st_mtim.st__tim.tv_nsec sys/stat.h {
+ #define ST_ATIME_NSEC_GET(st) ((st)->st_atim.st__tim.tv_nsec)
+ #define ST_CTIME_NSEC_GET(st) ((st)->st_ctim.st__tim.tv_nsec)
+ #define ST_MTIME_NSEC_GET(st) ((st)->st_mtim.st__tim.tv_nsec)
+}
+elif mem stat.st_mtim.tv_nsec sys/stat.h {
+ #define ST_ATIME_NSEC_GET(st) ((st)->st_atim.tv_nsec)
+ #define ST_CTIME_NSEC_GET(st) ((st)->st_ctim.tv_nsec)
+ #define ST_MTIME_NSEC_GET(st) ((st)->st_mtim.tv_nsec)
+}
+elif mem stat.st_mtimensec sys/stat.h {
+ #define ST_ATIME_NSEC_GET(st) ((st)->st_atimensec)
+ #define ST_CTIME_NSEC_GET(st) ((st)->st_ctimensec)
+ #define ST_MTIME_NSEC_GET(st) ((st)->st_mtimensec)
+}
+else pass{ no_stat_nsec=1 }end {
+ #define ST_ATIME_NSEC_GET(st) 0
+ #define ST_CTIME_NSEC_GET(st) 0
+ #define ST_MTIME_NSEC_GET(st) 0
+
+ #define ST_ATIME_NSEC_SET(st,n) 0
+ #define ST_CTIME_NSEC_SET(st,n) 0
+ #define ST_MTIME_NSEC_SET(st,n) 0
+}
+endif
+if ( !no_stat_nsec ) {
+ #define ST_ATIME_NSEC_SET(st,n) (ST_ATIME_NSEC_GET(st)=(n))
+ #define ST_CTIME_NSEC_SET(st,n) (ST_CTIME_NSEC_GET(st)=(n))
+ #define ST_MTIME_NSEC_SET(st,n) (ST_MTIME_NSEC_GET(st)=(n))
+}
+endif
+
+cat{
+ #define tvgetatime(t,s) ((t)->tv_nsec=ST_ATIME_NSEC_GET(s),(t)->tv_sec=(s)->st_atime)
+ #define tvgetmtime(t,s) ((t)->tv_nsec=ST_MTIME_NSEC_GET(s),(t)->tv_sec=(s)->st_mtime)
+ #define tvgetctime(t,s) ((t)->tv_nsec=ST_CTIME_NSEC_GET(s),(t)->tv_sec=(s)->st_ctime)
+
+ #define tvsetatime(t,s) (ST_ATIME_NSEC_SET(s,(t)->tv_nsec),(s)->st_atime=(t)->tv_sec)
+ #define tvsetmtime(t,s) (ST_MTIME_NSEC_SET(s,(t)->tv_nsec),(s)->st_mtime=(t)->tv_sec)
+ #define tvsetctime(t,s) (ST_CTIME_NSEC_SET(s,(t)->tv_nsec),(s)->st_ctime=(t)->tv_sec)
+
+ #if _BLD_ast && defined(__EXPORT__)
+ #define extern __EXPORT__
+ #endif
+
+ extern int tvgettime(Tv_t*);
+ extern int tvsettime(const Tv_t*);
+ extern int tvcmp(const Tv_t*, const Tv_t*);
+ extern int tvtouch(const char*, const Tv_t*, const Tv_t*, const Tv_t*, int);
+ extern int tvsleep(const Tv_t*, Tv_t*);
+
+ extern char* fmttv(const char*, Tv_t*);
+}end
diff --git a/src/lib/libast/features/tvlib b/src/lib/libast/features/tvlib
new file mode 100644
index 0000000..9b2f64f
--- /dev/null
+++ b/src/lib/libast/features/tvlib
@@ -0,0 +1,80 @@
+hdr time
+lib clock_settime,gettimeofday,settimeofday,stime,utimes
+lib nanosleep,usleep
+lib utimensat -D_ATFILE_SOURCE sys/stat.h note{ complete utimensat implementation }end link{
+ #include <fcntl.h>
+ static struct timespec ts[2];
+ int
+ main()
+ {
+ ts[0].tv_nsec = UTIME_NOW;
+ ts[1].tv_nsec = UTIME_OMIT;
+ return utimensat(AT_FDCWD, ".", ts, AT_SYMLINK_NOFOLLOW) != 0;
+ }
+}end
+
+if ! mem timeval.tv_sec sys/time.h {
+ struct timeval
+ {
+ time_t tv_sec;
+ time_t tv_usec;
+ };
+}
+endif
+
+lib clock_gettime execute{
+ #include <time.h>
+ int
+ main()
+ {
+ struct timespec tv;
+ return clock_gettime(CLOCK_REALTIME, &tv) != 0;
+ }
+}end
+
+lib utimets link{
+ #include <time.h>
+ #include <sys/time.h>
+ static struct timespec tv;
+ int
+ main()
+ {
+ return utimets(".", &tv) != 0;
+ }
+}end
+
+tst - -DN=1 - -DN=2 - -DN=3 - -DN=4 output{
+ #include <sys/types.h>
+ #include <sys/time.h>
+ int
+ main()
+ {
+ struct timeval tv;
+#if N == 1
+ struct timezone tz;
+ if (gettimeofday(&tv, (struct timezone*)0) < 0)
+ return 1;
+ printf("#define tmgettimeofday(p) gettimeofday(p,(struct timezone*)0)\n");
+#if _lib_settimeofday
+ printf("#define tmsettimeofday(p) settimeofday(p,(struct timezone*)0)\n");
+#endif
+#endif
+#if N == 2
+ if (gettimeofday(&tv, (void*)0) < 0)
+ return 1;
+ printf("#define tmgettimeofday(p) gettimeofday(p,(void*)0)\n");
+#if _lib_settimeofday
+ printf("#define tmsettimeofday(p) gettimeofday(p,(void*)0)\n");
+#endif
+#endif
+#if N == 3
+ if (gettimeofday(&tv) < 0)
+ return 1;
+ printf("#define tmgettimeofday(p) gettimeofday(p)\n");
+#if _lib_settimeofday
+ printf("#define tmsettimeofday(p) settimeofday(p)\n");
+#endif
+#endif
+ return 0;
+ }
+}end
diff --git a/src/lib/libast/features/uwin b/src/lib/libast/features/uwin
new file mode 100644
index 0000000..b42cea1
--- /dev/null
+++ b/src/lib/libast/features/uwin
@@ -0,0 +1,10 @@
+lib a64l,acosh,asinh,atanh,cbrt,ceil,crypt,erf,exp,expm1,floor
+lib gamma,getpass,lgamma,log,log1p,random,rcmd,rint,srand48
+lib copysign,logb,finite,drem,sqrt,ilogb,remainder,scalb
+lib _copysign,_finite,_scalb,__iob_func,_p__iob,__p__iob
+
+dat _iob
+
+cat{
+ #define stricmp strcasecmp
+}end
diff --git a/src/lib/libast/features/vfork b/src/lib/libast/features/vfork
new file mode 100644
index 0000000..f1a0ea7
--- /dev/null
+++ b/src/lib/libast/features/vfork
@@ -0,0 +1,13 @@
+set prototyped
+hdr vfork
+sys vfork
+
+tst run{
+ if test "$_hdr_vfork" = 1
+ then echo "#include <vfork.h>"
+ elif test "$_sys_vfork" = 1
+ then echo "#include <sys/vfork.h>"
+ else echo '#include <unistd.h>' > $tmp.c
+ $cc -E $tmp.c | grep vfork
+ fi
+}end
diff --git a/src/lib/libast/features/vmalloc b/src/lib/libast/features/vmalloc
new file mode 100644
index 0000000..b3cc2d0
--- /dev/null
+++ b/src/lib/libast/features/vmalloc
@@ -0,0 +1,220 @@
+#
+# This file defines probes for local features that vmalloc requires.
+# Such probes are interpreted by the "iffe" language interpreter.
+# Results are stored in the FEATURE directory. Some of the
+# {lib,hdr,sys,typ} tests may also be done in the AST features/lib;
+# repeating them here allows for single standalone and AST sources.
+#
+
+ref -D_def_map_ast=1
+
+lib atexit,getpagesize,mallinfo,mallopt,memalign,mstats
+lib onexit,pvalloc,strdup,valloc,vmalloc
+lib _malloc,__malloc,__libc_malloc
+hdr alloca,malloc,stat,stdlib,unistd
+mem mallinfo.arena,mstats.bytes_total malloc.h
+sys stat
+typ ssize_t
+
+tst mem_sbrk note{ brk()/sbrk() work as expected }end execute{
+ #include <sys/types.h>
+ #include <unistd.h>
+ #undef uchar
+ #define uchar unsigned char
+ int main()
+ { uchar *brk0, *brk1;
+
+ /* allocate a big chunk */
+ if(!(brk0 = (uchar*)sbrk(0)) || brk0 == (uchar*)(-1))
+ return 1;
+ brk0 += 256*1024;
+ if(brk(brk0) != 0)
+ return 1;
+ if((brk1 = (uchar*)sbrk(0)) != brk0)
+ return 1;
+
+ /* now return half of it */
+ brk1 -= 128*1024;
+ if(brk(brk1) != 0 )
+ return 1;
+ if((brk0 = (uchar*)sbrk(0)) != brk1)
+ return 1;
+
+ return 0;
+ }
+}end
+
+tst map_malloc note{ map malloc to _ast_malloc }end noexecute{
+ #if __CYGWIN__
+ int main() { return 1; }
+ #else
+ static int user = 0;
+ _BEGIN_EXTERNS_
+ #if _lib_strdup
+ extern char* strdup _ARG_((const char*));
+ #define LOCAL() strdup("s")
+ #else
+ extern void* calloc _ARG_((unsigned int, unsigned int));
+ #define LOCAL() calloc(1,1)
+ #endif
+ #if __CYGWIN__
+ #define extern __declspec(dllexport)
+ #endif
+ #define HT double
+ static HT heap[1024 * 4];
+ static HT* hp = &heap[1];
+ static HT* op;
+ #define MALLOC(n) if(user)return&heap[0];op=hp;hp+=(n+sizeof(HT)-1)/sizeof(HT);return(void*)op;
+ #define INTERCEPTED(p) (((char*)(p))==((char*)&heap[0]))
+ #if _STD_
+ extern void free(void* p) { }
+ extern void _free(void* p) { }
+ extern void __free(void* p) { }
+ extern void __libc_free(void* p) { }
+ extern void* malloc(unsigned int n) { MALLOC(n); }
+ extern void* _malloc(unsigned int n) { MALLOC(n); }
+ extern void* __malloc(unsigned int n) { MALLOC(n); }
+ extern void* __libc_malloc(unsigned int n) { MALLOC(n); }
+ #else
+ extern void free(p) char* p; { }
+ extern void _free(p) char* p; { }
+ extern void __free(p) char* p; { }
+ extern void __libc_free(p) char* p; { }
+ extern void* malloc(n) unsigned int n; { MALLOC(n); }
+ extern void* _malloc(n) unsigned int n; { MALLOC(n); }
+ extern void* __malloc(n) unsigned int n; { MALLOC(n); }
+ extern void* __libc_malloc(n) unsigned int n; { MALLOC(n); }
+ #endif
+ _END_EXTERNS_
+ int main() { user = 1; return !INTERCEPTED(LOCAL()); }
+ #endif
+}end
+
+tst map_malloc note{ map malloc to _ast_malloc -- wimp-o mach? }end noexecute{
+ #if _map_malloc
+ int main() { return 0; }
+ #else
+ _BEGIN_EXTERNS_
+ #if _STD_
+ void* calloc(unsigned n, unsigned m) { exit(1); }
+ #else
+ void* calloc(n, m) unsigned n, m; { exit(1); }
+ #endif
+ _END_EXTERNS_
+ int main() { return 0; }
+ #endif
+}end
+
+lib alloca note{ alloca exists }end link{
+ #if _hdr_alloca
+ #include <alloca.h>
+ #endif
+ int
+ main()
+ { alloca(10);
+ }
+}end
+
+tst mal_alloca note{ alloca is based on malloc() }end execute{
+ #if __CYGWIN__
+ int main() { return 1; }
+ #else
+ #if _hdr_alloca
+ #include <alloca.h>
+ #endif
+ #if _STD_
+ void* malloc(unsigned int size)
+ #else
+ void* malloc(size) unsigned int size;
+ #endif
+ { exit(0);
+ return 0;
+ }
+ int main()
+ { alloca(10);
+ return 1;
+ }
+ #endif
+}end
+
+tst stk_down note{ stack grows downward }end execute{
+ static growdown()
+ { static char* addr = 0;
+ char array[4];
+ if(!addr)
+ { addr = &array[0];
+ return growdown();
+ }
+ else if(addr < &array[0])
+ return 0;
+ else return 1;
+ }
+ int main() { return growdown() ? 0 : 1; }
+}end
+
+tst malloc_hook note{ gnu malloc hooks work }end execute{
+ #include <malloc.h>
+
+ static int test_free_hit = 0;
+ static int test_malloc_hit = 0;
+ static int test_memalign_hit = 0;
+ static int test_realloc_hit = 0;
+
+ static void test_free_hook(void* ptr, const void* caller)
+ {
+ test_free_hit++;
+ }
+
+ static void* test_malloc_hook(size_t size, const void* caller)
+ {
+ test_malloc_hit++;
+ return 0;
+ }
+
+ static void* test_memalign_hook(size_t align, size_t size, const void* caller)
+ {
+ test_memalign_hit++;
+ return 0;
+ }
+
+ static void* test_realloc_hook(void* ptr, size_t size, const void* caller)
+ {
+ test_realloc_hit++;
+ return 0;
+ }
+
+ static void test_initialize_hook(void)
+ {
+ __free_hook = test_free_hook;
+ __malloc_hook = test_malloc_hook;
+ __memalign_hook = test_memalign_hook;
+ __realloc_hook = test_realloc_hook;
+ }
+
+ void (*__malloc_initialize_hook)(void) = test_initialize_hook;
+
+ int main()
+ {
+ void* p;
+
+ p = malloc(16);
+ p = realloc(p, 32);
+ free(p);
+ p = memalign(32, 32);
+ return !test_free_hit || !test_malloc_hit || !test_memalign_hit || !test_realloc_hit;
+ }
+}end
+
+cat{
+ #include "FEATURE/mmap"
+ #if _BLD_INSTRUMENT || cray || _UWIN && _BLD_ast
+ #undef _map_malloc
+ #define _std_malloc 1 /* defer to standard malloc */
+ #endif
+ #if _mmap_anon
+ #define _mem_mmap_anon 1
+ #endif
+ #if _mmap_devzero
+ #define _mem_mmap_zero 1
+ #endif
+}end
diff --git a/src/lib/libast/features/wait b/src/lib/libast/features/wait
new file mode 100644
index 0000000..74c8c81
--- /dev/null
+++ b/src/lib/libast/features/wait
@@ -0,0 +1,9 @@
+lib wait,wait2,wait3,wait4,waitpid
+tst ok_wif sys/types.h sys/wait.h note{ posix wait macros ok }end compile{
+ int ifexited = WIFEXITED(0);
+ int exitstatus = WEXITSTATUS(0);
+ int ifsignaled = WIFSIGNALED(0);
+ int termsig = WTERMSIG(0);
+ int ifstopped = WIFSTOPPED(0);
+ int stopsig = WSTOPSIG(0);
+}end
diff --git a/src/lib/libast/features/wchar b/src/lib/libast/features/wchar
new file mode 100644
index 0000000..ac51f0f
--- /dev/null
+++ b/src/lib/libast/features/wchar
@@ -0,0 +1,158 @@
+set prototyped
+iff
+set stdio ast_common.h
+set include .
+
+cat{
+ #ifndef _AST_WCHAR_H
+ #define _AST_WCHAR_H 1
+}end
+
+lib mbstowcs,wctomb,wcrtomb,wcslen,wcstombs,wcwidth stdlib.h stdio.h wchar.h
+lib towlower,towupper stdlib.h stdio.h wchar.h
+typ mbstate_t stdlib.h stdio.h wchar.h
+nxt wchar
+
+cat{
+ #ifndef _SFSTDIO_H
+ #include <ast_common.h>
+ #include <stdio.h>
+ #endif
+}end
+
+if tst note{ <wchar.h> requires native <stdio.h> }end nocompile{
+ /*<NOSTDIO>*/
+ #define _STDIO_INCLUDED 1
+ #define FILE void
+ #include <wchar.h>
+ int tst;
+ }end
+ if tst note{ <stdio.h> defines __va_list for <wchar.h> }end compile{
+ /*<NOSTDIO>*/
+ #define _STDIO_INCLUDED 1
+ #define FILE void
+ #include <stdarg.h>
+ #define __va_list va_list
+ #include <wchar.h>
+ int tst;
+ }end && {
+ #define __va_list va_list
+ }
+ endif
+endif
+
+if hdr - wctype wchar.h
+ if ! npt - iswalpha wchar.h {
+ #include <wctype.h> /* <wchar.h> includes <wctype.h> */
+ }
+ endif
+endif
+
+run{
+cat <<!
+ #if _hdr_wchar && defined(_nxt_wchar)
+ #include ${_nxt_wchar-_nxt_wchar} /* the native wchar.h */
+ #endif
+
+ #ifndef WEOF
+ #define WEOF (-1)
+ #endif
+
+ #undef fgetwc
+ #undef fgetws
+ #undef fputwc
+ #undef fputws
+ #undef getwc
+ #undef getwchar
+ #undef getws
+ #undef putwc
+ #undef putwchar
+ #undef ungetwc
+
+ #define fgetwc _ast_fgetwc
+ #define fgetws _ast_fgetws
+ #define fputwc _ast_fputwc
+ #define fputws _ast_fputws
+ #define fwide _ast_fwide
+ #define fwprintf _ast_fwprintf
+ #define fwscanf _ast_fwscanf
+ #define getwc _ast_getwc
+ #define getwchar _ast_getwchar
+ #define getws _ast_getws
+ #define putwc _ast_putwc
+ #define putwchar _ast_putwchar
+ #define swprintf _ast_swprintf
+ #define swscanf _ast_swscanf
+ #define ungetwc _ast_ungetwc
+ #define vfwprintf _ast_vfwprintf
+ #define vfwscanf _ast_vfwscanf
+ #define vswprintf _ast_vswprintf
+ #define vswscanf _ast_vswscanf
+ #define vwprintf _ast_vwprintf
+ #define vwscanf _ast_vwscanf
+ #define wprintf _ast_wprintf
+ #define wscanf _ast_wscanf
+
+ #if !_typ_mbstate_t
+ #undef _typ_mbstate_t
+ #define _typ_mbstate_t 1
+ typedef char mbstate_t;
+ #endif
+
+ #if _BLD_ast && defined(__EXPORT__)
+ #define extern __EXPORT__
+ #endif
+
+ #if !_lib_mbstowcs
+ extern size_t mbstowcs(wchar_t*, const char*, size_t);
+ #endif
+ #if !_lib_wctomb
+ extern int wctomb(char*, wchar_t);
+ #endif
+ #if !_lib_wcrtomb
+ extern size_t wcrtomb(char*, wchar_t, mbstate_t*);
+ #endif
+ #if !_lib_wcslen
+ extern size_t wcslen(const wchar_t*);
+ #endif
+ #if !_lib_wcstombs
+ extern size_t wcstombs(char*, const wchar_t*, size_t);
+ #endif
+
+ extern int fwprintf(FILE*, const wchar_t*, ...);
+ extern int fwscanf(FILE*, const wchar_t*, ...);
+ extern wint_t fgetwc(FILE*);
+ extern wchar_t* fgetws(wchar_t*, int, FILE*);
+ extern wint_t fputwc(wchar_t, FILE*);
+ extern int fputws(const wchar_t*, FILE*);
+ extern int fwide(FILE*, int);
+ extern wint_t getwc(FILE*);
+ extern wint_t getwchar(void);
+ extern wchar_t* getws(wchar_t*);
+ extern wint_t putwc(wchar_t, FILE*);
+ extern wint_t putwchar(wchar_t);
+ extern int swprintf(wchar_t*, size_t, const wchar_t*, ...);
+ extern int swscanf(const wchar_t*, const wchar_t*, ...);
+ extern wint_t ungetwc(wint_t, FILE*);
+ extern int vfwprintf(FILE*, const wchar_t*, va_list);
+ extern int vfwscanf(FILE*, const wchar_t*, va_list);
+ extern int vwprintf(const wchar_t*, va_list);
+ extern int vwscanf(const wchar_t*, va_list);
+ extern int vswprintf(wchar_t*, size_t, const wchar_t*, va_list);
+ extern int vswscanf(const wchar_t*, const wchar_t*, va_list);
+ extern int wprintf(const wchar_t*, ...);
+ extern int wscanf(const wchar_t*, ...);
+
+ #undef extern
+
+ #else
+
+ /* on some systems <wchar.h> is included multiple times with multiple effects */
+
+ #if _hdr_wchar && defined(_nxt_wchar)
+ #include ${_nxt_wchar-_nxt_wchar} /* the native wchar.h */
+ #endif
+
+ #endif
+!
+}end
diff --git a/src/lib/libast/features/wctype b/src/lib/libast/features/wctype
new file mode 100644
index 0000000..0f59bc1
--- /dev/null
+++ b/src/lib/libast/features/wctype
@@ -0,0 +1,14 @@
+set prototyped
+nxt wctype
+
+run{
+cat <<!
+ #if _hdr_wctype && defined(_nxt_wctype)
+ #include ${_nxt_wctype-_nxt_wctype} /* the native wctype.h */
+ #endif
+
+ #undef iswalpha
+
+ #define iswalpha(w) (ast.mb_alpha?(*ast.mb_alpha)(w):isalpha(w))
+!
+}end
diff --git a/src/lib/libast/hash/hashalloc.c b/src/lib/libast/hash/hashalloc.c
new file mode 100644
index 0000000..8c923f3
--- /dev/null
+++ b/src/lib/libast/hash/hashalloc.c
@@ -0,0 +1,200 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * hash table library
+ */
+
+static const char id_hash[] = "\n@(#)$Id: hash (AT&T Research) 1996-08-11 $\0\n";
+
+#include "hashlib.h"
+
+Hash_info_t hash_info = { 0 };
+
+/*
+ * create a new hash table
+ */
+
+Hash_table_t*
+hashalloc(Hash_table_t* ref, ...)
+{
+ register Hash_table_t* tab;
+ register Hash_table_t* ret = 0;
+ register int internal;
+ int n;
+ va_list ap;
+ va_list va[4];
+ va_list* vp = va;
+ Hash_region_f region = 0;
+ void* handle;
+
+ va_start(ap, ref);
+
+ /*
+ * check for HASH_region which must be first
+ */
+
+ n = va_arg(ap, int);
+ if (!ref && n == HASH_region)
+ {
+ region = va_arg(ap, Hash_region_f);
+ handle = va_arg(ap, void*);
+ n = va_arg(ap, int);
+ if (!(tab = (Hash_table_t*)(*region)(handle, NiL, sizeof(Hash_table_t), 0)))
+ goto out;
+ memset(tab, 0, sizeof(Hash_table_t));
+ }
+ else if (!(tab = newof(0, Hash_table_t, 1, 0)))
+ goto out;
+ tab->bucketsize = (sizeof(Hash_header_t) + sizeof(char*) - 1) / sizeof(char*);
+ if (ref)
+ {
+ tab->flags = ref->flags & ~HASH_RESET;
+ tab->root = ref->root;
+ internal = HASH_INTERNAL;
+ }
+ else
+ {
+ if (region)
+ {
+ if (!(tab->root = (Hash_root_t*)(*region)(handle, NiL, sizeof(Hash_root_t), 0)))
+ goto out;
+ memset(tab->root, 0, sizeof(Hash_root_t));
+ }
+ else if (!(tab->root = newof(0, Hash_root_t, 1, 0)))
+ goto out;
+ if (!(tab->root->local = newof(0, Hash_local_t, 1, 0)))
+ goto out;
+ if (tab->root->local->region = region)
+ tab->root->local->handle = handle;
+ tab->root->meanchain = HASHMEANCHAIN;
+ internal = 0;
+ }
+ tab->size = HASHMINSIZE;
+ for (;;)
+ {
+ switch (n)
+ {
+ case HASH_alloc:
+ if (ref) goto out;
+ tab->root->local->alloc = va_arg(ap, Hash_alloc_f);
+ break;
+ case HASH_bucketsize:
+ n = (va_arg(ap, int) + sizeof(char*) - 1) / sizeof(char*);
+ if (n > UCHAR_MAX) goto out;
+ if (n > tab->bucketsize) tab->bucketsize = n;
+ break;
+ case HASH_clear:
+ tab->flags &= ~(va_arg(ap, int) & ~internal);
+ break;
+ case HASH_compare:
+ if (ref) goto out;
+ tab->root->local->compare = va_arg(ap, Hash_compare_f);
+ break;
+ case HASH_free:
+ if (ref) goto out;
+ tab->root->local->free = va_arg(ap, Hash_free_f);
+ break;
+ case HASH_hash:
+ if (ref) goto out;
+ tab->root->local->hash = va_arg(ap, Hash_hash_f);
+ break;
+ case HASH_meanchain:
+ if (ref) goto out;
+ tab->root->meanchain = va_arg(ap, int);
+ break;
+ case HASH_name:
+ tab->name = va_arg(ap, char*);
+ break;
+ case HASH_namesize:
+ if (ref) goto out;
+ tab->root->namesize = va_arg(ap, int);
+ break;
+ case HASH_region:
+ goto out;
+ case HASH_set:
+ tab->flags |= (va_arg(ap, int) & ~internal);
+ break;
+ case HASH_size:
+ tab->size = va_arg(ap, int);
+ if (tab->size & (tab->size - 1)) tab->flags |= HASH_FIXED;
+ break;
+ case HASH_table:
+ tab->table = va_arg(ap, Hash_bucket_t**);
+ tab->flags |= HASH_STATIC;
+ break;
+ case HASH_va_list:
+ if (vp < &va[elementsof(va)])
+ {
+ va_copy(*vp, ap);
+ vp++;
+ }
+ va_copy(ap, va_listval(va_arg(ap, va_listarg)));
+ break;
+ case 0:
+ if (vp > va)
+ {
+ vp--;
+ va_copy(ap, *vp);
+ break;
+ }
+ if (tab->flags & HASH_SCOPE)
+ {
+ if (!(tab->scope = ref)) goto out;
+ ref->frozen++;
+ }
+ if (!tab->table)
+ {
+ if (region)
+ {
+ if (!(tab->table = (Hash_bucket_t**)(*region)(handle, NiL, sizeof(Hash_bucket_t*) * tab->size, 0)))
+ goto out;
+ memset(tab->table, 0, sizeof(Hash_bucket_t*) * tab->size);
+ }
+ else if (!(tab->table = newof(0, Hash_bucket_t*, tab->size, 0))) goto out;
+ }
+ if (!ref)
+ {
+ tab->root->flags = tab->flags & HASH_INTERNAL;
+ tab->root->next = hash_info.list;
+ hash_info.list = tab->root;
+ }
+ if (!region)
+ {
+ tab->next = tab->root->references;
+ tab->root->references = tab;
+ }
+ ret = tab;
+ goto out;
+ default:
+ goto out;
+ }
+ n = va_arg(ap, int);
+ }
+ out:
+ va_end(ap);
+ if (!ret) hashfree(tab);
+ return(ret);
+}
diff --git a/src/lib/libast/hash/hashdump.c b/src/lib/libast/hash/hashdump.c
new file mode 100644
index 0000000..3c2829a
--- /dev/null
+++ b/src/lib/libast/hash/hashdump.c
@@ -0,0 +1,173 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * hash table library
+ */
+
+#include "hashlib.h"
+
+/*
+ * dump HASH_* flags
+ */
+
+static void
+dumpflags(register int flags)
+{
+ if (flags & HASH_ALLOCATE) sfprintf(sfstderr, "allocate ");
+ if (flags & HASH_BUCKET) sfprintf(sfstderr, "bucket ");
+ if (flags & HASH_FIXED) sfprintf(sfstderr, "fixed ");
+ if (flags & HASH_HASHED) sfprintf(sfstderr, "hashed ");
+ if (flags & HASH_RESIZE) sfprintf(sfstderr, "resize ");
+ if (flags & HASH_STATIC) sfprintf(sfstderr, "static ");
+ if (flags & HASH_VALUE) sfprintf(sfstderr, "value ");
+}
+
+/*
+ * dump hash table bucket info
+ */
+
+static void
+dumpbucket(register Hash_table_t* tab, int flags)
+{
+ register Hash_bucket_t** sp;
+ register Hash_bucket_t* b;
+ Hash_bucket_t** sx;
+ int n;
+ unsigned char* s;
+
+ NoP(flags);
+ sx = tab->table + tab->size;
+ for (sp = tab->table; sp < sx; sp++)
+ {
+ n = 0;
+ for (b = *sp; b; b = b->next)
+ if (!(b->hash & HASH_DELETED) && (!(tab->flags & HASH_VALUE) || b->value))
+ n++;
+ if (n)
+ {
+ sfprintf(sfstderr, "%5d %2d :", sp - tab->table, n);
+ for (b = *sp; b; b = b->next)
+ if (!(b->hash & HASH_DELETED) && (!(tab->flags & HASH_VALUE) || b->value))
+ {
+ if (n = tab->root->namesize)
+ {
+ sfprintf(sfstderr, " 0x");
+ s = (unsigned char*)hashname(b);
+ while (n-- > 0)
+ sfprintf(sfstderr, "%02x", *s++);
+ }
+ else sfprintf(sfstderr, " %s", hashname(b));
+ if (b->hash & HASH_FLAGS)
+ {
+ sfprintf(sfstderr, "|");
+ if (b->hash & HASH_HIDES) sfprintf(sfstderr, "hides|");
+ if (b->hash & HASH_HIDDEN) sfprintf(sfstderr, "hidden|");
+ if (b->hash & HASH_KEEP) sfprintf(sfstderr, "keep|");
+ if (b->hash & HASH_OPAQUED) sfprintf(sfstderr, "opaque|");
+ }
+ if (tab->flags & HASH_VALUE) sfprintf(sfstderr, "=0x%08lx", (long)b->value);
+ }
+ sfprintf(sfstderr, "\n");
+ }
+ }
+ sfprintf(sfstderr, "\n");
+}
+
+/*
+ * dump info on a single table
+ */
+
+static void
+dumptable(register Hash_table_t* tab, register int flags)
+{
+ Hash_table_t* scope;
+ int level;
+
+ sfprintf(sfstderr, " name: %s", tab->name ? tab->name : "*no name*");
+ if (scope = tab->scope)
+ {
+ level = 1;
+ while (scope = scope->scope) level++;
+ sfprintf(sfstderr, " level %d scope on 0x%08lx", level, (unsigned long)tab->scope);
+ }
+ sfprintf(sfstderr, "\n");
+ sfprintf(sfstderr, " address: 0x%08lx\n", (unsigned long)tab);
+ sfprintf(sfstderr, " flags: ");
+ if (tab->frozen) sfprintf(sfstderr, "frozen=%d ", tab->frozen);
+ dumpflags(tab->flags);
+ sfprintf(sfstderr, "\n");
+ sfprintf(sfstderr, " size: %d\n", tab->size);
+ sfprintf(sfstderr, " buckets: %d\n", tab->buckets);
+ sfprintf(sfstderr, " bucketsize: %d\n", tab->bucketsize * sizeof(char*));
+ sfprintf(sfstderr, "\n");
+ if ((flags | tab->flags) & HASH_BUCKET) dumpbucket(tab, flags);
+}
+
+/*
+ * dump hash table root info
+ */
+
+static void
+dumproot(register Hash_root_t* root, register int flags)
+{
+ register Hash_table_t* tab;
+
+ sfprintf(sfstderr, " root\n");
+ sfprintf(sfstderr, " address: 0x%08lx\n", (unsigned long)root);
+ sfprintf(sfstderr, " flags: ");
+ dumpflags(root->flags);
+ if (root->namesize) sfprintf(sfstderr, "namesize=%d ", root->namesize);
+ if (root->local->alloc) sfprintf(sfstderr, "alloc=0x%08lx ", (unsigned long)root->local->alloc);
+ if (root->local->compare) sfprintf(sfstderr, "compare=0x%08lx ", (unsigned long)root->local->compare);
+ if (root->local->free) sfprintf(sfstderr, "free=0x%08lx ", (unsigned long)root->local->free);
+ if (root->local->hash) sfprintf(sfstderr, "hash=0x%08lx ", (unsigned long)root->local->hash);
+ if (root->local->region) sfprintf(sfstderr, "region=0x%08lx handle=0x%08lx ", (unsigned long)root->local->region, (unsigned long)root->local->handle);
+ sfprintf(sfstderr, "\n");
+ sfprintf(sfstderr, " meanchain: %d\n", root->meanchain);
+ sfprintf(sfstderr, " accesses: %d\n", root->accesses);
+ sfprintf(sfstderr, " collisions: %d\n", root->collisions);
+ sfprintf(sfstderr, "\n");
+ for (tab = root->references; tab; tab = tab->next)
+ dumptable(tab, flags);
+}
+
+/*
+ * dump hash table accounting info
+ * if tab is 0 then dump all tables in hash_info.list
+ * flags are HASH_* flags that specifiy optional dump info
+ */
+
+void
+hashdump(register Hash_table_t* tab, int flags)
+{
+ register Hash_root_t* root;
+
+ sfprintf(sfstderr, "\nhash table information:\n\n");
+ if (tab) dumproot(tab->root, flags);
+ else for (root = hash_info.list; root; root = root->next)
+ dumproot(root, flags);
+ sfsync(sfstderr);
+}
diff --git a/src/lib/libast/hash/hashfree.c b/src/lib/libast/hash/hashfree.c
new file mode 100644
index 0000000..b6998a3
--- /dev/null
+++ b/src/lib/libast/hash/hashfree.c
@@ -0,0 +1,144 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * hash table library
+ */
+
+#include "hashlib.h"
+
+/*
+ * free (remove) a hash table
+ * can be called for partially constructed tables
+ * scope covered table pointer is returned
+ * root info freed when last reference freed
+ */
+
+Hash_table_t*
+hashfree(register Hash_table_t* tab)
+{
+ register Hash_bucket_t** sp;
+ register Hash_bucket_t* b;
+ register Hash_bucket_t* p;
+ Hash_bucket_t** sx;
+ Hash_root_t* rp;
+ Hash_table_t* tp;
+ Hash_free_f freevalue;
+ Hash_free_f freebucket;
+ Hash_region_f region;
+ void* handle;
+
+ if (!tab) return(0);
+ if (tab->table)
+ {
+ freebucket = 0;
+ freevalue = 0;
+ if (tab->root->local->free)
+ {
+ if (tab->root->flags & HASH_BUCKET) freebucket = tab->root->local->free;
+ else freevalue = tab->root->local->free;
+ }
+ if (region = tab->root->local->region)
+ handle = tab->root->local->handle;
+ sx = &tab->table[tab->size];
+ sp = &tab->table[0];
+ while (sp < sx)
+ {
+ b = *sp++;
+ while (b)
+ {
+ p = b;
+ b = b->next;
+ if (freebucket) (*freebucket)((char*)p);
+ else if (freevalue && p->value) (*freevalue)(p->value);
+ if (p->hash & HASH_FREENAME)
+ {
+ p->hash &= ~HASH_FREENAME;
+ if (region) (*region)(handle, p->name, 0, 0);
+ else free(p->name);
+ }
+ if (!(p->hash & HASH_KEEP))
+ {
+ if (region) (*region)(handle, p, 0, 0);
+ else free(p);
+ }
+ else if (p->hash & HASH_HIDES)
+ {
+ p->hash &= ~HASH_HIDES;
+ p->name = ((Hash_bucket_t*)p->name)->name;
+ }
+ }
+ }
+ if ((tab->flags & (HASH_RESIZE|HASH_STATIC)) != HASH_STATIC)
+ {
+ if (region) (*region)(handle, tab->table, 0, 0);
+ else free(tab->table);
+ }
+ }
+ else region = 0;
+ if (tab->root)
+ {
+ if (!region)
+ {
+ /*
+ * remove from the table lists
+ */
+
+ if ((tp = tab->root->references) != tab)
+ {
+ for (; tp; tp = tp->next)
+ if (tp->next == tab)
+ {
+ tp->next = tab->next;
+ break;
+ }
+ }
+ else if (!(tab->root->references = tp->next))
+ {
+ if ((rp = hash_info.list) != tab->root)
+ {
+ for (; rp; rp = rp->next)
+ if (rp->next == tab->root)
+ {
+ rp->next = tab->root->next;
+ break;
+ }
+ }
+ else hash_info.list = rp->next;
+ }
+ }
+ if (!(tab->root->references))
+ {
+ if (tab->root->local)
+ free(tab->root->local);
+ if (region) (*region)(handle, tab->root, 0, 0);
+ else free(tab->root);
+ }
+ }
+ if (tp = tab->scope) tp->frozen--;
+ if (region) (*region)(handle, tab, 0, 0);
+ else free(tab);
+ return(tp);
+}
diff --git a/src/lib/libast/hash/hashlast.c b/src/lib/libast/hash/hashlast.c
new file mode 100644
index 0000000..0083477
--- /dev/null
+++ b/src/lib/libast/hash/hashlast.c
@@ -0,0 +1,43 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/* OBSOLETE 19960229 -- use tab->root->last.{table|bucket} */
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * hash table library
+ */
+
+#include "hashlib.h"
+
+/*
+ * return last lookup bucket for table
+ */
+
+Hash_bucket_t*
+hashlast(Hash_table_t* tab)
+{
+ return(tab->root->last.bucket);
+}
diff --git a/src/lib/libast/hash/hashlib.h b/src/lib/libast/hash/hashlib.h
new file mode 100644
index 0000000..2d225b9
--- /dev/null
+++ b/src/lib/libast/hash/hashlib.h
@@ -0,0 +1,104 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * hash table library private definitions
+ */
+
+#ifndef _HASHLIB_H
+#define _HASHLIB_H
+
+#include <ast.h>
+
+#define hash_info _hash_info_
+
+typedef void* (*Hash_alloc_f)(size_t);
+typedef int (*Hash_compare_f)(const char*, const char*, ...);
+typedef unsigned int (*Hash_hash_f)(const char*, ...);
+typedef void (*Hash_free_f)(void*);
+typedef void* (*Hash_region_f)(void*, void*, size_t, int);
+
+typedef struct /* root local pointers */
+{
+ Hash_hash_f hash; /* name hash routine */
+ Hash_compare_f compare; /* name comparision routine */
+ Hash_alloc_f alloc; /* value allocation routine */
+ Hash_free_f free; /* value free routine */
+ Hash_region_f region; /* region alloc/free routine */
+ void* handle; /* region handle arg */
+} Hash_local_t;
+
+#define _HASH_POSITION_PRIVATE_ \
+ Hash_table_t* tab; /* table pointer */ \
+ int flags; /* scan flags */ \
+ Hash_bucket_t** slot; /* table slot */ \
+ Hash_bucket_t** limit; /* slot limit */
+
+#define _HASH_LAST_PRIVATE_ \
+ const char* name; /* last lookup name */ \
+ unsigned int hash; /* last lookup hash */
+
+#define _HASH_ROOT_PRIVATE_ \
+ int namesize; /* fixed name size: 0 => string */ \
+ int meanchain; /* resize mean chain length */ \
+ Hash_local_t* local; /* root local pointers */ \
+ Hash_root_t* next; /* next in list of all roots */ \
+ Hash_table_t* references; /* referencing table list */
+
+#define _HASH_TABLE_PRIVATE_ \
+ unsigned char frozen; /* table freeze nesting */ \
+ unsigned char bucketsize; /* min bucket size in char*'s */ \
+ Hash_bucket_t** table; /* hash slot table */ \
+ Hash_table_t* next; /* root reference list link */
+
+#include <hash.h>
+
+#define HASHMINSIZE (1<<4) /* min table slots (power of 2) */
+#define HASHMEANCHAIN 2 /* def resize mean chain len */
+
+#define HASHMOD(t,h) (h &= (t->size - 1))
+#define HASHVAL(x) ((x)&~HASH_FLAGS)
+
+#define HASH(r,n,h) if (r->local->hash) h = r->namesize ? (*r->local->hash)(n, r->namesize) : (*r->local->hash)(n);\
+ else\
+ {\
+ register const char* _hash_s1 = n;\
+ h = 0;\
+ if (r->namesize)\
+ {\
+ register const char* _hash_s2 = _hash_s1 + r->namesize;\
+ while (_hash_s1 < _hash_s2) HASHPART(h, *_hash_s1++);\
+ }\
+ else while (*_hash_s1) HASHPART(h, *_hash_s1++);\
+ }
+
+typedef struct /* library private info */
+{
+ Hash_root_t* list; /* root table list */
+} Hash_info_t;
+
+extern Hash_info_t hash_info;
+
+#endif
diff --git a/src/lib/libast/hash/hashlook.c b/src/lib/libast/hash/hashlook.c
new file mode 100644
index 0000000..4b0ae81
--- /dev/null
+++ b/src/lib/libast/hash/hashlook.c
@@ -0,0 +1,367 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * hash table library
+ */
+
+#include "hashlib.h"
+
+/*
+ * hash table lookup
+ */
+
+char*
+hashlook(register Hash_table_t* tab, const char* name, long flags, const char* value)
+{
+ register Hash_bucket_t* b;
+ register unsigned int n;
+ register Hash_last_t* last;
+ Hash_table_t* top;
+ Hash_bucket_t* prev;
+ unsigned int i;
+
+ if ((flags & (HASH_LOOKUP|HASH_INTERNAL)) == (HASH_LOOKUP|HASH_INTERNAL))
+ {
+ register char* s1;
+ register const char* s2;
+ register int c;
+
+ if (flags & HASH_HASHED) n = *((unsigned int*)value);
+ else
+ {
+ s2 = name;
+ n = 0;
+ while (c = *s2++) HASHPART(n, c);
+ }
+ i = n;
+ for (;;)
+ {
+ HASHMOD(tab, n);
+ for (b = tab->table[n]; b; b = b->next)
+ {
+ s1 = hashname(b);
+ s2 = name;
+ while ((c = *s1++) == *s2++)
+ if (!c) return((flags & HASH_VALUE) ? b->value : (char*)b);
+ }
+ if (!(tab = tab->scope) || (flags & HASH_NOSCOPE))
+ return(0);
+ n = i;
+ }
+ }
+ tab->root->accesses++;
+ top = tab;
+ last = &tab->root->last;
+ if (name)
+ {
+ last->table = tab;
+ if (flags & (HASH_BUCKET|HASH_INSTALL))
+ {
+ last->bucket = (Hash_bucket_t*)name;
+ name = hashname(last->bucket);
+ }
+ else last->bucket = 0;
+ last->name = name;
+ if (flags & HASH_BUCKET) n = last->bucket->hash;
+ else if (tab->flags & HASH_HASHED)
+ {
+ n = (unsigned int)integralof(name);
+ if (!(flags & HASH_HASHED)) n >>= 3;
+ }
+ else if (flags & HASH_HASHED) n = *((unsigned int*)value);
+ else HASH(tab->root, name, n);
+ last->hash = i = HASHVAL(n);
+ for (;;)
+ {
+ HASHMOD(tab, n);
+ for (prev = 0, b = tab->table[n]; b; prev = b, b = b->next)
+ {
+ if (i == HASHVAL(b->hash) && ((b->hash & (HASH_DELETED|HASH_OPAQUED)) != HASH_DELETED || (flags & (HASH_CREATE|HASH_DELETE|HASH_INSTALL|HASH_RENAME))))
+ {
+ if (!tab->root->local->compare)
+ {
+ register char* s1 = hashname(b);
+ register const char* s2 = name;
+
+ if (tab->root->namesize)
+ {
+ register char* s3 = s1 + tab->root->namesize;
+
+ while (*s1++ == *s2++)
+ if (s1 >= s3) goto found;
+ }
+ else while (*s1 == *s2++)
+ if (!*s1++) goto found;
+ }
+ else if (tab->root->namesize)
+ {
+ if (!(*tab->root->local->compare)(hashname(b), name, tab->root->namesize)) goto found;
+ }
+ else if (!(*tab->root->local->compare)(hashname(b), name)) goto found;
+ }
+ tab->root->collisions++;
+ }
+ if (!tab->scope || (flags & (HASH_CREATE|HASH_INSTALL|HASH_NOSCOPE)) == HASH_NOSCOPE) break;
+ tab = tab->scope;
+ n = i;
+ }
+ }
+ else
+ {
+ tab = last->table;
+ name = last->name;
+ n = i = last->hash;
+ prev = 0;
+ HASHMOD(tab, n);
+ if (b = last->bucket)
+ {
+ /*
+ * found the bucket
+ */
+
+ found:
+ if (prev && !tab->frozen)
+ {
+ /*
+ * migrate popular buckets to the front
+ */
+
+ prev->next = b->next;
+ b->next = tab->table[n];
+ tab->table[n] = b;
+ }
+ switch (flags & (HASH_CREATE|HASH_DELETE|HASH_INSTALL|HASH_RENAME))
+ {
+ case HASH_CREATE:
+ case HASH_CREATE|HASH_INSTALL:
+ case HASH_INSTALL:
+ if (tab != top && !(flags & HASH_SCOPE)) break;
+ if (flags & HASH_OPAQUE) b->hash |= HASH_OPAQUED;
+ goto exists;
+
+ case HASH_DELETE:
+ value = 0;
+ if (tab == top || (flags & HASH_SCOPE))
+ {
+ if (flags & HASH_OPAQUE) b->hash &= ~HASH_OPAQUED;
+ else if (!(tab->root->flags & HASH_BUCKET))
+ {
+ if (tab->root->local->free && b->value)
+ {
+ (*tab->root->local->free)(b->value);
+ b->value = 0;
+ }
+ else if (tab->flags & HASH_VALUE)
+ {
+ value = b->value;
+ b->value = 0;
+ }
+ }
+ tab->buckets--;
+ if (tab->frozen || (b->hash & HASH_OPAQUED)) b->hash |= HASH_DELETED;
+ else
+ {
+ tab->table[n] = b->next;
+ name = (b->hash & HASH_FREENAME) ? (char*)b->name : (char*)0;
+ if (tab->root->local->free && (tab->root->flags & HASH_BUCKET)) (*tab->root->local->free)((char*)b);
+ else if (!(b->hash & HASH_KEEP))
+ {
+ if (tab->root->local->region) (*tab->root->local->region)(tab->root->local->handle, b, 0, 0);
+ else free(b);
+ }
+ if (name)
+ {
+ if (tab->root->local->region) (*tab->root->local->region)(tab->root->local->handle, (char*)name, 0, 0);
+ else free((char*)name);
+ }
+ }
+ }
+ return((char*)value);
+
+ case HASH_RENAME:
+ if (tab != top || tab->frozen || (b->hash & (HASH_KEEP|HASH_OPAQUED)) || hashlook(top, value, (flags&(HASH_HASHED|HASH_INTERNAL))|HASH_LOOKUP, NiL))
+ return(0);
+ name = (char*)b->name;
+ if (!(tab->flags & HASH_ALLOCATE)) b->name = (char*)value;
+ else if (b->name && tab->root->namesize)
+ {
+ memcpy(b->name, value, tab->root->namesize);
+ name = 0;
+ }
+ else
+ {
+ int m;
+ char* t;
+
+ if (!(i = tab->bucketsize))
+ i = (sizeof(Hash_bucket_t) + sizeof(char*) - 1) / sizeof(char*);
+ i *= sizeof(char*);
+ m = strlen(value);
+ if (b->name == ((char*)b + i) && strlen(b->name) <= m)
+ {
+ strcpy(b->name, value);
+ name = 0;
+ }
+ else
+ {
+ m++;
+ if (!(t = tab->root->local->region ? (char*)(*tab->root->local->region)(tab->root->local->handle, NiL, m, 0) : (char*)malloc(m)))
+ return(0);
+ b->name = strcpy(t, value);
+ }
+ }
+ if (name && (b->hash & HASH_FREENAME))
+ {
+ b->hash &= ~HASH_FREENAME;
+ if (tab->root->local->region) (*tab->root->local->region)(tab->root->local->handle, (char*)name, 0, 0);
+ else free((char*)name);
+ }
+ tab->buckets--;
+ tab->table[n] = b->next;
+ flags = HASH_CREATE|HASH_INSTALL;
+ last->bucket = b;
+ i = last->hash;
+ goto create;
+
+ default:
+ if (!(b->hash & HASH_DELETED)) goto exists;
+ return(0);
+ }
+ }
+ }
+ if (!(flags & (HASH_CREATE|HASH_INSTALL))) return(0);
+
+ /*
+ * create a new bucket
+ */
+
+ create:
+ if (tab == top) prev = 0;
+ else
+ {
+ if (prev = b)
+ {
+ name = (b->hash & HASH_HIDES) ? b->name : (char*)b;
+ i |= HASH_HIDES;
+ }
+ if (!(flags & HASH_SCOPE)) tab = top;
+ }
+
+ /*
+ * check for table expansion
+ */
+
+ if (!tab->frozen && !(tab->flags & HASH_FIXED) && tab->buckets > tab->root->meanchain * tab->size)
+ hashsize(tab, tab->size << 1);
+ if (flags & HASH_INSTALL)
+ {
+ b = last->bucket;
+ i |= HASH_KEEP;
+ }
+ else
+ {
+ int m = tab->bucketsize * sizeof(char*);
+
+ if (flags & HASH_VALUE)
+ {
+ tab->flags |= HASH_VALUE;
+ if (m < sizeof(Hash_bucket_t))
+ {
+ tab->bucketsize = (sizeof(Hash_bucket_t) + sizeof(char*) - 1) / sizeof(char*);
+ m = tab->bucketsize * sizeof(char*);
+ }
+ n = m;
+ }
+ else if (!(n = HASH_SIZEOF(flags)))
+ {
+ if (!(flags & HASH_FIXED)) n = m;
+ else if ((n = (int)integralof(value)) < m) n = m;
+ }
+ else if (n < m) n = m;
+ if (!prev && (tab->flags & HASH_ALLOCATE))
+ {
+ m = tab->root->namesize ? tab->root->namesize : strlen(name) + 1;
+ if (tab->root->local->region)
+ {
+ if (!(b = (Hash_bucket_t*)(*tab->root->local->region)(tab->root->local->handle, NiL, n + m, 0)))
+ return(0);
+ memset(b, 0, n + m);
+ }
+ else if (!(b = newof(0, Hash_bucket_t, 0, n + m)))
+ return(0);
+ b->name = (char*)b + n;
+ memcpy(b->name, name, m);
+ }
+ else
+ {
+ if (tab->root->local->region)
+ {
+ if (!(b = (Hash_bucket_t*)(*tab->root->local->region)(tab->root->local->handle, NiL, n, 0)))
+ return(0);
+ memset(b, 0, n);
+ }
+ else if (!(b = newof(0, Hash_bucket_t, 0, n)))
+ return(0);
+ b->name = (char*)name;
+ }
+ }
+ b->hash = n = i;
+ HASHMOD(tab, n);
+ b->next = tab->table[n];
+ tab->table[n] = b;
+ tab->buckets++;
+ if (flags & HASH_OPAQUE)
+ {
+ tab->buckets--;
+ b->hash |= HASH_DELETED|HASH_OPAQUED;
+ return(0);
+ }
+
+ /*
+ * finally got the bucket
+ */
+
+ exists:
+ if (b->hash & HASH_DELETED)
+ {
+ b->hash &= ~HASH_DELETED;
+ tab->buckets++;
+ }
+ last->bucket = b;
+ last->table = tab;
+ switch (flags & (HASH_CREATE|HASH_VALUE))
+ {
+ case HASH_CREATE|HASH_VALUE:
+ if (tab->root->local->free && !(tab->root->flags & HASH_BUCKET) && b->value) (*tab->root->local->free)(b->value);
+ if (value && tab->root->local->alloc) value = (*tab->root->local->alloc)((unsigned int)integralof(value));
+ b->value = (char*)value;
+ return((char*)hashname(b));
+ case HASH_VALUE:
+ return(b->value);
+ default:
+ return((char*)b);
+ }
+}
diff --git a/src/lib/libast/hash/hashscan.c b/src/lib/libast/hash/hashscan.c
new file mode 100644
index 0000000..5162c08
--- /dev/null
+++ b/src/lib/libast/hash/hashscan.c
@@ -0,0 +1,139 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * hash table library
+ */
+
+#include "hashlib.h"
+
+/*
+ * hash table sequential scan
+ *
+ * Hash_position_t* pos;
+ * Hash_bucket_t* b;
+ * pos = hashscan(tab, flags);
+ * while (b = hashnext(&pos)) ...;
+ * hashdone(pos);
+ */
+
+/*
+ * return pos for scan on table
+ */
+
+Hash_position_t*
+hashscan(register Hash_table_t* tab, register int flags)
+{
+ register Hash_position_t* pos;
+
+ static Hash_bucket_t empty;
+
+ if (!(pos = newof(0, Hash_position_t, 1, 0))) return(0);
+ pos->tab = tab->root->last.table = tab;
+ pos->bucket = &empty;
+ pos->slot = tab->table - 1;
+ pos->limit = tab->table + tab->size;
+ if (tab->scope && !(flags & HASH_NOSCOPE))
+ {
+ pos->flags = HASH_SCOPE;
+ do
+ {
+ register Hash_bucket_t* b;
+
+ if (tab->frozen)
+ {
+ register Hash_bucket_t** sp = tab->table;
+ register Hash_bucket_t** sx = tab->table + tab->size;
+
+ while (sp < sx)
+ for (b = *sp++; b; b = b->next)
+ b->hash &= ~HASH_HIDDEN;
+ }
+ } while (tab = tab->scope);
+ tab = pos->tab;
+ }
+ else pos->flags = 0;
+ tab->frozen++;
+ return(pos);
+}
+
+/*
+ * return next scan element
+ */
+
+Hash_bucket_t*
+hashnext(register Hash_position_t* pos)
+{
+ register Hash_bucket_t* b;
+
+ if (!pos) return(0);
+ b = pos->bucket;
+ for (;;)
+ {
+ if (!(b = b->next))
+ {
+ do
+ {
+ if (++pos->slot >= pos->limit)
+ {
+ pos->tab->frozen--;
+ if (!pos->flags || !pos->tab->scope) return(0);
+ pos->tab = pos->tab->scope;
+ pos->tab->root->last.table = pos->tab;
+ pos->limit = (pos->slot = pos->tab->table) + pos->tab->size;
+ pos->tab->frozen++;
+ }
+ } while (!(b = *pos->slot));
+ }
+ if (!(b->hash & HASH_DELETED) && (!(pos->tab->flags & HASH_VALUE) || b->value) && (!pos->flags || !(b->hash & (HASH_HIDDEN|HASH_HIDES)))) break;
+ if (b->hash & HASH_HIDES)
+ {
+ register Hash_bucket_t* h = (Hash_bucket_t*)b->name;
+
+ if (!(h->hash & HASH_HIDDEN))
+ {
+ h->hash |= HASH_HIDDEN;
+ if (!(b->hash & HASH_DELETED)) break;
+ }
+ }
+ else b->hash &= ~HASH_HIDDEN;
+ }
+ return(pos->tab->root->last.bucket = pos->bucket = b);
+}
+
+/*
+ * terminate scan
+ */
+
+void
+hashdone(register Hash_position_t* pos)
+{
+ if (pos)
+ {
+ if (pos->tab->frozen)
+ pos->tab->frozen--;
+ free(pos);
+ }
+}
diff --git a/src/lib/libast/hash/hashsize.c b/src/lib/libast/hash/hashsize.c
new file mode 100644
index 0000000..0c458ba
--- /dev/null
+++ b/src/lib/libast/hash/hashsize.c
@@ -0,0 +1,84 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * hash table library
+ */
+
+#include "hashlib.h"
+
+/*
+ * change table size and rehash
+ * size must be a power of 2
+ */
+
+void
+hashsize(register Hash_table_t* tab, int size)
+{
+ register Hash_bucket_t** old_s;
+ register Hash_bucket_t** new_s;
+ register Hash_bucket_t* old_b;
+ register Hash_bucket_t* new_b;
+ Hash_bucket_t** old_sx;
+ unsigned int index;
+ Hash_region_f region;
+ void* handle;
+
+ if (size > 0 && size != tab->size && !(size & (size - 1)))
+ {
+ if (region = tab->root->local->region)
+ {
+ handle = tab->root->local->handle;
+ new_s = (Hash_bucket_t**)(*region)(handle, NiL, sizeof(Hash_bucket_t*) * size, 0);
+ }
+ else new_s = newof(0, Hash_bucket_t*, size, 0);
+ if (!new_s) tab->flags |= HASH_FIXED;
+ else
+ {
+ old_sx = (old_s = tab->table) + tab->size;
+ tab->size = size;
+ while (old_s < old_sx)
+ {
+ old_b = *old_s++;
+ while (old_b)
+ {
+ new_b = old_b;
+ old_b = old_b->next;
+ index = new_b->hash;
+ HASHMOD(tab, index);
+ new_b->next = new_s[index];
+ new_s[index] = new_b;
+ }
+ }
+ if ((tab->flags & (HASH_RESIZE|HASH_STATIC)) != HASH_STATIC)
+ {
+ if (region) (*region)(handle, tab->table, 0, 0);
+ else free(tab->table);
+ }
+ tab->table = new_s;
+ tab->flags |= HASH_RESIZE;
+ }
+ }
+}
diff --git a/src/lib/libast/hash/hashview.c b/src/lib/libast/hash/hashview.c
new file mode 100644
index 0000000..585f1a1
--- /dev/null
+++ b/src/lib/libast/hash/hashview.c
@@ -0,0 +1,88 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * hash table library
+ */
+
+#include "hashlib.h"
+
+/*
+ * push/pop/query hash table scope
+ *
+ * bot==0 pop top scope
+ * bot==top query
+ * bot!=0 push top on bot
+ *
+ * scope table pointer returned
+ */
+
+Hash_table_t*
+hashview(Hash_table_t* top, Hash_table_t* bot)
+{
+ register Hash_bucket_t* b;
+ register Hash_bucket_t* p;
+ register Hash_bucket_t** sp;
+ register Hash_bucket_t** sx;
+
+ if (!top || top->frozen)
+ bot = 0;
+ else if (top == bot)
+ bot = top->scope;
+ else if (bot)
+ {
+ if (top->scope)
+ bot = 0;
+ else
+ {
+ sx = &top->table[top->size];
+ sp = &top->table[0];
+ while (sp < sx)
+ for (b = *sp++; b; b = b->next)
+ if (p = (Hash_bucket_t*)hashlook(bot, b->name, HASH_LOOKUP, NiL))
+ {
+ b->name = (p->hash & HASH_HIDES) ? p->name : (char*)b;
+ b->hash |= HASH_HIDES;
+ }
+ top->scope = bot;
+ bot->frozen++;
+ }
+ }
+ else if (bot = top->scope)
+ {
+ sx = &top->table[top->size];
+ sp = &top->table[0];
+ while (sp < sx)
+ for (b = *sp++; b; b = b->next)
+ if (b->hash & HASH_HIDES)
+ {
+ b->hash &= ~HASH_HIDES;
+ b->name = ((Hash_bucket_t*)b->name)->name;
+ }
+ top->scope = 0;
+ bot->frozen--;
+ }
+ return(bot);
+}
diff --git a/src/lib/libast/hash/hashwalk.c b/src/lib/libast/hash/hashwalk.c
new file mode 100644
index 0000000..d3e4610
--- /dev/null
+++ b/src/lib/libast/hash/hashwalk.c
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * hash table library
+ */
+
+#include "hashlib.h"
+
+/*
+ * apply walker to each active bucket in the table
+ */
+
+int
+hashwalk(Hash_table_t* tab, int flags, register int (*walker)(const char*, char*, void*), void* handle)
+{
+ register Hash_bucket_t* b;
+ register int v;
+ Hash_position_t* pos;
+
+ if (!(pos = hashscan(tab, flags)))
+ return(-1);
+ v = 0;
+ while (b = hashnext(pos))
+ if ((v = (*walker)(hashname(b), (tab->flags & HASH_VALUE) ? b->value : (char*)b, handle)) < 0)
+ break;
+ hashdone(pos);
+ return(v);
+}
diff --git a/src/lib/libast/hash/memhash.c b/src/lib/libast/hash/memhash.c
new file mode 100644
index 0000000..24f6465
--- /dev/null
+++ b/src/lib/libast/hash/memhash.c
@@ -0,0 +1,45 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * hash table library
+ */
+
+#include "hashlib.h"
+
+/*
+ * return the hash of buffer s of length n
+ */
+
+unsigned int
+memhash(const void* as, int n)
+{
+ register const unsigned char* s = (const unsigned char*)as;
+ register const unsigned char* e = s + n;
+ register unsigned int c = 0;
+
+ while (s < e) HASHPART(c, *s++);
+ return(c);
+}
diff --git a/src/lib/libast/hash/memsum.c b/src/lib/libast/hash/memsum.c
new file mode 100644
index 0000000..c426215
--- /dev/null
+++ b/src/lib/libast/hash/memsum.c
@@ -0,0 +1,53 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * hash table library
+ */
+
+#include "hashlib.h"
+
+/*
+ * return a running 32 bit checksum of buffer b of length n
+ *
+ * c is the return value from a previous
+ * memsum() or strsum() call, 0 on the first call
+ *
+ * the result is the same on all implementations
+ */
+
+unsigned long
+memsum(const void* ap, int n, register unsigned long c)
+{
+ register const unsigned char* p = (const unsigned char*)ap;
+ register const unsigned char* e = p + n;
+
+ while (p < e) HASHPART(c, *p++);
+#if LONG_MAX > 2147483647
+ return(c & 0xffffffff);
+#else
+ return(c);
+#endif
+}
diff --git a/src/lib/libast/hash/strhash.c b/src/lib/libast/hash/strhash.c
new file mode 100644
index 0000000..e9f4976
--- /dev/null
+++ b/src/lib/libast/hash/strhash.c
@@ -0,0 +1,45 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * hash table library
+ */
+
+#include "hashlib.h"
+
+/*
+ * return the hash of the null terminated string s
+ */
+
+unsigned int
+strhash(const char* as)
+{
+ register const unsigned char* s = (const unsigned char*)as;
+ register unsigned int i = 0;
+ register unsigned int c;
+
+ while (c = *s++) HASHPART(i, c);
+ return(i);
+}
diff --git a/src/lib/libast/hash/strkey.c b/src/lib/libast/hash/strkey.c
new file mode 100644
index 0000000..3ff7ead
--- /dev/null
+++ b/src/lib/libast/hash/strkey.c
@@ -0,0 +1,49 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+#include <ast.h>
+#include <hashkey.h>
+
+long
+strkey(register const char* s)
+{
+ register long x = 0;
+ register int n = 0;
+ register int c;
+
+ while (n++ < HASHKEYMAX)
+ {
+ c = *s;
+ if (c >= 'a' && c <= 'z')
+ x = HASHKEYPART(x, c);
+ else if (c >= '0' && c <= '9')
+ x = HASHKEYPART(x, HASHKEYN(c));
+ else break;
+ s++;
+ }
+ return x;
+}
diff --git a/src/lib/libast/hash/strsum.c b/src/lib/libast/hash/strsum.c
new file mode 100644
index 0000000..92b413d
--- /dev/null
+++ b/src/lib/libast/hash/strsum.c
@@ -0,0 +1,53 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * hash table library
+ */
+
+#include "hashlib.h"
+
+/*
+ * return a running 32 bit checksum of string s
+ *
+ * c is the return value from a previous
+ * memsum() or strsum() call, 0 on the first call
+ *
+ * the result is the same on all implementations
+ */
+
+unsigned long
+strsum(const char* as, register unsigned long c)
+{
+ register const unsigned char* s = (const unsigned char*)as;
+ register int n;
+
+ while (n = *s++) HASHPART(c, n);
+#if LONG_MAX > 2147483647
+ return(c & 0xffffffff);
+#else
+ return(c);
+#endif
+}
diff --git a/src/lib/libast/include/aso.h b/src/lib/libast/include/aso.h
new file mode 100644
index 0000000..1007e93
--- /dev/null
+++ b/src/lib/libast/include/aso.h
@@ -0,0 +1,183 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#ifndef _ASO_H
+#define _ASO_H 1
+
+#define ASO_VERSION 20111111L
+
+#include <ast_common.h>
+
+/*
+ * ast atomic scalar operations interface definitions
+ */
+
+/* asometh() types (ordered mutually exclusive flags) */
+#define ASO_NEXT (-1)
+#define ASO_SIGNAL 1
+#define ASO_THREAD 2
+#define ASO_PROCESS 4
+#define ASO_INTRINSIC 8
+
+/* asolock() operations */
+#define ASO_UNLOCK 0 /* unlock if key matches */
+#define ASO_TRYLOCK 1 /* matched key means successful attempt */
+#define ASO_LOCK 2 /* matched key first, then spin-lock */
+#define ASO_SPINLOCK 3 /* no matching of key before locking */
+
+/* Asoerror_f types */
+#define ASO_EMETHOD 0 /* method specific error */
+#define ASO_EHUNG 1 /* asoloop() possibly hung */
+
+/* for internal use, but standardized for libs such as CDT and Vmalloc */
+#define ASO_RELAX ((1<<2)-1) /* cycles between spin-loop yield */
+#define ASOLOOP(k) asoloop(++(k))
+
+#define ASODISC(d,e) (memset(d,0,sizeof(*(d))),(d)->version=ASO_VERSION,(d)->errorf=(e))
+
+typedef int (*Asoerror_f)(int, const char*);
+typedef void* (*Asoinit_f)(void*, const char*);
+typedef ssize_t (*Asolock_f)(void*, ssize_t, void volatile*);
+
+typedef struct Asodisc_s
+{
+ uint32_t version;
+ unsigned int hung;
+ Asoerror_f errorf;
+} Asodisc_t;
+
+typedef struct Asometh_s
+{
+ const char* name;
+ int type;
+ Asoinit_f initf;
+ Asolock_f lockf;
+ const char* details;
+} Asometh_t;
+
+#if (_BLD_aso || _BLD_taso) && defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+#if !(_BLD_aso || _BLD_taso) && defined(__IMPORT__)
+#define extern extern __IMPORT__
+#endif
+
+extern Asometh_t* asometh(int, void*);
+
+#undef extern
+
+#if _BLD_aso && defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+#if !_BLD_aso && defined(__IMPORT__)
+#define extern extern __IMPORT__
+#endif
+
+extern Asometh_t* _asometh(int, void*);
+extern int asoinit(const char*, Asometh_t*, Asodisc_t*);
+extern int asolock(unsigned int volatile*, unsigned int, int);
+extern int asoloop(uintmax_t);
+extern int asorelax(long);
+
+extern uint8_t asocas8(uint8_t volatile*, int, int);
+extern uint8_t asoget8(uint8_t volatile*);
+extern uint8_t asoinc8(uint8_t volatile*);
+extern uint8_t asodec8(uint8_t volatile*);
+
+#define asocaschar(p,o,n) asocas8(p,o,n)
+#define asogetchar(p) asoget8(p)
+#define asoincchar(p) asoinc8(p)
+#define asodecchar(p) asodec8(p)
+
+extern uint16_t asocas16(uint16_t volatile*, uint16_t, uint16_t);
+extern uint16_t asoget16(uint16_t volatile*);
+extern uint16_t asoinc16(uint16_t volatile*);
+extern uint16_t asodec16(uint16_t volatile*);
+
+#define asocasshort(p,o,n) asocas16(p,o,n)
+#define asogetshort(p) asoget16(p)
+#define asoincshort(p) asoinc16(p)
+#define asodecshort(p) asodec16(p)
+
+extern uint32_t asocas32(uint32_t volatile*, uint32_t, uint32_t);
+extern uint32_t asoget32(uint32_t volatile*);
+extern uint32_t asoinc32(uint32_t volatile*);
+extern uint32_t asodec32(uint32_t volatile*);
+
+#if _ast_sizeof_int == 4
+#define asocasint(p,o,n) asocas32((uint32_t volatile*)p,o,n)
+#define asogetint(p) asoget32((uint32_t volatile*)p)
+#define asoincint(p) asoinc32((uint32_t volatile*)p)
+#define asodecint(p) asodec32((uint32_t volatile*)p)
+#endif
+
+#if _ast_sizeof_long == 4
+#define asocaslong(p,o,n) asocas32((uint32_t volatile*)p,o,n)
+#define asogetlong(p) asoget32((uint32_t volatile*)p)
+#define asoinclong(p) asoinc32((uint32_t volatile*)p)
+#define asodeclong(p) asodec32((uint32_t volatile*)p)
+#endif
+
+#if _ast_sizeof_size_t == 4
+#define asocassize(p,o,n) asocas32((uint32_t volatile*)p,o,n)
+#define asogetsize(p) asoget32((uint32_t volatile*)p)
+#define asoincsize(p) asoinc32((uint32_t volatile*)p)
+#define asodecsize(p) asodec32((uint32_t volatile*)p)
+#endif
+
+#ifdef _ast_int8_t
+
+extern uint64_t asocas64(uint64_t volatile*, uint64_t, uint64_t);
+extern uint64_t asoget64(uint64_t volatile*);
+extern uint64_t asoinc64(uint64_t volatile*);
+extern uint64_t asodec64(uint64_t volatile*);
+
+#if _ast_sizeof_int == 8
+#define asocasint(p,o,n) asocas64((uint64_t volatile*)p,o,n)
+#define asogetint(p) asoget64((uint64_t volatile*)p)
+#define asoincint(p) asoinc64((uint64_t volatile*)p)
+#define asodecint(p) asodec64((uint64_t volatile*)p)
+#endif
+
+#if _ast_sizeof_long == 8
+#define asocaslong(p,o,n) asocas64((uint64_t volatile*)p,o,n)
+#define asogetlong(p) asoget64((uint64_t volatile*)p)
+#define asoinclong(p) asoinc64((uint64_t volatile*)p)
+#define asodeclong(p) asodec64((uint64_t volatile*)p)
+#endif
+
+#if _ast_sizeof_size_t == 8
+#define asocassize(p,o,n) asocas64((uint64_t volatile*)p,o,n)
+#define asogetsize(p) asoget64((uint64_t volatile*)p)
+#define asoincsize(p) asoinc64((uint64_t volatile*)p)
+#define asodecsize(p) asodec64((uint64_t volatile*)p)
+#endif
+
+#endif
+
+extern void* asocasptr(void volatile*, void*, void*);
+extern void* asogetptr(void volatile*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/ast.h b/src/lib/libast/include/ast.h
new file mode 100644
index 0000000..719e7a9
--- /dev/null
+++ b/src/lib/libast/include/ast.h
@@ -0,0 +1,405 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Advanced Software Technology Library
+ * AT&T Research
+ *
+ * std + posix + ast
+ */
+
+#ifndef _AST_H
+#define _AST_H
+
+#ifndef _AST_STD_H
+#include <ast_std.h>
+#endif
+
+#ifndef _SFIO_H
+#include <sfio.h>
+#endif
+
+#ifndef ast
+#define ast _ast_info
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+/*
+ * workaround botched headers that assume <stdio.h>
+ */
+
+#ifndef FILE
+#ifndef _SFIO_H
+struct _sfio_s;
+#endif
+#define FILE struct _sfio_s
+#ifndef __FILE_typedef
+#define __FILE_typedef 1
+#endif
+#ifndef _FILEDEFED
+#define _FILEDEFED 1
+#endif
+#endif
+
+/*
+ * exit() support -- this matches shell exit codes
+ */
+
+#define EXIT_BITS 8 /* # exit status bits */
+
+#define EXIT_USAGE 2 /* usage exit code */
+#define EXIT_QUIT ((1<<(EXIT_BITS))-1) /* parent should quit */
+#define EXIT_NOTFOUND ((1<<(EXIT_BITS-1))-1) /* command not found */
+#define EXIT_NOEXEC ((1<<(EXIT_BITS-1))-2) /* other exec error */
+
+#define EXIT_CODE(x) ((x)&((1<<EXIT_BITS)-1))
+#define EXIT_CORE(x) (EXIT_CODE(x)|(1<<EXIT_BITS)|(1<<(EXIT_BITS-1)))
+#define EXIT_TERM(x) (EXIT_CODE(x)|(1<<EXIT_BITS))
+
+/*
+ * NOTE: for compatibility the following work for EXIT_BITS={7,8}
+ */
+
+#define EXIT_STATUS(x) (((x)&((1<<(EXIT_BITS-2))-1))?(x):EXIT_CODE((x)>>EXIT_BITS))
+
+#define EXITED_CORE(x) (((x)&((1<<EXIT_BITS)|(1<<(EXIT_BITS-1))))==((1<<EXIT_BITS)|(1<<(EXIT_BITS-1)))||((x)&((1<<(EXIT_BITS-1))|(1<<(EXIT_BITS-2))))==((1<<(EXIT_BITS-1))|(1<<(EXIT_BITS-2))))
+#define EXITED_TERM(x) ((x)&((1<<EXIT_BITS)|(1<<(EXIT_BITS-1))))
+
+/*
+ * astconflist() flags
+ */
+
+#define ASTCONF_parse 0x0001
+#define ASTCONF_write 0x0002
+#define ASTCONF_read 0x0004
+#define ASTCONF_lower 0x0008
+#define ASTCONF_base 0x0010
+#define ASTCONF_defined 0x0020
+#define ASTCONF_quote 0x0040
+#define ASTCONF_table 0x0080
+#define ASTCONF_matchcall 0x0100
+#define ASTCONF_matchname 0x0200
+#define ASTCONF_matchstandard 0x0400
+#define ASTCONF_error 0x0800
+#define ASTCONF_system 0x1000
+#define ASTCONF_AST 0x2000
+
+/*
+ * pathcanon() flags
+ */
+
+#define PATH_PHYSICAL 01
+#define PATH_DOTDOT 02
+#define PATH_EXISTS 04
+#define PATH_VERIFIED(n) (((n)&01777)<<5)
+
+/*
+ * pathaccess() flags
+ */
+
+#define PATH_READ 004
+#define PATH_WRITE 002
+#define PATH_EXECUTE 001
+#define PATH_REGULAR 010
+#define PATH_ABSOLUTE 020
+
+/*
+ * touch() flags
+ */
+
+#define PATH_TOUCH_CREATE 01
+#define PATH_TOUCH_VERBATIM 02
+
+/*
+ * pathcheck() info
+ */
+
+typedef struct
+{
+ unsigned long date;
+ char* feature;
+ char* host;
+ char* user;
+} Pathcheck_t;
+
+/*
+ * strgrpmatch() flags
+ */
+
+#define STR_MAXIMAL 01 /* maximal match */
+#define STR_LEFT 02 /* implicit left anchor */
+#define STR_RIGHT 04 /* implicit right anchor */
+#define STR_ICASE 010 /* ignore case */
+#define STR_GROUP 020 /* (|&) inside [@|&](...) only */
+
+/*
+ * fmtquote() flags
+ */
+
+#define FMT_ALWAYS 0x01 /* always quote */
+#define FMT_ESCAPED 0x02 /* already escaped */
+#define FMT_SHELL 0x04 /* escape $ ` too */
+#define FMT_WIDE 0x08 /* don't escape 8 bit chars */
+#define FMT_PARAM 0x10 /* disable FMT_SHELL ${$( quote */
+
+/*
+ * chrexp() flags
+ */
+
+#define FMT_EXP_CHAR 0x020 /* expand single byte chars */
+#define FMT_EXP_LINE 0x040 /* expand \n and \r */
+#define FMT_EXP_WIDE 0x080 /* expand \u \U \x wide chars */
+#define FMT_EXP_NOCR 0x100 /* skip \r */
+#define FMT_EXP_NONL 0x200 /* skip \n */
+
+/*
+ * multibyte macros
+ */
+
+#define mbmax() (ast.mb_cur_max)
+#define mberr() (ast.tmp_int<0)
+
+#define mbcoll() (ast.mb_xfrm!=0)
+#define mbwide() (mbmax()>1)
+
+#define mb2wc(w,p,n) (*ast.mb_towc)(&w,(char*)p,n)
+#define mbchar(p) (mbwide()?((ast.tmp_int=(*ast.mb_towc)(&ast.tmp_wchar,(char*)(p),mbmax()))>0?((p+=ast.tmp_int),ast.tmp_wchar):(p+=ast.mb_sync+1,ast.tmp_int)):(*(unsigned char*)(p++)))
+#define mbnchar(p,n) (mbwide()?((ast.tmp_int=(*ast.mb_towc)(&ast.tmp_wchar,(char*)(p),n))>0?((p+=ast.tmp_int),ast.tmp_wchar):(p+=ast.mb_sync+1,ast.tmp_int)):(*(unsigned char*)(p++)))
+#define mbinit() (mbwide()?(*ast.mb_towc)((wchar_t*)0,(char*)0,mbmax()):0)
+#define mbsize(p) (mbwide()?(*ast.mb_len)((char*)(p),mbmax()):((p),1))
+#define mbnsize(p,n) (mbwide()?(*ast.mb_len)((char*)(p),n):((p),1))
+#define mbconv(s,w) (ast.mb_conv?(*ast.mb_conv)(s,w):((*(s)=(w)),1))
+#define mbwidth(w) (ast.mb_width?(*ast.mb_width)(w):1)
+#define mbxfrm(t,f,n) (mbcoll()?(*ast.mb_xfrm)((char*)(t),(char*)(f),n):0)
+#define mbalpha(w) (ast.mb_alpha?(*ast.mb_alpha)(w):isalpha((w)&0xff))
+
+/*
+ * common macros
+ */
+
+#define elementsof(x) (sizeof(x)/sizeof(x[0]))
+#define integralof(x) (((char*)(x))-((char*)0))
+#define newof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)calloc(1,sizeof(t)*(n)+(x)))
+#define oldof(p,t,n,x) ((p)?(t*)realloc((char*)(p),sizeof(t)*(n)+(x)):(t*)malloc(sizeof(t)*(n)+(x)))
+#define pointerof(x) ((void*)((char*)0+(x)))
+#define roundof(x,y) (((x)+(y)-1)&~((y)-1))
+#define ssizeof(x) ((int)sizeof(x))
+
+#define streq(a,b) (*(a)==*(b)&&!strcmp(a,b))
+#define strneq(a,b,n) (*(a)==*(b)&&!strncmp(a,b,n))
+#define strsignal(s) fmtsignal(s)
+
+#if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
+#define NiL 0
+#define NoP(x) (void)(x)
+#else
+#define NiL ((char*)0)
+#define NoP(x) (&x,1)
+#endif
+
+#if !defined(NoF)
+#define NoF(x) void _DATA_ ## x () {}
+#if !defined(_DATA_)
+#define _DATA_
+#endif
+#endif
+
+#if !defined(NoN)
+#define NoN(x) void _STUB_ ## x () {}
+#if !defined(_STUB_)
+#define _STUB_
+#endif
+#endif
+
+#define NOT_USED(x) NoP(x)
+
+typedef int (*Error_f)(void*, void*, int, ...);
+
+typedef int (*Ast_confdisc_f)(const char*, const char*, const char*);
+typedef int (*Strcmp_context_f)(const char*, const char*, void*);
+typedef int (*Strcmp_f)(const char*, const char*);
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char* astgetconf(const char*, const char*, const char*, int, Error_f);
+extern char* astconf(const char*, const char*, const char*);
+extern Ast_confdisc_f astconfdisc(Ast_confdisc_f);
+extern void astconflist(Sfio_t*, const char*, int, const char*);
+extern off_t astcopy(int, int, off_t);
+extern int astlicense(char*, int, char*, char*, int, int, int);
+extern int astquery(int, const char*, ...);
+extern void astwinsize(int, int*, int*);
+
+extern ssize_t base64encode(const void*, size_t, void**, void*, size_t, void**);
+extern ssize_t base64decode(const void*, size_t, void**, void*, size_t, void**);
+extern int chresc(const char*, char**);
+extern int chrexp(const char*, char**, int*, int);
+extern int chrtoi(const char*);
+extern char* conformance(const char*, size_t);
+extern int eaccess(const char*, int);
+extern char* fmtbase(intmax_t, int, int);
+#define fmtbasell(a,b,c) fmtbase(a,b,c) /* until 2014-01-01 */
+extern char* fmtbuf(size_t);
+extern char* fmtclock(Sfulong_t);
+extern char* fmtelapsed(unsigned long, int);
+extern char* fmterror(int);
+extern char* fmtesc(const char*);
+extern char* fmtesq(const char*, const char*);
+extern char* fmtident(const char*);
+extern char* fmtip4(uint32_t, int);
+extern char* fmtfmt(const char*);
+extern char* fmtgid(int);
+extern char* fmtint(intmax_t, int);
+extern char* fmtmatch(const char*);
+extern char* fmtmode(int, int);
+extern char* fmtnesq(const char*, const char*, size_t);
+extern char* fmtnum(unsigned long, int);
+extern char* fmtperm(int);
+extern char* fmtquote(const char*, const char*, const char*, size_t, int);
+extern char* fmtre(const char*);
+extern char* fmtscale(Sfulong_t, int);
+extern char* fmtsignal(int);
+extern char* fmttime(const char*, time_t);
+extern char* fmtuid(int);
+extern char* fmtversion(unsigned long);
+extern void* memdup(const void*, size_t);
+extern void memfatal(void);
+extern unsigned int memhash(const void*, int);
+extern unsigned long memsum(const void*, int, unsigned long);
+extern char* pathaccess(char*, const char*, const char*, const char*, int);
+extern char* pathaccess_20100601(const char*, const char*, const char*, int, char*, size_t);
+extern char* pathbin(void);
+extern char* pathcanon(char*, int);
+extern char* pathcanon_20100601(char*, size_t, int);
+extern char* pathcat(char*, const char*, int, const char*, const char*);
+extern char* pathcat_20100601(const char*, int, const char*, const char*, char*, size_t);
+extern int pathcd(const char*, const char*);
+extern int pathcheck(const char*, const char*, Pathcheck_t*);
+extern int pathexists(char*, int);
+extern char* pathfind(const char*, const char*, const char*, char*, size_t);
+extern int pathgetlink(const char*, char*, int);
+extern int pathinclude(const char*);
+extern char* pathkey(char*, char*, const char*, const char*, const char*);
+extern char* pathkey_20100601(const char*, const char*, const char*, char*, size_t, char*, size_t);
+extern size_t pathnative(const char*, char*, size_t);
+extern char* pathpath(char*, const char*, const char*, int);
+extern char* pathpath_20100601(const char*, const char*, int, char*, size_t);
+extern size_t pathposix(const char*, char*, size_t);
+extern char* pathprobe(char*, char*, const char*, const char*, const char*, int);
+extern char* pathprobe_20100601(const char*, const char*, const char*, int, char*, size_t, char*, size_t);
+extern size_t pathprog(const char*, char*, size_t);
+extern char* pathrepl(char*, const char*, const char*);
+extern char* pathrepl_20100601(char*, size_t, const char*, const char*);
+extern int pathsetlink(const char*, const char*);
+extern char* pathshell(void);
+extern char* pathtemp(char*, size_t, const char*, const char*, int*);
+extern char* pathtmp(char*, const char*, const char*, int*);
+extern char* setenviron(const char*);
+extern int stracmp(const char*, const char*);
+extern char* strcopy(char*, const char*);
+extern unsigned long strelapsed(const char*, char**, int);
+extern int stresc(char*);
+extern int strexp(char*, int);
+extern long streval(const char*, char**, long(*)(const char*, char**));
+extern long strexpr(const char*, char**, long(*)(const char*, char**, void*), void*);
+extern int strgid(const char*);
+extern int strgrpmatch(const char*, const char*, int*, int, int);
+extern unsigned int strhash(const char*);
+extern void* strlook(const void*, size_t, const char*);
+extern int strmatch(const char*, const char*);
+extern int strmode(const char*);
+extern int strnacmp(const char*, const char*, size_t);
+extern char* strncopy(char*, const char*, size_t);
+extern int strnpcmp(const char*, const char*, size_t);
+extern double strntod(const char*, size_t, char**);
+extern _ast_fltmax_t strntold(const char*, size_t, char**);
+extern long strntol(const char*, size_t, char**, int);
+extern intmax_t strntoll(const char*, size_t, char**, int);
+extern long strnton(const char*, size_t, char**, char*, int);
+extern unsigned long strntoul(const char*, size_t, char**, int);
+extern intmax_t strntonll(const char*, size_t, char**, char*, int);
+extern uintmax_t strntoull(const char*, size_t, char**, int);
+extern int strnvcmp(const char*, const char*, size_t);
+extern int stropt(const char*, const void*, int, int(*)(void*, const void*, int, const char*), void*);
+extern int strpcmp(const char*, const char*);
+extern int strperm(const char*, char**, int);
+extern void* strpsearch(const void*, size_t, size_t, const char*, char**);
+extern void* strsearch(const void*, size_t, size_t, Strcmp_f, const char*, void*);
+extern void strsort(char**, int, int(*)(const char*, const char*));
+extern char* strsubmatch(const char*, const char*, int);
+extern unsigned long strsum(const char*, unsigned long);
+extern char* strtape(const char*, char**);
+extern int strtoip4(const char*, char**, uint32_t*, unsigned char*);
+extern long strton(const char*, char**, char*, int);
+extern intmax_t strtonll(const char*, char**, char*, int);
+extern int struid(const char*);
+extern int struniq(char**, int);
+extern int strvcmp(const char*, const char*);
+extern int wc2utf8(char*, uint32_t);
+
+#undef extern
+
+/*
+ * C library global data symbols not prototyped by <unistd.h>
+ */
+
+#if !defined(environ) && defined(__DYNAMIC__)
+#define environ __DYNAMIC__(environ)
+#else
+extern char** environ;
+#endif
+
+/*
+ * really handy malloc()/free() (__FILE__,__LINE__,__FUNCTION__) tracing
+ * make with VMDEBUG==1 or debug=1 or CCFLAGS=$(CC.DEBUG)
+ * VMDEBUG==0 disables
+ * at runtime export VMALLOC_OPTIONS per vmalloc.3
+ * to list originating call locations
+ */
+
+#if !_std_malloc && !defined(VMFL) && !defined(_VMHDR_H) && \
+ (VMDEBUG || !defined(VMDEBUG) && _BLD_DEBUG)
+
+#define VMFL 1
+#include <vmalloc.h>
+
+#endif
+
+#include <ast_api.h>
+
+#undef AST_PLUGIN_VERSION
+#define AST_PLUGIN_VERSION(v) ((v)>AST_VERSION?(v):AST_VERSION)
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern unsigned long plugin_version(void);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/ast_dir.h b/src/lib/libast/include/ast_dir.h
new file mode 100644
index 0000000..260d4b6
--- /dev/null
+++ b/src/lib/libast/include/ast_dir.h
@@ -0,0 +1,77 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * AT&T Research
+ *
+ * common dirent maintenance interface
+ */
+
+#ifndef _AST_DIR_H
+#define _AST_DIR_H
+
+#include <ast_lib.h>
+
+#if _mem_d_fileno_dirent || _mem_d_ino_dirent
+#if !_mem_d_fileno_dirent
+#undef _mem_d_fileno_dirent
+#define _mem_d_fileno_dirent 1
+#define d_fileno d_ino
+#endif
+#endif
+
+#if _BLD_ast
+#include "dirlib.h"
+#else
+#include <dirent.h>
+#endif
+
+#if _mem_d_fileno_dirent
+#define D_FILENO(d) ((d)->d_fileno)
+#endif
+
+#if _mem_d_namlen_dirent
+#define D_NAMLEN(d) ((d)->d_namlen)
+#else
+#define D_NAMLEN(d) (strlen((d)->d_name))
+#endif
+
+#if _mem_d_reclen_dirent
+#define D_RECLEN(d) ((d)->d_reclen)
+#else
+#define D_RECLEN(d) D_RECSIZ(d,D_NAMLEN(d))
+#endif
+
+#define D_RECSIZ(d,n) (sizeof(*(d))-sizeof((d)->d_name)+((n)+sizeof(char*))&~(sizeof(char*)-1))
+
+/*
+ * NOTE: 2003-03-27 mac osx bug symlink==DT_REG bug discovered;
+ * the kernel *and* all directories must be fixed, so d_type
+ * is summarily disabled until we see that happen
+ */
+
+#if _mem_d_type_dirent && defined(DT_UNKNOWN) && defined(DT_REG) && defined(DT_DIR) && defined(DT_LNK) && ! ( __APPLE__ || __MACH__ )
+#define D_TYPE(d) ((d)->d_type)
+#endif
+
+#endif
diff --git a/src/lib/libast/include/ast_getopt.h b/src/lib/libast/include/ast_getopt.h
new file mode 100644
index 0000000..cf5efd3
--- /dev/null
+++ b/src/lib/libast/include/ast_getopt.h
@@ -0,0 +1,42 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * legacy standard getopt interface
+ */
+
+#ifdef _AST_STD_I
+#undef _AST_GETOPT_H
+#define _AST_GETOPT_H -1
+#endif
+#ifndef _AST_GETOPT_H
+#define _AST_GETOPT_H 1
+
+extern int opterr;
+extern int optind;
+extern int optopt;
+extern char* optarg;
+
+extern int getopt(int, char* const*, const char*);
+extern int getsubopt(char**, char* const*, char**);
+
+#endif
diff --git a/src/lib/libast/include/ast_std.h b/src/lib/libast/include/ast_std.h
new file mode 100644
index 0000000..03f4fb3
--- /dev/null
+++ b/src/lib/libast/include/ast_std.h
@@ -0,0 +1,362 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Advanced Software Technology Library
+ * AT&T Research
+ *
+ * a union of standard headers that works
+ * with local extensions enabled
+ * and local omission compensation
+ */
+
+#ifndef _AST_STD_H
+#define _AST_STD_H 1
+#define _AST_STD_I 1
+
+#include <ast_common.h>
+
+#if _BLD_ast
+#define _BLD_aso 1
+#define _BLD_cdt 1
+#define _BLD_sfio 1
+#if !_UWIN
+#define _BLD_vmalloc 1
+#endif
+#endif
+
+#ifdef _SFSTDIO_H
+#define _SKIP_SFSTDIO_H
+#else
+#define _SFSTDIO_H
+#ifndef FILE
+#ifndef _SFIO_H
+struct _sfio_s;
+#endif
+#define FILE struct _sfio_s
+#ifndef __FILE_typedef
+#define __FILE_typedef 1
+#endif
+#ifndef _FILEDEFED
+#define _FILEDEFED 1
+#endif
+#endif
+#endif
+
+#include <ast_lib.h>
+#include <ast_sys.h>
+#include <ast_getopt.h> /* <stdlib.h> does this */
+#include <ast_fcntl.h>
+#include <ast_limits.h>
+#include <ast_botch.h>
+
+#ifdef _SKIP_SFSTDIO_H
+#undef _SKIP_SFSTDIO_H
+#else
+#undef _SFSTDIO_H
+#undef FILE
+#endif
+
+/* locale stuff */
+
+#if !_hdr_locale
+
+struct lconv
+{
+ char* decimal_point;
+ char* thousands_sep;
+ char* grouping;
+ char* int_curr_symbol;
+ char* currency_symbol;
+ char* mon_decimal_point;
+ char* mon_thousands_sep;
+ char* mon_grouping;
+ char* positive_sign;
+ char* negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+};
+
+#endif
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#if !_UWIN /* for ast54 compatibility */
+
+#undef getenv
+#define getenv _ast_getenv
+
+#undef setenviron
+#define setenviron _ast_setenviron
+
+extern char* getenv(const char*);
+
+#endif
+
+#undef localeconv
+#define localeconv _ast_localeconv
+
+#undef setlocale
+#define setlocale _ast_setlocale
+
+#undef strerror
+#define strerror _ast_strerror
+
+extern struct lconv* localeconv(void);
+extern char* setenviron(const char*);
+extern char* setlocale(int, const char*);
+extern char* strerror(int);
+
+#define AST_MESSAGE_SET 3 /* see <mc.h> mcindex() */
+
+/*
+ * maintain this order when adding categories
+ */
+
+#define AST_LC_ALL 0
+#define AST_LC_COLLATE 1
+#define AST_LC_CTYPE 2
+#define AST_LC_MESSAGES 3
+#define AST_LC_MONETARY 4
+#define AST_LC_NUMERIC 5
+#define AST_LC_TIME 6
+#define AST_LC_IDENTIFICATION 7
+#define AST_LC_ADDRESS 8
+#define AST_LC_NAME 9
+#define AST_LC_TELEPHONE 10
+#define AST_LC_XLITERATE 11
+#define AST_LC_MEASUREMENT 12
+#define AST_LC_PAPER 13
+#define AST_LC_COUNT 14
+#define AST_LC_LANG 255
+
+#define AST_LC_internal 1
+#define AST_LC_test (1L<<26)
+#define AST_LC_setenv (1L<<27)
+#define AST_LC_find (1L<<28)
+#define AST_LC_debug (1L<<29)
+#define AST_LC_setlocale (1L<<30)
+#define AST_LC_translate (1L<<31)
+
+#ifndef LC_ALL
+#define LC_ALL (-AST_LC_ALL)
+#endif
+#ifndef LC_COLLATE
+#define LC_COLLATE (-AST_LC_COLLATE)
+#endif
+#ifndef LC_CTYPE
+#define LC_CTYPE (-AST_LC_CTYPE)
+#endif
+#ifndef LC_MESSAGES
+#define LC_MESSAGES (-AST_LC_MESSAGES)
+#endif
+#ifndef LC_MONETARY
+#define LC_MONETARY (-AST_LC_MONETARY)
+#endif
+#ifndef LC_NUMERIC
+#define LC_NUMERIC (-AST_LC_NUMERIC)
+#endif
+#ifndef LC_TIME
+#define LC_TIME (-AST_LC_TIME)
+#endif
+#ifndef LC_ADDRESS
+#define LC_ADDRESS (-AST_LC_ADDRESS)
+#endif
+#ifndef LC_IDENTIFICATION
+#define LC_IDENTIFICATION (-AST_LC_IDENTIFICATION)
+#endif
+#ifndef LC_NAME
+#define LC_NAME (-AST_LC_NAME)
+#endif
+#ifndef LC_TELEPHONE
+#define LC_TELEPHONE (-AST_LC_TELEPHONE)
+#endif
+#ifndef LC_XLITERATE
+#define LC_XLITERATE (-AST_LC_XLITERATE)
+#endif
+#ifndef LC_MEASUREMENT
+#define LC_MEASUREMENT (-AST_LC_MEASUREMENT)
+#endif
+#ifndef LC_PAPER
+#define LC_PAPER (-AST_LC_PAPER)
+#endif
+#ifndef LC_LANG
+#define LC_LANG (-AST_LC_LANG)
+#endif
+
+#undef extern
+
+#undef strcoll
+#if _std_strcoll
+#define strcoll _ast_info.collate
+#else
+#define strcoll strcmp
+#endif
+
+typedef struct
+{
+
+ char* id;
+
+ struct
+ {
+ uint32_t serial;
+ uint32_t set;
+ } locale;
+
+ long tmp_long;
+ size_t tmp_size;
+ short tmp_short;
+ char tmp_char;
+ wchar_t tmp_wchar;
+
+ int (*collate)(const char*, const char*);
+
+ int tmp_int;
+ void* tmp_pointer;
+
+ int mb_cur_max;
+ int (*mb_len)(const char*, size_t);
+ int (*mb_towc)(wchar_t*, const char*, size_t);
+ size_t (*mb_xfrm)(char*, const char*, size_t);
+ int (*mb_width)(wchar_t);
+ int (*mb_conv)(char*, wchar_t);
+
+ uint32_t env_serial;
+ uint32_t mb_sync;
+ uint32_t version;
+
+ int (*mb_alpha)(wchar_t);
+
+ char pad[936 - sizeof(void*)];
+
+} _Ast_info_t;
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+#if !_BLD_ast && defined(__IMPORT__)
+#define extern extern __IMPORT__
+#endif
+
+extern _Ast_info_t _ast_info;
+
+#undef extern
+
+/* largefile hackery -- ast uses the large versions by default */
+
+#if _typ_off64_t
+#undef off_t
+#define off_t off64_t
+#endif
+#if !defined(ftruncate) && _lib_ftruncate64
+#define ftruncate ftruncate64
+extern int ftruncate64(int, off64_t);
+#endif
+#if !defined(lseek) && _lib_lseek64
+#define lseek lseek64
+extern off64_t lseek64(int, off64_t, int);
+#endif
+#if !defined(truncate) && _lib_truncate64
+#define truncate truncate64
+extern int truncate64(const char*, off64_t);
+#endif
+
+/* direct macro access for bsd crossover */
+
+#if !defined(__cplusplus)
+
+#if !defined(memcpy) && !defined(_lib_memcpy) && defined(_lib_bcopy)
+#define memcpy(t,f,n) (bcopy(f,t,n),(t))
+#endif
+
+#if !defined(memzero) && !defined(_lib_memzero)
+#if defined(_lib_memset) || !defined(_lib_bzero)
+#define memzero(b,n) memset(b,0,n)
+#else
+#define memzero(b,n) (bzero(b,n),(b))
+#endif
+#endif
+
+#endif
+
+#if !defined(remove)
+extern int remove(const char*);
+#endif
+
+#if !defined(rename)
+extern int rename(const char*, const char*);
+#endif
+
+#if !defined(strchr) && !defined(_lib_strchr) && defined(_lib_index)
+#define strchr(s,c) index(s,c)
+#endif
+
+#if !defined(strrchr) && !defined(_lib_strrchr) && defined(_lib_rindex)
+#define strrchr(s,c) rindex(s,c)
+#endif
+
+/* and now introducing prototypes botched by the standard(s) */
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#undef getpgrp
+#define getpgrp() _ast_getpgrp()
+extern int _ast_getpgrp(void);
+
+#undef extern
+
+/*
+ * and finally, standard interfaces hijacked by ast
+ * _AST_STD_I delays headers that require <ast_map.h>
+ */
+
+#include <ast_map.h>
+
+#undef _AST_STD_I
+
+#if _AST_GETOPT_H < 0
+#undef _AST_GETOPT_H
+#include <ast_getopt.h>
+#endif
+
+#if _GETOPT_H < 0
+#undef _GETOPT_H
+#include <getopt.h>
+#endif
+
+#if _REGEX_H < 0
+#undef _REGEX_H
+#include <regex.h>
+#endif
+
+#endif
diff --git a/src/lib/libast/include/ast_windows.h b/src/lib/libast/include/ast_windows.h
new file mode 100644
index 0000000..ed853e9
--- /dev/null
+++ b/src/lib/libast/include/ast_windows.h
@@ -0,0 +1,39 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * AT&T Research
+ *
+ * ast <windows.h> wrapper
+ * for libast only
+ * include after ast headers
+ */
+
+#ifndef _AST_WINDOWS_H
+#define _AST_WINDOWS_H 1
+
+#undef SF_ERROR /* clash in <oaidl.h> */
+
+#include <windows.h>
+
+#endif
diff --git a/src/lib/libast/include/ccode.h b/src/lib/libast/include/ccode.h
new file mode 100644
index 0000000..1335c85
--- /dev/null
+++ b/src/lib/libast/include/ccode.h
@@ -0,0 +1,90 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * character code map interface
+ *
+ * NOTE: used for mapping between 8-bit character encodings
+ * ISO character sets are handled by sfio
+ */
+
+#ifndef _CHARCODE_H
+#define _CHARCODE_H 1
+
+#include <ast_common.h>
+#include <ast_ccode.h>
+
+typedef struct Ccmap_s
+{
+ const char* name; /* code set name */
+ const char* match; /* strmatch() pattern */
+ const char* desc; /* code set description */
+ const char* canon; /* canonical name format */
+ const char* index; /* default index */
+ int ccode; /* <ccode.h> code index */
+ void* data; /* map specific data */
+} Ccmap_t;
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern unsigned char* _ccmap(int, int);
+extern void* _ccmapcpy(unsigned char*, void*, const void*, size_t);
+extern void* _ccmapstr(unsigned char*, void*, size_t);
+
+extern int ccmapid(const char*);
+extern char* ccmapname(int);
+extern void* ccnative(void*, const void*, size_t);
+extern Ccmap_t* ccmaplist(Ccmap_t*);
+
+#undef extern
+
+#define CCOP(i,o) ((i)==(o)?0:(((o)<<8)|(i)))
+#define CCIN(x) ((x)&0xFF)
+#define CCOUT(x) (((x)>>8)&0xFF)
+#define CCCONVERT(x) ((x)&0xFF00)
+
+#define CCCVT(x) CCMAP(x,0)
+#define CCMAP(i,o) ((i)==(o)?(unsigned char*)0:_ccmap(i,o))
+#define CCMAPCHR(m,c) ((m)?(m)[c]:(c))
+#define CCMAPCPY(m,t,f,n) ((m)?_ccmapcpy(m,t,f,n):memcpy(t,f,n))
+#define CCMAPSTR(m,s,n) ((m)?_ccmapstr(m,s,n):(void*)(s))
+
+#define ccmap(i,o) CCMAP(i,o)
+#define ccmapchr(m,c) CCMAPCHR(m,c)
+#define ccmapcpy(m,t,f,n) CCMAPCPY(m,t,f,n)
+#define ccmapstr(m,s,n) CCMAPSTR(m,s,n)
+
+#define CCMAPC(c,i,o) ((i)==(o)?(c):CCMAP(i,o)[c])
+#define CCMAPM(t,f,n,i,o) ((i)==(o)?memcpy(t,f,n):_ccmapcpy(CCMAP(i,o),t,f,n))
+#define CCMAPS(s,n,i,o) ((i)==(o)?(void*)(s):_ccmapstr(CCMAP(i,o),s,n))
+
+#define ccmapc(c,i,o) CCMAPC(c,i,o)
+#define ccmapm(t,f,n,i,o) CCMAPM(t,f,n,i,o)
+#define ccmaps(s,n,i,o) CCMAPS(s,n,i,o)
+
+#endif
diff --git a/src/lib/libast/include/cdt.h b/src/lib/libast/include/cdt.h
new file mode 100644
index 0000000..b757e74
--- /dev/null
+++ b/src/lib/libast/include/cdt.h
@@ -0,0 +1,354 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _CDT_H
+#define _CDT_H 1
+
+/* Public interface for the dictionary library
+**
+** Written by Kiem-Phong Vo
+*/
+
+#ifndef CDT_VERSION
+#ifdef _API_ast
+#define CDT_VERSION _API_ast
+#else
+#define CDT_VERSION 20111111L
+#endif /*_AST_api*/
+#endif /*CDT_VERSION*/
+#ifndef AST_PLUGIN_VERSION
+#define AST_PLUGIN_VERSION(v) (v)
+#endif
+#define CDT_PLUGIN_VERSION AST_PLUGIN_VERSION(20111111L)
+
+#if _PACKAGE_ast
+#include <ast_std.h>
+#else
+#include <ast_common.h>
+#include <string.h>
+#endif
+
+/* commonly used integers */
+#define DT_ZERO ((unsigned int)0) /* all zero bits */
+#define DT_ONES (~DT_ZERO) /* all one bits */
+#define DT_HIBIT (~(DT_ONES >> 1) ) /* highest 1 bit */
+#define DT_LOBIT ((unsigned int)1) /* lowest 1 bit */
+#define DT_NBITS (sizeof(unsigned int)*8) /* #bits */
+
+/* type of an integer with the same size as a pointer */
+#define Dtuint_t uintptr_t
+
+/* various types used by CDT */
+typedef struct _dtlink_s Dtlink_t;
+typedef struct _dthold_s Dthold_t;
+typedef struct _dtdisc_s Dtdisc_t;
+typedef struct _dtmethod_s Dtmethod_t;
+typedef struct _dtdata_s Dtdata_t;
+typedef struct _dtuser_s Dtuser_t;
+typedef struct _dt_s Dt_t;
+typedef struct _dtstat_s Dtstat_t;
+typedef Void_t* (*Dtsearch_f)_ARG_((Dt_t*,Void_t*,int));
+typedef Void_t* (*Dtmake_f)_ARG_((Dt_t*,Void_t*,Dtdisc_t*));
+typedef void (*Dtfree_f)_ARG_((Dt_t*,Void_t*,Dtdisc_t*));
+typedef int (*Dtcompar_f)_ARG_((Dt_t*,Void_t*,Void_t*,Dtdisc_t*));
+typedef unsigned int (*Dthash_f)_ARG_((Dt_t*,Void_t*,Dtdisc_t*));
+typedef Void_t* (*Dtmemory_f)_ARG_((Dt_t*,Void_t*,size_t,Dtdisc_t*));
+typedef int (*Dtevent_f)_ARG_((Dt_t*,int,Void_t*,Dtdisc_t*));
+typedef int (*Dttype_f)_ARG_((Dt_t*,int));
+
+struct _dtuser_s /* for application to access and use */
+{ unsigned int lock; /* used by dtapplock */
+ Void_t* data; /* for whatever data */
+};
+
+struct _dtlink_s
+{
+#if CDT_VERSION < 20111111L
+ Dtlink_t* right; /* right child */
+ union
+ { unsigned int _hash; /* hash value */
+ Dtlink_t* _left; /* left child */
+ } hl;
+#else
+ union
+ { Dtlink_t* __rght; /* right child or next */
+ Dtlink_t* __ptbl; /* Dtrehash parent tbl */
+ } rh;
+ union
+ { Dtlink_t* __left; /* left child or prev */
+ unsigned int __hash; /* hash value of object */
+ } lh;
+#endif
+};
+
+/* private structure to hold an object */
+struct _dthold_s
+{ Dtlink_t hdr; /* header to hold obj */
+ Void_t* obj; /* application object */
+};
+
+/* method to manipulate dictionary structure */
+struct _dtmethod_s
+{ Dtsearch_f searchf; /* search function */
+ unsigned int type; /* type of operation */
+ int (*eventf)_ARG_((Dt_t*, int, Void_t*));
+ char* name; /* name of method */
+ char* description; /* description */
+};
+
+/* structure to hold methods that manipulate an object */
+struct _dtdisc_s
+{ int key; /* where the key resides */
+ int size; /* key size and type */
+ int link; /* offset to Dtlink_t field */
+ Dtmake_f makef; /* object constructor */
+ Dtfree_f freef; /* object destructor */
+ Dtcompar_f comparf;/* to compare two objects */
+ Dthash_f hashf; /* to compute hash value */
+ Dtmemory_f memoryf;/* to allocate/free memory */
+ Dtevent_f eventf; /* to process events */
+};
+
+#define DTDISC(dc,ky,sz,lk,mkf,frf,cmpf,hshf,memf,evf) \
+ ( (dc)->key = (int)(ky), (dc)->size = (int)(sz), (dc)->link = (int)(lk), \
+ (dc)->makef = (mkf), (dc)->freef = (frf), \
+ (dc)->comparf = (cmpf), (dc)->hashf = (hshf), \
+ (dc)->memoryf = (memf), (dc)->eventf = (evf) )
+
+#ifdef offsetof
+#define DTOFFSET(struct_s, member) offsetof(struct_s, member)
+#else
+#define DTOFFSET(struct_s, member) ((int)(&((struct_s*)0)->member))
+#endif
+
+/* the dictionary structure itself */
+struct _dt_s
+{ Dtsearch_f searchf;/* search function */
+ Dtdisc_t* disc; /* object type definitition */
+ Dtdata_t* data; /* sharable data */
+ Dtmemory_f memoryf;/* for memory allocation */
+ Dtmethod_t* meth; /* storage method */
+ ssize_t nview; /* #parent view dictionaries */
+ Dt_t* view; /* next on viewpath */
+ Dt_t* walk; /* dictionary being walked */
+ Dtuser_t* user; /* for user's usage */
+ Dttype_f typef; /* for binary compatibility */
+};
+
+/* structure to get status of a dictionary */
+#define DT_MAXRECURSE 1024 /* limit to avoid stack overflow */
+#define DT_MAXSIZE 256 /* limit for size of below arrays */
+struct _dtstat_s
+{ unsigned int meth; /* method type */
+ ssize_t size; /* total # of elements in dictionary */
+ ssize_t space; /* memory usage of data structure */
+ ssize_t mlev; /* max #levels in tree or hash table */
+ ssize_t msize; /* max #defined elts in below arrays */
+ ssize_t lsize[DT_MAXSIZE]; /* #objects by level */
+ ssize_t tsize[DT_MAXSIZE]; /* #tables by level */
+};
+
+/* supported storage methods */
+#define DT_SET 0000000001 /* unordered set, unique elements */
+#define DT_BAG 0000000002 /* unordered set, repeated elements */
+#define DT_OSET 0000000004 /* ordered set */
+#define DT_OBAG 0000000010 /* ordered multiset */
+#define DT_LIST 0000000020 /* linked list */
+#define DT_STACK 0000000040 /* stack: insert/delete at top */
+#define DT_QUEUE 0000000100 /* queue: insert top, delete at tail */
+#define DT_DEQUE 0000000200 /* deque: insert top, append at tail */
+#define DT_RHSET 0000000400 /* rhset: sharable unique objects */
+#define DT_RHBAG 0000001000 /* rhbag: sharable repeated objects */
+#define DT_METHODS 0000001777 /* all currently supported methods */
+#define DT_ORDERED (DT_OSET|DT_OBAG)
+
+/* asserts to dtdisc() to improve performance when changing disciplines */
+#define DT_SAMECMP 0000000001 /* compare functions are equivalent */
+#define DT_SAMEHASH 0000000002 /* hash functions are equivalent */
+
+/* operation types */
+#define DT_INSERT 0000000001 /* insert object if not found */
+#define DT_DELETE 0000000002 /* delete a matching object if any */
+#define DT_SEARCH 0000000004 /* look for an object */
+#define DT_NEXT 0000000010 /* look for next element */
+#define DT_PREV 0000000020 /* find previous element */
+#define DT_FIRST 0000000200 /* get first object */
+#define DT_LAST 0000000400 /* get last object */
+#define DT_MATCH 0000001000 /* find object matching key */
+#define DT_ATTACH 0000004000 /* attach an object to dictionary */
+#define DT_DETACH 0000010000 /* detach an object from dictionary */
+#define DT_APPEND 0000020000 /* append an object */
+#define DT_ATLEAST 0000040000 /* find the least elt >= object */
+#define DT_ATMOST 0000100000 /* find the biggest elt <= object */
+#define DT_REMOVE 0002000000 /* remove a specific object */
+#define DT_TOANNOUNCE (DT_INSERT|DT_DELETE|DT_SEARCH|DT_NEXT|DT_PREV|DT_FIRST|DT_LAST|DT_MATCH|DT_ATTACH|DT_DETACH|DT_APPEND|DT_ATLEAST|DT_ATMOST|DT_REMOVE)
+
+#define DT_RELINK 0000002000 /* re-inserting (dtdisc,dtmethod...) */
+#define DT_FLATTEN 0000000040 /* flatten objects into a list */
+#define DT_CLEAR 0000000100 /* clearing all objects */
+#define DT_EXTRACT 0000200000 /* FLATTEN and clear dictionary */
+#define DT_RESTORE 0000400000 /* reinsert a list of elements */
+#define DT_STAT 0001000000 /* get statistics of dictionary */
+#define DT_OPERATIONS (DT_TOANNOUNCE|DT_RELINK|DT_FLATTEN|DT_CLEAR|DT_EXTRACT|DT_RESTORE|DT_STAT)
+
+/* these bits may combine with the DT_METHODS and DT_OPERATIONS bits */
+#define DT_INDATA 0010000000 /* Dt_t was allocated with Dtdata_t */
+#define DT_SHARE 0020000000 /* concurrent access mode */
+#define DT_ANNOUNCE 0040000000 /* announcing a successful operation */
+ /* the actual event will be this bit */
+ /* combined with the operation bit */
+#define DT_OPTIMIZE 0100000000 /* optimizing data structure */
+
+/* events for discipline and method event-handling functions */
+#define DT_OPEN 1 /* a dictionary is being opened */
+#define DT_ENDOPEN 5 /* end of dictionary opening */
+#define DT_CLOSE 2 /* a dictionary is being closed */
+#define DT_ENDCLOSE 6 /* end of dictionary closing */
+#define DT_DISC 3 /* discipline is about to be changed */
+#define DT_METH 4 /* method is about to be changed */
+#define DT_HASHSIZE 7 /* initialize hash table size */
+#define DT_ERROR 0xbad /* announcing an error */
+
+_BEGIN_EXTERNS_ /* data structures and functions */
+#if _BLD_cdt && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+#if !_BLD_cdt && defined(__IMPORT__)
+#define extern __IMPORT__
+#endif
+
+extern Dtmethod_t* Dtset;
+extern Dtmethod_t* Dtbag;
+extern Dtmethod_t* Dtoset;
+extern Dtmethod_t* Dtobag;
+extern Dtmethod_t* Dtlist;
+extern Dtmethod_t* Dtstack;
+extern Dtmethod_t* Dtqueue;
+extern Dtmethod_t* Dtdeque;
+
+#if _PACKAGE_ast /* dtplugin() for proprietary and non-standard methods -- requires -ldll */
+
+#define dtplugin(name) ((Dtmethod_t*)dllmeth("cdt", name, CDT_PLUGIN_VERSION))
+
+#define Dtrhbag dtplugin("rehash:Dtrhbag")
+#define Dtrhset dtplugin("rehash:Dtrhset")
+
+#else
+
+#if CDTPROPRIETARY
+
+extern Dtmethod_t* Dtrhset;
+extern Dtmethod_t* Dtrhbag;
+
+#endif /*CDTPROPRIETARY*/
+
+#endif /*_PACKAGE_ast*/
+
+#undef extern
+
+#if _BLD_cdt && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern Dt_t* dtopen _ARG_((Dtdisc_t*, Dtmethod_t*));
+extern int dtclose _ARG_((Dt_t*));
+extern Dt_t* dtview _ARG_((Dt_t*, Dt_t*));
+extern Dtdisc_t* dtdisc _ARG_((Dt_t* dt, Dtdisc_t*, int));
+extern Dtmethod_t* dtmethod _ARG_((Dt_t*, Dtmethod_t*));
+extern int dtwalk _ARG_((Dt_t*, int(*)(Dt_t*,Void_t*,Void_t*), Void_t*));
+extern int dtcustomize _ARG_((Dt_t*, int, int));
+extern unsigned int dtstrhash _ARG_((unsigned int, Void_t*, ssize_t));
+extern int dtuserlock _ARG_((Dt_t*, unsigned int, int));
+extern Void_t* dtuserdata _ARG_((Dt_t*, Void_t*, unsigned int));
+
+/* deal with upward binary compatibility (operation bit translation, etc.) */
+extern Dt_t* _dtopen _ARG_((Dtdisc_t*, Dtmethod_t*, unsigned long));
+#define dtopen(dc,mt) _dtopen((dc), (mt), CDT_VERSION)
+
+#undef extern
+
+#if _PACKAGE_ast && !defined(_CDTLIB_H)
+
+#if _BLD_dll && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern void* dllmeth(const char*, const char*, unsigned long);
+
+#undef extern
+
+#endif
+
+_END_EXTERNS_
+
+/* internal functions for translating among holder, object and key */
+#define _DT(dt) ((Dt_t*)(dt))
+
+#define _DTLNK(dc,o) ((Dtlink_t*)((char*)(o) + (dc)->link) ) /* get link from obj */
+
+#define _DTO(dc,l) (Void_t*)((char*)(l) - (dc)->link) /* get object from link */
+#define _DTOBJ(dc,l) ((dc)->link >= 0 ? _DTO(dc,l) : ((Dthold_t*)(l))->obj )
+
+#define _DTK(dc,o) ((char*)(o) + (dc)->key) /* get key from object */
+#define _DTKEY(dc,o) (Void_t*)((dc)->size >= 0 ? _DTK(dc,o) : *((char**)_DTK(dc,o)) )
+
+#define _DTCMP(dt,k1,k2,dc) \
+ ((dc)->comparf ? (*(dc)->comparf)((dt), (k1), (k2), (dc)) : \
+ (dc)->size > 0 ? memcmp((Void_t*)(k1), ((Void_t*)k2), (dc)->size) : \
+ strcmp((char*)(k1), ((char*)k2)) )
+
+#define _DTHSH(dt,ky,dc) ((dc)->hashf ? (*(dc)->hashf)((dt), (ky), (dc)) : \
+ dtstrhash(0, (ky), (dc)->size) )
+
+#define dtvnext(d) (_DT(d)->view)
+#define dtvcount(d) (_DT(d)->nview)
+#define dtvhere(d) (_DT(d)->walk)
+
+#define dtlink(d,e) (((Dtlink_t*)(e))->rh.__rght)
+#define dtobj(d,e) _DTOBJ(_DT(d)->disc, (e))
+
+#define dtfirst(d) (*(_DT(d)->searchf))((d),(Void_t*)(0),DT_FIRST)
+#define dtnext(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_NEXT)
+#define dtatleast(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_ATLEAST)
+#define dtlast(d) (*(_DT(d)->searchf))((d),(Void_t*)(0),DT_LAST)
+#define dtprev(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_PREV)
+#define dtatmost(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_ATMOST)
+#define dtsearch(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_SEARCH)
+#define dtmatch(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_MATCH)
+#define dtinsert(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_INSERT)
+#define dtappend(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_APPEND)
+#define dtdelete(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_DELETE)
+#define dtremove(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_REMOVE)
+#define dtattach(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_ATTACH)
+#define dtdetach(d,o) (*(_DT(d)->searchf))((d),(Void_t*)(o),DT_DETACH)
+#define dtclear(d) (*(_DT(d)->searchf))((d),(Void_t*)(0),DT_CLEAR)
+
+#define dtflatten(d) (Dtlink_t*)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_FLATTEN)
+#define dtextract(d) (Dtlink_t*)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_EXTRACT)
+#define dtrestore(d,l) (Dtlink_t*)(*(_DT(d)->searchf))((d),(Void_t*)(l),DT_RESTORE)
+
+#define dtstat(d,s) (ssize_t)(*(_DT(d)->searchf))((d),(Void_t*)(s),DT_STAT)
+#define dtsize(d) (ssize_t)(*(_DT(d)->searchf))((d),(Void_t*)(0),DT_STAT)
+
+#define DT_PRIME 17109811 /* 2#00000001 00000101 00010011 00110011 */
+#define dtcharhash(h,c) (((unsigned int)(h) + (unsigned int)(c)) * DT_PRIME )
+
+#endif /* _CDT_H */
diff --git a/src/lib/libast/include/cmdarg.h b/src/lib/libast/include/cmdarg.h
new file mode 100644
index 0000000..94ad39e
--- /dev/null
+++ b/src/lib/libast/include/cmdarg.h
@@ -0,0 +1,92 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * xargs/tw command arg list interface definitions
+ */
+
+#ifndef _CMDARG_H
+#define _CMDARG_H
+
+#include <error.h>
+
+#define CMD_CHECKED (1<<9) /* cmdopen() argv[0] ok */
+#define CMD_EMPTY (1<<0) /* run once, even if no args */
+#define CMD_EXACT (1<<1) /* last command must have argmax*/
+#define CMD_EXIT (1<<11) /* fatal error_info.exit() */
+#define CMD_IGNORE (1<<2) /* ignore EXIT_QUIT exit */
+#define CMD_INSERT (1<<3) /* argpat for insertion */
+#define CMD_MINIMUM (1<<4) /* argmax is a minimum */
+#define CMD_NEWLINE (1<<5) /* echo separator is newline */
+#define CMD_POST (1<<6) /* argpat is post arg position */
+#define CMD_QUERY (1<<7) /* trace and query each command */
+#define CMD_SILENT (1<<10) /* no error messages */
+#define CMD_TRACE (1<<8) /* trace each command */
+
+#define CMD_USER (1<<12)
+
+typedef struct Cmdarg_s /* cmd + args info */
+{
+ struct
+ {
+ size_t args; /* total args */
+ size_t commands; /* total commands */
+ } total;
+
+ Error_f errorf; /* optional error callback */
+
+ int argcount; /* current arg count */
+ int argmax; /* max # args */
+ int echo; /* just an echo */
+ int flags; /* CMD_* flags */
+ int insertlen; /* strlen(insert) */
+ int offset; /* post arg offset */
+
+ char** argv; /* exec argv */
+ char** firstarg; /* first argv file arg */
+ char** insertarg; /* argv before insert */
+ char** postarg; /* start of post arg list */
+ char** nextarg; /* next argv file arg */
+ char* nextstr; /* next string ends before here */
+ char* laststr; /* last string ends before here */
+ char* insert; /* replace with current arg */
+ char buf[1]; /* argv and arg buffer */
+} Cmdarg_t;
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#ifndef cmdopen
+extern Cmdarg_t* cmdopen(char**, int, int, const char*, int);
+#endif
+extern Cmdarg_t* cmdopen_20110505(char**, int, int, const char*, int, Error_f);
+extern int cmdflush(Cmdarg_t*);
+extern int cmdarg(Cmdarg_t*, const char*, int);
+extern int cmdclose(Cmdarg_t*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/debug.h b/src/lib/libast/include/debug.h
new file mode 100644
index 0000000..994fedb
--- /dev/null
+++ b/src/lib/libast/include/debug.h
@@ -0,0 +1,109 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * common ast debug definitions
+ * include after the ast headers
+ */
+
+#ifndef _DEBUG_H
+#define _DEBUG_H
+
+#include <ast.h>
+#include <error.h>
+
+#if !defined(DEBUG) && _BLD_DEBUG
+#define DEBUG _BLD_DEBUG
+#endif
+
+#if DEBUG || _BLD_DEBUG
+
+#define debug(x) x
+#define message(x) do if (error_info.trace < 0) { error x; } while (0)
+#define messagef(x) do if (error_info.trace < 0) { errorf x; } while (0)
+
+#define DEBUG_BEGTIME() debug_elapsed(1)
+#define DEBUG_GETTIME() debug_elapsed(0)
+#define DEBUG_ASSERT(p) ((p) ? 0 : (debug_fatal(__FILE__, __LINE__),0))
+#define DEBUG_COUNT(n) ((n) += 1)
+#define DEBUG_TALLY(c,n,v) ((c) ? ((n) += (v)) : (n))
+#define DEBUG_INCREASE(n) ((n) += 1)
+#define DEBUG_DECREASE(n) ((n) -= 1)
+#define DEBUG_DECLARE(t,v) t v
+#define DEBUG_SET(n,v) ((n) = (v))
+#define DEBUG_PRINT(fd,s,v) do {char _b[1024];write(fd,_b,sfsprintf(_b,sizeof(_b),s,v));} while(0)
+#define DEBUG_WRITE(fd,d,n) write((fd),(d),(n))
+#define DEBUG_TEMP(temp) (temp) /* debugging stuff that should be removed */
+#define DEBUG_BREAK break
+#define DEBUG_CONTINUE continue
+#define DEBUG_GOTO(label) do { debug_fatal(__FILE__, __LINE__); goto label; } while(0)
+#define DEBUG_RETURN(x) do { debug_fatal(__FILE__, __LINE__); return(x); } while(0)
+
+#else
+
+#define debug(x)
+#define message(x)
+#define messagef(x)
+
+#define DEBUG_BEGTIME()
+#define DEBUG_GETTIME()
+#define DEBUG_ASSERT(p)
+#define DEBUG_COUNT(n)
+#define DEBUG_TALLY(c,n,v)
+#define DEBUG_INCREASE(n)
+#define DEBUG_DECREASE(n)
+#define DEBUG_DECLARE(t,v)
+#define DEBUG_SET(n,v)
+#define DEBUG_PRINT(fd,s,v)
+#define DEBUG_WRITE(fd,d,n)
+#define DEBUG_TEMP(x)
+#define DEBUG_BREAK break
+#define DEBUG_CONTINUE continue
+#define DEBUG_GOTO(label) goto label
+#define DEBUG_RETURN(x) return(x)
+
+#endif
+
+#ifndef BREAK
+#define BREAK DEBUG_BREAK
+#endif
+#ifndef CONTINUE
+#define CONTINUE DEBUG_CONTINUE
+#endif
+#ifndef GOTO
+#define GOTO(label) DEBUG_GOTO(label)
+#endif
+#ifndef RETURN
+#define RETURN(x) DEBUG_RETURN(x)
+#endif
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern double debug_elapsed(int);
+extern void debug_fatal(const char*, int);
+extern void systrace(const char*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/dt.h b/src/lib/libast/include/dt.h
new file mode 100644
index 0000000..acc6713
--- /dev/null
+++ b/src/lib/libast/include/dt.h
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#ifndef _DT_H
+#define _DT_H 1
+
+#include <cdt.h>
+#include <vmalloc.h>
+
+#if _BLD_cdt && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern Dt_t* dtnew(Vmalloc_t*, Dtdisc_t*, Dtmethod_t*);
+extern Dt_t* _dtnew(Vmalloc_t*, Dtdisc_t*, Dtmethod_t*, unsigned long);
+
+#undef extern
+
+#define dtnew(v,d,m) _dtnew(v,d,m,CDT_VERSION)
+
+#endif
diff --git a/src/lib/libast/include/error.h b/src/lib/libast/include/error.h
new file mode 100644
index 0000000..0253e4d
--- /dev/null
+++ b/src/lib/libast/include/error.h
@@ -0,0 +1,182 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * option, error and message formatter external definitions
+ */
+
+#ifndef _ERROR_H
+#define _ERROR_H
+
+#include <ast.h>
+#include <option.h>
+#include <errno.h>
+
+#define ERROR_VERSION 20070319L
+
+#if !defined(errno) && defined(__DYNAMIC__)
+#define errno __DYNAMIC__(errno)
+#endif
+
+#define ERROR_debug(n) (-(n))
+#define ERROR_exit(n) ((n)+ERROR_ERROR)
+#define ERROR_system(n) (((n)+ERROR_ERROR)|ERROR_SYSTEM)
+#define ERROR_usage(n) ((((n)?2:0)+ERROR_ERROR)|ERROR_USAGE)
+#define ERROR_warn(n) (ERROR_WARNING)
+
+#ifndef ERROR_catalog
+#define ERROR_catalog(t) t
+#endif
+#ifndef ERROR_dictionary
+#define ERROR_dictionary(t) t
+#endif
+
+#ifndef ERROR_translate
+#define ERROR_translating() (error_info.translate&&(ast.locale.set&(1<<AST_LC_MESSAGES)))
+#define ERROR_translate(l,i,d,m) (ERROR_translating()?errorx((const char*)(l),(const char*)(i),(const char*)(d),(const char*)(m)):(char*)(m))
+#endif
+
+#define ERROR_INFO 0 /* info message -- no err_id */
+#define ERROR_WARNING 1 /* warning message */
+#define ERROR_ERROR 2 /* error message -- no err_exit */
+#define ERROR_FATAL 3 /* error message with err_exit */
+#define ERROR_NOEXEC EXIT_NOEXEC /* shell convention */
+#define ERROR_NOENT EXIT_NOTFOUND /* shell convention */
+#define ERROR_PANIC ERROR_LEVEL /* panic message with err_exit */
+
+#define ERROR_LEVEL 0x00ff /* level portion of status */
+#define ERROR_SYSTEM 0x0100 /* report system errno message */
+#define ERROR_OUTPUT 0x0200 /* next arg is error fd */
+#define ERROR_SOURCE 0x0400 /* next 2 args are FILE,LINE */
+#define ERROR_USAGE 0x0800 /* usage message */
+#define ERROR_PROMPT 0x1000 /* omit trailing newline */
+#define ERROR_NOID 0x2000 /* omit err_id */
+#define ERROR_LIBRARY 0x4000 /* library routine error */
+
+#define ERROR_INTERACTIVE 0x0001 /* context is interactive */
+#define ERROR_SILENT 0x0002 /* context is silent */
+#define ERROR_NOTIFY 0x0004 /* main(-sig,0,ctx) on signal */
+
+#define ERROR_FREE 0x0010 /* free context on pop */
+#define ERROR_POP 0x0020 /* pop context */
+#define ERROR_PUSH 0x0040 /* push context */
+#define ERROR_SET 0x0080 /* set context */
+
+/*
+ * errorpush()/errorpop() are obsolete -- use errorctx() instead
+ */
+
+#ifndef ERROR_CONTEXT_T
+#define ERROR_CONTEXT_T Error_info_t
+#endif
+
+#define ERROR_CONTEXT_BASE ((Error_context_t*)&error_info.context)
+
+#define errorpush(p,f) (*(p)=*ERROR_CONTEXT_BASE,*ERROR_CONTEXT_BASE=error_info.empty,error_info.context=(Error_context_t*)(p),error_info.flags=(f))
+#define errorpop(p) (*ERROR_CONTEXT_BASE=*(p))
+
+typedef struct Error_info_s Error_info_t;
+typedef struct Error_context_s Error_context_t;
+
+#define ERROR_CONTEXT \
+ ERROR_CONTEXT_T* context; /* prev context stack element */ \
+ int errors; /* >= ERROR_ERROR count */ \
+ int flags; /* context flags */ \
+ int line; /* input|output line number */ \
+ int warnings; /* ERROR_WARNING count */ \
+ char* file; /* input|output file name */ \
+ char* id; /* command id */
+
+struct Error_context_s /* context stack element */
+{
+ ERROR_CONTEXT
+};
+
+struct Error_info_s /* error state */
+{
+ int fd; /* write(2) fd */
+
+ void (*exit)(int); /* error exit */
+ ssize_t (*write)(int, const void*, size_t); /* error output */
+
+ /* the rest are implicitly initialized */
+
+ int clear; /* default clear ERROR_* flags */
+ int core; /* level>=core -> core dump */
+ int indent; /* debug trace indent level */
+ int init; /* initialized */
+ int last_errno; /* last reported errno */
+ int mask; /* multi level debug trace mask */
+ int set; /* default set ERROR_* flags */
+ int trace; /* debug trace level */
+
+ char* version; /* ERROR_SOURCE command version */
+
+ int (*auxilliary)(Sfio_t*, int, int); /* aux info to append */
+
+ ERROR_CONTEXT /* top of context stack */
+
+ Error_context_t empty; /* empty context stack element */
+
+ unsigned long time; /* debug time trace */
+
+ char* (*translate)(const char*, const char*, const char*, const char*); /* format translator */
+
+ const char* catalog; /* message catalog */
+};
+
+#ifndef errno
+extern int errno; /* system call error status */
+#endif
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+#if !_BLD_ast && defined(__IMPORT__)
+#define extern extern __IMPORT__
+#endif
+
+extern Error_info_t* _error_infop_;
+
+#define error_info (*_error_infop_)
+
+#undef extern
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern void error(int, ...);
+extern int errormsg(const char*, int, ...);
+extern int errorf(void*, void*, int, ...);
+extern void errorv(const char*, int, va_list);
+#ifndef errorx
+extern char* errorx(const char*, const char*, const char*, const char*);
+#endif
+extern Error_info_t* errorctx(Error_info_t*, int, int);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/find.h b/src/lib/libast/include/find.h
new file mode 100644
index 0000000..81049be
--- /dev/null
+++ b/src/lib/libast/include/find.h
@@ -0,0 +1,86 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * fast find interface definitions
+ */
+
+#ifndef _FIND_H
+#define _FIND_H
+
+#define FIND_VERSION 19980301L
+
+#ifndef FIND_CODES
+#define FIND_CODES "lib/find/codes"
+#endif
+
+#define FIND_CODES_ENV "FINDCODES"
+
+#define FIND_GENERATE (1<<0) /* generate new codes */
+#define FIND_ICASE (1<<1) /* ignore case in match */
+#define FIND_GNU (1<<2) /* generate gnu format codes */
+#define FIND_OLD (1<<3) /* generate old format codes */
+#define FIND_TYPE (1<<4) /* generate type with codes */
+#define FIND_VERIFY (1<<5) /* verify the dir hierarchy */
+
+#define FIND_USER (1L<<16) /* first user flag bit */
+
+struct Find_s;
+struct Finddisc_s;
+
+typedef int (*Findverify_f)(struct Find_s*, const char*, size_t, struct Finddisc_s*);
+
+typedef struct Finddisc_s
+{
+ unsigned long version; /* interface version */
+ unsigned long flags; /* FIND_* flags */
+ Error_f errorf; /* error function */
+ Findverify_f verifyf; /* dir verify function */
+ char** dirs; /* dir prefixes to search */
+} Finddisc_t;
+
+typedef struct Find_s
+{
+ const char* id; /* library id string */
+ unsigned long stamp; /* codes time stamp */
+
+#ifdef _FIND_PRIVATE_
+ _FIND_PRIVATE_
+#endif
+
+} Find_t;
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern Find_t* findopen(const char*, const char*, const char*, Finddisc_t*);
+extern char* findread(Find_t*);
+extern int findwrite(Find_t*, const char*, size_t, const char*);
+extern int findclose(Find_t*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/fnv.h b/src/lib/libast/include/fnv.h
new file mode 100644
index 0000000..793dde0
--- /dev/null
+++ b/src/lib/libast/include/fnv.h
@@ -0,0 +1,72 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * Landon Kurt Knoll
+ * Phong Vo
+ *
+ * FNV-1 linear congruent checksum/hash/PRNG
+ * see http://www.isthe.com/chongo/tech/comp/fnv/
+ */
+
+#ifndef _FNV_H
+#define _FNV_H
+
+#include <ast_common.h>
+
+#define FNV_INIT 0x811c9dc5L
+#define FNV_MULT 0x01000193L
+
+#define FNVINIT(h) (h = FNV_INIT)
+#define FNVPART(h,c) (h = (h) * FNV_MULT ^ (c))
+#define FNVSUM(h,s,n) do { \
+ register size_t _i_ = 0; \
+ while (_i_ < n) \
+ FNVPART(h, ((unsigned char*)s)[_i_++]); \
+ } while (0)
+
+#if _typ_int64_t
+
+#ifdef _ast_LL
+
+#define FNV_INIT64 0xcbf29ce484222325LL
+#define FNV_MULT64 0x00000100000001b3LL
+
+#else
+
+#define FNV_INIT64 ((int64_t)0xcbf29ce484222325)
+#define FNV_MULT64 ((int64_t)0x00000100000001b3)
+
+#endif
+
+#define FNVINIT64(h) (h = FNV_INIT64)
+#define FNVPART64(h,c) (h = (h) * FNV_MULT64 ^ (c))
+#define FNVSUM64(h,s,n) do { \
+ register int _i_ = 0; \
+ while (_i_ < n) \
+ FNVPART64(h, ((unsigned char*)s)[_i_++]); \
+ } while (0)
+
+#endif
+
+#endif
diff --git a/src/lib/libast/include/fs3d.h b/src/lib/libast/include/fs3d.h
new file mode 100644
index 0000000..9d3c992
--- /dev/null
+++ b/src/lib/libast/include/fs3d.h
@@ -0,0 +1,117 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * 3d fs interface definitions
+ */
+
+#ifndef _FS3D_H
+#define _FS3D_H
+
+#include <ast_fs.h>
+
+#if _int_st_spare1
+#define iview(p) ((p)->st_spare1)
+#define IVIEW(p,v) ((p)->st_spare1=(v))
+#else
+#if _ary_st_spare4
+#define iview(p) ((p)->st_spare4[0])
+#define IVIEW(p,v) ((p)->st_spare4[0]=(v))
+#else
+#if _ary_st_extra
+#define iview(p) ((p)->st_extra[0])
+#define IVIEW(p,v) ((p)->st_extra[0]=(v))
+#else
+#if _ary_st_pad4
+#define iview(p) ((p)->st_pad4[0])
+#define IVIEW(p,v) ((p)->st_pad4[0]=(v))
+#else
+#if _mem_st_rdev_stat
+#define iview(p) ((S_ISBLK((p)->st_mode)||S_ISCHR((p)->st_mode))?0:(p)->st_rdev)
+#define IVIEW(p,v) do{if(!S_ISBLK((p)->st_mode)&&!S_ISCHR((p)->st_mode))(p)->st_rdev=(v);}while(0)
+#else
+#define iview(p) 0
+#define IVIEW(p,v)
+#endif
+#endif
+#endif
+#endif
+#endif
+
+/*
+ * special options
+ */
+
+#define FS3D_init "/#option/init"
+#define FS3D_on "/#option/3d"
+#define FS3D_off "/#option/2d"
+
+/*
+ * fs3d(3) ops
+ */
+
+#define FS3D_OP(o,a) (((a)<<3)|(o))
+
+#define FS3D_INIT FS3D_OP_INIT /* re-initialize tables */
+#define FS3D_OFF FS3D_OP_OFF
+#define FS3D_ON FS3D_OP_ON
+#define FS3D_TEST FS3D_OP_TEST
+#define FS3D_LIMIT(n) FS3D_OP(FS3D_OP_LIMIT,n)
+
+#define FS3D_op(x) ((x)&07)
+#define FS3D_arg(x) (((x)>>3)&07777)
+
+#define FS3D_OP_OFF 0
+#define FS3D_OP_ON 1
+#define FS3D_OP_TEST 2
+#define FS3D_OP_LIMIT 3
+#define FS3D_OP_INIT 7
+
+/*
+ * mount(2) ops
+ */
+
+#define FS3D_ALL (FS3D_VIEW|FS3D_VERSION)
+#define FS3D_VIEW 002
+#define FS3D_VERSION 004
+#define FS3D_GET 010
+#define FS3D_SIZE(n) ((n)<<4)
+#define FS3D_SIZEOF(n) ((n)>>4)
+
+#if !_BLD_3d
+#define mount(s,t,f,d) fs3d_mount(s,t,f,d)
+#endif
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int fs3d(int);
+extern int fs3d_mount(const char*, char*, int, void*);
+extern char* pathnext(char*, char*, long*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/fts.h b/src/lib/libast/include/fts.h
new file mode 100644
index 0000000..3a22ad2
--- /dev/null
+++ b/src/lib/libast/include/fts.h
@@ -0,0 +1,162 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * David Korn
+ * Phong Vo
+ * AT&T Research
+ *
+ * fts interface definitions
+ */
+
+#ifndef _FTS_H
+#define _FTS_H
+
+#include <ast_std.h>
+#include <ast_fs.h>
+#include <ast_mode.h>
+
+/*
+ * fts_open flags
+ */
+
+#define FTS_LOGICAL 0 /* logical traversal, follow symlinks */
+#define FTS_META (1<<0) /* follow top dir symlinks even if phys */
+#define FTS_NOCHDIR (1<<1) /* don't chdir */
+#define FTS_NOPOSTORDER (1<<2) /* no postorder visits */
+#define FTS_NOPREORDER (1<<3) /* no preorder visits */
+#define FTS_NOSEEDOTDIR (1<<11) /* never retain leading . dir */
+#define FTS_NOSTAT (1<<4) /* don't stat children */
+#define FTS_ONEPATH (1<<5) /* pathnames arg is one const char* */
+#define FTS_PHYSICAL (1<<6) /* physical traversal, don't follow */
+#define FTS_SEEDOT (1<<7) /* return . and .. */
+#define FTS_SEEDOTDIR (1<<10) /* always retain leading . dir */
+#define FTS_TOP (1<<8) /* don't traverse subdirectories */
+#define FTS_XDEV (1<<9) /* don't cross mount points */
+
+#define FTS_USER (1<<12) /* first user flag bit */
+
+#define FTS_COMFOLLOW FTS_META
+
+/*
+ * fts_info flags
+ */
+
+#define FTS_DEFAULT 0 /* ok, someone must have wanted this */
+
+#define FTS_NS (1<<0) /* stat failed */
+#define FTS_F (1<<1) /* file - not directory or symbolic link*/
+#define FTS_SL (1<<2) /* symbolic link */
+#define FTS_D (1<<3) /* directory - pre-order visit */
+
+#define FTS_C (1<<4) /* causes cycle */
+#define FTS_ERR (1<<5) /* some other error */
+#define FTS_DD (1<<6) /* . or .. */
+#define FTS_NR (1<<7) /* cannot read */
+#define FTS_NX (1<<8) /* cannot search */
+#define FTS_OK (1<<9) /* no info but otherwise ok */
+#define FTS_P (1<<10) /* post-order visit */
+
+#define FTS_DC (FTS_D|FTS_C) /* dir - would cause cycle */
+#define FTS_DNR (FTS_D|FTS_NR) /* dir - no read permission */
+#define FTS_DNX (FTS_D|FTS_NX) /* dir - no search permission */
+#define FTS_DOT (FTS_D|FTS_DD) /* . or .. */
+#define FTS_DP (FTS_D|FTS_P) /* dir - post-order visit */
+#define FTS_NSOK (FTS_NS|FTS_OK) /* no stat (because you asked) */
+#define FTS_SLNONE (FTS_SL|FTS_NS) /* symlink - to nowhere */
+
+/*
+ * fts_set flags
+ */
+
+#define FTS_AGAIN FTS_TOP /* process entry again */
+#define FTS_FOLLOW FTS_META /* follow FTS_SL symlink */
+#define FTS_SKIP FTS_NOSTAT /* skip FTS_D directory */
+#define FTS_STAT FTS_PHYSICAL /* stat() done by user */
+
+typedef struct Fts FTS;
+typedef struct Ftsent FTSENT;
+
+struct Ftsent
+{
+ char* fts_accpath; /* path relative to . */
+ char* fts_name; /* file name */
+ char* fts_path; /* path relative to top dir */
+ FTSENT* fts_cycle; /* offender if cycle */
+ FTSENT* fts_link; /* next child */
+ FTSENT* fts_parent; /* parent directory */
+ struct stat* fts_statp; /* stat info */
+#ifdef _FTSENT_LOCAL_PRIVATE_
+ _FTSENT_LOCAL_PRIVATE_
+#else
+ void* fts_pointer; /* local pointer value */
+#endif
+ long fts_number; /* local numeric value */
+ int fts_errno; /* errno for this entry */
+ unsigned short fts_info; /* info flags */
+
+ unsigned short _fts_namelen; /* old fts_namelen */
+ unsigned short _fts_pathlen; /* old fts_pathlen */
+ short _fts_level; /* old fts_level */
+
+ short _fts_status; /* <ftwalk.h> compatibility */
+ struct stat _fts_statb; /* <ftwalk.h> compatibility */
+
+ FTS* fts; /* fts_open() handle */
+ size_t fts_namelen; /* strlen(fts_name) */
+ size_t fts_pathlen; /* strlen(fts_path) */
+ ssize_t fts_level; /* file tree depth, 0 at top */
+
+#ifdef _FTSENT_PRIVATE_
+ _FTSENT_PRIVATE_
+#endif
+
+};
+
+struct Fts
+{
+ int fts_errno; /* last errno */
+ void* fts_handle; /* user defined handle */
+
+#ifdef _FTS_PRIVATE_
+ _FTS_PRIVATE_
+#endif
+
+};
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern FTSENT* fts_children(FTS*, int);
+extern int fts_close(FTS*);
+extern int fts_flags(void);
+extern int fts_local(FTSENT*);
+extern int fts_notify(int(*)(FTS*, FTSENT*, void*), void*);
+extern FTS* fts_open(char* const*, int, int(*)(FTSENT* const*, FTSENT* const*));
+extern FTSENT* fts_read(FTS*);
+extern int fts_set(FTS*, FTSENT*, int);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/ftwalk.h b/src/lib/libast/include/ftwalk.h
new file mode 100644
index 0000000..a4f3955
--- /dev/null
+++ b/src/lib/libast/include/ftwalk.h
@@ -0,0 +1,124 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Phong Vo
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * ast ftwalk interface definitions
+ * ftwalk was the initial improvement on ftw and nftw
+ * which formed the basis for the POSIX fts proposal
+ *
+ * NOTE: this file is in cahoots with the fts implementation
+ */
+
+#ifndef _FTWALK_H
+#define _FTWALK_H
+
+#define fts_info info
+#define fts_level level
+#define fts_link link
+#define fts_name name
+#define fts_namelen namelen
+#define fts_parent parent
+#define fts_path path
+#define fts_pathlen pathlen
+#define _fts_status status
+#define _fts_statb statb
+
+#define FTSENT Ftw_t /* <fts.h> internal */
+#define Ftsent FTW /* <fts.h> internal */
+
+#define _FTSENT_LOCAL_PRIVATE_ /* <fts.h> internal */ \
+ union \
+ { \
+ long number; /* local numeric value */ \
+ void* pointer; /* local pointer value */ \
+ } local;
+
+#include <fts.h>
+
+/*
+ * ftwalk() argument flags
+ */
+
+#define FTW_CANON FTS_CANON
+#define FTW_CHILDREN (FTS_USER<<0)
+#define FTW_DELAY FTS_NOSTAT
+#define FTW_DOT FTS_NOCHDIR
+#define FTW_META FTS_META
+#define FTW_MOUNT FTS_XDEV
+#define FTW_MULTIPLE FTS_ONEPATH
+#define FTW_NOSEEDOTDIR FTS_NOSEEDOTDIR
+#define FTW_PHYSICAL FTS_PHYSICAL
+#define FTW_POST (FTS_USER<<1)
+#define FTW_SEEDOTDIR FTS_SEEDOTDIR
+#define FTW_TOP FTS_TOP
+#define FTW_TWICE (FTS_USER<<2)
+#define FTW_USER (FTS_USER<<3)
+
+/*
+ * Ftw_t.info type bits
+ */
+
+#define FTW_C FTS_C
+#define FTW_D FTS_D
+#define FTW_DC FTS_DC
+#define FTW_DNR FTS_DNR
+#define FTW_DNX FTS_DNX
+#define FTW_DP FTS_DP
+#define FTW_F FTS_F
+#define FTW_NR FTS_NR
+#define FTW_NS FTS_NS
+#define FTW_NSOK FTS_NSOK
+#define FTW_NX FTS_NX
+#define FTW_P FTS_P
+#define FTW_SL FTS_SL
+
+/*
+ * Ftw_t.status entry values
+ */
+
+#define FTW_NAME FTS_DOT /* access by Ftw_t.name */
+#define FTW_PATH FTS_NOCHDIR /* access by Ftw_t.path */
+
+/*
+ * Ftw_t.status return values
+ */
+
+#define FTW_AGAIN FTS_AGAIN
+#define FTW_FOLLOW FTS_FOLLOW
+#define FTW_NOPOST FTS_NOPOSTORDER
+#define FTW_SKIP FTS_SKIP
+#define FTW_STAT FTS_STAT
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int ftwalk(const char*, int(*)(Ftw_t*), int, int(*)(Ftw_t*, Ftw_t*));
+extern int ftwflags(void);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/glob.h b/src/lib/libast/include/glob.h
new file mode 100644
index 0000000..a118db9
--- /dev/null
+++ b/src/lib/libast/include/glob.h
@@ -0,0 +1,146 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * posix glob interface definitions with gnu extensions
+ */
+
+#ifndef _GLOB_H
+#define _GLOB_H
+
+#define GLOB_VERSION 20060717L
+
+#include <stdlib.h>
+
+struct dirent;
+struct stat;
+
+struct _glob_;
+struct _globlist_;
+
+typedef struct _glob_ glob_t;
+typedef struct _globlist_ globlist_t;
+
+struct _globlist_
+{
+ globlist_t* gl_next;
+ char* gl_begin;
+ unsigned char gl_flags;
+ char gl_path[1];
+};
+
+struct _glob_
+{
+ size_t gl_pathc;
+ char** gl_pathv;
+ size_t gl_offs;
+ globlist_t* gl_list;
+ int gl_flags;
+
+ /* GLOB_DISC data -- memset(&gl,0,sizeof(gl)) before using! */
+
+ const char* gl_fignore;
+ const char* gl_suffix;
+ unsigned char* gl_intr;
+
+ int gl_delim;
+
+ void* gl_handle;
+ void* (*gl_diropen)(glob_t*, const char*);
+ char* (*gl_dirnext)(glob_t*, void*);
+ void (*gl_dirclose)(glob_t*, void*);
+ int (*gl_type)(glob_t*, const char*, int);
+ int (*gl_attr)(glob_t*, const char*, int);
+
+ /* gnu extensions -- but how do you synthesize dirent and stat? */
+
+ void* (*gl_opendir)(const char*);
+ struct dirent* (*gl_readdir)(void*);
+ void (*gl_closedir)(void*);
+ int (*gl_stat)(const char*, struct stat*);
+ int (*gl_lstat)(const char*, struct stat*);
+
+ /* ast additions */
+
+ char* (*gl_nextdir)(glob_t*, char*);
+ unsigned long gl_status;
+ unsigned long gl_version;
+ unsigned short gl_extra;
+
+#ifdef _GLOB_PRIVATE_
+ _GLOB_PRIVATE_
+#else
+ char* gl_pad[23];
+#endif
+
+};
+
+/* standard interface */
+#define GLOB_APPEND 0x0001 /* append to previous */
+#define GLOB_DOOFFS 0x0002 /* gl_offs defines argv offset */
+#define GLOB_ERR 0x0004 /* abort on error */
+#define GLOB_MARK 0x0008 /* append / to directories */
+#define GLOB_NOCHECK 0x0010 /* nomatch is original pattern */
+#define GLOB_NOESCAPE 0x0020 /* don't treat \ specially */
+#define GLOB_NOSORT 0x0040 /* don't sort the list */
+
+/* extended interface */
+#define GLOB_STARSTAR 0x0080 /* enable [/]**[/] expansion */
+#define GLOB_BRACE 0x0100 /* enable {...} expansion */
+#define GLOB_ICASE 0x0200 /* ignore case on match */
+#define GLOB_COMPLETE 0x0400 /* shell file completeion */
+#define GLOB_AUGMENTED 0x0800 /* augmented shell patterns */
+#define GLOB_STACK 0x1000 /* allocate on current stack */
+#define GLOB_LIST 0x2000 /* just create gl_list */
+#define GLOB_ALTDIRFUNC 0x4000 /* gnu discipline functions */
+#define GLOB_DISC 0x8000 /* discipline initialized */
+
+#define GLOB_GROUP 0x10000 /* REG_SHELL_GROUP */
+
+/* gl_status */
+#define GLOB_NOTDIR 0x0001 /* last gl_dirnext() not a dir */
+
+/* gl_type return */
+#define GLOB_NOTFOUND 0 /* does not exist */
+#define GLOB_DEV 1 /* exists but not DIR EXE REG */
+#define GLOB_DIR 2 /* directory */
+#define GLOB_EXE 3 /* executable regular file */
+#define GLOB_REG 4 /* regular file */
+
+/* error return values */
+#define GLOB_ABORTED 1
+#define GLOB_NOMATCH 2
+#define GLOB_NOSPACE 3
+#define GLOB_INTR 4
+#define GLOB_APPERR 5
+#define GLOB_NOSYS 6
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int glob(const char*, int, int(*)(const char*,int), glob_t*);
+extern void globfree(glob_t*);
+
+#undef extern
+
+#endif /* _GLOB_H */
diff --git a/src/lib/libast/include/hash.h b/src/lib/libast/include/hash.h
new file mode 100644
index 0000000..b91e550
--- /dev/null
+++ b/src/lib/libast/include/hash.h
@@ -0,0 +1,202 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * hash table library interface definitions
+ *
+ * NOTE: new code should use the more general <cdt.h>
+ */
+
+#ifndef _HASH_H
+#define _HASH_H
+
+#define HASH_ALLOCATE (1L<<0) /* allocate new key names */
+#define HASH_FIXED (1L<<1) /* fixed table size */
+#define HASH_HASHED (1L<<6) /* key names already hashed */
+#define HASH_RESIZE (1L<<2) /* table has been resized */
+#define HASH_SCANNING (1L<<3) /* currently scanning scope */
+#define HASH_SCOPE (1L<<4) /* push scope / create in bot */
+#define HASH_STATIC (1L<<5) /* static table allocation */
+
+#define HASH_CREATE (1L<<8) /* create bucket if not found */
+#define HASH_DELETE (1L<<9) /* delete bucket if found */
+#define HASH_LOOKUP 0 /* default op */
+#define HASH_RENAME (1L<<7) /* rename bucket if found */
+
+#define HASH_BUCKET (1L<<11) /* name is installed bucket */
+#define HASH_INSTALL (1L<<12) /* install allocated bucket */
+#define HASH_NOSCOPE (1L<<13) /* top scope only */
+#define HASH_OPAQUE (1L<<14) /* opaque bucket */
+#define HASH_VALUE (1L<<15) /* value bucket field used */
+
+#define HASH_SIZE(n) (((long)(n))<<16) /* fixed bucket size */
+#define HASH_SIZEOF(f) ((((long)(f))>>16)&0xffff) /* extract size */
+
+#define HASH_DELETED ((unsigned long)1<<(8*sizeof(int)-1)) /* deleted placeholder */
+#define HASH_KEEP (1L<<(8*sizeof(int)-2)) /* no free on bucket */
+#define HASH_HIDDEN (1L<<(8*sizeof(int)-3)) /* hidden by scope */
+#define HASH_HIDES (1L<<(8*sizeof(int)-4)) /* hides lower scope */
+#define HASH_OPAQUED (1L<<(8*sizeof(int)-5)) /* opaqued placeholder */
+#define HASH_FREENAME (1L<<(8*sizeof(int)-6)) /* free bucket name */
+
+#define HASH_RESET (HASH_RESIZE|HASH_SCOPE|HASH_STATIC|HASH_VALUE)
+#define HASH_INTERNAL (HASH_BUCKET|HASH_RESIZE|HASH_SCANNING|HASH_STATIC)
+#define HASH_FLAGS (HASH_DELETED|HASH_FREENAME|HASH_HIDDEN|HASH_HIDES|HASH_KEEP|HASH_OPAQUED)
+
+#define HASH_alloc 1
+#define HASH_clear 2
+#define HASH_compare 3
+#define HASH_free 4
+#define HASH_hash 5
+#define HASH_meanchain 6
+#define HASH_name 7
+#define HASH_namesize 8
+#define HASH_set 9
+#define HASH_size 10
+#define HASH_table 11
+#define HASH_va_list 12
+
+#define HASH_bucketsize 13
+
+#define HASH_region 14
+
+#include <hashpart.h>
+
+#define hashclear(t,f) ((t)->flags &= ~((f) & ~HASH_INTERNAL))
+#define hashcover(b) (((b)->hash&HASH_HIDES)?(Hash_bucket_t*)((b)->name):(Hash_bucket_t*)0)
+#define hashdel(t,n) hashlook(t, (char*)(n), HASH_DELETE, (char*)0)
+#define hashget(t,n) hashlook(t, (char*)(n), HASH_LOOKUP|HASH_VALUE, (char*)0)
+#define hashgetbucket(s) ((Hash_bucket_t*)((s)-((sizeof(Hash_bucket_t)+sizeof(char*)-1)/sizeof(char*))*sizeof(char*)))
+#define hashkeep(b) ((b)->hash|=HASH_KEEP)
+#define hashname(b) ((((b)->hash&HASH_HIDES)?((Hash_bucket_t*)((b)->name)):(b))->name)
+#define hashput(t,n,v) hashlook(t, (char*)(n), HASH_CREATE|HASH_VALUE, (char*)(v))
+#define hashref(t,n) hashlook(t, (char*)(n), HASH_LOOKUP|HASH_INTERNAL|HASH_VALUE, (char*)0)
+#define hashscope(t) ((t)->scope)
+#define hashset(t,f) ((t)->flags |= ((f) & ~HASH_INTERNAL))
+
+/*
+ * DEPRECATED renames for compatibility
+ */
+
+#define Hashbin_t Hash_bucket_t
+#define HASHBUCKET Hash_bucket_t
+#define Hashhdr_t Hash_header_t
+#define HASHHEADER Hash_header_t
+#define Hashpos_t Hash_position_t
+#define HASHPOSITION Hash_position_t
+#define Hashtab_t Hash_table_t
+#define HASHTABLE Hash_table_t
+
+#define vhashalloc hashvalloc
+#define hashvalloc(t,a) hashalloc(t,HASH_va_list,a,0)
+
+/*
+ * the #define's avoid union tags
+ */
+
+typedef struct Hash_bucket Hash_bucket_t;
+typedef struct Hash_root Hash_root_t;
+typedef struct Hash_table Hash_table_t;
+
+#define HASH_HEADER /* common bucket header */ \
+ Hash_bucket_t* next; /* next in collision chain */ \
+ unsigned int hash; /* hash flags and value */ \
+ char* name /* key name */
+
+#define HASH_DEFAULT /* HASH_VALUE bucket elements */ \
+ char* value /* key value */
+
+typedef struct /* bucket header */
+{
+ HASH_HEADER;
+} Hash_header_t;
+
+struct Hash_bucket /* prototype bucket */
+{
+ HASH_HEADER;
+ HASH_DEFAULT;
+};
+
+typedef struct /* hash scan bucket position */
+{
+ Hash_bucket_t* bucket; /* bucket */
+#ifdef _HASH_POSITION_PRIVATE_
+ _HASH_POSITION_PRIVATE_
+#endif
+} Hash_position_t;
+
+typedef struct /* last lookup cache */
+{
+ Hash_table_t* table; /* last lookup table */
+ Hash_bucket_t* bucket; /* last lookup bucket */
+#ifdef _HASH_LAST_PRIVATE_
+ _HASH_LAST_PRIVATE_
+#endif
+} Hash_last_t;
+
+struct Hash_root /* root hash table information */
+{
+ int accesses; /* number of accesses */
+ int collisions; /* number of collisions */
+ int flags; /* flags: see HASH_[A-Z]* */
+ Hash_last_t last; /* last lookup cache */
+ void* context; /* user defined context */
+#ifdef _HASH_ROOT_PRIVATE_
+ _HASH_ROOT_PRIVATE_
+#endif
+};
+
+struct Hash_table /* hash table information */
+{
+ Hash_root_t* root; /* root hash table information */
+ int size; /* table size */
+ int buckets; /* active bucket count */
+ char* name; /* table name */
+ Hash_table_t* scope; /* scope covered table */
+ short flags; /* flags: see HASH_[A-Z]* */
+#ifdef _HASH_TABLE_PRIVATE_
+ _HASH_TABLE_PRIVATE_
+#endif
+};
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern Hash_table_t* hashalloc(Hash_table_t*, ...);
+extern void hashdone(Hash_position_t*);
+extern void hashdump(Hash_table_t*, int);
+extern Hash_table_t* hashfree(Hash_table_t*);
+extern Hash_bucket_t* hashlast(Hash_table_t*);
+extern char* hashlook(Hash_table_t*, const char*, long, const char*);
+extern Hash_bucket_t* hashnext(Hash_position_t*);
+extern Hash_position_t* hashscan(Hash_table_t*, int);
+extern void hashsize(Hash_table_t*, int);
+extern Hash_table_t* hashview(Hash_table_t*, Hash_table_t*);
+extern int hashwalk(Hash_table_t*, int, int (*)(const char*, char*, void*), void*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/hashkey.h b/src/lib/libast/include/hashkey.h
new file mode 100644
index 0000000..338f017
--- /dev/null
+++ b/src/lib/libast/include/hashkey.h
@@ -0,0 +1,62 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * 1-6 char lower-case keyword -> long hash
+ * digit args passed as HASHKEYN('2')
+ */
+
+#ifndef _HASHKEY_H
+#define _HASHKEY_H
+
+#define HASHKEYMAX 6
+#define HASHKEYBIT 5
+#define HASHKEYOFF ('a'-1)
+#define HASHKEYPART(h,c) (((h)<<HASHKEYBIT)+HASHKEY1(c))
+
+#define HASHKEYN(n) ((n)-'0'+'z'+1)
+
+#define HASHKEY1(c1) ((c1)-HASHKEYOFF)
+#define HASHKEY2(c1,c2) HASHKEYPART(HASHKEY1(c1),c2)
+#define HASHKEY3(c1,c2,c3) HASHKEYPART(HASHKEY2(c1,c2),c3)
+#define HASHKEY4(c1,c2,c3,c4) HASHKEYPART(HASHKEY3(c1,c2,c3),c4)
+#define HASHKEY5(c1,c2,c3,c4,c5) HASHKEYPART(HASHKEY4(c1,c2,c3,c4),c5)
+#define HASHKEY6(c1,c2,c3,c4,c5,c6) HASHKEYPART(HASHKEY5(c1,c2,c3,c4,c5),c6)
+
+#define HASHNKEY1(n,c1) HASHKEY2((n)+HASHKEYOFF,c1)
+#define HASHNKEY2(n,c2,c1) HASHKEY3((n)+HASHKEYOFF,c2,c1)
+#define HASHNKEY3(n,c3,c2,c1) HASHKEY4((n)+HASHKEYOFF,c3,c2,c1)
+#define HASHNKEY4(n,c4,c3,c2,c1) HASHKEY5((n)+'a',c4,c3,c2,c1)
+#define HASHNKEY5(n,c5,c4,c3,c2,c1) HASHKEY6((n)+'a',c5,c4,c3,c2,c1)
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern long strkey(const char*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/hashpart.h b/src/lib/libast/include/hashpart.h
new file mode 100644
index 0000000..ae38262
--- /dev/null
+++ b/src/lib/libast/include/hashpart.h
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * K. P. Vo
+ * G. S. Fowler
+ * AT&T Research
+ *
+ * ``the best'' combined linear congruent checksum/hash/PRNG
+ */
+
+#ifndef _HASHPART_H
+#define _HASHPART_H
+
+#define HASH_ADD(h) (0x9c39c33dL)
+
+#if __sparc__ || __sparc || sparc
+
+#define HASH_A(h,n) ((((h) << 2) - (h)) << (n))
+#define HASH_B(h,n) ((((h) << 4) - (h)) << (n))
+#define HASH_C(h,n) ((HASH_A(h,7) + HASH_B(h,0)) << (n))
+#define HASH_MPY(h) (HASH_C(h,22)+HASH_C(h,10)+HASH_A(h,6)+HASH_A(h,3)+(h))
+
+#else
+
+#define HASH_MPY(h) ((h)*0x63c63cd9L)
+
+#endif
+
+#define HASHPART(h,c) (h = HASH_MPY(h) + HASH_ADD(h) + (c))
+
+#endif
diff --git a/src/lib/libast/include/ip6.h b/src/lib/libast/include/ip6.h
new file mode 100644
index 0000000..382ead8
--- /dev/null
+++ b/src/lib/libast/include/ip6.h
@@ -0,0 +1,40 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#ifndef _IP6_H
+#define _IP6_H 1
+
+#define IP6ADDR 16
+#define IP6BITS IP6ADDR
+#define IP6PREFIX (IP6ADDR+1)
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char* fmtip6(const unsigned char*, int);
+extern int strtoip6(const char*, char**, unsigned char*, unsigned char*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/ls.h b/src/lib/libast/include/ls.h
new file mode 100644
index 0000000..fc1d623
--- /dev/null
+++ b/src/lib/libast/include/ls.h
@@ -0,0 +1,88 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * ls formatter interface definitions
+ */
+
+#ifndef _LS_H
+#define _LS_H
+
+#include <ast_std.h>
+#include <ast_fs.h>
+#include <ast_mode.h>
+
+/*
+ * some systems (could it beee AIX) pollute the std name space
+ */
+
+#undef fileid
+#define fileid fileID
+
+#define LS_BLOCKSIZE 512
+
+#define iblocks(p) _iblocks(p)
+
+#if _mem_st_rdev_stat
+#define idevice(p) ((p)->st_rdev)
+#define IDEVICE(p,v) ((p)->st_rdev=(v))
+#else
+#define idevice(p) 0
+#define IDEVICE(p,v)
+#endif
+
+#define LS_ATIME (1<<0) /* list st_atime */
+#define LS_BLOCKS (1<<1) /* list blocks used by file */
+#define LS_CTIME (1<<2) /* list st_ctime */
+#define LS_EXTERNAL (1<<3) /* st_mode is modex canonical */
+#define LS_INUMBER (1<<4) /* list st_ino */
+#define LS_LONG (1<<5) /* long listing */
+#define LS_MARK (1<<6) /* append file name marks */
+#define LS_NOGROUP (1<<7) /* omit group name for LS_LONG */
+#define LS_NOUSER (1<<8) /* omit user name for LS_LONG */
+#define LS_NUMBER (1<<9) /* number instead of name */
+
+#define LS_USER (1<<10) /* first user flag bit */
+
+#define LS_W_BLOCKS 6 /* LS_BLOCKS field width */
+#define LS_W_INUMBER 9 /* LS_INUMBER field width */
+#define LS_W_LONG 57 /* LS_LONG width (w/o names) */
+#define LS_W_LINK 4 /* link text width (w/o names) */
+#define LS_W_MARK 1 /* LS_MARK field width */
+#define LS_W_NAME 9 /* group|user name field width */
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern off_t _iblocks(struct stat*);
+extern char* fmtdev(struct stat*);
+extern char* fmtfs(struct stat*);
+extern char* fmtls(char*, const char*, struct stat*, const char*, const char*, int);
+extern int pathstat(const char*, struct stat*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/magic.h b/src/lib/libast/include/magic.h
new file mode 100644
index 0000000..9b2f96b
--- /dev/null
+++ b/src/lib/libast/include/magic.h
@@ -0,0 +1,86 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * magic interface definitions
+ */
+
+#ifndef _MAGIC_H
+#define _MAGIC_H
+
+#include <sfio.h>
+#include <ls.h>
+
+#define MAGIC_VERSION 19961031L
+
+#ifndef MAGIC_FILE
+#define MAGIC_FILE "lib/file/magic"
+#endif
+
+#ifndef MAGIC_DIR
+#define MAGIC_DIR "lib/file"
+#endif
+
+#define MAGIC_FILE_ENV "MAGICFILE"
+
+#define MAGIC_MIME (1<<0) /* magictype returns MIME type */
+#define MAGIC_VERBOSE (1<<1) /* verbose magic file errors */
+#define MAGIC_ALL (1<<2) /* list all table matches */
+
+#define MAGIC_USER (1L<<16) /* first user flag bit */
+
+struct Magic_s;
+struct Magicdisc_s;
+
+typedef struct Magicdisc_s
+{
+ unsigned long version; /* interface version */
+ unsigned long flags; /* MAGIC_* flags */
+ Error_f errorf; /* error function */
+} Magicdisc_t;
+
+typedef struct Magic_s
+{
+ const char* id; /* library id string */
+
+#ifdef _MAGIC_PRIVATE_
+ _MAGIC_PRIVATE_
+#endif
+
+} Magic_t;
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern Magic_t* magicopen(Magicdisc_t*);
+extern int magicload(Magic_t*, const char*, unsigned long);
+extern int magiclist(Magic_t*, Sfio_t*);
+extern char* magictype(Magic_t*, Sfio_t*, const char*, struct stat*);
+extern int magicclose(Magic_t*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/magicid.h b/src/lib/libast/include/magicid.h
new file mode 100644
index 0000000..73197d7
--- /dev/null
+++ b/src/lib/libast/include/magicid.h
@@ -0,0 +1,46 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * generic binary magic id definitions
+ */
+
+#ifndef _MAGICID_H
+#define _MAGICID_H 1
+
+#include <ast_common.h>
+
+#define MAGICID 0x00010203
+
+typedef uint32_t Magicid_data_t;
+
+typedef struct Magicid_s
+{
+ Magicid_data_t magic; /* magic number */
+ char name[8]; /* generic data/application name*/
+ char type[12]; /* specific data type */
+ Magicid_data_t version; /* YYYYMMDD or 0xWWXXYYZZ */
+ Magicid_data_t size;
+} Magicid_t;
+
+#endif
diff --git a/src/lib/libast/include/mc.h b/src/lib/libast/include/mc.h
new file mode 100644
index 0000000..a23c7bb
--- /dev/null
+++ b/src/lib/libast/include/mc.h
@@ -0,0 +1,96 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * machine independent binary message catalog interface
+ *
+ * file layout
+ * all numbers are sfputu() format
+ *
+ * 4 char magic (^M^S^G0)
+ * <method locale YYYY-MM-DD>\0
+ * (<optional strings>\0)*
+ * \0
+ * string table size
+ * #msgs total
+ * #max set number
+ * #set-id 1
+ * #msgs in set 1
+ * ...
+ * #set-id #sets
+ * #msgs in set #sets
+ * end of sets (0)
+ * msg(1,1) size
+ * ...
+ * msg(#sets,#msgs) size
+ * string table
+ */
+
+#ifndef _MC_H
+#define _MC_H
+
+#include <ast.h>
+
+#define MC_MAGIC "\015\023\007\000"
+#define MC_MAGIC_SIZE 4
+
+#define MC_SET_MAX 1023
+#define MC_NUM_MAX 32767
+
+#define MC_NLS (1<<10)
+
+#define MC_MESSAGE_SET(s) mcindex(s,NiL,NiL,NiL)
+
+typedef struct Mcset_s
+{
+ char** msg;
+ int num;
+ int gen;
+} Mcset_t;
+
+typedef struct Mc_s
+{
+ Mcset_t* set;
+ int num;
+ int gen;
+ char* translation;
+#ifdef _MC_PRIVATE_
+ _MC_PRIVATE_
+#endif
+} Mc_t;
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char* mcfind(const char*, const char*, int, int, char*, size_t);
+extern Mc_t* mcopen(Sfio_t*);
+extern char* mcget(Mc_t*, int, int, const char*);
+extern int mcput(Mc_t*, int, int, const char*);
+extern int mcdump(Mc_t*, Sfio_t*);
+extern int mcindex(const char*, char**, int*, int*);
+extern int mcclose(Mc_t*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/mime.h b/src/lib/libast/include/mime.h
new file mode 100644
index 0000000..6fa7657
--- /dev/null
+++ b/src/lib/libast/include/mime.h
@@ -0,0 +1,91 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * mime/mailcap interface
+ */
+
+#ifndef _MIMETYPE_H
+#define _MIMETYPE_H 1
+
+#include <sfio.h>
+#include <ls.h>
+
+#define MIME_VERSION 19970717L
+
+#ifndef MIME_FILES
+#define MIME_FILES "~/.mailcap:/usr/local/etc/mailcap:/usr/etc/mailcap:/etc/mailcap:/etc/mail/mailcap:/usr/public/lib/mailcap"
+#endif
+
+#define MIME_FILES_ENV "MAILCAP"
+
+#define MIME_LIST (1<<0) /* mimeload arg is : list */
+#define MIME_NOMAGIC (1<<1) /* no magic for mimetype() */
+#define MIME_PIPE (1<<2) /* mimeview() io is piped */
+#define MIME_REPLACE (1<<3) /* replace existing definition */
+
+#define MIME_USER (1L<<16) /* first user flag bit */
+
+struct Mime_s;
+typedef struct Mime_s Mime_t;
+
+struct Mimedisc_s;
+typedef struct Mimedisc_s Mimedisc_t;
+
+typedef int (*Mimevalue_f)(Mime_t*, void*, char*, size_t, Mimedisc_t*);
+
+struct Mimedisc_s
+{
+ unsigned long version; /* interface version */
+ unsigned long flags; /* MIME_* flags */
+ Error_f errorf; /* error function */
+ Mimevalue_f valuef; /* value extraction function */
+};
+
+struct Mime_s
+{
+ const char* id; /* library id string */
+
+#ifdef _MIME_PRIVATE_
+ _MIME_PRIVATE_
+#endif
+
+};
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern Mime_t* mimeopen(Mimedisc_t*);
+extern int mimeload(Mime_t*, const char*, unsigned long);
+extern int mimelist(Mime_t*, Sfio_t*, const char*);
+extern int mimeclose(Mime_t*);
+extern int mimeset(Mime_t*, char*, unsigned long);
+extern char* mimetype(Mime_t*, Sfio_t*, const char*, struct stat*);
+extern char* mimeview(Mime_t*, const char*, const char*, const char*, const char*);
+extern int mimehead(Mime_t*, void*, size_t, size_t, char*);
+extern int mimecmp(const char*, const char*, char**);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/mnt.h b/src/lib/libast/include/mnt.h
new file mode 100644
index 0000000..698c730
--- /dev/null
+++ b/src/lib/libast/include/mnt.h
@@ -0,0 +1,58 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * mounted filesystem scan interface
+ */
+
+#ifndef _MNT_H
+#define _MNT_H 1
+
+#undef MNT_REMOTE /* aix clash */
+#define MNT_REMOTE (1<<0) /* remote mount */
+
+typedef struct
+{
+ char* fs; /* filesystem name */
+ char* dir; /* mounted dir */
+ char* type; /* filesystem type */
+ char* options; /* options */
+ int freq; /* backup frequency */
+ int npass; /* number of parallel passes */
+ int flags; /* MNT_* flags */
+} Mnt_t;
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern void* mntopen(const char*, const char*);
+extern Mnt_t* mntread(void*);
+extern int mntwrite(void*, const Mnt_t*);
+extern int mntclose(void*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/modecanon.h b/src/lib/libast/include/modecanon.h
new file mode 100644
index 0000000..5d1721f
--- /dev/null
+++ b/src/lib/libast/include/modecanon.h
@@ -0,0 +1,65 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * canonical mode_t representation
+ */
+
+#ifndef _MODECANON_H
+#define _MODECANON_H
+
+#define X_ITYPE(m) ((m)&X_IFMT)
+
+#define X_IFMT 0170000
+#define X_IFWHT 0160000
+#define X_IFDOOR 0150000
+#define X_IFSOCK 0140000
+#define X_IFLNK 0120000
+#define X_IFCTG 0110000
+#define X_IFREG 0100000
+#define X_IFBLK 0060000
+#define X_IFDIR 0040000
+#define X_IFCHR 0020000
+#define X_IFIFO 0010000
+
+#define X_IPERM 0007777
+#define X_ISUID 0004000
+#define X_ISGID 0002000
+#define X_ISVTX 0001000
+#define X_IRUSR 0000400
+#define X_IWUSR 0000200
+#define X_IXUSR 0000100
+#define X_IRGRP 0000040
+#define X_IWGRP 0000020
+#define X_IXGRP 0000010
+#define X_IROTH 0000004
+#define X_IWOTH 0000002
+#define X_IXOTH 0000001
+
+#define X_IRWXU (X_IRUSR|X_IWUSR|X_IXUSR)
+#define X_IRWXG (X_IRGRP|X_IWGRP|X_IXGRP)
+#define X_IRWXO (X_IROTH|X_IWOTH|X_IXOTH)
+
+#endif
diff --git a/src/lib/libast/include/modex.h b/src/lib/libast/include/modex.h
new file mode 100644
index 0000000..e8b52f7
--- /dev/null
+++ b/src/lib/libast/include/modex.h
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Research
+ *
+ * external mode_t representation support
+ */
+
+#ifndef _MODEX_H
+#define _MODEX_H
+
+#include <ast_fs.h>
+#include <modecanon.h>
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int modei(int);
+extern int modex(int);
+
+#undef extern
+
+#if _S_IDPERM
+#define modei(m) ((m)&X_IPERM)
+#if _S_IDTYPE
+#define modex(m) (m)
+#endif
+#endif
+
+#endif
diff --git a/src/lib/libast/include/namval.h b/src/lib/libast/include/namval.h
new file mode 100644
index 0000000..9c055cc
--- /dev/null
+++ b/src/lib/libast/include/namval.h
@@ -0,0 +1,42 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * common name-value struct support
+ */
+
+#ifndef _NAMVAL_H
+#define _NAMVAL_H
+
+typedef struct
+{
+ char* name;
+ int value;
+#ifdef _NAMVAL_PRIVATE_
+ _NAMVAL_PRIVATE_
+#endif
+} Namval_t;
+
+#endif
diff --git a/src/lib/libast/include/option.h b/src/lib/libast/include/option.h
new file mode 100644
index 0000000..1d24690
--- /dev/null
+++ b/src/lib/libast/include/option.h
@@ -0,0 +1,106 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * command line option parse interface
+ */
+
+#ifndef _OPTION_H
+#define _OPTION_H
+
+#include <ast.h>
+
+#define OPT_VERSION 20070319L
+
+#define OPT_USER (1L<<16) /* first user flag bit */
+
+struct Opt_s;
+struct Optdisc_s;
+
+typedef int (*Optinfo_f)(struct Opt_s*, Sfio_t*, const char*, struct Optdisc_s*);
+
+typedef struct Optdisc_s
+{
+ unsigned long version; /* OPT_VERSION */
+ unsigned long flags; /* OPT_* flags */
+ char* catalog; /* error catalog id */
+ Optinfo_f infof; /* runtime info function */
+} Optdisc_t;
+
+/* NOTE: Opt_t member order fixed by a previous binary release */
+
+#ifndef _OPT_PRIVATE_
+#define _OPT_PRIVATE_ \
+ char pad[3*sizeof(void*)];
+#endif
+
+typedef struct Opt_s
+{
+ int again; /* see optjoin() */
+ char* arg; /* {:,#} string argument */
+ char** argv; /* most recent argv */
+ int index; /* argv index */
+ char* msg; /* error/usage message buffer */
+ long num; /* OBSOLETE -- use number */
+ int offset; /* char offset in argv[index] */
+ char option[8]; /* current flag {-,+} + option */
+ char name[64]; /* current long name or flag */
+ Optdisc_t* disc; /* user discipline */
+ intmax_t number; /* # numeric argument */
+ unsigned char assignment; /* option arg assigment op */
+ unsigned char pads[sizeof(void*)-1];
+ _OPT_PRIVATE_
+} Opt_t;
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+#if !_BLD_ast && defined(__IMPORT__)
+#define extern extern __IMPORT__
+#endif
+
+extern Opt_t* _opt_infop_;
+
+#define opt_info (*_opt_infop_)
+
+#undef extern
+
+#define optinit(d,f) (memset(d,0,sizeof(*(d))),(d)->version=OPT_VERSION,(d)->infof=(f),opt_info.disc=(d))
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int optget(char**, const char*);
+extern int optjoin(char**, ...);
+extern char* opthelp(const char*, const char*);
+extern char* optusage(const char*);
+extern int optstr(const char*, const char*);
+extern int optesc(Sfio_t*, const char*, int);
+extern Opt_t* optctx(Opt_t*, Opt_t*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/proc.h b/src/lib/libast/include/proc.h
new file mode 100644
index 0000000..76fdf83
--- /dev/null
+++ b/src/lib/libast/include/proc.h
@@ -0,0 +1,108 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * process library interface
+ */
+
+#ifndef _PROC_H
+#define _PROC_H
+
+#include <ast.h>
+
+#define PROC_ARGMOD (1<<0) /* argv[-1],argv[0] can be modified */
+#define PROC_BACKGROUND (1<<1) /* shell background (&) setup */
+#define PROC_CHECK (1<<17) /* check that command exists */
+#define PROC_CLEANUP (1<<2) /* close parent redirect fds on error */
+#define PROC_DAEMON (1<<3) /* daemon setup */
+#define PROC_ENVCLEAR (1<<4) /* clear environment */
+#define PROC_FOREGROUND (1<<14) /* system(3) setup */
+#define PROC_GID (1<<5) /* setgid(getgid()) */
+#define PROC_IGNORE (1<<6) /* ignore parent pipe errors */
+#define PROC_IGNOREPATH (1<<16) /* procrun() intercept to ignore path */
+#define PROC_ORPHAN (1<<18) /* create orphaned process */
+#define PROC_OVERLAY (1<<7) /* overlay current process if possible */
+#define PROC_PARANOID (1<<8) /* restrict everything */
+#define PROC_PRIVELEGED (1<<9) /* setuid(0), setgid(getegid()) */
+#define PROC_READ (1<<10) /* proc pipe fd 1 returned */
+#define PROC_SESSION (1<<11) /* session leader */
+#define PROC_UID (1<<12) /* setuid(getuid()) */
+#define PROC_WRITE (1<<13) /* proc pipe fd 0 returned */
+#define PROC_ZOMBIE (1<<15) /* proc may leave a zombie behind */
+
+#define PROC_ARG_BIT 14 /* bits per op arg */
+#define PROC_OP_BIT 4 /* bits per op */
+
+#define PROC_ARG_NULL ((1<<PROC_ARG_BIT)-1)
+
+#define PROC_fd_dup 0x4
+#define PROC_FD_CHILD 0x1
+#define PROC_FD_PARENT 0x2
+
+#define PROC_sig_dfl 0x8
+#define PROC_sig_ign 0x9
+
+#define PROC_sys_pgrp 0xa
+#define PROC_sys_umask 0xb
+
+#define PROC_fd_ctty 0xc
+
+#define PROC_op1(o,a) (((o)<<(2*PROC_ARG_BIT))|((a)&((PROC_ARG_NULL<<PROC_ARG_BIT)|PROC_ARG_NULL)))
+#define PROC_op2(o,a,b) (((o)<<(2*PROC_ARG_BIT))|(((b)&PROC_ARG_NULL)<<PROC_ARG_BIT)|((a)&PROC_ARG_NULL))
+
+#define PROC_FD_CLOSE(p,f) PROC_op2(PROC_fd_dup|(f),p,PROC_ARG_NULL)
+#define PROC_FD_CTTY(f) PROC_op1(PROC_fd_ctty,f)
+#define PROC_FD_DUP(p,c,f) PROC_op2(PROC_fd_dup|(f),p,c)
+#define PROC_SIG_DFL(s) PROC_op1(PROC_sig_dfl,s,0)
+#define PROC_SIG_IGN(s) PROC_op1(PROC_sig_ign,s,0)
+#define PROC_SYS_PGRP(g) PROC_op1(PROC_sys_pgrp,g)
+#define PROC_SYS_UMASK(m) PROC_op1(PROC_sys_umask,m,0)
+
+#define PROC_OP(x) (((x)>>(2*PROC_ARG_BIT))&((1<<PROC_OP_BIT)-1))
+#define PROC_ARG(x,n) ((n)?(((x)>>(((n)-1)*PROC_ARG_BIT))&PROC_ARG_NULL):(((x)&~((1<<(2*PROC_ARG_BIT))-1))==~((1<<(2*PROC_ARG_BIT))-1))?(-1):((x)&~((1<<(2*PROC_ARG_BIT))-1)))
+
+typedef struct
+{
+ pid_t pid; /* process id */
+ pid_t pgrp; /* process group id */
+ int rfd; /* read fd if applicable */
+ int wfd; /* write fd if applicable */
+
+#ifdef _PROC_PRIVATE_
+_PROC_PRIVATE_
+#endif
+
+} Proc_t;
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int procclose(Proc_t*);
+extern int procfree(Proc_t*);
+extern Proc_t* procopen(const char*, char**, char**, long*, int);
+extern int procrun(const char*, char**, int);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/recfmt.h b/src/lib/libast/include/recfmt.h
new file mode 100644
index 0000000..aaae3c0
--- /dev/null
+++ b/src/lib/libast/include/recfmt.h
@@ -0,0 +1,83 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * record format interface
+ */
+
+#ifndef _RECFMT_H
+#define _RECFMT_H 1
+
+#include <ast.h>
+
+typedef uint32_t Recfmt_t;
+
+#define REC_delimited 0
+#define REC_fixed 1
+#define REC_variable 2
+#define REC_method 14
+#define REC_none 15
+
+#define REC_M_path 0
+#define REC_M_data 1
+
+#define RECTYPE(f) (((f)>>28)&((1<<4)-1))
+
+#define REC_D_TYPE(d) ((REC_delimited<<28)|((d)&((1<<8)-1)))
+#define REC_D_DELIMITER(f) ((f)&((1<<8)-1))
+
+#define REC_F_TYPE(s) ((REC_fixed<<28)|((s)&((1<<28)-1)))
+#define REC_F_SIZE(f) ((f)&((1<<28)-1))
+
+#define REC_U_TYPE(t,a) (((t)<<28)|((a)&((1<<28)-1)))
+#define REC_U_ATTRIBUTES(f) ((f)&~((1<<28)-1))
+
+#define REC_V_TYPE(h,o,z,l,i) ((REC_variable<<28)|((h)<<23)|((o)<<19)|(((z)-1)<<18)|((l)<<17)|((i)<<16))
+#define REC_V_RECORD(f,s) (((f)&(((1<<16)-1)<<16))|(s))
+#define REC_V_HEADER(f) (((f)>>23)&((1<<5)-1))
+#define REC_V_OFFSET(f) (((f)>>19)&((1<<4)-1))
+#define REC_V_LENGTH(f) ((((f)>>18)&1)+1)
+#define REC_V_LITTLE(f) (((f)>>17)&1)
+#define REC_V_INCLUSIVE(f) (((f)>>16)&1)
+#define REC_V_SIZE(f) ((f)&((1<<16)-1))
+#define REC_V_ATTRIBUTES(f) ((f)&~((1<<16)-1))
+
+#define REC_M_TYPE(i) ((REC_method<<28)|(i))
+#define REC_M_INDEX(f) ((f)&((1<<28)-1))
+
+#define REC_N_TYPE() 0xffffffff
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char* fmtrec(Recfmt_t, int);
+extern Recfmt_t recfmt(const void*, size_t, off_t);
+extern Recfmt_t recstr(const char*, char**);
+extern ssize_t reclen(Recfmt_t, const void*, size_t);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/regex.h b/src/lib/libast/include/regex.h
new file mode 100644
index 0000000..8b357fe
--- /dev/null
+++ b/src/lib/libast/include/regex.h
@@ -0,0 +1,248 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * regex library interface
+ */
+
+#ifdef _AST_STD_I
+#define _REGEX_H -1
+#define regex_t int
+#define regmatch_t int
+#endif
+#ifndef _REGEX_H
+#define _REGEX_H 1
+#undef regex_t
+#undef regmatch_t
+
+#include <ast_common.h>
+#include <ast_wchar.h>
+
+#define REG_VERSION 20100930L
+
+/* regcomp flags */
+
+#define REG_AUGMENTED 0x00000001 /* enable ! & < > */
+#define REG_EXTENDED 0x00000002 /* enable ( | ) */
+#define REG_ICASE 0x00000004 /* ignore case in match */
+#define REG_NEWLINE 0x00000008 /* ^/$ match embedded \n */
+#define REG_NOSUB 0x00000010 /* don't report subexp matches */
+#define REG_SHELL 0x00000020 /* shell pattern syntax */
+
+/* nonstandard regcomp flags */
+
+#define REG_LEFT 0x00000100 /* implicit ^... */
+#define REG_LITERAL 0x00000200 /* no operators */
+#define REG_MINIMAL 0x00000400 /* minimal match */
+#define REG_NULL 0x00000800 /* allow null patterns */
+#define REG_RIGHT 0x00001000 /* implicit ...$ */
+#define REG_LENIENT 0x00002000 /* look the other way */
+#define REG_ESCAPE 0x00004000 /* \ escapes delimiter in [...] */
+#define REG_FIRST 0x00008000 /* first match found will do */
+#define REG_MULTIPLE 0x00010000 /* multiple \n sep patterns */
+#define REG_DISCIPLINE 0x00020000 /* regex_t.re_disc is valid */
+#define REG_SPAN 0x00040000 /* . matches \n */
+#define REG_COMMENT 0x00080000 /* ignore pattern space & #...\n*/
+#define REG_MULTIREF 0x00100000 /* multiple digit backrefs */
+#define REG_MUSTDELIM 0x08000000 /* all delimiters required */
+#define REG_DELIMITED 0x10000000 /* pattern[0] is delimiter */
+#define REG_CLASS_ESCAPE 0x80000000 /* \ escapes in [...] */
+
+#define REG_SHELL_DOT 0x00200000 /* explicit leading . match */
+#define REG_SHELL_ESCAPED 0x00400000 /* \ not special */
+#define REG_SHELL_GROUP 0x20000000 /* (|&) inside [@|&](...) only */
+#define REG_SHELL_PATH 0x00800000 /* explicit / match */
+
+#define REG_REGEXP 0x40000000 /* <regexp.h> compatibility */
+
+/* regexec flags */
+
+#define REG_NOTBOL 0x00000040 /* ^ is not a special char */
+#define REG_NOTEOL 0x00000080 /* $ is not a special char */
+
+/* nonstandard regexec flags */
+
+#define REG_INVERT 0x01000000 /* invert regrexec match sense */
+#define REG_STARTEND 0x02000000 /* subject==match[0].rm_{so,eo} */
+#define REG_ADVANCE 0x04000000 /* advance match[0].rm_{so,eo} */
+
+/* regalloc flags */
+
+#define REG_NOFREE 0x00000001 /* don't free */
+
+/* regsub flags */
+
+#define REG_SUB_ALL 0x00000001 /* substitute all occurrences */
+#define REG_SUB_LOWER 0x00000002 /* substitute to lower case */
+#define REG_SUB_UPPER 0x00000004 /* substitute to upper case */
+#define REG_SUB_PRINT 0x00000010 /* internal no-op */
+#define REG_SUB_NUMBER 0x00000020 /* internal no-op */
+#define REG_SUB_STOP 0x00000040 /* internal no-op */
+#define REG_SUB_WRITE 0x00000080 /* internal no-op */
+#define REG_SUB_LAST 0x00000100 /* last substitution option */
+#define REG_SUB_FULL 0x00000200 /* fully delimited */
+#define REG_SUB_USER 0x00001000 /* first user flag bit */
+
+/* regex error codes */
+
+#define REG_ENOSYS (-1) /* not supported */
+#define REG_NOMATCH 1 /* regexec didn't match */
+#define REG_BADPAT 2 /* invalid regular expression */
+#define REG_ECOLLATE 3 /* invalid collation element */
+#define REG_ECTYPE 4 /* invalid character class */
+#define REG_EESCAPE 5 /* trailing \ in pattern */
+#define REG_ESUBREG 6 /* invalid \digit backreference */
+#define REG_EBRACK 7 /* [...] imbalance */
+#define REG_EPAREN 8 /* \(...\) or (...) imbalance */
+#define REG_EBRACE 9 /* \{...\} or {...} imbalance */
+#define REG_BADBR 10 /* invalid {...} digits */
+#define REG_ERANGE 11 /* invalid [...] range endpoint */
+#define REG_ESPACE 12 /* out of space */
+#define REG_BADRPT 13 /* unary op not preceded by re */
+#define REG_ENULL 14 /* empty subexpr in pattern */
+#define REG_ECOUNT 15 /* re component count overflow */
+#define REG_BADESC 16 /* invalid \char escape */
+#define REG_VERSIONID 17 /* version id (pseudo error) */
+#define REG_EFLAGS 18 /* flags conflict */
+#define REG_EDELIM 19 /* invalid or omitted delimiter */
+#define REG_PANIC 20 /* unrecoverable internal error */
+
+struct regex_s; typedef struct regex_s regex_t;
+struct regdisc_s; typedef struct regdisc_s regdisc_t;
+
+typedef int (*regclass_t)(int);
+typedef uint32_t regflags_t;
+typedef int regoff_t;
+typedef int (*regerror_t)(const regex_t*, regdisc_t*, int, ...);
+typedef void* (*regcomp_t)(const regex_t*, const char*, size_t, regdisc_t*);
+typedef int (*regexec_t)(const regex_t*, void*, const char*, size_t, const char*, size_t, char**, regdisc_t*);
+typedef void* (*regresize_t)(void*, void*, size_t);
+typedef int (*regrecord_t)(void*, const char*, size_t);
+
+typedef struct regmatch_s
+{
+ regoff_t rm_so; /* offset of start */
+ regoff_t rm_eo; /* offset of end */
+} regmatch_t;
+
+typedef struct regsub_s
+{
+ regflags_t re_flags; /* regsubcomp() flags */
+ char* re_buf; /* regsubexec() output buffer */
+ size_t re_len; /* re_buf length */
+ int re_min; /* regsubcomp() min matches */
+#ifdef _REG_SUB_PRIVATE_
+ _REG_SUB_PRIVATE_
+#endif
+} regsub_t;
+
+struct regdisc_s
+{
+ unsigned long re_version; /* discipline version */
+ regflags_t re_flags; /* discipline flags */
+ regerror_t re_errorf; /* error function */
+ int re_errorlevel; /* errorf level */
+ regresize_t re_resizef; /* alloc/free function */
+ void* re_resizehandle;/* resizef handle */
+ regcomp_t re_compf; /* (?{...}) compile function */
+ regexec_t re_execf; /* (?{...}) execute function */
+ unsigned char* re_map; /* external to native ccode map */
+};
+
+typedef struct regstat_s
+{
+ regflags_t re_flags; /* REG_* */
+ ssize_t re_min; /* min anchored match length */
+ ssize_t re_max; /* max anchored match length */
+ ssize_t re_record; /* regrexec() match length */
+ regflags_t re_info; /* REG_* info */
+} regstat_t;
+
+struct regex_s
+{
+ size_t re_nsub; /* number of subexpressions */
+ struct reglib_s*re_info; /* library private info */
+ size_t re_npat; /* number of pattern chars used */
+ regdisc_t* re_disc; /* REG_DISCIPLINE discipline */
+ regsub_t* re_sub; /* regsubcomp() data */
+};
+
+#define reginit(disc) (memset(disc,0,sizeof(*(disc))),(disc)->re_version=REG_VERSION)
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int regcomp(regex_t*, const char*, regflags_t);
+extern size_t regerror(int, const regex_t*, char*, size_t);
+extern int regexec(const regex_t*, const char*, size_t, regmatch_t*, regflags_t);
+extern void regfree(regex_t*);
+
+/* nonstandard hooks */
+
+#define _REG_cache 1 /* have regcache() */
+#define _REG_class 1 /* have regclass() */
+#define _REG_collate 1 /* have regcollate(), regclass() */
+#define _REG_comb 1 /* have regcomb() */
+#define _REG_decomp 1 /* have regdecomp() */
+#define _REG_dup 1 /* have regdup() */
+#define _REG_fatal 1 /* have regfatal(), regfatalpat() */
+#define _REG_ncomp 1 /* have regncomp() */
+#define _REG_nexec 1 /* have regnexec() */
+#define _REG_rexec 1 /* have regrexec(), regrecord() */
+#define _REG_stat 1 /* have regstat() */
+#define _REG_subcomp 1 /* have regsubcomp(), regsubexec() */
+
+extern regclass_t regclass(const char*, char**);
+extern int regaddclass(const char*, regclass_t);
+extern int regcollate(const char*, char**, char*, size_t, wchar_t*);
+extern int regcomb(regex_t*, regex_t*);
+extern size_t regdecomp(regex_t*, regflags_t, char*, size_t);
+extern int regdup(regex_t*, regex_t*);
+extern int regncomp(regex_t*, const char*, size_t, regflags_t);
+extern int regnexec(const regex_t*, const char*, size_t, size_t, regmatch_t*, regflags_t);
+extern void regfatal(regex_t*, int, int);
+extern void regfatalpat(regex_t*, int, int, const char*);
+extern int regrecord(const regex_t*);
+extern int regrexec(const regex_t*, const char*, size_t, size_t, regmatch_t*, regflags_t, int, void*, regrecord_t);
+extern regstat_t* regstat(const regex_t*);
+
+extern regex_t* regcache(const char*, regflags_t, int*);
+
+extern int regsubcomp(regex_t*, const char*, const regflags_t*, int, regflags_t);
+extern int regsubexec(const regex_t*, const char*, size_t, regmatch_t*);
+extern int regsubflags(regex_t*, const char*, char**, int, const regflags_t*, int*, regflags_t*);
+extern void regsubfree(regex_t*);
+
+/* obsolete hooks */
+
+#ifndef _SFIO_H
+struct _sfio_s;
+#endif
+
+extern void regalloc(void*, regresize_t, regflags_t);
+extern int regsub(const regex_t*, struct _sfio_s*, const char*, const char*, size_t, regmatch_t*, regflags_t);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/sfdisc.h b/src/lib/libast/include/sfdisc.h
new file mode 100644
index 0000000..b48eb43
--- /dev/null
+++ b/src/lib/libast/include/sfdisc.h
@@ -0,0 +1,70 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Research
+ *
+ * sfio discipline interface definitions
+ */
+
+#ifndef _SFDISC_H
+#define _SFDISC_H
+
+#include <ast.h>
+
+#define SFDCEVENT(a,b,n) ((((a)-'A'+1)<<11)^(((b)-'A'+1)<<6)^(n))
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#define SFSK_DISCARD SFDCEVENT('S','K',1)
+
+/*
+ * %(...) printf support
+ */
+
+typedef int (*Sf_key_lookup_t)(void*, Sffmt_t*, const char*, char**, Sflong_t*);
+typedef char* (*Sf_key_convert_t)(void*, Sffmt_t*, const char*, char*, Sflong_t);
+
+extern int sfkeyprintf(Sfio_t*, void*, const char*, Sf_key_lookup_t, Sf_key_convert_t);
+extern int sfkeyprintf_20000308(Sfio_t*, void*, const char*, Sf_key_lookup_t, Sf_key_convert_t);
+
+/*
+ * pure sfio read and/or write disciplines
+ */
+
+extern int sfdcdio(Sfio_t*, size_t);
+extern int sfdcdos(Sfio_t*);
+extern int sfdcfilter(Sfio_t*, const char*);
+extern int sfdcmore(Sfio_t*, const char*, int, int);
+extern int sfdcprefix(Sfio_t*, const char*);
+extern int sfdcseekable(Sfio_t*);
+extern int sfdcslow(Sfio_t*);
+extern int sfdctee(Sfio_t*, Sfio_t*);
+extern int sfdcunion(Sfio_t*, Sfio_t**, int);
+
+extern Sfio_t* sfdcsubstream(Sfio_t*, Sfio_t*, Sfoff_t, Sfoff_t);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/sfio.h b/src/lib/libast/include/sfio.h
new file mode 100644
index 0000000..1e3ede5
--- /dev/null
+++ b/src/lib/libast/include/sfio.h
@@ -0,0 +1,457 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _SFIO_H
+#define _SFIO_H 1
+
+#define SFIO_VERSION 20090915L
+
+/* Public header file for the sfio library
+**
+** Written by Kiem-Phong Vo
+*/
+
+typedef struct _sfio_s Sfio_t;
+typedef struct _sfdisc_s Sfdisc_t;
+
+#if defined(_AST_STD_H) || defined(_PACKAGE_ast) && defined(_SFIO_PRIVATE)
+#include <ast_std.h>
+#else
+#include <ast_common.h>
+#endif /* _PACKAGE_ast */
+
+/* Sfoff_t should be large enough for largest file address */
+#define Sfoff_t intmax_t
+#define Sflong_t intmax_t
+#define Sfulong_t uintmax_t
+#define Sfdouble_t _ast_fltmax_t
+
+typedef ssize_t (*Sfread_f)_ARG_((Sfio_t*, Void_t*, size_t, Sfdisc_t*));
+typedef ssize_t (*Sfwrite_f)_ARG_((Sfio_t*, const Void_t*, size_t, Sfdisc_t*));
+typedef Sfoff_t (*Sfseek_f)_ARG_((Sfio_t*, Sfoff_t, int, Sfdisc_t*));
+typedef int (*Sfexcept_f)_ARG_((Sfio_t*, int, Void_t*, Sfdisc_t*));
+typedef int (*Sfwalk_f)_ARG_((Sfio_t*, Void_t*));
+
+/* discipline structure */
+struct _sfdisc_s
+{ Sfread_f readf; /* read function */
+ Sfwrite_f writef; /* write function */
+ Sfseek_f seekf; /* seek function */
+ Sfexcept_f exceptf; /* to handle exceptions */
+ Sfdisc_t* disc; /* the continuing discipline */
+};
+
+#include <sfio_s.h>
+
+/* formatting environment */
+typedef struct _sffmt_s Sffmt_t;
+typedef int (*Sffmtext_f)_ARG_((Sfio_t*, Void_t*, Sffmt_t*));
+typedef int (*Sffmtevent_f)_ARG_((Sfio_t*, int, Void_t*, Sffmt_t*));
+struct _sffmt_s
+{ long version;/* version of this structure */
+ Sffmtext_f extf; /* function to process arguments */
+ Sffmtevent_f eventf; /* process events */
+
+ char* form; /* format string to stack */
+ va_list args; /* corresponding arg list */
+
+ int fmt; /* format character */
+ ssize_t size; /* object size */
+ int flags; /* formatting flags */
+ int width; /* width of field */
+ int precis; /* precision required */
+ int base; /* conversion base */
+
+ char* t_str; /* type string */
+ ssize_t n_str; /* length of t_str */
+
+ Void_t* mbs; /* multibyte state for format string */
+
+ Void_t* none; /* unused for now */
+};
+#define sffmtversion(fe,type) \
+ ((type) ? ((fe)->version = SFIO_VERSION) : (fe)->version)
+
+#define SFFMT_SSHORT 000000010 /* 'hh' flag, char */
+#define SFFMT_TFLAG 000000020 /* 't' flag, ptrdiff_t */
+#define SFFMT_ZFLAG 000000040 /* 'z' flag, size_t */
+
+#define SFFMT_LEFT 000000100 /* left-justification */
+#define SFFMT_SIGN 000000200 /* must have a sign */
+#define SFFMT_BLANK 000000400 /* if not signed, prepend a blank */
+#define SFFMT_ZERO 000001000 /* zero-padding on the left */
+#define SFFMT_ALTER 000002000 /* alternate formatting */
+#define SFFMT_THOUSAND 000004000 /* thousand grouping */
+#define SFFMT_SKIP 000010000 /* skip assignment in scanf() */
+#define SFFMT_SHORT 000020000 /* 'h' flag */
+#define SFFMT_LONG 000040000 /* 'l' flag */
+#define SFFMT_LLONG 000100000 /* 'll' flag */
+#define SFFMT_LDOUBLE 000200000 /* 'L' flag */
+#define SFFMT_VALUE 000400000 /* value is returned */
+#define SFFMT_ARGPOS 001000000 /* getting arg for $ patterns */
+#define SFFMT_IFLAG 002000000 /* 'I' flag */
+#define SFFMT_JFLAG 004000000 /* 'j' flag, intmax_t */
+#define SFFMT_CENTER 010000000 /* '=' flag, center justification */
+#define SFFMT_CHOP 020000000 /* chop long string values from left */
+#define SFFMT_SET 037777770 /* flags settable on calling extf */
+
+/* for sfmutex() call */
+#define SFMTX_LOCK 0 /* up mutex count */
+#define SFMTX_TRYLOCK 1 /* try to up mutex count */
+#define SFMTX_UNLOCK 2 /* down mutex count */
+#define SFMTX_CLRLOCK 3 /* clear mutex count */
+
+/* various constants */
+#ifndef NULL
+#define NULL 0
+#endif
+#ifndef EOF
+#define EOF (-1)
+#endif
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+#endif
+
+/* bits for various types of files */
+#define SF_READ 0000001 /* open for reading */
+#define SF_WRITE 0000002 /* open for writing */
+#define SF_STRING 0000004 /* a string stream */
+#define SF_APPENDWR 0000010 /* file is in append mode only */
+#define SF_MALLOC 0000020 /* buffer is malloc-ed */
+#define SF_LINE 0000040 /* line buffering */
+#define SF_SHARE 0000100 /* stream with shared file descriptor */
+#define SF_EOF 0000200 /* eof was detected */
+#define SF_ERROR 0000400 /* an error happened */
+#define SF_STATIC 0001000 /* a stream that cannot be freed */
+#define SF_IOCHECK 0002000 /* call exceptf before doing IO */
+#define SF_PUBLIC 0004000 /* SF_SHARE and follow physical seek */
+#define SF_MTSAFE 0010000 /* need thread safety */
+#define SF_WHOLE 0020000 /* preserve wholeness of sfwrite/sfputr */
+#define SF_IOINTR 0040000 /* return on interrupts */
+#define SF_WCWIDTH 0100000 /* wcwidth display stream */
+
+#define SF_FLAGS 0177177 /* PUBLIC FLAGS PASSABLE TO SFNEW() */
+#define SF_SETS 0177163 /* flags passable to sfset() */
+
+#ifndef _SF_NO_OBSOLETE
+#define SF_BUFCONST 0400000 /* unused flag - for compatibility only */
+#endif
+
+/* for sfgetr/sfreserve to hold a record */
+#define SF_LOCKR 0000010 /* lock record, stop access to stream */
+#define SF_LASTR 0000020 /* get the last incomplete record */
+
+/* exception events: SF_NEW(0), SF_READ(1), SF_WRITE(2) and the below */
+#define SF_SEEK 3 /* seek error */
+#define SF_CLOSING 4 /* when stream is about to be closed */
+#define SF_DPUSH 5 /* when discipline is being pushed */
+#define SF_DPOP 6 /* when discipline is being popped */
+#define SF_DPOLL 7 /* see if stream is ready for I/O */
+#define SF_DBUFFER 8 /* buffer not empty during push or pop */
+#define SF_SYNC 9 /* announcing start/end synchronization */
+#define SF_PURGE 10 /* a sfpurge() call was issued */
+#define SF_FINAL 11 /* closing is done except stream free */
+#define SF_READY 12 /* a polled stream is ready */
+#define SF_LOCKED 13 /* stream is in a locked state */
+#define SF_ATEXIT 14 /* process is exiting */
+#define SF_EVENT 100 /* start of user-defined events */
+
+/* for stack and disciplines */
+#define SF_POPSTACK ((Sfio_t*)0) /* pop the stream stack */
+#define SF_POPDISC ((Sfdisc_t*)0) /* pop the discipline stack */
+
+/* for the notify function and discipline exception */
+#define SF_NEW 0 /* new stream */
+#define SF_SETFD (-1) /* about to set the file descriptor */
+#define SF_MTACCESS (-2) /* starting a multi-threaded stream */
+
+#define SF_BUFSIZE 8192 /* default buffer size */
+#define SF_UNBOUND (-1) /* unbounded buffer size */
+
+/* namespace incursion workarounds -- migrate to the new names */
+#if !_mac_SF_APPEND
+#define SF_APPEND SF_APPENDWR /* BSDI sys/stat.h */
+#endif
+#if !_mac_SF_CLOSE
+#define SF_CLOSE SF_CLOSING /* AIX sys/socket.h */
+#endif
+
+_BEGIN_EXTERNS_
+
+#if _BLD_sfio && defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+#if !_BLD_sfio && defined(__IMPORT__)
+#define extern extern __IMPORT__
+#endif
+
+extern ssize_t _Sfi;
+extern ssize_t _Sfmaxr;
+
+/* standard in/out/err streams */
+extern Sfio_t* sfstdin;
+extern Sfio_t* sfstdout;
+extern Sfio_t* sfstderr;
+
+#if _UWIN
+#undef extern
+#endif
+
+extern Sfio_t _Sfstdin;
+extern Sfio_t _Sfstdout;
+extern Sfio_t _Sfstderr;
+
+#undef extern
+
+#if _BLD_sfio && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern Sfio_t* sfnew _ARG_((Sfio_t*, Void_t*, size_t, int, int));
+extern Sfio_t* sfopen _ARG_((Sfio_t*, const char*, const char*));
+extern Sfio_t* sfpopen _ARG_((Sfio_t*, const char*, const char*));
+extern Sfio_t* sfstack _ARG_((Sfio_t*, Sfio_t*));
+extern Sfio_t* sfswap _ARG_((Sfio_t*, Sfio_t*));
+extern Sfio_t* sftmp _ARG_((size_t));
+extern int sfwalk _ARG_((Sfwalk_f, Void_t*, int));
+extern int sfpurge _ARG_((Sfio_t*));
+extern int sfpoll _ARG_((Sfio_t**, int, int));
+extern Void_t* sfreserve _ARG_((Sfio_t*, ssize_t, int));
+extern int sfresize _ARG_((Sfio_t*, Sfoff_t));
+extern int sfsync _ARG_((Sfio_t*));
+extern int sfclrlock _ARG_((Sfio_t*));
+extern Void_t* sfsetbuf _ARG_((Sfio_t*, Void_t*, size_t));
+extern Sfdisc_t* sfdisc _ARG_((Sfio_t*,Sfdisc_t*));
+extern int sfraise _ARG_((Sfio_t*, int, Void_t*));
+extern int sfnotify _ARG_((void(*)(Sfio_t*, int, void*)));
+extern int sfset _ARG_((Sfio_t*, int, int));
+extern int sfsetfd _ARG_((Sfio_t*, int));
+extern Sfio_t* sfpool _ARG_((Sfio_t*, Sfio_t*, int));
+extern ssize_t sfread _ARG_((Sfio_t*, Void_t*, size_t));
+extern ssize_t sfwrite _ARG_((Sfio_t*, const Void_t*, size_t));
+extern Sfoff_t sfmove _ARG_((Sfio_t*, Sfio_t*, Sfoff_t, int));
+extern int sfclose _ARG_((Sfio_t*));
+extern Sfoff_t sftell _ARG_((Sfio_t*));
+extern Sfoff_t sfseek _ARG_((Sfio_t*, Sfoff_t, int));
+extern ssize_t sfputr _ARG_((Sfio_t*, const char*, int));
+extern char* sfgetr _ARG_((Sfio_t*, int, int));
+extern ssize_t sfnputc _ARG_((Sfio_t*, int, size_t));
+extern int sfungetc _ARG_((Sfio_t*, int));
+extern int sfprintf _ARG_((Sfio_t*, const char*, ...));
+extern char* sfprints _ARG_((const char*, ...));
+extern ssize_t sfaprints _ARG_((char**, const char*, ...));
+extern ssize_t sfsprintf _ARG_((char*, size_t, const char*, ...));
+extern ssize_t sfvsprintf _ARG_((char*, size_t, const char*, va_list));
+extern ssize_t sfvasprints _ARG_((char**, const char*, va_list));
+extern int sfvprintf _ARG_((Sfio_t*, const char*, va_list));
+extern int sfscanf _ARG_((Sfio_t*, const char*, ...));
+extern int sfsscanf _ARG_((const char*, const char*, ...));
+extern int sfvsscanf _ARG_((const char*, const char*, va_list));
+extern int sfvscanf _ARG_((Sfio_t*, const char*, va_list));
+
+/* mutex locking for thread-safety */
+extern int sfmutex _ARG_((Sfio_t*, int));
+
+/* io functions with discipline continuation */
+extern ssize_t sfrd _ARG_((Sfio_t*, Void_t*, size_t, Sfdisc_t*));
+extern ssize_t sfwr _ARG_((Sfio_t*, const Void_t*, size_t, Sfdisc_t*));
+extern Sfoff_t sfsk _ARG_((Sfio_t*, Sfoff_t, int, Sfdisc_t*));
+extern ssize_t sfpkrd _ARG_((int, Void_t*, size_t, int, long, int));
+
+/* portable handling of primitive types */
+extern int sfdlen _ARG_((Sfdouble_t));
+extern int sfllen _ARG_((Sflong_t));
+extern int sfulen _ARG_((Sfulong_t));
+
+extern int sfputd _ARG_((Sfio_t*, Sfdouble_t));
+extern int sfputl _ARG_((Sfio_t*, Sflong_t));
+extern int sfputu _ARG_((Sfio_t*, Sfulong_t));
+extern int sfputm _ARG_((Sfio_t*, Sfulong_t, Sfulong_t));
+extern int sfputc _ARG_((Sfio_t*, int));
+
+extern Sfdouble_t sfgetd _ARG_((Sfio_t*));
+extern Sflong_t sfgetl _ARG_((Sfio_t*));
+extern Sfulong_t sfgetu _ARG_((Sfio_t*));
+extern Sfulong_t sfgetm _ARG_((Sfio_t*, Sfulong_t));
+extern int sfgetc _ARG_((Sfio_t*));
+
+extern int _sfputd _ARG_((Sfio_t*, Sfdouble_t));
+extern int _sfputl _ARG_((Sfio_t*, Sflong_t));
+extern int _sfputu _ARG_((Sfio_t*, Sfulong_t));
+extern int _sfputm _ARG_((Sfio_t*, Sfulong_t, Sfulong_t));
+extern int _sfflsbuf _ARG_((Sfio_t*, int));
+
+extern int _sffilbuf _ARG_((Sfio_t*, int));
+
+extern int _sfdlen _ARG_((Sfdouble_t));
+extern int _sfllen _ARG_((Sflong_t));
+extern int _sfulen _ARG_((Sfulong_t));
+
+/* miscellaneous function analogues of fast in-line functions */
+extern Sfoff_t sfsize _ARG_((Sfio_t*));
+extern int sfclrerr _ARG_((Sfio_t*));
+extern int sfeof _ARG_((Sfio_t*));
+extern int sferror _ARG_((Sfio_t*));
+extern int sffileno _ARG_((Sfio_t*));
+extern int sfstacked _ARG_((Sfio_t*));
+extern ssize_t sfvalue _ARG_((Sfio_t*));
+extern ssize_t sfslen _ARG_((void));
+extern ssize_t sfmaxr _ARG_((ssize_t, int));
+
+#undef extern
+_END_EXTERNS_
+
+/* coding long integers in a portable and compact fashion */
+#define SF_SBITS 6
+#define SF_UBITS 7
+#define SF_BBITS 8
+#define SF_SIGN (1 << SF_SBITS)
+#define SF_MORE (1 << SF_UBITS)
+#define SF_BYTE (1 << SF_BBITS)
+#define SF_U1 SF_MORE
+#define SF_U2 (SF_U1*SF_U1)
+#define SF_U3 (SF_U2*SF_U1)
+#define SF_U4 (SF_U3*SF_U1)
+
+#if __cplusplus
+#define _SF_(f) (f)
+#else
+#define _SF_(f) ((Sfio_t*)(f))
+#endif
+
+#define __sf_putd(f,v) (_sfputd(_SF_(f),(Sfdouble_t)(v)))
+#define __sf_putl(f,v) (_sfputl(_SF_(f),(Sflong_t)(v)))
+#define __sf_putu(f,v) (_sfputu(_SF_(f),(Sfulong_t)(v)))
+#define __sf_putm(f,v,m) (_sfputm(_SF_(f),(Sfulong_t)(v),(Sfulong_t)(m)))
+
+#define __sf_putc(f,c) (_SF_(f)->_next >= _SF_(f)->_endw ? \
+ _sfflsbuf(_SF_(f),(int)((unsigned char)(c))) : \
+ (int)(*_SF_(f)->_next++ = (unsigned char)(c)) )
+#define __sf_getc(f) (_SF_(f)->_next >= _SF_(f)->_endr ? _sffilbuf(_SF_(f),0) : \
+ (int)(*_SF_(f)->_next++) )
+
+#define __sf_dlen(v) (_sfdlen((Sfdouble_t)(v)) )
+#define __sf_llen(v) (_sfllen((Sflong_t)(v)) )
+#define __sf_ulen(v) ((Sfulong_t)(v) < SF_U1 ? 1 : (Sfulong_t)(v) < SF_U2 ? 2 : \
+ (Sfulong_t)(v) < SF_U3 ? 3 : (Sfulong_t)(v) < SF_U4 ? 4 : 5)
+
+#define __sf_fileno(f) (_SF_(f)->_file)
+#define __sf_eof(f) (_SF_(f)->_flags&SF_EOF)
+#define __sf_error(f) (_SF_(f)->_flags&SF_ERROR)
+#define __sf_clrerr(f) (_SF_(f)->_flags &= ~(SF_ERROR|SF_EOF))
+#define __sf_stacked(f) (_SF_(f)->_push != (Sfio_t*)0)
+#define __sf_value(f) (_SF_(f)->_val)
+#define __sf_slen() (_Sfi)
+#define __sf_maxr(n,s) ((s)?((_Sfi=_Sfmaxr),(_Sfmaxr=(n)),_Sfi):_Sfmaxr)
+
+#if defined(__INLINE__) && !_BLD_sfio
+
+__INLINE__ int sfputd(Sfio_t* f, Sfdouble_t v) { return __sf_putd(f,v); }
+__INLINE__ int sfputl(Sfio_t* f, Sflong_t v) { return __sf_putl(f,v); }
+__INLINE__ int sfputu(Sfio_t* f, Sfulong_t v) { return __sf_putu(f,v); }
+__INLINE__ int sfputm(Sfio_t* f, Sfulong_t v, Sfulong_t m)
+ { return __sf_putm(f,v,m); }
+
+__INLINE__ int sfputc(Sfio_t* f, int c) { return __sf_putc(f,c); }
+__INLINE__ int sfgetc(Sfio_t* f) { return __sf_getc(f); }
+
+__INLINE__ int sfdlen(Sfdouble_t v) { return __sf_dlen(v); }
+__INLINE__ int sfllen(Sflong_t v) { return __sf_llen(v); }
+__INLINE__ int sfulen(Sfulong_t v) { return __sf_ulen(v); }
+
+__INLINE__ int sffileno(Sfio_t* f) { return __sf_fileno(f); }
+__INLINE__ int sfeof(Sfio_t* f) { return __sf_eof(f); }
+__INLINE__ int sferror(Sfio_t* f) { return __sf_error(f); }
+__INLINE__ int sfclrerr(Sfio_t* f) { return __sf_clrerr(f); }
+__INLINE__ int sfstacked(Sfio_t* f) { return __sf_stacked(f); }
+__INLINE__ ssize_t sfvalue(Sfio_t* f) { return __sf_value(f); }
+__INLINE__ ssize_t sfslen() { return __sf_slen(); }
+__INLINE__ ssize_t sfmaxr(ssize_t n, int s) { return __sf_maxr(n,s); }
+
+#else
+
+#define sfputd(f,v) ( __sf_putd((f),(v)) )
+#define sfputl(f,v) ( __sf_putl((f),(v)) )
+#define sfputu(f,v) ( __sf_putu((f),(v)) )
+#define sfputm(f,v,m) ( __sf_putm((f),(v),(m)) )
+
+#define sfputc(f,c) ( __sf_putc((f),(c)) )
+#define sfgetc(f) ( __sf_getc(f) )
+
+#define sfdlen(v) ( __sf_dlen(v) )
+#define sfllen(v) ( __sf_llen(v) )
+#define sfulen(v) ( __sf_ulen(v) )
+
+#define sffileno(f) ( __sf_fileno(f) )
+#define sfeof(f) ( __sf_eof(f) )
+#define sferror(f) ( __sf_error(f) )
+#define sfclrerr(f) ( __sf_clrerr(f) )
+#define sfstacked(f) ( __sf_stacked(f) )
+#define sfvalue(f) ( __sf_value(f) )
+#define sfslen() ( __sf_slen() )
+#define sfmaxr(n,s) ( __sf_maxr(n,s) )
+
+#endif /*__INLINE__*/
+
+#ifndef _SFSTR_H /* GSF's string manipulation stuff */
+#define _SFSTR_H 1
+
+#define sfstropen() sfnew(0, 0, -1, -1, SF_READ|SF_WRITE|SF_STRING)
+#define sfstrclose(f) sfclose(f)
+
+#define sfstrseek(f,p,m) \
+ ( (m) == SEEK_SET ? \
+ (((p) < 0 || (p) > (f)->_size) ? (char*)0 : \
+ (char*)((f)->_next = (f)->_data+(p)) ) \
+ : (m) == SEEK_CUR ? \
+ ((f)->_next += (p), \
+ (((f)->_next < (f)->_data || (f)->_next > (f)->_data+(f)->_size) ? \
+ ((f)->_next -= (p), (char*)0) : (char*)(f)->_next ) ) \
+ : (m) == SEEK_END ? \
+ ( ((p) > 0 || (f)->_size+(p) < 0) ? (char*)0 : \
+ (char*)((f)->_next = (f)->_data+(f)->_size+(p)) ) \
+ : (char*)0 \
+ )
+
+#define sfstrsize(f) ((f)->_size)
+#define sfstrtell(f) ((f)->_next - (f)->_data)
+#define sfstrpend(f) ((f)->_size - sfstrtell())
+#define sfstrbase(f) ((char*)(f)->_data)
+
+#define sfstruse(f) \
+ (sfputc((f),0) < 0 ? (char*)0 : (char*)((f)->_next = (f)->_data) \
+ )
+
+#define sfstrrsrv(f,n) \
+ (sfreserve((f),(n),SF_WRITE|SF_LOCKR), sfwrite((f),(f)->_next,0), \
+ ((f)->_next+(n) <= (f)->_data+(f)->_size ? (char*)(f)->_next : (char*)0) \
+ )
+
+#define sfstrbuf(f,b,n,m) \
+ (sfsetbuf((f),(b),(n)), ((f)->_flags |= (m) ? SF_MALLOC : 0), \
+ ((f)->_data == (unsigned char*)(b) ? 0 : -1) \
+ )
+
+#endif /* _SFSTR_H */
+
+#endif /* _SFIO_H */
diff --git a/src/lib/libast/include/sfio_s.h b/src/lib/libast/include/sfio_s.h
new file mode 100644
index 0000000..0fb33de
--- /dev/null
+++ b/src/lib/libast/include/sfio_s.h
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _SFIO_S_H
+#define _SFIO_S_H 1
+
+/*
+ * sfio file structure used by sfio and the stdio source compatibility library
+ */
+
+#if !defined(_SFHDR_H) && defined(_SFIO_H) && SFIO_VERSION < 20020214L
+#define _data data
+#define _endb endb
+#define _next next
+#endif
+
+struct _sfio_s
+{ unsigned char* _next; /* next position to read/write from */
+ unsigned char* _endw; /* end of write buffer */
+ unsigned char* _endr; /* end of read buffer */
+ unsigned char* _endb; /* end of buffer */
+ struct _sfio_s* _push; /* the stream that was pushed on */
+ unsigned short _flags; /* type of stream */
+ short _file; /* file descriptor */
+ unsigned char* _data; /* base of data buffer */
+ ssize_t _size; /* buffer size */
+ ssize_t _val; /* values or string lengths */
+#ifdef _SFIO_PRIVATE
+ _SFIO_PRIVATE
+#endif
+};
+
+#endif
diff --git a/src/lib/libast/include/sfio_t.h b/src/lib/libast/include/sfio_t.h
new file mode 100644
index 0000000..9ff54a8
--- /dev/null
+++ b/src/lib/libast/include/sfio_t.h
@@ -0,0 +1,126 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _SFIO_T_H
+#define _SFIO_T_H 1
+
+/* This header file is for library writers who need to know certain
+** internal info concerning the full Sfio_t structure. Including this
+** file means that you agree to track closely with sfio development
+** in case its internal architecture is changed.
+**
+** Written by Kiem-Phong Vo
+*/
+
+/* the parts of Sfio_t private to sfio functions */
+#define _SFIO_PRIVATE \
+ Sfoff_t extent; /* current file size */ \
+ Sfoff_t here; /* current physical location */ \
+ unsigned char getr; /* the last sfgetr separator */ \
+ unsigned char tiny[1];/* for unbuffered read stream */ \
+ unsigned short bits; /* private flags */ \
+ unsigned int mode; /* current io mode */ \
+ struct _sfdisc_s* disc; /* discipline */ \
+ struct _sfpool_s* pool; /* the pool containing this */ \
+ struct _sfrsrv_s* rsrv; /* reserved buffer */ \
+ struct _sfproc_s* proc; /* coprocess id, etc. */ \
+ Void_t* mutex; /* mutex for thread-safety */ \
+ Void_t* stdio; /* stdio FILE if any */ \
+ Sfoff_t lpos; /* last seek position */ \
+ size_t iosz; /* preferred size for I/O */ \
+ size_t blksz; /* preferred block size */ \
+ Void_t* fill[1];/* modest expansion */
+
+#include "sfio.h"
+
+/* mode bit to indicate that the structure hasn't been initialized */
+#define SF_INIT 0000004
+#define SF_DCDOWN 00010000
+
+/* short-hand for common stream types */
+#define SF_RDWR (SF_READ|SF_WRITE)
+#define SF_RDSTR (SF_READ|SF_STRING)
+#define SF_WRSTR (SF_WRITE|SF_STRING)
+#define SF_RDWRSTR (SF_RDWR|SF_STRING)
+
+/* for static initialization of an Sfio_t structure */
+#define SFNEW(data,size,file,type,disc,mutex) \
+ { (unsigned char*)(data), /* next */ \
+ (unsigned char*)(data), /* endw */ \
+ (unsigned char*)(data), /* endr */ \
+ (unsigned char*)(data), /* endb */ \
+ (Sfio_t*)0, /* push */ \
+ (unsigned short)((type)&SF_FLAGS), /* flags */ \
+ (short)(file), /* file */ \
+ (unsigned char*)(data), /* data */ \
+ (ssize_t)(size), /* size */ \
+ (ssize_t)(-1), /* val */ \
+ (Sfoff_t)0, /* extent */ \
+ (Sfoff_t)0, /* here */ \
+ 0, /* getr */ \
+ {0}, /* tiny */ \
+ 0, /* bits */ \
+ (unsigned int)(((type)&(SF_RDWR))|SF_INIT), /* mode */ \
+ (struct _sfdisc_s*)(disc), /* disc */ \
+ (struct _sfpool_s*)0, /* pool */ \
+ (struct _sfrsrv_s*)0, /* rsrv */ \
+ (struct _sfproc_s*)0, /* proc */ \
+ (mutex), /* mutex */ \
+ (Void_t*)0, /* stdio */ \
+ (Sfoff_t)0, /* lpos */ \
+ (size_t)0 /* iosz */ \
+ }
+
+/* function to clear an Sfio_t structure */
+#define SFCLEAR(f,mtx) \
+ ( (f)->next = (unsigned char*)0, /* next */ \
+ (f)->endw = (unsigned char*)0, /* endw */ \
+ (f)->endr = (unsigned char*)0, /* endr */ \
+ (f)->endb = (unsigned char*)0, /* endb */ \
+ (f)->push = (Sfio_t*)0, /* push */ \
+ (f)->flags = (unsigned short)0, /* flags */ \
+ (f)->file = -1, /* file */ \
+ (f)->data = (unsigned char*)0, /* data */ \
+ (f)->size = (ssize_t)(-1), /* size */ \
+ (f)->val = (ssize_t)(-1), /* val */ \
+ (f)->extent = (Sfoff_t)(-1), /* extent */ \
+ (f)->here = (Sfoff_t)0, /* here */ \
+ (f)->getr = 0, /* getr */ \
+ (f)->tiny[0] = 0, /* tiny */ \
+ (f)->bits = 0, /* bits */ \
+ (f)->mode = 0, /* mode */ \
+ (f)->disc = (struct _sfdisc_s*)0, /* disc */ \
+ (f)->pool = (struct _sfpool_s*)0, /* pool */ \
+ (f)->rsrv = (struct _sfrsrv_s*)0, /* rsrv */ \
+ (f)->proc = (struct _sfproc_s*)0, /* proc */ \
+ (f)->mutex = (mtx), /* mutex */ \
+ (f)->stdio = (Void_t*)0, /* stdio */ \
+ (f)->lpos = (Sfoff_t)0, /* lpos */ \
+ (f)->iosz = (size_t)0 /* iosz */ \
+ )
+
+/* expose next stream inside discipline function; state saved in int f */
+#define SFDCNEXT(sp,f) (((f)=(sp)->bits&SF_DCDOWN),(sp)->bits|=SF_DCDOWN)
+
+/* restore SFDCNEXT() state from int f */
+#define SFDCPREV(sp,f) ((f)?(0):((sp)->bits&=~SF_DCDOWN))
+
+#endif /* _SFIO_T_H */
diff --git a/src/lib/libast/include/shcmd.h b/src/lib/libast/include/shcmd.h
new file mode 100644
index 0000000..16acdac
--- /dev/null
+++ b/src/lib/libast/include/shcmd.h
@@ -0,0 +1,112 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * ksh builtin command api
+ */
+
+#ifndef _SHCMD_H
+#define _SHCMD_H 1
+
+#ifndef AST_PLUGIN_VERSION
+#define AST_PLUGIN_VERSION(v) (v)
+#endif
+#define SH_PLUGIN_VERSION AST_PLUGIN_VERSION(20111111L)
+
+#if __STDC__
+#define SHLIB(m) unsigned long plugin_version(void) { return SH_PLUGIN_VERSION; }
+#else
+#define SHLIB(m) unsigned long plugin_version() { return SH_PLUGIN_VERSION; }
+#endif
+
+#ifndef SH_VERSION
+# define Shell_t void
+#endif
+#ifndef NV_DEFAULT
+# define Namval_t void
+#endif
+
+#undef Shbltin_t
+struct Shbltin_s;
+typedef struct Shbltin_s Shbltin_t;
+
+#ifdef _SHTABLE_H /* pre-ksh93u+ -- obsolete */
+typedef int (*Shbltin_f)(int, char**, void*);
+#else
+typedef int (*Shbltin_f)(int, char**, Shbltin_t*);
+#endif /* _SHTABLE_H */
+
+struct Shbltin_s
+{
+ Shell_t* shp;
+ void* ptr;
+ int version;
+ int (*shrun)(int, char**);
+ int (*shtrap)(const char*, int);
+ void (*shexit)(int);
+ Namval_t* (*shbltin)(const char*, Shbltin_f, void*);
+ unsigned char notify;
+ unsigned char sigset;
+ unsigned char nosfio;
+ Namval_t* bnode;
+ Namval_t* vnode;
+ char* data;
+ int flags;
+ char* (*shgetenv)(const char*);
+ char* (*shsetenv)(const char*);
+ int invariant;
+};
+
+#if defined(SH_VERSION) || defined(_SH_PRIVATE)
+# undef Shell_t
+# undef Namval_t
+#else
+# define sh_context(c) ((Shbltin_t*)(c))
+# define sh_run(c, ac, av) ((c)?(*sh_context(c)->shrun)(ac,av):-1)
+# define sh_system(c,str) ((c)?(*sh_context(c)->shtrap)(str,0):system(str))
+# define sh_exit(c,n) ((c)?(*sh_context(c)->shexit)(n):exit(n))
+# define sh_checksig(c) ((c) && sh_context(c)->sigset)
+# define sh_builtin(c,n,f,p) ((c)?(*sh_context(c)->shbltin)(n,(Shbltin_f)(f),sh_context(p)):0)
+# if defined(SFIO_VERSION) || defined(_AST_H)
+# define LIB_INIT(c)
+# else
+# define LIB_INIT(c) ((c) && (sh_context(c)->nosfio = 1))
+# endif
+# ifndef _CMD_H
+# ifndef ERROR_NOTIFY
+# define ERROR_NOTIFY 1
+# endif
+# define cmdinit(ac,av,c,cat,flg) do { if((ac)<=0) return(0); \
+ (sh_context(c)->notify = ((flg)&ERROR_NOTIFY)?1:0);} while(0)
+# endif
+#endif
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int astintercept(Shbltin_t*, int);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/stack.h b/src/lib/libast/include/stack.h
new file mode 100644
index 0000000..593a08c
--- /dev/null
+++ b/src/lib/libast/include/stack.h
@@ -0,0 +1,83 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * homogenous stack routine definitions
+ */
+
+#ifndef _STACK_H
+#define _STACK_H
+
+typedef struct stacktable* STACK; /* stack pointer */
+typedef struct stackposition STACKPOS; /* stack position */
+
+struct stackblock /* stack block cell */
+{
+ void** stack; /* actual stack */
+ struct stackblock* prev; /* previous block in list */
+ struct stackblock* next; /* next block in list */
+};
+
+struct stackposition /* stack position */
+{
+ struct stackblock* block; /* current block pointer */
+ int index; /* index within current block */
+};
+
+struct stacktable /* stack information */
+{
+ struct stackblock* blocks; /* stack table blocks */
+ void* error; /* error return value */
+ int size; /* size of each block */
+ STACKPOS position; /* current stack position */
+};
+
+/*
+ * map old names to new
+ */
+
+#define mkstack stackalloc
+#define rmstack stackfree
+#define clrstack stackclear
+#define getstack stackget
+#define pushstack stackpush
+#define popstack stackpop
+#define posstack stacktell
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern STACK stackalloc(int, void*);
+extern void stackfree(STACK);
+extern void stackclear(STACK);
+extern void* stackget(STACK);
+extern int stackpush(STACK, void*);
+extern int stackpop(STACK);
+extern void stacktell(STACK, int, STACKPOS*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/stak.h b/src/lib/libast/include/stak.h
new file mode 100644
index 0000000..ee34773
--- /dev/null
+++ b/src/lib/libast/include/stak.h
@@ -0,0 +1,55 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * David Korn
+ * AT&T Research
+ *
+ * Interface definitions for a stack-like storage library
+ *
+ */
+
+#ifndef _STAK_H
+#define _STAK_H
+
+#include <stk.h>
+
+#define Stak_t Sfio_t
+#define staksp stkstd
+#define STAK_SMALL STK_SMALL
+
+#define stakptr(n) stkptr(stkstd,n)
+#define staktell() stktell(stkstd)
+#define stakputc(c) sfputc(stkstd,(c))
+#define stakwrite(b,n) sfwrite(stkstd,(b),(n))
+#define stakputs(s) (sfputr(stkstd,(s),0),--stkstd->_next)
+#define stakseek(n) stkseek(stkstd,n)
+#define stakcreate(n) stkopen(n)
+#define stakinstall(s,f) stkinstall(s,f)
+#define stakdelete(s) stkclose(s)
+#define staklink(s) stklink(s)
+#define stakalloc(n) stkalloc(stkstd,n)
+#define stakcopy(s) stkcopy(stkstd,s)
+#define stakset(c,n) stkset(stkstd,c,n)
+#define stakfreeze(n) stkfreeze(stkstd,n)
+
+#endif
diff --git a/src/lib/libast/include/stk.h b/src/lib/libast/include/stk.h
new file mode 100644
index 0000000..851e408
--- /dev/null
+++ b/src/lib/libast/include/stk.h
@@ -0,0 +1,78 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * David Korn
+ * AT&T Research
+ *
+ * Interface definitions for a stack-like storage library
+ *
+ */
+
+#ifndef _STK_H
+#define _STK_H
+
+#include <sfio.h>
+
+#define _Stk_data _Stak_data
+
+#define stkstd (&_Stk_data)
+
+#define Stk_t Sfio_t
+
+#define STK_SMALL 1 /* small stkopen stack */
+#define STK_NULL 2 /* return NULL on overflow */
+
+#define stkptr(sp,n) ((char*)((sp)->_data)+(n))
+#define stktop(sp) ((char*)(sp)->_next)
+#define stktell(sp) ((sp)->_next-(sp)->_data)
+#define stkseek(sp,n) ((n)==0?(char*)((sp)->_next=(sp)->_data):_stkseek(sp,n))
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+#if !_BLD_ast && defined(__IMPORT__)
+#define extern extern __IMPORT__
+#endif
+
+extern Sfio_t _Stk_data;
+
+#undef extern
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern Stk_t* stkopen(int);
+extern Stk_t* stkinstall(Stk_t*, char*(*)(int));
+extern int stkclose(Stk_t*);
+extern int stklink(Stk_t*);
+extern char* stkalloc(Stk_t*, size_t);
+extern char* stkcopy(Stk_t*, const char*);
+extern char* stkset(Stk_t*, char*, size_t);
+extern char* _stkseek(Stk_t*, ssize_t);
+extern char* stkfreeze(Stk_t*, size_t);
+extern int stkon(Stk_t*, char*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/swap.h b/src/lib/libast/include/swap.h
new file mode 100644
index 0000000..03a81f4
--- /dev/null
+++ b/src/lib/libast/include/swap.h
@@ -0,0 +1,53 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * integral representation conversion support definitions
+ * supports sizeof(integral_type)<=sizeof(intmax_t)
+ */
+
+#ifndef _SWAP_H
+#define _SWAP_H
+
+#include <ast_common.h>
+
+#define int_swap _ast_intswap
+
+#define SWAP_MAX 8
+
+#define SWAPOP(n) (((n)&int_swap)^(n))
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern void* swapmem(int, const void*, void*, size_t);
+extern intmax_t swapget(int, const void*, int);
+extern void* swapput(int, void*, int, intmax_t);
+extern int swapop(const void*, const void*, int);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/tar.h b/src/lib/libast/include/tar.h
new file mode 100644
index 0000000..847d6c6
--- /dev/null
+++ b/src/lib/libast/include/tar.h
@@ -0,0 +1,118 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Standard Archive Format
+ * USTAR - Uniform Standard Tape ARchive
+ */
+
+#ifndef _TAR_H
+#define _TAR_H
+
+#define TBLOCK 512
+#define NAMSIZ 100
+#define PFXSIZ 155
+
+#define TMODLEN 8
+#define TUIDLEN 8
+#define TGIDLEN 8
+#define TSIZLEN 12
+#define TMTMLEN 12
+#define TCKSLEN 8
+
+#define TMAGIC "ustar" /* ustar and a null */
+#define TMAGLEN 6
+#define TVERSION "00" /* 00 and no null */
+#define TVERSLEN 2
+#define TUNMLEN 32
+#define TGNMLEN 32
+#define TDEVLEN 8
+
+/*
+ * values used in typeflag field
+ */
+
+#define REGTYPE '0' /* regular file */
+#define AREGTYPE 0 /* alternate REGTYPE */
+#define LNKTYPE '1' /* hard link */
+#define SYMTYPE '2' /* soft link */
+#define CHRTYPE '3' /* character special */
+#define BLKTYPE '4' /* block special */
+#define DIRTYPE '5' /* directory */
+#define FIFOTYPE '6' /* FIFO special */
+#define CONTTYPE '7' /* reserved */
+#define SOKTYPE '8' /* socket */
+#define EXTTYPE 'x' /* extended header */
+#define GLBTYPE 'g' /* global extended header */
+#define LLNKTYPE 'K' /* long link path */
+#define LREGTYPE 'L' /* long file path */
+#define VERTYPE 'V' /* version */
+
+/*
+ * bits used in mode field
+ */
+
+#define TSUID 04000 /* set uid on exec */
+#define TSGID 02000 /* set gid on exec */
+#define TSVTX 01000 /* sticky bit -- reserved */
+
+/*
+ * file permissions
+ */
+
+#define TUREAD 00400 /* read by owner */
+#define TUWRITE 00200 /* write by owner */
+#define TUEXEC 00100 /* execute by owner */
+#define TGREAD 00040 /* read by group */
+#define TGWRITE 00020 /* execute by group */
+#define TGEXEC 00010 /* write by group */
+#define TOREAD 00004 /* read by other */
+#define TOWRITE 00002 /* write by other */
+#define TOEXEC 00001 /* execute by other */
+
+struct header
+{
+ char name[NAMSIZ];
+ char mode[TMODLEN];
+ char uid[TUIDLEN];
+ char gid[TGIDLEN];
+ char size[TSIZLEN];
+ char mtime[TMTMLEN];
+ char chksum[TCKSLEN];
+ char typeflag;
+ char linkname[NAMSIZ];
+ char magic[TMAGLEN];
+ char version[TVERSLEN];
+ char uname[TUNMLEN];
+ char gname[TGNMLEN];
+ char devmajor[TDEVLEN];
+ char devminor[TDEVLEN];
+ char prefix[PFXSIZ];
+};
+
+union hblock
+{
+ char dummy[TBLOCK];
+ struct header dbuf;
+};
+
+#endif
diff --git a/src/lib/libast/include/times.h b/src/lib/libast/include/times.h
new file mode 100644
index 0000000..c0c458d
--- /dev/null
+++ b/src/lib/libast/include/times.h
@@ -0,0 +1,54 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * -last clock_t,time_t interface definitions plus
+ *
+ * <ast.h>
+ * <time.h>
+ * <sys/time.h>
+ * <sys/times.h>
+ */
+
+#ifndef _TIMES_H
+#define _TIMES_H
+
+#include <ast.h>
+
+#undef _TIMES_H
+#include <ast_time.h>
+#ifndef _TIMES_H
+#define _TIMES_H
+#endif
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int touch(const char*, time_t, time_t, int);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/tm.h b/src/lib/libast/include/tm.h
new file mode 100644
index 0000000..bbd5980
--- /dev/null
+++ b/src/lib/libast/include/tm.h
@@ -0,0 +1,192 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * time conversion support definitions
+ */
+
+#ifndef _TM_H
+#define _TM_H
+
+#define TM_VERSION 20070319L
+
+#include <ast.h>
+#include <times.h>
+
+#undef daylight
+
+#define tmset(z) tminit(z)
+#define tmisleapyear(y) (!((y)%4)&&(((y)%100)||!((((y)<1900)?((y)+1900):(y))%400)))
+
+#define TM_ADJUST (1<<0) /* local doesn't do leap secs */
+#define TM_LEAP (1<<1) /* do leap seconds */
+#define TM_UTC (1<<2) /* universal coordinated ref */
+
+#define TM_PEDANTIC (1<<3) /* pedantic date parse */
+#define TM_DATESTYLE (1<<4) /* date(1) style mmddHHMMccyy */
+#define TM_SUBSECOND (1<<5) /* <something>%S => ...%S.%P */
+
+#define TM_DST (-60) /* default minutes for DST */
+#define TM_LOCALZONE (25 * 60) /* use local time zone offset */
+#define TM_UTCZONE (26 * 60) /* UTC "time zone" */
+#define TM_MAXLEAP 1 /* max leap secs per leap */
+#define TM_WINDOW 69 /* century windowing guard year */
+
+/*
+ * these indices must agree with tm_dform[]
+ */
+
+#define TM_MONTH_ABBREV 0
+#define TM_MONTH 12
+#define TM_DAY_ABBREV 24
+#define TM_DAY 31
+#define TM_TIME 38
+#define TM_DATE 39
+#define TM_DEFAULT 40
+#define TM_MERIDIAN 41
+
+#define TM_UT 43
+#define TM_DT 47
+#define TM_SUFFIXES 51
+#define TM_PARTS 55
+#define TM_HOURS 62
+#define TM_DAYS 66
+#define TM_LAST 69
+#define TM_THIS 72
+#define TM_NEXT 75
+#define TM_EXACT 78
+#define TM_NOISE 81
+#define TM_ORDINAL 85
+#define TM_DIGITS 95
+#define TM_CTIME 105
+#define TM_DATE_1 106
+#define TM_INTERNATIONAL 107
+#define TM_RECENT 108
+#define TM_DISTANT 109
+#define TM_MERIDIAN_TIME 110
+#define TM_ERA 111
+#define TM_ERA_DATE 112
+#define TM_ERA_TIME 113
+#define TM_ERA_DEFAULT 114
+#define TM_ERA_YEAR 115
+#define TM_ORDINALS 116
+#define TM_FINAL 126
+#define TM_WORK 129
+
+#define TM_NFORM 132
+
+typedef struct /* leap second info */
+{
+ time_t time; /* the leap second event */
+ int total; /* inclusive total since epoch */
+} Tm_leap_t;
+
+typedef struct /* time zone info */
+{
+ char* type; /* type name */
+ char* standard; /* standard time name */
+ char* daylight; /* daylight or summertime name */
+ short west; /* minutes west of GMT */
+ short dst; /* add to tz.west for DST */
+} Tm_zone_t;
+
+typedef struct /* tm library readonly data */
+{
+ char** format; /* default TM_* format strings */
+ unsigned char* lex; /* format lex type classes */
+ char* digit; /* output digits */
+ short* days; /* days in month i */
+ short* sum; /* days in months before i */
+ Tm_leap_t* leap; /* leap second table */
+ Tm_zone_t* zone; /* alternate timezone table */
+} Tm_data_t;
+
+typedef struct /* tm library global info */
+{
+ char* deformat; /* TM_DEFAULT override */
+ int flags; /* flags */
+ char** format; /* current format strings */
+ Tm_zone_t* date; /* timezone from last tmdate() */
+ Tm_zone_t* local; /* local timezone */
+ Tm_zone_t* zone; /* current timezone */
+} Tm_info_t;
+
+typedef struct Tm_s
+{
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ uint32_t tm_nsec;
+ Tm_zone_t* tm_zone;
+} Tm_t;
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+#if !_BLD_ast && defined(__IMPORT__)
+#define extern extern __IMPORT__
+#endif
+
+extern Tm_data_t* _tm_datap_;
+extern Tm_info_t* _tm_infop_;
+
+#define tm_data (*_tm_datap_)
+#define tm_info (*_tm_infop_)
+
+#undef extern
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern time_t tmdate(const char*, char**, time_t*);
+extern int tmequiv(Tm_t*);
+extern Tm_t* tmfix(Tm_t*);
+extern char* tmfmt(char*, size_t, const char*, time_t*);
+extern char* tmform(char*, const char*, time_t*);
+extern int tmgoff(const char*, char**, int);
+extern void tminit(Tm_zone_t*);
+extern time_t tmleap(time_t*);
+extern int tmlex(const char*, char**, char**, int, char**, int);
+extern char** tmlocale(void);
+extern Tm_t* tmmake(time_t*);
+extern char* tmpoff(char*, size_t, const char*, int, int);
+extern time_t tmscan(const char*, char**, const char*, char**, time_t*, long);
+extern int tmsleep(time_t, time_t);
+extern time_t tmtime(Tm_t*, int);
+extern Tm_zone_t* tmtype(const char*, char**);
+extern int tmweek(Tm_t*, int, int, int);
+extern int tmword(const char*, char**, const char*, char**, int);
+extern Tm_zone_t* tmzone(const char*, char**, const char*, int*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/tok.h b/src/lib/libast/include/tok.h
new file mode 100644
index 0000000..f898218
--- /dev/null
+++ b/src/lib/libast/include/tok.h
@@ -0,0 +1,47 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * token stream interface definitions
+ */
+
+#ifndef _TOK_H
+#define _TOK_H
+
+#include <ast.h>
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern Sfio_t* tokline(const char*, int, int*);
+extern int tokscan(char*, char**, const char*, ...);
+extern char* tokopen(char*, int);
+extern void tokclose(char*);
+extern char* tokread(char*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/usage.h b/src/lib/libast/include/usage.h
new file mode 100644
index 0000000..c1ba317
--- /dev/null
+++ b/src/lib/libast/include/usage.h
@@ -0,0 +1,37 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * error catalog and usage defaults
+ */
+
+#ifndef _USAGE_H
+#define _USAGE_H
+
+#ifndef ERROR_CATALOG
+#define ERROR_CATALOG 0
+#endif
+
+#ifndef USAGE_LICENSE
+#define USAGE_LICENSE "[-license?THIS IS AN UNLICENSED COPY]"
+#endif
+
+#endif
diff --git a/src/lib/libast/include/vdb.h b/src/lib/libast/include/vdb.h
new file mode 100644
index 0000000..e647215
--- /dev/null
+++ b/src/lib/libast/include/vdb.h
@@ -0,0 +1,46 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * virtual db file directory entry constants
+ */
+
+#ifndef VDB_MAGIC
+
+#define VDB_MAGIC "vdb"
+
+#define VDB_DIRECTORY "DIRECTORY"
+#define VDB_UNION "UNION"
+#define VDB_DATE "DATE"
+#define VDB_MODE "MODE"
+
+#define VDB_DELIMITER ';'
+#define VDB_IGNORE '_'
+#define VDB_FIXED 10
+#define VDB_LENGTH ((int)sizeof(VDB_DIRECTORY)+2*(VDB_FIXED+1))
+#define VDB_OFFSET ((int)sizeof(VDB_DIRECTORY))
+#define VDB_SIZE (VDB_OFFSET+VDB_FIXED+1)
+
+#endif
diff --git a/src/lib/libast/include/vecargs.h b/src/lib/libast/include/vecargs.h
new file mode 100644
index 0000000..548c0b4
--- /dev/null
+++ b/src/lib/libast/include/vecargs.h
@@ -0,0 +1,45 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * vector argument interface definitions
+ */
+
+#ifndef _VECARGS_H
+#define _VECARGS_H
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int vecargs(char**, int*, char***);
+extern char** vecfile(const char*);
+extern void vecfree(char**, int);
+extern char** vecload(char*);
+extern char** vecstring(const char*);
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/include/vmalloc.h b/src/lib/libast/include/vmalloc.h
new file mode 100644
index 0000000..4825143
--- /dev/null
+++ b/src/lib/libast/include/vmalloc.h
@@ -0,0 +1,335 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _VMALLOC_H
+#define _VMALLOC_H 1
+
+/* Public header file for the virtual malloc package.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/1994.
+*/
+
+#define VMALLOC_VERSION 20110808L
+
+#if _PACKAGE_ast
+#include <ast_std.h>
+#else
+#include <ast_common.h>
+#endif
+
+typedef struct _vmalloc_s Vmalloc_t;
+typedef struct _vmstat_s Vmstat_t;
+typedef struct _vmdisc_s Vmdisc_t;
+typedef struct _vmethod_s Vmethod_t;
+typedef struct _vmdata_s Vmdata_t;
+typedef Void_t* (*Vmemory_f)_ARG_((Vmalloc_t*, Void_t*, size_t, size_t, Vmdisc_t*));
+typedef int (*Vmexcept_f)_ARG_((Vmalloc_t*, int, Void_t*, Vmdisc_t*));
+
+struct _vmstat_s
+{ int n_busy; /* number of busy blocks */
+ int n_free; /* number of free blocks */
+ size_t s_busy; /* total amount of busy space */
+ size_t s_free; /* total amount of free space */
+ size_t m_busy; /* largest busy piece */
+ size_t m_free; /* largest free piece */
+ int n_seg; /* number of segments */
+ size_t extent; /* total size of region */
+ int n_region; /* #parallel regions (Vmregion) */
+ int n_open; /* #calls that finds open reg */
+ int n_lock; /* #calls where reg was locked */
+ int n_probe; /* #probes to find a region */
+ int mode; /* region mode bits */
+};
+
+struct _vmdisc_s
+{ Vmemory_f memoryf; /* memory manipulator */
+ Vmexcept_f exceptf; /* exception handler */
+ size_t round; /* rounding requirement */
+ size_t size; /* actual size of discipline */
+};
+
+struct _vmethod_s
+{ Void_t* (*allocf)_ARG_((Vmalloc_t*,size_t,int));
+ Void_t* (*resizef)_ARG_((Vmalloc_t*,Void_t*,size_t,int,int));
+ int (*freef)_ARG_((Vmalloc_t*,Void_t*,int));
+ long (*addrf)_ARG_((Vmalloc_t*,Void_t*,int));
+ long (*sizef)_ARG_((Vmalloc_t*,Void_t*,int));
+ int (*compactf)_ARG_((Vmalloc_t*,int));
+ Void_t* (*alignf)_ARG_((Vmalloc_t*,size_t,size_t,int));
+ unsigned short meth;
+};
+
+struct _vmalloc_s
+{ Vmethod_t meth; /* method for allocation */
+ char* file; /* file name */
+ int line; /* line number */
+ char* func; /* calling function */
+ Vmdisc_t* disc; /* discipline to get space */
+ Vmdata_t* data; /* the real region data */
+ Vmalloc_t* next; /* linked list of regions */
+};
+
+#define VM_TRUST 0000000 /* obsolete */
+#define VM_TRACE 0000001 /* generate traces of calls */
+#define VM_DBCHECK 0000002 /* check for boundary overwrite */
+#define VM_DBABORT 0000004 /* abort on any warning */
+#define VM_SHARE 0000010 /* sharable across processes */
+#define VM_MEMORYF 0000020 /* vm was allocated by memoryf */
+#define VM_FLAGS 0000017 /* user-settable flags */
+
+#define VM_MTBEST 0000100 /* Vmbest method */
+#define VM_MTPOOL 0000200 /* Vmpool method */
+#define VM_MTLAST 0000400 /* Vmlast method */
+#define VM_MTDEBUG 0001000 /* Vmdebug method */
+#define VM_MTPROFILE 0002000 /* Vmdebug method */
+#define VM_METHODS 0003700 /* available allocation methods */
+
+#define VM_RSCOPY 0000001 /* copy old contents */
+#define VM_RSMOVE 0000002 /* old contents is moveable */
+#define VM_RSZERO 0000004 /* clear new space */
+
+/* exception types */
+#define VM_OPEN 1 /* region being opened */
+#define VM_ENDOPEN 2 /* end of region opening */
+#define VM_CLOSE 3 /* announce being closed */
+#define VM_ENDCLOSE 4 /* end of region closing */
+#define VM_DISC 5 /* discipline being changed */
+#define VM_NOMEM 6 /* can't obtain memory */
+#define VM_BADADDR (-1) /* currently a no-op */
+
+/* for application-specific data in shared/persistent regions */
+#define VM_MMGET 0 /* get data value (void*) */
+#define VM_MMSET 1 /* set data value (void*) */
+#define VM_MMADD 2 /* add data value (long) */
+
+_BEGIN_EXTERNS_ /* public data */
+#if _BLD_vmalloc && defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+#if !_BLD_vmalloc && defined(__IMPORT__)
+#define extern extern __IMPORT__
+#endif
+
+extern Vmethod_t* Vmbest; /* best allocation */
+extern Vmethod_t* Vmlast; /* last-block allocation */
+extern Vmethod_t* Vmpool; /* pool allocation */
+extern Vmethod_t* Vmdebug; /* allocation with debugging */
+extern Vmethod_t* Vmprofile; /* profiling memory usage */
+
+extern Vmdisc_t* Vmdcsystem; /* get memory from the OS */
+extern Vmdisc_t* Vmdcheap; /* get memory from Vmheap */
+extern Vmdisc_t* Vmdcsbrk; /* like Vmdcsystem - legacy use */
+
+extern Vmalloc_t _Vmheap; /* heap region - use with care! */
+extern Vmalloc_t* Vmheap; /* = &_Vmheap - safe to use */
+extern Vmalloc_t* Vmregion; /* malloc region */
+
+#undef extern
+_END_EXTERNS_
+
+_BEGIN_EXTERNS_ /* public functions */
+#if _BLD_vmalloc && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern Vmalloc_t* vmopen _ARG_(( Vmdisc_t*, Vmethod_t*, int ));
+extern int vmclose _ARG_(( Vmalloc_t* ));
+extern int vmclear _ARG_(( Vmalloc_t* ));
+extern int vmcompact _ARG_(( Vmalloc_t* ));
+
+extern Vmdisc_t* vmdisc _ARG_(( Vmalloc_t*, Vmdisc_t* ));
+
+extern Vmalloc_t* vmmopen _ARG_(( char*, int, ssize_t ));
+extern Void_t* vmmvalue _ARG_(( Vmalloc_t*, int, Void_t*, int ));
+extern void vmmrelease _ARG_(( Vmalloc_t*, int ));
+extern Void_t* vmmaddress _ARG_(( size_t ));
+
+extern Void_t* vmalloc _ARG_(( Vmalloc_t*, size_t ));
+extern Void_t* vmalign _ARG_(( Vmalloc_t*, size_t, size_t ));
+extern Void_t* vmresize _ARG_(( Vmalloc_t*, Void_t*, size_t, int ));
+extern Void_t* vmgetmem _ARG_(( Vmalloc_t*, Void_t*, size_t ));
+extern int vmfree _ARG_(( Vmalloc_t*, Void_t* ));
+
+extern long vmaddr _ARG_(( Vmalloc_t*, Void_t* ));
+extern long vmsize _ARG_(( Vmalloc_t*, Void_t* ));
+
+extern Vmalloc_t* vmregion _ARG_(( Void_t* ));
+extern Void_t* vmsegment _ARG_(( Vmalloc_t*, Void_t* ));
+extern int vmset _ARG_(( Vmalloc_t*, int, int ));
+
+extern Void_t* vmdbwatch _ARG_(( Void_t* ));
+extern int vmdbcheck _ARG_(( Vmalloc_t* ));
+extern int vmdebug _ARG_(( int ));
+
+extern int vmprofile _ARG_(( Vmalloc_t*, int ));
+
+extern int vmtrace _ARG_(( int ));
+extern int vmtrbusy _ARG_((Vmalloc_t*));
+
+extern int vmstat _ARG_((Vmalloc_t*, Vmstat_t*));
+
+extern int vmwalk _ARG_((Vmalloc_t*,
+ int(*)(Vmalloc_t*,Void_t*,size_t,Vmdisc_t*,Void_t*), Void_t*));
+extern char* vmstrdup _ARG_((Vmalloc_t*, const char*));
+
+#if !defined(_BLD_vmalloc) && !defined(_AST_STD_H) && \
+ !defined(__stdlib_h) && !defined(__STDLIB_H) && \
+ !defined(_STDLIB_INCLUDED) && !defined(_INC_STDLIB)
+extern Void_t* malloc _ARG_(( size_t ));
+extern Void_t* realloc _ARG_(( Void_t*, size_t ));
+extern void free _ARG_(( Void_t* ));
+extern void cfree _ARG_(( Void_t* ));
+extern Void_t* calloc _ARG_(( size_t, size_t ));
+extern Void_t* memalign _ARG_(( size_t, size_t ));
+extern Void_t* valloc _ARG_(( size_t ));
+#endif
+extern int setregmax _ARG_(( int ));
+
+#undef extern
+_END_EXTERNS_
+
+/* to coerce any value to a Vmalloc_t*, make ANSI happy */
+#define _VM_(vm) ((Vmalloc_t*)(vm))
+
+/* enable recording of where a call originates from */
+#ifdef VMFL
+
+#if defined(__FILE__)
+#define _VMFILE_(vm) (_VM_(vm)->file = (char*)__FILE__)
+#else
+#define _VMFILE_(vm) (_VM_(vm)->file = (char*)0)
+#endif
+
+#if defined(__LINE__)
+#define _VMLINE_(vm) (_VM_(vm)->line = __LINE__)
+#else
+#define _VMLINE_(vm) (_VM_(vm)->line = 0)
+#endif
+
+#if defined(__FUNCTION__)
+#define _VMFUNC_(vm) (_VM_(vm)->func = (char*)__FUNCTION__)
+#else
+#define _VMFUNC_(vm) (_VM_(vm)->func = (char*)0)
+#endif
+
+#define _VMFL_(vm) (_VMFILE_(vm), _VMLINE_(vm), _VMFUNC_(vm))
+
+#define vmalloc(vm,sz) (_VMFL_(vm), \
+ (*(_VM_(vm)->meth.allocf))((vm),(sz),0) )
+#define vmresize(vm,d,sz,type) (_VMFL_(vm), \
+ (*(_VM_(vm)->meth.resizef))\
+ ((vm),(Void_t*)(d),(sz),(type),0) )
+#define vmfree(vm,d) (_VMFL_(vm), \
+ (*(_VM_(vm)->meth.freef))((vm),(Void_t*)(d),0) )
+#define vmalign(vm,sz,align) (_VMFL_(vm), \
+ (*(_VM_(vm)->meth.alignf))((vm),(sz),(align),0) )
+
+#undef malloc
+#undef realloc
+#undef calloc
+#undef free
+#undef memalign
+#undef valloc
+
+#if _map_malloc
+
+#define malloc(s) (_VMFL_(Vmregion), _ast_malloc((size_t)(s)) )
+#define realloc(d,s) (_VMFL_(Vmregion), _ast_realloc((Void_t*)(d),(size_t)(s)) )
+#define calloc(n,s) (_VMFL_(Vmregion), _ast_calloc((size_t)n, (size_t)(s)) )
+#define free(d) (_VMFL_(Vmregion), _ast_free((Void_t*)(d)) )
+#define memalign(a,s) (_VMFL_(Vmregion), _ast_memalign((size_t)(a),(size_t)(s)) )
+#define valloc(s) (_VMFL_(Vmregion), _ast_valloc((size_t)(s) )
+
+#else
+
+#if !_std_malloc
+
+#if __STD_C || defined(__STDPP__) || defined(__GNUC__)
+
+#define malloc(s) (_VMFL_(Vmregion), malloc((size_t)(s)) )
+#define realloc(d,s) (_VMFL_(Vmregion), realloc((Void_t*)(d),(size_t)(s)) )
+#define calloc(n,s) (_VMFL_(Vmregion), calloc((size_t)n, (size_t)(s)) )
+#define free(d) (_VMFL_(Vmregion), free((Void_t*)(d)) )
+#define memalign(a,s) (_VMFL_(Vmregion), memalign((size_t)(a),(size_t)(s)) )
+#define valloc(s) (_VMFL_(Vmregion), valloc((size_t)(s) )
+#ifndef strdup
+#define strdup(s) ( _VMFL_(Vmregion), (strdup)((char*)(s)) )
+#endif
+
+#else
+
+#define _VMNM_(a,b,c,d,e,f) a/**/b/**/c/**/d/**/e/**/f
+#define malloc(s) (_VMFL_(Vmregion), _VMNM_(mallo,/,*,*,/,c)\
+ ((size_t)(s)) )
+#define realloc(d,s) (_VMFL_(Vmregion), _VMNM_(reallo,/,*,*,/,c)\
+ ((Void_t*)(d),(size_t)(s)) )
+#define calloc(n,s) (_VMFL_(Vmregion), _VMNM_(callo,/,*,*,/,c)\
+ ((size_t)n, (size_t)(s)) )
+#define free(d) (_VMFL_(Vmregion), _VMNM_(fre,/,*,*,/,e)((Void_t*)(d)) )
+#define memalign(a,s) (_VMFL_(Vmregion), _VMNM_(memalig,/,*,*,/,n)\
+ ((size_t)(a),(size_t)(s)) )
+#define valloc(s) (_VMFL_(Vmregion), _VMNM_(vallo,/,*,*,/,c)\
+ ((size_t)(s) )
+#ifndef strdup
+#define strdup(s) ( _VMFL_(Vmregion), _VMNM_(strdu,/,*,*,/,p)\
+ ((char*)(s)) )
+#endif
+
+#endif /*__STD_C || defined(__STDPP__) || defined(__GNUC__)*/
+
+#define cfree(d) free(d)
+
+#endif /*!_std_malloc*/
+
+#endif /*_map_malloc*/
+
+#endif /*VMFL*/
+
+/* non-debugging/profiling allocation calls */
+#ifndef vmalloc
+#define vmalloc(vm,sz) (*(_VM_(vm)->meth.allocf))((vm),(sz),0)
+#endif
+
+#ifndef vmresize
+#define vmresize(vm,d,sz,type) (*(_VM_(vm)->meth.resizef))\
+ ((vm),(Void_t*)(d),(sz),(type),0)
+#endif
+
+#ifndef vmfree
+#define vmfree(vm,d) (*(_VM_(vm)->meth.freef))((vm),(Void_t*)(d),0)
+#endif
+
+#ifndef vmalign
+#define vmalign(vm,sz,align) (*(_VM_(vm)->meth.alignf))((vm),(sz),(align),0)
+#endif
+
+#define vmaddr(vm,addr) (*(_VM_(vm)->meth.addrf))((vm),(Void_t*)(addr),0)
+#define vmsize(vm,addr) (*(_VM_(vm)->meth.sizef))((vm),(Void_t*)(addr),0)
+#define vmcompact(vm) (*(_VM_(vm)->meth.compactf))((vm),0)
+#define vmoldof(v,p,t,n,x) (t*)vmresize((v), (p), sizeof(t)*(n)+(x), \
+ (VM_RSMOVE) )
+#define vmnewof(v,p,t,n,x) (t*)vmresize((v), (p), sizeof(t)*(n)+(x), \
+ (VM_RSMOVE|VM_RSCOPY|VM_RSZERO) )
+
+#define vmdata(vm) ((Void_t*)(_VM_(vm)->data) )
+#define vmlocked(vm) (*((unsigned int*)(_VM_(vm)->data)) )
+
+#endif /* _VMALLOC_H */
diff --git a/src/lib/libast/include/wait.h b/src/lib/libast/include/wait.h
new file mode 100644
index 0000000..0dff619
--- /dev/null
+++ b/src/lib/libast/include/wait.h
@@ -0,0 +1,98 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * ast POSIX wait/exit support
+ */
+
+#ifndef _WAIT_H
+#define _WAIT_H
+
+#include <ast.h>
+#include <ast_wait.h>
+
+#if _sys_wait
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide wait waitpid
+#else
+#define wait ______wait
+#define waitpid ______waitpid
+#endif
+#include <sys/wait.h>
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide wait waitpid
+#else
+#undef wait
+#undef waitpid
+#endif
+#endif
+
+#ifndef WNOHANG
+#define WNOHANG 1
+#endif
+
+#ifndef WUNTRACED
+#define WUNTRACED 2
+#endif
+
+#if !_ok_wif
+#undef WIFEXITED
+#undef WEXITSTATUS
+#undef WIFSIGNALED
+#undef WTERMSIG
+#undef WIFSTOPPED
+#undef WSTOPSIG
+#undef WTERMCORE
+#endif
+
+#ifndef WIFEXITED
+#define WIFEXITED(x) (!((x)&((1<<(EXIT_BITS-1))-1)))
+#endif
+
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(x) (((x)>>EXIT_BITS)&((1<<EXIT_BITS)-1))
+#endif
+
+#ifndef WIFSIGNALED
+#define WIFSIGNALED(x) (((x)&((1<<(EXIT_BITS-1))-1))!=0)
+#endif
+
+#ifndef WTERMSIG
+#define WTERMSIG(x) ((x)&((1<<(EXIT_BITS-1))-1))
+#endif
+
+#ifndef WIFSTOPPED
+#define WIFSTOPPED(x) (((x)&((1<<EXIT_BITS)-1))==((1<<(EXIT_BITS-1))-1))
+#endif
+
+#ifndef WSTOPSIG
+#define WSTOPSIG(x) WEXITSTATUS(x)
+#endif
+
+#ifndef WTERMCORE
+#define WTERMCORE(x) ((x)&(1<<(EXIT_BITS-1)))
+#endif
+
+extern pid_t wait(int*);
+extern pid_t waitpid(pid_t, int*, int);
+
+#endif
diff --git a/src/lib/libast/man/LIBAST.3 b/src/lib/libast/man/LIBAST.3
new file mode 100644
index 0000000..380ebde
--- /dev/null
+++ b/src/lib/libast/man/LIBAST.3
@@ -0,0 +1,98 @@
+.fp 5 CW
+.de Af
+.if \\$2 .nr ;G \\$1
+.ie !\\$3 \{\
+\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8"
+\}
+..
+.de aF
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8"
+.ft \\n(;G
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH LIBAST 3
+.UC 4
+.SH NAME
+libast \- introduction to the ast library
+.SH DESCRIPTION
+This section describes the
+.I AST
+(AT&T Software Technology) library functions of the
+.B libast
+library.
+.B libast
+serves three major purposes.
+First, it presents (a subset of) POSIX/ANSI standard headers and interfaces on
+non-compliant systems.
+Second, it provides a portable base of routines that implement concepts
+common to all UNIX system variants.
+Finally, it is a forum for
+modern implementations of features present (or lacking)
+in the standard C libraries.
+Features better provided by separate libraries are omitted from
+.BR libast .
+For example, most terminal driver interface issues are left for
+special purpose libraries such as
+.IR curses (3).
+.PP
+The
+.B libast
+related header files are installed in the directories
+.LR include/ast .
+Routines that do not advertize their own headers are prototyped in
+.LR <ast.h> .
+.L <ast.h>
+is ANSI, K&R and C++ compatible and includes or defines the equivalent of
+.LR <limits.h> ,
+.LR <stddef.h> ,
+.LR <stdlib.h> ,
+.LR <sys/types.h> ,
+.L <string.h>
+and
+.LR <unistd.h> .
+Other libraries that depend on
+.B libast
+may also have headers installed in the
+.L include/ast
+directories.
+.SH FILES
+.nf
+include/ast the \fBast\fP package header directory
+lib/libast.a the \fBlibast\fP library
+lib/libast-g.a the \fBlibast\fP library compiled for debugging
+lib/libast-pg.a the \fBlibast\fP library compiled for profiling
+lib/libast.so.4.0 the \fBlibast\fP shared library
+.fi
+.SH "SEE ALSO"
+intro(3),
+intro(2),
+cc(1)
+.SH CAVEATS
+The library documentation is still under construction.
+Yes, some of it has been in this state for 20 years.
+Thank goodness our commands self-document.
diff --git a/src/lib/libast/man/aso.3 b/src/lib/libast/man/aso.3
new file mode 100644
index 0000000..0e41d30
--- /dev/null
+++ b/src/lib/libast/man/aso.3
@@ -0,0 +1,355 @@
+.fp 5 CW
+.TH LIBASO 3
+.SH NAME
+\fBASO\fP \- Atomic Scalar Operations
+.SH SYNOPSIS
+.de Tp
+.fl
+.ne 2
+.TP
+..
+.de Ss
+.fl
+.ne 2
+.SS "\\$1"
+..
+.de Cs
+.nf
+.ft 5
+..
+.de Ce
+.ft 1
+.fi
+..
+.ta 1.0i 2.0i 3.0i 4.0i 5.0i
+.Cs
+#include <aso.h>
+.Ce
+.Ss "TYPES"
+.Cs
+typedef int (*Asoerror_f)(int, const char*);
+typedef void* (*Asoinit_f)(void*, const char*);
+typedef ssize_t (*Asolock_f)(void*, ssize_t, void volatile*);
+
+typedef struct Asodisc_s
+{
+ uint32_t version;
+ unsigned int hung;
+ Asoerror_f errorf;
+} Asodisc_t;
+
+typedef struct Asometh_s
+{
+ const char* name;
+ int type;
+ Asoinit_f initf;
+ Asolock_f lockf;
+ const char* details;
+} Asometh_t;
+.Ce
+.Ss "OPERATIONS"
+.Cs
+uint8_t asocas8(uint8_t volatile*, int, int);
+uint8_t asoget8(uint8_t volatile*);
+uint8_t asoinc8(uint8_t volatile*);
+uint8_t asodec8(uint8_t volatile*);
+
+uint16_t asocas16(uint16_t volatile*, uint16_t, uint16_t);
+uint16_t asoget16(uint16_t volatile*);
+uint16_t asoinc16(uint16_t volatile*);
+uint16_t asodec16(uint16_t volatile*);
+
+uint32_t asocas32(uint32_t volatile*, uint32_t, uint32_t);
+uint32_t asoget32(uint32_t volatile*);
+uint32_t asoinc32(uint32_t volatile*);
+uint32_t asodec32(uint32_t volatile*);
+
+uint64_t asocas64(uint64_t volatile*, uint64_t, uint64_t);
+uint64_t asoget64(uint64_t volatile*);
+uint64_t asoinc64(uint64_t volatile*);
+uint64_t asodec64(uint64_t volatile*);
+
+unsigned char asocaschar(unsigned char volatile*, int, int);
+unsigned char asogetchar(unsigned char volatile*);
+unsigned char asoincchar(unsigned char volatile*);
+unsigned char asodecchar(unsigned char volatile*);
+
+unsigned short asocasshort(unsigned short volatile*, unsigned short, unsigned short);
+unsigned short asogetshort(unsigned short volatile*);
+unsigned short asoincshort(unsigned short volatile*);
+unsigned short asodecshort(unsigned short volatile*);
+
+unsigned int asocasint(unsigned int volatile*, unsigned int, unsigned int);
+unsigned int asogetint(unsigned int volatile*);
+unsigned int asoincint(unsigned int volatile*);
+unsigned int asodecint(unsigned int volatile*);
+
+unsigned long asocaslong(unsigned long volatile*, unsigned long, unsigned long);
+unsigned long asogetlong(unsigned long volatile*);
+unsigned long asoinclong(unsigned long volatile*);
+unsigned long asodeclong(unsigned long volatile*);
+
+size_t asocassize(size_t volatile*, size_t, size_t);
+size_t asogetsize(size_t volatile*);
+size_t asoincsize(size_t volatile*);
+size_t asodecsize(size_t volatile*);
+
+void* asocasptr(void volatile*, void*, void*);
+void* asogetptr(void volatile*);
+
+void ASODISC(Asodisc_t*, Asoerror_f);
+Asometh_t* asometh(int, void*);
+int asoinit(const char*, Asometh_t*, Asodisc_t*);
+int asolock(unsigned int volatile*, unsigned int, int);
+int asoloop(uintmax_t);
+int asorelax(long);
+.Ce
+.SH DESCRIPTION
+.PP
+\fIASO\fP provides functions to perform atomic scalar operations.
+The functions on the type \f5uint32_t\fP will be fully described below.
+Other functions work similarly on their respective types.
+Some of the functions may be macros that call other functions.
+64 bit operations are provided if the compiler supports 64 bit integers and/or pointers.
+.PP
+.Ss "TYPES"
+.PP
+\f5uint8_t, uint16_t, uint32_t, uint64_t\fP
+
+These are \fIunsigned integer\fP types of different sizes in bits.
+For example, \f5uint32_t\fP represents the type of unsigned integer with 32 bits or 4 bytes.
+.PP
+.Ss "OPERATIONS"
+.PP
+.Ss " uint32_t asoget32(uint32_t* from);"
+This function returns the value \f5*from\fP.
+.PP
+.Ss " uint32_t asoinc32(uint32_t* dest);"
+.Ss " uint32_t asodec32(uint32_t* dest);"
+These functions increment \f5*dest\fP by 1 and decrement \f5*dest\fP by 1 in an atomic step.
+The return value is the old value in \f5*dest\fP.
+
+Consider an example where two concurrent threads/processes call \f5asoinc32()\fP
+on the same \f5dest\fP with values, say \fIv1\fP and \fIv2\fP.
+The eventual value in \f5dest\fP
+will be as if \f5*dest += 2\fP was performed in a single-threaded execution.
+
+That should be constrasted with a situation where, instead of \f5asoinc32()\fP or \f5asodec32()\fP,
+only normal increment (++) or decrement (--) were used.
+Then, the end result could be either \f5*dest += 1\fP or \f5*dest += 2\fP,
+depending on states of the hardware cache and process scheduling.
+.PP
+.Ss " uint32_t asocas32(uint32_t* dest, uint32_t tstval, uint32_t newval);"
+This function provides the atomic \fIcompare-and-swap\fP operation.
+If the current content of \f5dest\fP is equal to \f5tstval\fP then it will be set to \f5newval\fP.
+If multiple threads/processes are performing the same operations only one will succeed with a
+return value of \f5tstval\fP.
+The return value is the old value in \f5*dest\fP.
+.PP
+.Ss " void asorelax(long nsec)"
+This function causes the calling process or thread to briefly pause
+for \f5nsec\fP nanoseconds.
+It is useful to implement tight loops that occasionally yield control.
+.PP
+.Ss " int asolock(unsigned int* lock, unsigned int key, int type)"
+This function uses \f5key\fP, a non-zero unsigned integer, to lock or unlock the \f5lock\fP.
+It returns \f50\fP on success and \f5-1\fP on failure.
+The argument \f5type\fP can take one of the following values:
+.Tp
+\f5ASO_UNLOCK\fP:
+This unlocks the lock if it was locked with \f5key\fP. It is an error to try
+unlocking a lock of a different key.
+.Tp
+\f5ASO_TRYLOCK\fP:
+This makes a single attempt to use the given \f5key\fP to acquire a lock.
+An error will result if the lock is already locked with a different key.
+.Tp
+\f5ASO_LOCK\fP:
+This is a regular locking call. If the lock is locked with a different key,
+this call will wait until the lock is open, then lock it with the given \f5key\fP.
+.Tp
+\f5ASO_SPINLOCK\fP:
+Regardless of what key is currently locking the lock,
+this call will always wait until the lock is open, then lock it with the given \f5key\fP.
+Note that, if the lock is already locked with \f5key\fP, this call can result
+in a deadlock unless that lock can be opened by some other mechanism, e.g.,
+by a different process or thread.
+.PP
+.Ss " int asoloop(uintmax_t iteration);"
+This function is used to implement spin locks that periodically relinquish the processor:
+.Cs
+uintmax_t iteration;
+iteration = 0;
+for (;;) {
+ /* test resource with an aso*() call */
+ if (asoloop(++iteration))
+ /* an error occurred */;
+}
+.Ce
+The value of \f5iteration\fP should be \f51\fP (\fInot\fP \f50\fP) for the first loop iteration.
+\f50\fP is returned on success, \f5-1\fP on failure.
+If \f5iteration mod 4\fP is \f50\fP then \f5asorelax(1)\fP is called to temporarily relinquish
+the processor.
+If \f5Asodisc_t.hung != 0\fP and \f5Asodisc_t.errorf != 0\fP and
+\f5iteration mod (2**Asodisc_t.hung-1)\fP is \f50\fP,
+then \f5Asodisc_t.errorf\fP is called with type \f5ASO_HUNG\fP
+and \f5-1\fP is returned.
+.PP
+.Ss "DISCIPLINE"
+.PP
+The Asodisc_t discipline structure allows the caller to modify default behavior.
+The \fIASO\fP discipline is global for all threads and forked children of the current process.
+The discipline is set and modified by the \f5asoinit()\fP function, described below.
+The structure members are:
+.Tp
+\f5uint32_t version;\fP
+This must be set to \f5ASO_VERSION\fP by the caller and is used by the implementation to detect
+release differences between the caller and the implementation.
+The version is integer of the form \fIYYYYMMDD\fP where \fIYYYY\fP is the release year, \fIMM\fP
+is the release month, and \fIDD\fP is the release day of month.
+This allows the implementation to be forwards and backwards binary compatible with all releases.
+.Tp
+\f5unsigned int hung;\fP
+An error occurs if \f5asoloop\fP() is called \f52**Asometh_t.hung\fP times without gaining access to the loop resource.
+The default value \f50\fP disables the test.
+.Tp
+\f5Asoerror_f errorf;\fP
+\f5int (*errorf)(int type, const char* mesg);\fP
+If \f5errorf\fP != \f50\fP then it is called for each \fIASO\fP fatal library condition.
+\f5type\fP may be one of: \f5ASO_METHOD\fP - a method error; \f5ASO_HUNG\fP - \f5asoloop\fP() was called
+\f52**Asometh_t.hung\fP times with no access to the loop resource.
+\f5mesg\fP is a 0-terminated messsage description.
+.Ss " void ASODISC(Asodisc_t* disc, Asoerror_f errorf);"
+.PP
+This function-like-macro initializes \f5disc->version = ASO_VERSION\fP, \f5disc->errorf = errorf\fP,
+and the remaining \f5disc\fP members to \f50\fP.
+.PP
+.Ss "METHODS"
+.PP
+Several atomic locking methods are implemented for atomic operations
+not supported by \fIintrinsic\fP functions or assembly instructions.
+Methods are controlled by the \f5asometh()\fP and \f5asoinit()\fP
+functions, described below.
+The \fIASO\fP method is global for all threads and forked children of the current process.
+A given method may have multiple types.
+The methods types are:
+.Tp
+\f5ASO_INTRINSIC\fP:
+Some hardware platforms provide machine instructions to implement these operations directly.
+In that case, if a local compiler permits, calls to these \fIintrinsic\fP functions
+may be translated directly into their corresponding machine instructions.
+When necessary the implementation can use only the intrinsic \fIcompare-and-swap\fP
+function on the largest integer type to emulate all other \fIASO\fP operations.
+The \f5ASO_INTRINSIC\fP method type is the default when supported by the compiler.
+It may be used for single-process single-thread, multi-thread, and
+multi-process applications.
+When supported by the hardware / compiler, the library provides the "\fBintrinsic\fP" method with type
+\f5ASO_INTRINSIC|ASO_PROCESS|ASO_THREAD|ASO_SIGNAL\fP.
+.Tp
+\f5ASO_SIGNAL\fP:
+This method type is suitable only for single-process single-thread applications.
+It can be used to provide locking between asyncronous \fBsignal\fP(2) handlers
+and the main program.
+The library provides the "\fBsignal\fP" method with type \f5ASO_SIGNAL\fP.
+This is the default method type when \f5ASO_INTRINSIC\fP is not supported.
+.Tp
+\f5ASO_THREAD\fP:
+This method type is suitable for single-process single-thread, and multi-thread applications.
+It typically requires thread library support, and since the default \f5aso\fP library
+is not linked with a thread library, no \f5ASO_THREAD\fP method is provided by default.
+Threaded applications must link with \fB-ltaso\fP (before \fB-laso\fP or \fB-last\fP)
+in order to access \f5ASO_THREAD\fP methods.
+The \fB-ltaso\fP library provides the "\fBspin\fP" (using \fBpthread_spin_lock\fP(3)) and
+"\fBmutex"\fP (using \fBpthread_mutex_lock\fP(3)) methods with type \f5ASO_THREAD|ASO_SIGNAL\fP.
+.Tp
+\f5ASO_PROCESS\fP:
+This method type is suitable for single-process single-thread, and multi-process applications.
+Some \f5ASO_PROCESS\fP methods may also be suitable for multi-thread applications (if they have the \f5ASO_THREAD\fP type.)
+These methods are typically and noticably \fIslow\fP, up to 2 orders of magnitude slower than
+\f5ASO_INTRINSIC\fP for some applications.
+They are provided as a last resort when other methods are not available.
+The library provides the "\fBsemaphore\fP" method with type \f5ASO_PROCESS|ASO_THREAD|ASO_SIGNAL\fP
+and the "\fBfcntl\fP" method with type \f5ASO_PROCESS|ASO_SIGNAL\fP.
+
+.Ss " Asometh_t* asometh(int type, void* data);"
+This function looks up methods by type or name.
+If type is \f50\fP and \f5data\fP is \f50\fP then the current method is returned; a valid method
+will always be returned for this call.
+If type is \f50\fP then \f5data\fP is treated as a \f50\fP-terminated string method name;
+\f50\fP is returned if no matching method is found.
+The pseudo-type \f5ASO_NEXT\fP generates the list of all methods in successive calls:
+.Cs
+Asometh_t* meth;
+meth = 0;
+while (meth = asometh(ASO_NEXT, meth))
+ /* examine meth->... */
+.Ce
+Otherwise if \f5type\fP is not \f50\fP and not \f5ASO_NEXT\fP it is treated as a combination of the ordered types
+\f5ASO_THREAD\fP, \f5ASO_SIGNAL\fP, \f5ASO_INTRINSIC\fP, \f5ASO_PROCESS\fP:
+the first method with \f5(meth->type & type) != 0\fP is returned;
+\f50\fP is returned if no matching method is found.
+
+Method names are treated as a name, optionally followed by a list of
+\fB,\fP\fIname\fP=\fIvalue\fP details, and optionally ending with \fB,\fP\fIpathname\fP.
+The \fBsemaphore\fP method uses \fBsize\fP=\fInumber\fP to specify
+the number of semaphores and hashes \fIpathname\fP to determine the semaphore IPC key.
+The \fBfcntl\fP method uses \fBsize\fP=\fInumber\fP to specify
+the number of 1 byte file locks and uses \fIpathname\fP as the
+file to lock using \f5fcntl(F_SETLCK[W])\fP.
+
+.Ss " int asoinit(const char* details, Asometh_t* meth, Asodisc_t* disc);"
+This function sets the global discipline to \f5disc\fP,
+closes the current method (releasing its resources),
+temporarily instantiates the default method
+(either \f5ASO_INTRINSIC\fP if available or \f5AS_SIGNAL\fP otherwise),
+and initializes \f5meth\fP and instantiates it as the new method.
+If \f5disc\fP is \f50\fP the the global discpline is not modified.
+If \f5meth\fP is \f50\fP or \f5meth->lockf\fP is \f50\fP and \f5(meth->type & ASO_INTRINSIC) != 0\fP
+then \f5-1\fP is returned and the current method is not changed.
+If an error occurs instantiating \f5meth\fP then the current method is
+set to the default and \f5-1\fP is returned.
+Otherwise \f50\fP is returned on success.
+
+Method resources are released by the next \f5asometh()\fP call,
+or by an \fIASO\fP cleanup function called via \f5atexit\fP(2).
+System global method resources are released on last use;
+this includes removing semaphore keys or
+physical files that may be used by some methods.
+In some cases \fIASO\fP maintains reference counts within
+the resource to determine last use.
+
+An application requiring a specific method must check the default method before
+using any \fIASO\fP operations. For example, a threaded application would
+do something like this:
+.Cs
+void* data = 0 /* \fIor\fP a method name string with optional details */
+Asometh_t* meth;
+if (data || !(asometh(0, 0)->type & (ASO_INTRINSIC|ASO_THREAD))) {
+ if (!(meth = asometh(ASO_INTRINSIC|ASO_THREAD, data)))
+ /* error -- suitable method not found */;
+ else if (asoinit(meth, 0, 0, ASO_VERSION))
+ /* error -- method initialization error */;
+}
+/* ready for \fIASO\fP operaions */
+.Ce
+A multi-process application would check for \f5(ASO_INTRINSIC|ASO_PROCESS)\fP
+instead of \f5(ASO_INTRINSIC|ASO_THREAD)\fP.
+
+.PP
+.SH IMPLEMENTATION NOTES
+Unlike other \fIAST\fP library discipline/method functions which can instantiate
+multiple discpline/method handles within a single process, the \fIASO\fP
+library allows only one discipline and method to be set at a time, with the additional
+restriction that it may only be set by the main and only thread of the calling process.
+For this reason there is no open/close interface with an instantation handle;
+instead the global discipline/method is simply initialized by \f5asoinit()\fP.
+
+\f5ASO_THREAD\fP and \f5ASO_PROCESS\fP methods rely on the \f5Asometh_t.lockf()\fP
+being sufficiently "heavy" to flush the calling thread/process memory cache
+so the subsequent \fIASO\fP operation operates on the physical memory location
+instead of the cached location. There is currently no other portable mechanism
+that guarantees this other than the \f5ASO_INTRINSIC\fP method.
+
+.PP
+.SH AUTHOR
+Kiem-Phong Vo, Adam Edgar, and Glenn Fowler
diff --git a/src/lib/libast/man/ast.3 b/src/lib/libast/man/ast.3
new file mode 100644
index 0000000..8055be9
--- /dev/null
+++ b/src/lib/libast/man/ast.3
@@ -0,0 +1,283 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH AST 3
+.SH NAME
+ast \- miscellaneous libast support
+.SH SYNOPSIS
+.EX
+#include <ast.h>
+
+char* astconf(const char* \fIname\fP, const char* \fIpath\fP, const char* \fIvalue\fP);
+Ast_confdisc_t astconfdisc(Ast_confdisc_t new_notify);
+void astconflist(Sfio_t* stream, const char* path, int flags);
+off_t astcopy(int \fIrfd\fP, int \fIwfd\fP, off_t \fIn\fP);
+int astquery(int \fIfd\fP, const char* \fIformat\fP , ...);
+.EE
+.SH DESCRIPTION
+.L astconf
+is a string interface to the
+.IR confstr (2),
+.IR pathconf (2),
+and
+.IR sysconf (2)
+calls.
+If
+.I value
+is
+.L 0
+then the configuration parameter value for
+.I name
+is returned.
+Some
+.I name
+configuration parameters may consult the
+.I path
+argument.
+In this case if
+.I path
+is
+.L 0
+then
+\f5"/"\fP
+is used.
+Otherwise if
+.I path
+is not
+.L 0
+then it must exist.
+The string return value for
+.I name
+remains unchanged until the next
+.L astconf
+call on
+.IR name .
+If
+.I value
+is
+.L 0
+then a valid string is always returned;
+\f5""\fP
+is returned if
+.I name
+has no configuration value.
+This simplifies the programming interface:
+.EX
+if (!strcmp(astconf("PATH_RESOLVE", NiL, NiL), "logical"))
+ /* the logical way ... */
+.EE
+If
+.I value
+is not
+.L 0
+then the configuration parameter value for
+.I name
+is set to
+.IR value .
+.L 0
+is returned if the value cannot be set.
+The paradigm is:
+.EX
+universe = astconf("UNIVERSE", 0, "att");
+\|.\|.\|.
+astconf("UNIVERSE", 0, universe);
+.EE
+The settable configuration names are:
+.TP
+.L FS_3D
+.L 1
+if
+.IR 3d (1)
+viewpathing is enabled,
+.L 0
+otherwise.
+This is an alternative to the
+.IR fs3d (3)
+interface.
+.TP
+.L PATH_RESOLVE
+.L logical
+if symbolic links are followed during file tree traversal,
+.L physical
+if symbolic links are not followed during file tree traversal,
+and
+.L metaphysical
+if symbolic links are followed at the top level during file tree traversal.
+These correspond to the generic
+.LR \-L ,
+.LR \-P ,
+and
+.L \-H
+command options.
+.TP
+.L UNIVERSE
+.L ucb
+for
+.I Berkeley
+style and
+.L att
+otherwise.
+This configuration parameter controls the
+.I universe
+setting on machines that support it (e.g., Pyramid).
+.L UNIVERSE
+also controls the behavior of some commands like
+.IR cat (1)
+and
+.IR echo (1).
+.PP
+User defined
+.I name
+values may also be set and queried, but these should probably have
+some form of vendor prefix to avoid being stomped by future standards.
+.PP
+.L astconfdisc
+registers a discipline function
+.EX
+int (*notify)(const char* \fIname\fP, const char* \fIpath\fP, const char* \fIvalue\fP);
+.EE
+that is called just before the configuration parameter
+.I name
+is set to
+.I value
+relative to
+.IR path .
+If
+.I notify
+returns
+.L 0
+then the configuration parameter value is not changed.
+.PP
+.L astconflist
+lists the current configuration names and values of
+.IR stream .
+If
+.I path
+is
+.L 0
+then \f5"/"\fP is used where appropriate.
+If
+.I flags
+is
+.L 0
+or
+.L R_OK|W_OK
+then all configuration parameters are listed.
+.L R_OK
+lists the readonly configuration parameters and
+.L W_OK
+lists the settable configuration parameters.
+.L X_OK
+lists the settable configuration parameters in a form that can be
+snarfed for input to the
+.IR getconf (1)
+command.
+.PP
+.L astcopy
+efficiently copies up to
+.I n
+bytes from the file descriptor
+.I rfd
+to the file descriptor
+.IR wfd .
+The actual number of bytes copied is returned; \-1 is returned on error.
+If
+.I n
+is 0 then an optimal number of bytes (with respect to both
+.I rfd
+and
+.IR wfd )
+is copied.
+.PP
+If possible
+.IR mmap (2)
+is used to do the transfer.
+Some implementations may bypass user buffer copies usually required by the
+.IR read (2)- write (2)
+paradigm.
+.PP
+.L astquery
+outputs an
+.IR sfprintf (3)
+prompt specified by
+.I "format, .\|.\|."
+to the controlling terminal and reads a response from the controlling terminal.
+Offirmative response returns
+.LR 0 ,
+.L EOF
+or quit response returns
+.LR \-1 ,
+otherwise
+.L 1
+is returned.
+If
+.I quit
+is greater than
+.L 0
+then
+.I exit(quit)
+is called on a quit response.
+The responses will eventually be locale specific.
+.PP
+.L astwinsize
+returns the number of rows in
+.I *rows
+and the number of columns
+.I *col
+for the terminal file descriptor
+.IR fd .
+If the number of rows or columns cannot be determined or if
+.I fd
+is not a terminal then
+.I *rows
+and
+.I *cols
+are set to
+.LR 0 .
+If
+.I ioctl (2)
+methods fail then the environment variable
+.L LINES
+is used to set
+.I *rows
+and the environment variable
+.L COLUMNS
+is used to set
+.IR *cols .
+.SH "SEE ALSO"
+getconf(1), confstr(2), mmap(2), pathconf(2), read(2), sysconf(2), write(2)
diff --git a/src/lib/libast/man/astsa.3 b/src/lib/libast/man/astsa.3
new file mode 100644
index 0000000..5b588a8
--- /dev/null
+++ b/src/lib/libast/man/astsa.3
@@ -0,0 +1,161 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.PP
+..
+.de Tp
+.fl
+.ne 3
+.TP
+..
+.de Ss
+.fl
+.ne 3
+.SS "\\$1"
+..
+.ta 1.0i 2.0i 3.0i 4.0i 5.0i
+.TH ASTSA 3
+.SH NAME
+astsa \- standalone libast support
+.SH SYNOPSIS
+.EX
+#include <ast.h>
+#include <ccode.h>
+#include <error.h>
+#include <option.h>
+#include <stk.h>
+.EE
+.SH DESCRIPTION
+.B astsa
+is a standalone subset of
+.BR ast (3)
+that requires only
+.BR cdt (3)
+and
+.BR sfio (3).
+.PP
+.B <ast.h>
+includes
+.BR <ast_common.h> ,
+.B <stdarg.h>
+or
+.BR <varargs.h> ,
+.BR <sfio.h> ,
+.BR <limits.h> ,
+and
+.B <limits.h>
+and
+.B <unistd.h>
+if supported by the local system.
+.PP
+The macros and functions provided by
+.B <ast.h>
+are described below.
+The other headers are described in
+.BR ccode (3),
+.BR error (3),
+.BR optget (3),
+and
+.BR stk (3).
+.SH MACROS
+.Ss "size_t elementsof(\fIx\fP)"
+Evaluates to the number of elements in the array variable
+.IR x .
+.Ss "\fItype\fP* newof(void* old, \fItype\fP, size_t \fIelements\fP, size_t \fIextra\fP)"
+Equivalent to (\fItype\fP*)realloc((char*)\fIold\fP,sizeof(\fItype\fP)*\fIelements\fP+\fIextra\fP)
+if \fIold\fP!=0 and
+(\fItype\fP*)calloc(1,sizeof(\fItype\fP)*\fIelements\fP+\fIextra\fP)
+otherwise.
+.Ss "\fItype\fP* oldof(void* old, \fItype\fP, size_t \fIelements\fP, size_t \fIextra\fP)"
+Equivalent to (\fItype\fP*)realloc((char*)\fIold\fP,sizeof(\fItype\fP)*\fIelements\fP+\fIextra\fP)
+if \fIold\fP!=0 and
+(\fItype\fP*)malloc(1,sizeof(\fItype\fP)*\fIelements\fP+\fIextra\fP)
+otherwise.
+.Ss "size_t roundof(\fIx\fP,\fIy\fP)"
+Evaluates to \fIx\fP rounded up to the next power of 2 boundary \fIy\fP.
+.Ss "int ssizeof(\fIx\fP)"
+Equivalent to (int)sizeof(\fIx\fP).
+.Ss "int streq(\fIa\fP,\fIb\fP)"
+Equivalent to (*(\fIa\fP)==*(\fIb\fP)&&strcmp(\fIa\fP,\fIb\fP)==0).
+.Ss "int strneq(\fIa\fP,\fIb\fP,\fIn\fP)"
+Equivalent to (*(\fIa\fP)==*(\fIb\fP)&&strncmp(\fIa\fP,\fIb\fP,\fIn\fP)==0).
+.SH FUNCTIONS
+.Ss "void astwinsize(int \fIfd\fP, int* \fIplines\fP, int* \fIpcolumns\fP)"
+If \fIplines\fP!=0 then *\fIplines\fP is set to the number of lines on the
+tty device corresponding to \fIfd\fP.
+If \fIpcolumns\fP!=0 then *\fIpcolumns\fP is set to the number of columns
+on the tty device corresponding to \fIfd\fP.
+The default if \fIfd\fP is not a terminal device, or if \fIfd\fP queries fail,
+is 24 lines and 80 columns.
+.Ss "char* fmterror(int \fIerrno\fP)"
+Returns the error message text corresponding to the
+.BR errno (3)
+\fIerrno\fP.
+.Ss "char* strerror(int \fIerrno\fP)"
+Equivalent to fmterror(\fIerrno\fP).
+.Ss "int strgrpmatch(const char* \fIstring\fP, const char* \fIpattern\fP, int* \fIsub\fP, int \fInsub\fP, int \fIflags\fP)"
+Matches the null terminated \fIstring\fP against the null terminated
+.BR ksh (1)
+augmented \fIpattern\fP.
+If \fIsub\fP!=0 then \fIsub\fP[2*\fIi\fP] is set to the start offset and \fIsub\fP[2*\fIi\fP+1] is set
+to the end offset of the \fIi\fP-th parenthesized subexpression.
+\fInsub\fP is 1/2 the number of elements in \fIsub\fP.
+\fIflags\fP controls the matching:
+.Tp
+\f5STR_MAXIMAL\fP:
+Maximal match.
+The default is minimal (first) match.
+.Tp
+\f5STR_LEFT\fP:
+Implicit left anchor.
+.Tp
+\f5STR_RIGHT\fP:
+Implicit right anchor.
+.Tp
+\f5STR_ICASE\fP:
+Ignore case.
+.Tp
+\f5STR_GROUP\fP:
+(|&) inside [@|*|+{n,m}](...) only.
+.Ss "int strmatch(const char* \fIstring\fP, const char* \fIpattern\fP, int* \fIsub\fP, int \fInsub\fP, int \fIflags\fP)"
+Equivalent to strgrpmatch(\fIstring\fP,\fIpattern\fP,0,0,STR_MAXIMAL|STR_LEFT|STR_RIGHT).
+.SH "SEE ALSO"
+.BR ast (3),
+.BR ccode (3),
+.BR cdt (3),
+.BR error (3),
+.BR malloc (3),
+.BR option (3),
+.BR sfio (3),
+.BR stk (3)
diff --git a/src/lib/libast/man/cdt.3 b/src/lib/libast/man/cdt.3
new file mode 100644
index 0000000..46bfe13
--- /dev/null
+++ b/src/lib/libast/man/cdt.3
@@ -0,0 +1,617 @@
+.fp 5 CW
+.TH LIBCDT 3
+.SH NAME
+\fBCdt\fR \- container data types
+.SH SYNOPSIS
+.de Tp
+.fl
+.ne 2
+.TP
+..
+.de Ss
+.fl
+.ne 2
+.SS "\\$1"
+..
+.de Cs
+.nf
+.ft 5
+..
+.de Ce
+.ft 1
+.fi
+..
+.ta 1.0i 2.0i 3.0i 4.0i 5.0i
+.Cs
+#include <cdt.h>
+.Ce
+.Ss "DICTIONARY TYPES"
+.Cs
+Void_t*;
+Dt_t;
+Dtdisc_t;
+Dtmethod_t;
+Dtlink_t;
+Dtstat_t;
+.Ce
+.Ss "DICTIONARY CONTROL"
+.Cs
+Dt_t* dtopen(const Dtdisc_t* disc, const Dtmethod_t* meth);
+int dtclose(Dt_t* dt);
+void dtclear(dt);
+Dtdisc_t* dtdisc(Dt_t* dt, const Dtdisc_t* disc, int type);
+Dtmethod_t* dtmethod(Dt_t* dt, const Dtmethod_t* meth);
+Dt_t* dtview(Dt_t* dt, Dt_t* view);
+int dtcustomize(Dt_t* dt, int type, Void_t* arg);
+int dtoptimize(Dt_t* dt);
+int dtshare(Dt_t* dt, int type);
+int dtlock(Dt_t* dt, unsigned int key, int type);
+.Ce
+.Ss "STORAGE METHODS"
+.Cs
+Dtmethod_t* Dtset;
+Dtmethod_t* Dtbag;
+Dtmethod_t* Dtrhset;
+Dtmethod_t* Dtrhbag;
+Dtmethod_t* Dtoset;
+Dtmethod_t* Dtobag;
+Dtmethod_t* Dtlist;
+Dtmethod_t* Dtstack;
+Dtmethod_t* Dtqueue;
+Dtmethod_t* Dtdeque;
+.Ce
+.Ss "DISCIPLINE"
+.Cs
+#define DTOFFSET(struct_s,member)
+#define DTDISC(disc,key,size,link,makef,freef,comparf,hashf,memoryf,eventf)
+typedef Void_t* (*Dtmake_f)(Dt_t*, Void_t*, Dtdisc_t*);
+typedef void (*Dtfree_f)(Dt_t*, Void_t*, Dtdisc_t*);
+typedef int (*Dtcompar_f)(Dt_t*, Void_t*, Void_t*, Dtdisc_t*);
+typedef unsigned int (*Dthash_f)(Dt_t*, Void_t*, Dtdisc_t*);
+typedef Void_t* (*Dtmemory_f)(Dt_t*, Void_t*, size_t, Dtdisc_t*);
+typedef int (*Dtevent_f)(Dt_t*, int, Void_t*, Dtdisc_t*);
+.Ce
+.Ss "OBJECT OPERATIONS"
+.Cs
+Void_t* dtinsert(Dt_t* dt, Void_t* obj);
+Void_t* dtappend(Dt_t* dt, Void_t* obj);
+Void_t* dtdelete(Dt_t* dt, Void_t* obj);
+Void_t* dtattach(Dt_t* dt, Void_t* obj);
+Void_t* dtdetach(Dt_t* dt, Void_t* obj);
+Void_t* dtsearch(Dt_t* dt, Void_t* obj);
+Void_t* dtmatch(Dt_t* dt, Void_t* key);
+Void_t* dtfirst(Dt_t* dt);
+Void_t* dtnext(Dt_t* dt, Void_t* obj);
+Void_t* dtlast(Dt_t* dt);
+Void_t* dtprev(Dt_t* dt, Void_t* obj);
+Void_t* dtleast(Dt_t* dt, Void_t* obj);
+Void_t* dtmost(Dt_t* dt, Void_t* obj);
+int dtwalk(Dt_t* dt, int (*userf)(Dt_t*, Void_t*, Void_t*), Void_t*);
+Dtlink_t* dtflatten(Dt_t* dt);
+Dtlink_t* dtlink(Dt_t* dt, Dtlink_t* link);
+Void_t* dtobj(Dt_t* dt, Dtlink_t* link);
+Dtlink_t* dtextract(Dt_t* dt);
+Dtlink_t* dtrestore(Dt_t* dt, Dtlink_t* link);
+.Ce
+.Ss "DICTIONARY STATUS"
+.Cs
+Dt_t* dtvnext(Dt_t* dt);
+ssize_t dtvcount(Dt_t* dt);
+Dt_t* dtvhere(Dt_t* dt);
+ssize_t dtsize(Dt_t* dt);
+ssize_t dtstat(Dt_t* dt, Dtstat_t* st);
+.Ce
+.Ss "HASH FUNCTIONS"
+.Cs
+unsigned int dtstrhash(unsigned int h, char* str, int n);
+unsigned int dtcharhash(unsigned int h, unsigned char c);
+.Ce
+.SH DESCRIPTION
+.PP
+\fICdt\fP manages run-time dictionaries using standard container data types:
+unordered set/multiset, ordered set/multiset, list, stack, and queue.
+.PP
+.Ss "DICTIONARY TYPES"
+.PP
+.Ss " Void_t*"
+This type is used to pass objects between \fICdt\fP and application code.
+\f5Void_t\fP is defined as \f5void\fP for ANSI-C and C++
+and \f5char\fP for older C compilation environments.
+.PP
+.Ss " Dt_t"
+This is the type of a dictionary handle.
+.PP
+.Ss " Dtdisc_t"
+This defines the type of a discipline structure which define the lay-out of
+an object and functions to compare, hash, make, delete objects, etc. (see \f5dtdisc()\fP).
+.PP
+.Ss " Dtmethod_t"
+This defines the type of a container method.
+.PP
+.Ss " Dtlink_t"
+This is the type of a dictionary object holder (see \f5dtdisc()\fP.)
+.PP
+.Ss " Dtstat_t"
+This is the type of a structure to return dictionary statistics (see \f5dtstat()\fP.)
+.PP
+.Ss "DICTIONARY CONTROL"
+.PP
+.Ss " Dt_t* dtopen(const Dtdisc_t* disc, const Dtmethod_t* meth)"
+This creates a new dictionary.
+\f5disc\fP is a discipline structure to describe object format.
+\f5meth\fP specifies a manipulation method.
+\f5dtopen()\fP returns the new dictionary or \f5NULL\fP on error.
+See also the events \f5DT_OPEN\fP and \f5DT_ENDOPEN\fP below.
+.PP
+.Ss " int dtclose(Dt_t* dt)"
+This deletes \f5dt\fP and its objects.
+Note that \f5dtclose()\fP fails if \f5dt\fP is being viewed by
+some other dictionaries (see \f5dtview()\fP).
+\f5dtclose()\fP returns \f50\fP on success and \f5-1\fP on error.
+See also the events \f5DT_CLOSE\fP and \f5DT_ENDCLOSE\fP below.
+.PP
+.Ss " void dtclear(Dt_t* dt)"
+This deletes all objects in \f5dt\fP without closing \f5dt\fP.
+.PP
+.Ss " Dtdisc_t* dtdisc(Dt_t* dt, const Dtdisc_t* disc, int type)"
+If \f5disc\fP is \f5NULL\fP, \f5dtdisc()\fP returns the current discipline.
+Otherwise, it changes the discipline of \f5dt\fP to \f5disc\fP.
+Objects may be rehashed, reordered, or removed as appropriate.
+\f5type\fP can be any bit combination of \f5DT_SAMECMP\fP and \f5DT_SAMEHASH\fP.
+\f5DT_SAMECMP\fP means that objects will compare exactly the same as before
+thus obviating the need for reordering or removing new duplicates.
+\f5DT_SAMEHASH\fP means that hash values of objects remain the same
+thus obviating the need to rehash.
+\f5dtdisc()\fP returns the previous discipline on success
+and \f5NULL\fP on error.
+.PP
+.Ss " Dtmethod_t dtmethod(Dt_t* dt, const Dtmethod_t* meth)"
+If \f5meth\fP is \f5NULL\fP, \f5dtmethod()\fP returns the current method.
+Otherwise, it changes the storage method of \f5dt\fP to \f5meth\fP.
+Objects may be rehashed, reordered, or removed as appropriate.
+\f5dtmethod()\fP returns the previous method or \f5NULL\fP on error.
+.PP
+.Ss " Dt_t* dtview(Dt_t* dt, Dt_t* view)"
+A viewpath allows a search or walk starting from a dictionary to continue to another.
+\f5dtview()\fP first terminates any current view from \f5dt\fP to another dictionary.
+Then, if \f5view\fP is \f5NULL\fP, \f5dtview\fP returns the terminated view dictionary.
+If \f5view\fP is not \f5NULL\fP, a viewpath from \f5dt\fP to \f5view\fP is established.
+\f5dtview()\fP returns \f5dt\fP on success and \f5NULL\fP on error.
+.PP
+It is an error to have dictionaries on a viewpath with different storage methods.
+In addition, dictionaries on the same view path should
+treat objects in a consistent manner with respect to comparison or hashing.
+If not, undefined behaviors may result.
+.PP
+.Ss " int dtcustomize(Dt_t* dt, int type, Void_t* arg)"
+This customizes a storage method. The \f5type\fP argument
+indicates the type of customization and \f5arg\fP gives additional
+information for the operation. Here are the types:
+.Tp
+\f5DT_SHARE\fP:
+This turns on/off the share mode for a dictionary.
+Concurrent accesses of a dictionary not in share mode
+may exhibit undefined behaviors including memory segmentation.
+
+Share mode allows multiple accessors, threads or processes, to access objects.
+Such objects could be in the same directory in the case of threads or shared
+memory in the case of processes.
+.Tp
+\f5DT_OPTIMIZE\fP:
+This causes the underlying method to optimize its internal
+data structure. For example, the splay tree underlying \f5Dtoset\fP
+would be balanced.
+.PP
+.Ss " int dtoptimize(Dt_t* dt)"
+This is a short-hand for invoking \f5dtcustomize()\fP with the \f5DT_OPTIMIZE\fP event.
+.PP
+.Ss " int dtshare(Dt_t* dt, int type)"
+This turns on or off share mode for dictionary \f5dt\fP depending on whether \f5type\fP
+is positive or non-positive. It returns -1 on failure.
+.PP
+.Ss " int dtlock(Dt_t* dt, unsigned int key, int type)"
+This globally locks/unlocks a dictionary using the given \f5key\fP.
+It returns 0 on success and -1 on failure.
+The value of \f5key\fP must not be 0.
+The argument \f5type\fP is used as follows:
+.Tp
+\f5type < 0\fP:
+Unlock the dictionary if it was locked with \f5key\fP.
+An error will result if the dictionary was locked with a different key.
+.Tp
+\f5type == 0\fP:
+Attempt to lock the dictionary with \f5key\fP if it is unlocked.
+An error will result if the dictionary was already locked with a different key.
+.Tp
+\f5type > 0\fP:
+Attempt to lock the dictionary with \f5key\fP.
+If the dictionary is already locked with a different key,
+the call will loop and wait until the lock is open to lock it.
+
+.PP
+.Ss "STORAGE METHODS"
+.PP
+Storage methods are of type \f5Dtmethod_t*\fP.
+\fICdt\fP supports the following methods:
+.PP
+.Ss " Dtoset"
+.Ss " Dtobag"
+Objects are ordered by comparisons.
+\f5Dtoset\fP keeps unique objects.
+\f5Dtobag\fP allows repeatable objects.
+.PP
+.Ss " Dtset"
+.Ss " Dtbag"
+Objects are unordered.
+\f5Dtset\fP keeps unique objects.
+\f5Dtbag\fP allows repeatable objects.
+The underlying data structure is a hash table with chaining to handle collisions.
+.PP
+.Ss " Dtrhset"
+.Ss " Dtrhbag"
+These methods are like \f5Dtset\fP and \f5Dtbag\fP but are based on
+a recursive hashing data structure that allows table extension without
+object relocation. The data structure also supports lock-free
+concurrent search operations for share dictionaries.
+.PP
+.Ss " Dtlist"
+Objects are kept in a list.
+\fIA current object\fP is always defined to be either the head of
+the list or an object resulting from a recent search or insert operation.
+The call \f5dtinsert()\fP will insert a new object
+in front of such a current object
+while the call \f5dtappend()\fP will append in back of it.
+.PP
+.Ss " Dtdeque"
+Objects are kept in a deque. This is similar to \f5Dtlist\fP
+except that objects are always inserted at the front and appended at the tail
+of the list.
+.PP
+.Ss " Dtstack"
+Objects are kept in a stack, i.e., in reverse order of insertion.
+Thus, the last object inserted is at stack top
+and will be the first to be deleted.
+.PP
+.Ss " Dtqueue"
+Objects are kept in a queue, i.e., in order of insertion.
+Thus, the first object inserted is at queue head
+and will be the first to be deleted.
+.PP
+.Ss "DISCIPLINE"
+.PP
+Object format and associated management functions are
+defined in the type \f5Dtdisc_t\fP:
+.Cs
+ typedef struct
+ { ssize_t key, size;
+ ssize_t link;
+ Dtmake_f makef;
+ Dtfree_f freef;
+ Dtcompar_f comparf;
+ Dthash_f hashf;
+ Dtmemory_f memoryf;
+ Dtevent_f eventf;
+ } Dtdisc_t;
+.Ce
+.Ss " ssize_t key, size"
+Each object \f5obj\fP is identified by a key used for object comparison or hashing.
+\f5key\fP should be non-negative and defines an offset into \f5obj\fP.
+If \f5size\fP is negative, the key is a null-terminated
+string with starting address \f5*(Void_t**)((char*)obj+key)\fP.
+If \f5size\fP is zero, the key is a null-terminated string with starting address
+\f5(Void_t*)((char*)obj+key)\fP.
+Finally, if \f5size\fP is positive, the key is a byte array of length \f5size\fP
+starting at \f5(Void_t*)((char*)obj+key)\fP.
+.PP
+.Ss " ssize_t link"
+Let \f5obj\fP be an object to be inserted into \f5dt\fP.
+If \f5link\fP is negative, an object holder of type \f5Dtlink_t\fP
+will be allocated to hold \f5obj\fP.
+Otherwise, \f5obj\fP should have
+a \f5Dtlink_t\fP structure embedded \f5link\fP bytes into it,
+i.e., at address \f5(Dtlink_t*)((char*)obj+link)\fP.
+.PP
+.Ss " Void_t* (*makef)(Dt_t* dt, Void_t* obj, Dtdisc_t* disc)"
+If \f5makef\fP is not \f5NULL\fP,
+\f5dtinsert(dt,obj)\fP or \f5dtappend()\fP will call it
+to make a copy of \f5obj\fP suitable for insertion into \f5dt\fP.
+If \f5makef\fP is \f5NULL\fP, \f5obj\fP itself will be inserted into \f5dt\fP.
+.PP
+.Ss " void (*freef)(Dt_t* dt, Void_t* obj, Dtdisc_t* disc)"
+If not \f5NULL\fP,
+\f5freef\fP is used to destroy data associated with \f5obj\fP.
+.PP
+.Ss "int (*comparf)(Dt_t* dt, Void_t* key1, Void_t* key2, Dtdisc_t* disc)"
+If not \f5NULL\fP, \f5comparf\fP is used to compare two keys.
+Its return value should be \f5<0\fP, \f5=0\fP, or \f5>0\fP to indicate
+whether \f5key1\fP is smaller, equal to, or larger than \f5key2\fP.
+All three values are significant for method \f5Dtoset\fP and \f5Dtobag\fP.
+For other methods, a zero value
+indicates equality and a non-zero value indicates inequality.
+If \f5(*comparf)()\fP is \f5NULL\fP, an internal function is used
+to compare the keys as defined by the \f5Dtdisc_t.size\fP field.
+.PP
+.Ss " unsigned int (*hashf)(Dt_t* dt, Void_t* key, Dtdisc_t* disc)"
+If not \f5NULL\fP,
+\f5hashf\fP is used to compute the hash value of \f5key\fP.
+It is required that keys compared equal will also have same hash values.
+If \f5hashf\fP is \f5NULL\fP, an internal function is used to hash
+the key as defined by the \f5Dtdisc_t.size\fP field.
+.PP
+.Ss " Void_t* (*memoryf)(Dt_t* dt, Void_t* addr, size_t size, Dtdisc_t* disc)"
+If not \f5NULL\fP, \f5memoryf\fP is used to allocate and free memory.
+When \f5addr\fP is \f5NULL\fP, a memory segment of size \f5size\fP is requested.
+If \f5addr\fP is not \f5NULL\fP and \f5size\fP is zero, \f5addr\fP is to be freed.
+If \f5addr\fP is not \f5NULL\fP and \f5size\fP is positive,
+\f5addr\fP is to be resized to the given size.
+If \f5memoryf\fP is \f5NULL\fP, \fImalloc(3)\fP is used.
+.PP
+.Ss " int (*eventf)(Dt_t* dt, int type, Void_t* data, Dtdisc_t* disc)"
+If not \f5NULL\fP, \f5eventf\fP announces various events.
+Each event may have particular handling of the return values from \f5eventf\fP.
+But a negative return value typically means failure.
+Following are the events:
+.Tp
+\f5DT_OPEN\fP:
+This event is raised at the start of the process to open a new dictionary.
+The argument \f5data\fP will be a pointer to an object of type \f5Void_t*\fP
+initialized to \f5NULL\fP before the call. The return value of \f5eventf()\fP
+is significant as follows:
+
+On a negative return value, \f5dtopen()\fP will return failure.
+
+On a zero return value, \f5eventf()\fP may set \f5*(Void_t**)data\fP to some non-\f5NULL\fP
+value to indicate that the dictionary structure itself should be allocated
+along with the \f5Dtdisc_t.data\fP section.
+Otherwise, it will be allocated separately with \f5malloc(3)\fP.
+
+On a positive return value, the dictionary is being reconstructed
+based on existing states of some previous dictionary.
+In this case, \f5eventf()\fP should set \f5*(Void_t**)data\fP to point to
+the field \f5Dt_t.data\fP of the corresponding previous dictionary (see \f5DT_CLOSE\fP below).
+If the handle of the previous dictionary was created as discussed above
+in the case of the zero return value, it will be exactly restored.
+Otherwise, a new handle will be allocated with \f5malloc()\fP.
+The ability to create different dictionaries sharing the same set of objects
+allows for managing objects in shared and/or persistent memory.
+.Tp
+\f5DT_ENDOPEN\fP:
+This event is raised at the end of the process to open a dictionary.
+The return value of \f5eventf()\fP will be ignored.
+.Tp
+\f5DT_CLOSE\fP:
+This event is raised at the start of the process to close dictionary \f5dt\fP.
+The return value of \f5eventf\fP is significant as follows:
+
+On a negative return value, \f5dtclose()\fP will return failure.
+
+On a zero return value, all dictionary objects will be deleted and
+and all associated memory will be freed.
+
+On a positive return value, allocated objects and memory will be kept intact.
+This means that \f5dt->data\fP remains intact and can be reused in some future
+dictionary (see \f5DT_OPEN\fP above).
+Note, however, that \f5dt\fP itself would still be freed if it was allocated with \f5malloc(3)\fP.
+.Tp
+\f5DT_ENDCLOSE\fP:
+This event is raised at the end of the process to close a dictionary.
+The return value of \f5eventf()\fP will be ignored.
+.Tp
+\f5DT_DISC\fP:
+The discipline of \f5dt\fP is being changed to a new one given in
+\f5(Dtdisc_t*)data\fP.
+.Tp
+\f5DT_METH\fP:
+The method of \f5dt\fP is being changed to a new one given in
+\f5(Dtmethod_t*)data\fP.
+.Tp
+\f5DT_HASHSIZE\fP:
+This event is applicable to
+the methods \f5Dtset\fP, \f5Dtbag\fP, \f5Dtrhset\fP and \f5Dtrhbag\fP.
+It is typically issued when the respective internal data structure of
+a method is about to be initialized.
+If the return value of the event handling function is positive,
+\f5*(ssize_t*)data\fP is examined for further action;
+else, it is ignored.
+A positive return value means that the event function wishes to suggest a table size.
+It does that by setting \f5*(ssize_t*)data\fP to the desired size.
+Then, the actual table size will be the maximum of the absolute value
+of \f5*(ssize_t*)data\fP and some predefined value set by the method.
+In addition, if \f5*(ssize_t*)data\fP was negative,
+the \f5Dtset\fP and \f5Dtbag\fP methods will never resize the hash table.
+.Tp
+\f5DT_ERROR\fP:
+This event announces an error that occurred during some operations.
+The argument \f5(char*)data\fP is a null-terminated string describing the error.
+.PP
+.Ss "#define DTOFFSET(struct_s,member)"
+This macro function computes the offset of \f5member\fP from the start
+of structure \f5struct_s\fP. It is useful for getting the offset of
+a \f5Dtlink_t\fP embedded inside an object.
+.PP
+.Ss "#define DTDISC(disc,key,size,link,makef,freef,comparf,hashf,memoryf,eventf)"
+This macro function initializes the discipline pointed to by \f5disc\fP
+with the given values.
+.PP
+.Ss "OBJECT OPERATIONS"
+.PP
+.Ss " Void_t* dtinsert(Dt_t* dt, Void_t* obj)"
+.Ss " Void_t* dtappend(Dt_t* dt, Void_t* obj)"
+These functions add an object prototyped by \f5obj\fP into \f5dt\fP.
+\f5dtinsert()\fP and \f5dtappend()\fP perform the same function
+for all methods except for \f5Dtlist\fP (see \f5Dtlist\fP for details).
+If there is an existing object in \f5dt\fP matching \f5obj\fP
+and the storage method is \f5Dtset\fP, \f5Dtrhset\fP or \f5Dtoset\fP,
+\f5dtinsert()\fP and \f5dtappend()\fP will simply return the matching object.
+Otherwise, a new object is inserted according to the method in use.
+See \f5Dtdisc_t.makef\fP for object construction.
+The new object or a matching object as noted will be returned on success
+while \f5NULL\fP is returned on error.
+.PP
+.Ss " Void_t* dtdelete(Dt_t* dt, Void_t* obj)"
+If \f5obj\fP is \f5NULL\fP, methods \f5Dtstack\fP and \f5Dtqueue\fP
+delete respectively stack top or queue head while other methods do nothing.
+If \f5obj\fP is not \f5NULL\fP, an object matching \f5obj\fP is deleted.
+See \f5Dtdisc_t.freef\fP for object destruction.
+\f5dtdelete()\fP returns the deleted object (even if it was deallocated)
+or \f5NULL\fP on error.
+.PP
+.Ss " Void_t* dtattach(Dt_t* dt, Void_t* obj)"
+This function is similar to \f5dtinsert()\fP but \f5obj\fP itself
+will be inserted into \f5dt\fP even if a discipline
+function \f5makef\fP is defined.
+.PP
+.Ss " Void_t* dtdetach(Dt_t* dt, Void_t* obj)"
+This function is similar to \f5dtdelete()\fP but the object to be deleted
+from \f5dt\fP will not be freed (via the discipline \f5freef\fP function).
+.PP
+.Ss " Void_t* dtsearch(Dt_t* dt, Void_t* obj)"
+.Ss " Void_t* dtmatch(Dt_t* dt, Void_t* key)"
+These functions find an object matching \f5obj\fP or \f5key\fP either from \f5dt\fP or
+from some dictionary accessible from \f5dt\fP via a viewpath (see \f5dtview()\fP.)
+\f5dtsearch()\fP and \f5dtmatch()\fP return the matching object or
+\f5NULL\fP on failure.
+.PP
+.Ss " Void_t* dtfirst(Dt_t* dt)"
+.Ss " Void_t* dtnext(Dt_t* dt, Void_t* obj)"
+\f5dtfirst()\fP returns the first object in \f5dt\fP.
+\f5dtnext()\fP returns the object that follows an object matching \f5obj\fP.
+Objects are ordered based on the storage method in use.
+For \f5Dtoset\fP and \f5Dtobag\fP, objects are ordered by object comparisons.
+For \f5Dtstack\fP, objects are ordered in reverse order of insertion.
+For \f5Dtqueue\fP, objects are ordered in order of insertion.
+For \f5Dtlist\fP, objects are ordered by list position.
+For \f5Dtset\fP, \f5Dtbag\fP, \f5Dtrhset\fP and \f5Dtrhbag\fP,
+objects are ordered by some internal order defined at the time when these
+functions are called.
+
+Objects in a dictionary or a viewpath can be walked using
+a \f5for(;;)\fP loop as below.
+.Cs
+ for(obj = dtfirst(dt); obj; obj = dtnext(dt,obj))
+.Ce
+.PP
+.Ss " Void_t* dtlast(Dt_t* dt)"
+.Ss " Void_t* dtprev(Dt_t* dt, Void_t* obj)"
+\f5dtlast()\fP and \f5dtprev()\fP are like \f5dtfirst()\fP and \f5dtnext()\fP
+but work in reverse order.
+For \f5Dtset\fP, \f5Dtbag\fP, \f5Dtrhset\fP and \f5Dtrhbag\fP,
+both reverse and forward orders are the same.
+Note that dictionaries on a viewpath are still walked in the order
+of the viewpath.
+.PP
+.Ss " Void_t* dtleast(Dt_t* dt, Void_t* obj)"
+.Ss " Void_t* dtmost(Dt_t* dt, Void_t* obj)"
+\f5dtleast()\fP returns the smallest object greater or equal to \f5obj\fP.
+\f5dtmost()\fP returns the largest object smaller or equal to \f5obj\fP.
+Again, object ordering depends on the storage method in use.
+For example, with \f5Dtoset\fP and \f5Dtobag\fP, the ordering of objects
+is well-defined and it is possible to call \f5dtleast()\fP or \f5dtmost()\fP
+on an object not in the dictionary and still get a meaningful result.
+On the other hand, with \f5Dtset\fP or \f5Dtrhset\fP, such a call will
+essentially be the same as \f5dtsearch()\fP because without matching
+an object, it cannot be determined what comes before or after.
+.PP
+.Ss " dtwalk(Dt_t* dt, int (*userf)(Dt_t*, Void_t*, Void_t*), Void_t* data)"
+This function calls \f5(*userf)(walk,obj,data)\fP on each object in \f5dt\fP and
+other dictionaries viewable from it.
+\f5walk\fP is the dictionary containing \f5obj\fP.
+If \f5userf()\fP returns a \f5<0\fP value,
+\f5dtwalk()\fP terminates and returns the same value.
+\f5dtwalk()\fP returns \f50\fP on completion.
+.PP
+.Ss " Dtlink_t* dtflatten(Dt_t* dt)"
+.Ss " Dtlink_t* dtlink(Dt_t* dt, Dtlink_t* link)"
+.Ss " Void_t* dtobj(Dt_t* dt, Dtlink_t* link)"
+Using \f5dtfirst()/dtnext()\fP or \f5dtlast()/dtprev()\fP
+to walk a single dictionary can incur significant cost due to function calls.
+For efficient walking of a single directory (i.e., no viewpathing),
+\f5dtflatten()\fP and \f5dtlink()\fP can be used.
+Objects in \f5dt\fP are made into a linked list and walked as follows:
+.Cs
+ for(link = dtflatten(dt); link; link = dtlink(dt,link) )
+.Ce
+.PP
+Note that \f5dtflatten()\fP returns a list of type \f5Dtlink_t*\fP,
+not \f5Void_t*\fP. That is, it returns a dictionary holder pointer,
+not a user object pointer
+(although both are the same if the discipline field \f5link\fP is zero.)
+The macro function \f5dtlink()\fP
+returns the dictionary holder object following \f5link\fP.
+The macro function \f5dtobj(dt,link)\fP
+returns the user object associated with \f5link\fP,
+Beware that the flattened object list is unflattened on any
+dictionary operations other than \f5dtlink()\fP.
+.PP
+.Ss " Dtlink_t* dtextract(Dt_t* dt)"
+.Ss " Dtlink_t* dtrestore(Dt_t* dt, Dtlink_t* list)"
+\f5dtextract()\fP extracts the list of objects from \f5dt\fP and makes it appear empty.
+\f5dtrestore()\fP repopulates \f5dt\fP with
+a list of objects previously obtained via \f5dtextract()\fP.
+It is important that the same discipline and method are in use at both
+extraction and restoration. Otherwise, undefined behaviors may result.
+These functions return \f5NULL\fP on error.
+
+.PP
+.Ss "DICTIONARY INFORMATION"
+.PP
+.Ss " Dt_t* dtvnext(Dt_t* dt)"
+This returns the dictionary that \f5dt\fP is viewing, if any.
+.Ss " ssize_t dtvcount(Dt_t* dt)"
+This returns the number of dictionaries that view \f5dt\fP.
+.Ss " Dt_t* dtvhere(Dt_t* dt)"
+This returns the dictionary \f5v\fP viewable from \f5dt\fP
+where an object was found from the most recent search or walk operation.
+.Ss " ssize_t dtsize(Dt_t* dt)"
+This function returns the number of objects stored in \f5dt\fP.
+.PP
+.Ss " ssize_t dtstat(Dt_t *dt, Dtstat_t* st)"
+This function reports dictionary statistics.
+It returns the number of objects stored in \f5dt\fP.
+.PP
+\f5Dtstat_t\fP contains the below fields:
+.Tp
+\f5int meth\fP:
+This returns the method used for the dictionary, e.g., \f5DT_SET\fP, \f5DT_OSET\fP, etc.
+.Tp
+\f5ssize_t size\fP:
+This has the number of objects in the dictionary.
+.Tp
+\f5ssize_t mlev\fP:
+This returns the maximum number of levels in the data structure used for object storage, i.e.,
+the binary tree or the recursive hash table.
+For a hash table with chaining (i.e., \f5Dtset\fP and \f5Dtbag\fP),
+it gives the length of the longest chain.
+.Tp
+\f5ssize_t lsize[]\fP:
+This gives the object counts at each level.
+For a hash table with chaining (i.e., \f5Dtset\fP and \f5Dtbag\fP),
+a level is defined as objects at that position in their chains.
+Since chains can be arbitrarily long, the report is limited
+to objects at a level less than \f5DT_MAXSIZE\fP.
+.Tp
+\f5ssize_t tsize[]\fP:
+For a hash table using a trie structure, this counts the number of
+sub-tables at each level. For example, \f5tsize[0]\fP should be 1
+only for this hash table type.
+.PP
+.Ss "HASH FUNCTIONS"
+.PP
+.Ss " unsigned int dtcharhash(unsigned int h, char c)"
+.Ss " unsigned int dtstrhash(unsigned int h, char* str, int n)"
+These functions compute hash values from bytes or strings.
+\f5dtcharhash()\fP computes a new hash value from byte \f5c\fP and seed value \f5h\fP.
+\f5dtstrhash()\fP computes a new hash value from string \f5str\fP and seed value \f5h\fP.
+If \f5n\fP is positive, \f5str\fP is a byte array of length \f5n\fP;
+otherwise, \f5str\fP is a null-terminated string.
+.PP
+.SH IMPLEMENTATION NOTES
+\f5Dtlist\fP, \f5Dtstack\fP and \f5Dtqueue\fP are based on doubly linked list.
+\f5Dtoset\fP and \f5Dtobag\fP are based on top-down splay trees.
+\f5Dtset\fP and \f5Dtbag\fP are based on hash tables with
+move-to-front collision chains.
+\f5Dtrhset\fP and \f5Dtrhbag\fP are based on a recursive hashing data structure
+that avoids table resizing.
+.PP
+.SH AUTHOR
+Kiem-Phong Vo, kpv@research.att.com
diff --git a/src/lib/libast/man/chr.3 b/src/lib/libast/man/chr.3
new file mode 100644
index 0000000..8d57648
--- /dev/null
+++ b/src/lib/libast/man/chr.3
@@ -0,0 +1,126 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH CHR 3
+.SH NAME
+chr \- character constant conversion routines
+.SH SYNOPSIS
+.EX
+#include <ast.h>
+
+int chresc(const char* \fIs\fP, char** \fIe\fP);
+int chrtoi(const char* \fIs\fP);
+.EE
+.SH DESCRIPTION
+.L chresc
+converts and returns the next character constant in the 0-terminated string
+.IR s .
+If
+.I e
+is not 0 then
+.I *e
+is set to point to the next character in
+.I s
+on return.
+0 is returned and
+.I e
+is not modified when the end of
+.I s
+is reached.
+.PP
+.L chrtoi
+converts the 0-terminated string
+.I s
+to an
+.I int
+and returns the value.
+The characters in
+.I s
+are converted in order from the left and shifted into the
+.I int
+value until up to the number of characters in an
+.I int
+is reached.
+This operation is inherently machine-dependent,
+but at least its defined in one place.
+.PP
+The following
+.B \e
+escape sequences are recognized:
+.TP
+.RI \e ooo
+The character represented by the octal code
+.IR ooo .
+.TP
+.RI \ex xx
+The character represented by the hex code
+.IR xx .
+.TP
+.L \ea
+Alert (bell).
+.TP
+.L \eb
+Backspace.
+.TP
+.L \ef
+Formfeed.
+.TP
+.L \en
+Newline.
+.TP
+.L \er
+Carriage return.
+.TP
+.L \et
+Horizontal tab.
+.TP
+.L \ev
+Vertical tab.
+.TP
+.L \eE
+ESC (escape).
+.TP
+.L \e\e
+Backslash.
+.PP
+Other characters following
+.B \e
+are undefined (although for backwards compatibility they
+translate to themselves).
+.SH "SEE ALSO"
+str(3)
diff --git a/src/lib/libast/man/compat.3 b/src/lib/libast/man/compat.3
new file mode 100644
index 0000000..eb5e8a7
--- /dev/null
+++ b/src/lib/libast/man/compat.3
@@ -0,0 +1,103 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH COMPATIBILITY 3
+.SH NAME
+compatibility \- ast library compatibility routines
+.SH SYNOPSIS
+.EX
+#include <ast.h>
+
+int atexit(void(*)(void));
+char* confstr(int);
+int dup2(int, int);
+long fpathconf(int, int);
+int getgroups(int, int*);
+char* getwd(char*);
+int killpg(int, int);
+int link(const char*, const char*);
+int lstat(const char*, struct stat*);
+int memcmp(const char*, const char*, unsigned int);
+char* memcpy(char*, const char*, int);
+char* memset(char*, char, int);
+int mkdir(const char*, mode_t);
+int mkfifo(const char*, mode_t);
+int mknod(const char*, mode_t);
+char* mktemp(char*);
+int mount(const char*, const char*, int);
+long pathconf(const char*, int);
+int perror(const char*);
+FILE* popen(const char*, const char*);
+int readlink(const char*, char*, int);
+int remove(const char*);
+int rename(const char*, const char*);
+int rmdir(const char*);
+int setpgid(pid_t, pid_t);
+int sigmask(int);
+int sigsetmask(long);
+int sigunblock(int);
+char* strchr(const char*, int);
+char* strrchr(const char*, int);
+double strtod(const char*, char**);
+long strtol(const char*, char**, int);
+int symlink(const char*, const char*);
+long sysconf(int);
+int system(const char*);
+char* tmpnam(char*);
+int unlink(const char*);
+int vfork(void);
+int waitpid(pid_t, int*, int);
+.EE
+.SH DESCRIPTION
+These routines are described in the ANSI C, POSIX, BSD and System V manual
+sections 2 and 3.
+The interfaces are preserved and present in all libast implementations.
+Where conflicts exist the POSIX syntax and semantics are implied.
+The appropriate error value is returned and
+.I errno
+is set to
+.L EINVAL
+when emulation is either too expensive or not possible.
+.SH CAVEATS
+If you
+.L "#undef foo"
+and then call
+.L foo
+you may end up with the local implementation of
+.LR foo ,
+and then you get what you payed for.
diff --git a/src/lib/libast/man/error.3 b/src/lib/libast/man/error.3
new file mode 100644
index 0000000..df47d34
--- /dev/null
+++ b/src/lib/libast/man/error.3
@@ -0,0 +1,283 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH ERROR 3
+.SH NAME
+error \- error and debug trace message formatter
+.SH SYNOPSIS
+.EX
+#include <error.h>
+
+Error_info_t error_info;
+
+void error(int \fIlevel\fP, ...);
+void errorv(const char* \fIlibrary\fP, int \fIlevel\fP, va_alist \fIargs\fP);
+void liberror(const char* \fIlibrary\fP, int \fIlevel\fP, ...);
+
+#include <debug.h>
+
+debug(\fIstatement\fP)
+message((int \fIlevel\fP, ...))
+libmessage((const char* \fIlibrary\fI, int \fIlevel\fP, ...))
+.EE
+.SH DESCRIPTION
+.L error
+is the error and debug trace message formatter.
+.I level
+is the severity level.
+Messages with
+.I "level < error_info.trace"
+are suppressed.
+.I error_info.trace
+is initially
+.LR 0 .
+The remaining arguments are passed on to
+.LR printf .
+A
+.I newline
+is appended to the message text, so none should appear in the
+.L printf
+format.
+If
+.I error_info.id
+is not
+.L 0
+then messages with
+.I "level > 0"
+are prefixed by
+.IR error_info.id: .
+.PP
+Before the message text is output to standard error
+it is passed to the function
+.LR "char* ERROR_translate(const char* \fItext\fP, int \fIflag\fP)" .
+By default
+.L ERROR_translate
+returns the
+.L text
+argument, but on some systems it may do language translation via lookup
+on the original source text.
+.RL ( error
+calls
+.L ERROR_translate
+with a 0
+.L flag
+argument).
+.PP
+.I level
+may be one of:
+.TP
+.B <0
+Negative values are for debug tracing.
+Debug messages are prefixed with
+.BI debug level.
+If
+.I "errno != error_info.last_errno"
+then
+.I error_info.last_errno
+is set to
+.I errno
+and the error text for errno is appended to the message.
+.TP
+.B "ERROR_INFO [0]"
+Information only; no prefixes are added to the message.
+.TP
+.B "ERROR_WARNING [1]"
+.L "warning:"
+is added after
+.L error_info.id
+and
+.I error_info.warnings
+is incremented.
+.TP
+.I "ERROR_ERROR [2]"
+(soft error)
+.I error_info.errors
+is incremented.
+.TP
+.B ">= ERROR_FATAL [3]"
+(hard error)
+.I error_info.errors
+is incremented and
+.L exit(\fIlevel\fP\-2)
+is called after the message is emitted.
+.TP
+.B "ERROR_PANIC [77]"
+(unrecoverable internal error)
+.L "panic:"
+is added after
+.IR error_info.id .
+.PP
+The following may be inclusive-or'd into
+.I level
+for alternate behavior:
+.TP
+.L ERROR_SYSTEM
+The error text for
+.I errno
+is appended to the message.
+.TP
+.L ERROR_OUTPUT
+The next argument is the file descriptor where the error message
+should be emitted.
+.TP
+.L ERROR_SOURCE
+Then next two arguments are a file name and line number that are added
+to the message after
+.IR error_info.id .
+.TP
+.L ERROR_USAGE
+A usage message is emitted.
+.TP
+.L ERROR_PROMPT
+The trailing
+.I newline
+is suppressed.
+.TP
+.L ERROR_NOID
+The
+.I error_info.id
+prefix is suppressed.
+.TP
+.L ERROR_LIBRARY
+The message is from a library routine.
+.SH ENVIRONMENT
+The elements of the global struct
+.I error_info
+control error output and actions.
+Parts of
+.I error_info
+can be initialized from the
+.L ERROR_OPTIONS
+environment variable.
+.L ERROR_OPTIONS
+contains space separated
+.IR name [ =value ]
+options, described below.
+.TP
+.I "int core"
+If
+.I "error_info.core != 0"
+then
+.I "level >= error_info.core"
+generates a core dump.
+Initialized by
+.EX
+ERROR_OPTIONS="core=\fIlevel\fP"
+.EE
+where
+.I level
+can be a number or one of
+.LR error ,
+.LR fatal ,
+or
+.LR panic .
+.I error_info.core
+is a handy way to get a stack trace at the exact point of error.
+.TP
+.I "int error_info.trace"
+If
+.I "error_info.trace != 0"
+and
+.I "level < error_info.trace"
+then the error message text is suppressed.
+.L exit()
+may still be called if appropriate for
+.IR level .
+Initialized by
+.EX
+ERROR_OPTIONS="trace=\fIlevel\fP"
+.EE
+where
+.I error_info.trace
+is set to the negative of
+.IR level .
+.PP
+Library error messages, suppressed by default, are enabled by
+.EX
+ERROR_OPTIONS="library"
+.EE
+The system
+.I errno
+message text can be forced for each message by
+.EX
+ERROR_OPTIONS="system"
+.EE
+.SH "EXTENDED DESCRIPTION"
+.L "<debug.h>"
+provides debugging message macros when
+.L DEBUG
+or
+.L _TRACE_
+are defined
+.RL ( _TRACE_
+is defined by
+.I makerules
+when
+.L CCFLAGS
+contains
+.LR \-g ).
+All of the macros expand to nothing when both
+.L DEBUG
+and
+.L _TRACE_
+are not defined.
+Otherwise
+.L debug
+expands its arg and
+.L libmessage
+and
+.L message
+call
+.L liberror
+and
+.L error
+respectively if
+.IR "error_info.trace<0" .
+Notice that
+.L libmessage
+and
+.L message
+are macro hacks that require double parentheses ((...)) around the
+arguments.
+.SH EXAMPLE
+To enable debugging message level -3, library messages, and system
+.I errno
+text for all commands:
+.EX
+export ERROR_OPTIONS="trace=3 library system"
+.EE
diff --git a/src/lib/libast/man/find.3 b/src/lib/libast/man/find.3
new file mode 100644
index 0000000..a14ceae
--- /dev/null
+++ b/src/lib/libast/man/find.3
@@ -0,0 +1,89 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH FIND 3
+.SH NAME
+find \- fastfind algorithm interface
+.SH SYNOPSIS
+.EX
+#include <find.h>
+
+void* findopen(const char* \fIpattern\fP);
+char* findnext(void* \fIhandle\fP);
+void findclose(void* \fIhandle\fP);
+.EE
+.SH DESCRIPTION
+These routines access the data generated by the
+.I fastfind
+algorithm.
+The data itself is generated by a standalone program that is run daily
+via
+.I cron
+or
+.IR at .
+.PP
+.L findopen
+returns a handle to a
+.I fastfind
+stream for the
+.I ksh
+file pattern
+.IR pattern .
+.L findnext
+returns the next pathname that matches the pattern specified by
+.IR handle .
+.L findnext
+returns
+.L 0
+when no more pathnames match the pattern.
+Finally,
+.L findclose
+closes the
+.I fastfind
+stream for
+.IR handle .
+.SH BUGS
+These rotuines are only as good as the
+.I fastfind
+information which is in the system administration domain.
+.SH "SEE ALSO"
+tw(1),
+find(1),
+strmatch(3)
+.br
+James A. Woods, \fIFast Find Algorithm\fP, Usenix ;login:, February/March, 1983, p. 8
diff --git a/src/lib/libast/man/fmt.3 b/src/lib/libast/man/fmt.3
new file mode 100644
index 0000000..dbe1aab
--- /dev/null
+++ b/src/lib/libast/man/fmt.3
@@ -0,0 +1,213 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH FMT 3
+.SH NAME
+fmt \- string formatting routines
+.SH SYNOPSIS
+.EX
+#include <ast.h>
+#include <ls.h>
+
+char* fmtbase(long \fInumber\fP, int \fIbase\fP, int \fIprefix\fP);
+char* fmtdev(struct stat* \fIst\fP);
+char* fmtelapsed(unsigned long \fIcount\fP, int \fIpersec\fP)
+char* fmterror(int \fIerrno\fP);
+char* fmtesc(const char* \fIstring\fP);
+char* fmtfs(struct stat* \fIst\fP);
+char* fmtgid(int \fIgid\fP);
+char* fmtmatch(const char* \fIre\fP);
+char* fmtmode(int \fImode\fP, int \fIexternal\fP);
+char* fmtperm(int \fIperm\fP);
+char* fmtre(const char* \fIpattern\fP);
+char* fmtsignal(int \fIsig\fP);
+char* fmttime(const char* \fIformat\fP, time_t \fItm\fP);
+char* fmtuid(int \fIuid\fP);
+.EE
+.SH DESCRIPTION
+These routines return a pointer to a formatted string for various numeric
+and string entities.
+Some routines may cache information to speed up the next call.
+Most of the routines return a pointer to a private buffer, the
+contents of which are overwritten on the next call to that routine.
+Most
+.L fmt
+routines have a corresponding
+.L str
+routine that converts in the other direction.
+There is nothing spectacular about this collection other than that
+it provides a single place where the exact format is spelled out.
+.PP
+.L fmtbase
+formats a base
+.I base
+representation for
+.IR number .
+If
+.I "prefix != 0"
+then the base prefix is included in the formatted string.
+If
+.I "number == 0"
+or
+.I "base == 0"
+then the output is signed base 10.
+.PP
+.L fmtdev
+returns the device handle name specified by the
+.L stat
+structure
+.IR st .
+This is the device information displayed by
+.IR "ls \-l" .
+.PP
+.L fmtelapsed
+formats the elapsed time for
+.I (count/persec)
+seconds.
+The two largest time units are used, limiting the return value length
+to at most 6 characters.
+The units are:
+.RS
+.TP
+.B s
+seconds
+.TP
+.B m
+minutes
+.TP
+.B h
+hours
+.TP
+.B days
+.TP
+.B weeks
+.TP
+.B M
+months
+.TP
+.B Y
+years
+.TP
+.B S
+scores
+.RE
+.PP
+.L fmterror
+returns the system error message text for the error number
+.IR errno .
+.PP
+.L fmtesc
+formats non-ASCII characters in
+.I string
+into C-style
+.B \e
+sequences.
+These sequences are understood by
+.L chresc
+and
+.LR chrtoi .
+.PP
+.L fmtfs
+returns the file system type name corresponding to the
+.L stat
+structure
+.IR st .
+.PP
+.L fmtgid
+returns the group name for
+.IR gid .
+.PP
+.L fmtmatch
+returns the
+.L strmatch
+equivalent pattern for the regular expression pattern
+.IR re .
+0 is returned for invalid
+.IR re .
+.PP
+.L fmtmode
+returns the
+.I "ls \-l"
+mode string for the file mode bits in
+.IR mode .
+If
+.I "external != 0"
+then
+.I mode
+is
+.IR modecanon (3)
+canonical.
+.PP
+.L fmtperm
+returns the
+.I chmod
+permission string for the permission bits in
+.IR perm .
+.PP
+.L fmtre
+returns the regular expression
+equivalent pattern for the
+.L strmatch
+pattern
+.IR pattern .
+0 is returned for invalid
+.IR pattern .
+.PP
+.L fmtsignal
+returns the signal name, sans
+.LR SIG ,
+for the signal number
+.IR sig .
+If
+.I "sig < 0"
+then the description text for
+.I \-sig
+is returned.
+.PP
+.L fmttime
+returns the results of
+.I "tmfmt(buf,sizeof(buf),format,tm)"
+in the private buffer
+.IR buf .
+.PP
+.L fmtuid
+returns the user name for
+.IR uid .
+.SH "SEE ALSO"
+modecanon(3),
+str(3)
diff --git a/src/lib/libast/man/fmtls.3 b/src/lib/libast/man/fmtls.3
new file mode 100644
index 0000000..50d872b
--- /dev/null
+++ b/src/lib/libast/man/fmtls.3
@@ -0,0 +1,143 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STRLS 3
+.SH NAME
+fmtls \- format file information in buffer
+.SH SYNOPSIS
+.EX
+#include <ls.h>
+
+char* fmtls(char* \fIbuf\fP, char* \fIname\fP, struct stat* \fIst\fP, char* \fIinfo\fP, char* \fIlink\fP, int \fIflags\fP);
+.EE
+.SH DESCRIPTION
+.L fmtls
+formats
+.IR ls (1)
+style file information into the buffer
+.IR buf .
+A pointer to the trailing 0 in
+.I buf
+is returned.
+.I name
+is the file name.
+.I st
+is a pointer to the
+.B "struct stat
+status information for
+.I name
+obtained from one of the
+.IR stat (2)
+routines.
+.I info
+is an additional string that will appear before
+.I name
+in
+.I buf
+and
+.I link
+is the name of the related hard or soft link file.
+Both
+.I info
+and
+.I link
+may be 0.
+.I flags
+controls the format style and may be a combination of the following:
+.PP
+.TP
+.B LS_ATIME
+Use
+.I st->st_atime
+rather than
+.I st->st_mtime
+for
+.BR LS_LONG .
+.TP
+.B LS_CTIME
+Use
+.I st->st_mtime
+rather than
+.I st->st_mtime
+for
+.BR LS_LONG .
+.TP
+.B LS_BLOCKS
+List the number of blocks.
+.TP
+.B LS_INUMBER
+List the file serial number (inode number).
+.TP
+.B LS_LONG
+List the file mode, link count, user and group name,
+size or major/minor device number, and date along with the
+file name.
+.TP
+.B LS_MARK
+The file name is appended with
+.L /
+for directories,
+.L @
+for symbolic links,
+and
+.L *
+for executable files.
+.TP
+.B LS_NOGROUP
+Omit the group name from
+.BR LS_LONG .
+.TP
+.B LS_NOUSER
+Omit the user name from
+.BR LS_LONG .
+.PP
+The user and group fields are each
+.B LS_W_NAME
+characters wide,
+the
+.B LS_INUMBER
+field is
+.B LS_W_INUMBER
+characters wide,
+and the
+.B LS_BLOCKS
+field is
+.B LS_W_BLOCKS
+characters wide.
+.SH "SEE ALSO"
+ls(1), stat(2), strmode(3)
diff --git a/src/lib/libast/man/fs3d.3 b/src/lib/libast/man/fs3d.3
new file mode 100644
index 0000000..7dfd448
--- /dev/null
+++ b/src/lib/libast/man/fs3d.3
@@ -0,0 +1,92 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH FS3D 3
+.SH NAME
+fs3d \- 3D (nDFS) on/off switch
+.SH SYNOPSIS
+.EX
+#include <fs3d.h>
+
+int fs3d(int \fIop\fP);
+.EE
+.SH DESCRIPTION
+.L fs3d
+controls and queries the
+.B 3D
+file system
+.RB (aka nDFS )
+enable state.
+.L 0
+is returned if the current process cannot mount
+.B 3D
+files.
+.I op
+may be one of:
+.TP
+.B FS3D_TEST
+Returns
+.L "FS3D_ON [1]"
+if
+.B 3D
+is enabled,
+.L "FS3D_OFF [0]"
+otherwise.
+.TP
+.B FS3D_ON
+Enables
+.B 3D
+and returns the previous
+.L 3D
+state (either
+.B FS3D_ON
+or
+.BR FS3D_OFF ).
+.TP
+\fBFS3D_LIMIT(\fIlimit\fB)\fR
+Sets the viewpath level limit to
+.IR limit .
+The previous limit is returned.
+.TP
+.B FS3D_INIT
+Re-initialize the
+.B 3D
+tables.
+Used for debugging.
+.SH "SEE ALSO"
+3D(1)
diff --git a/src/lib/libast/man/ftwalk.3 b/src/lib/libast/man/ftwalk.3
new file mode 100644
index 0000000..f339ab7
--- /dev/null
+++ b/src/lib/libast/man/ftwalk.3
@@ -0,0 +1,235 @@
+.fp 5 CW
+.TH FTWALK 3
+.SH NAME
+\fBftwalk\fR \- file tree walker
+.SH SYNOPSIS
+.ta .75i 1.5i 2.25i 3i 3.75i 4.5i 5.25i 6i
+.PP
+.nf
+\f5
+#include <ftwalk.h>
+
+int ftwalk(char* path, int (*userf)(struct FTW* ftw), int options,
+ int (*comparf)(struct FTW* ftw1, struct FTW* ftw2));
+
+
+int ftwflags(void);
+\fR
+.fi
+.SH DESCRIPTION
+.PP
+\fIFtwalk\fR traverses a directory hierarchy using depth-first search.
+Upon visiting each file or directory in the hierarchy, it calls
+the user function \fIuserf\fP to process that file or directory.
+On a directory object, \fIuserf\fR may be called twice, once in preorder
+and once in postorder.
+On a terminal object such as a file or an unreadable directory,
+\fIuserf\fP is called only once.
+Cycles due to hard links or symbolic links are detected
+to avoid infinite loops.
+.PP
+\fIPath\fR is the starting point of the search.
+It may be an absolute path name or a path name relative to
+the current directory.
+If \fIpath\fR is a null pointer or points to an empty string, it is treated
+as if it points to the current (dot) directory.
+.PP
+\fIOptions\fR consists of zero or more of the following bits:
+.IP
+FTW_CHILDREN:
+This implies preorder calls to \fIuserf\fR on directory objects.
+On such a call to \fIuserf\fR,
+the field \fIftw->link\fR (below) points to a link list of
+the children of the respective directory.
+Upon returning from \fIuserf\fP,
+if the field \fIftw->status\fR of any child object
+is set to FTW_SKIP (below), that child is pruned from the search.
+.IP
+FTW_DELAY: When \fBFTW_CHILDREN\fP is turned on,
+the fields \fIftw->statb\fP (\fIstruct stat\fP) of children objects
+remain undefined until these objects are visited.
+.IP
+FTW_DOT: Do not use \fIchdir\fR(2) during the traversal.
+Normally \fIchdir\fR is used so that
+the base name of the object about to be processed can be used
+in accessing its data.
+This can enhance \fIftwalk\fR efficiency but certain program effects
+such as core dumps may be generated in unexpected places
+or may not even be generated at all.
+Whenever \fIchdir\fR generates an error, if possible,
+the current directory is restored to the starting directory
+(see FTW_NAME and FTW_PATH).
+.IP
+FTW_MULTIPLE: The \fIpath\fP argument is treated as a \fIchar**\fP
+pointer to a null-terminated array of path names.
+All hierarchies rooted at these paths will be searched
+.IP
+FTW_POST: Calls to the user function are issued only in postorder.
+That is, \fIuserf\fP is called on a directory only after its descendants have
+been processed.
+The absence of this bit indicates that calls to the user functions
+are issued in preorder. That is, \fIuserf\fP is
+called on a directory before its descendants are processed.
+.IP
+FTW_PHYSICAL: Use \fIlstat\fR(2) instead of \fIstat\fR(2) to get
+file status and allow detection of symbolic links.
+In addition, if each component
+of the absolute path to the starting object has search permission,
+the absolute path is used for early detection of cycles.
+.IP
+FTW_META|FTW_PHYSICAL: Use \fIstat\fR(2) for top level file status and
+\fIlstat\fR(2) for all other files.
+Used to implement the POSIX
+.B \-H
+option for commands like
+.IR ls .
+.IP
+FTW_TWICE: Calls to the user function are issued in both preorder and postorder
+for directory objects.
+.IP
+FTW_USER: The first of 6 user defined option bits.
+These bits are ignored by \fIftwalk\fP.
+.PP
+\fIUserf\fR is a user supplied function that is
+called upon different visits of an object.
+If the return value of \fIuserf\fR is non-zero,
+\fIftwalk\fR returns immediately with the same value.
+The \fIuserf\fP prototype is:
+.PP
+.nf
+ int userf(struct FTW* ftw)
+.fi
+.PP
+\fBstruct FTW\fP contains at least the following elements:
+.PP
+.nf
+ struct FTW* link; /* link list of children */
+ struct FTW* parent; /* parent object on the search path */
+ union
+ {
+ long number; /* local number */
+ void* pointer; /* local pointer */
+ } local; /* user defined */
+ struct stat statb; /* stat buffer of this object */
+ char* path; /* full pathname */
+ short pathlen; /* strlen(path) */
+ unsigned short info; /* type of object */
+ unsigned short status; /* status of object */
+ short level; /* depth of object on the search path */
+ short namelen; /* strlen(name) */
+ char name[]; /* file name of object */
+.fi
+.PP
+The \fIlink\fR field is normally NULL.
+If the option FTW_CHILDREN was turned on,
+it points to the start of the list of children
+of the directory being visited in preorder.
+Finally, if the directory being visited causes a cycle,
+\fIlink\fR points to the object on the search path that is
+identical to this directory. Note that if FTW_PHYSICAL was turned on,
+this may point to a directory that is an ancestor of the starting
+object.
+.PP
+The \fIparent\fR field points to the parent object
+on the search path. For convenience, a parent object is also supplied for
+the starting object.
+In this case, except for the \fIlocal\fR field which is initialized
+to 0 and the \fIlevel\fR field which contains a negative number,
+the rest of the structure may be undefined.
+.PP
+The \fIinfo\fR field indicates the type of the object
+being visited and the type of the visit. The types are:
+.IP
+FTW_D: A directory being visited in preorder, i.e.,
+none of its children has been visited by the search.
+.IP
+FTW_DNX: A directory being visited in preorder that does not have
+search permission.
+.IP
+FTW_DP: A directory being visited in postorder, i.e., all of its
+descendants have been completely processed.
+.IP
+FTW_DC: A directory that causes cycles. This is a terminal object.
+.IP
+FTW_DNR: A directory that cannot be opened for reading. This is a terminal object.
+.IP
+FTW_F: An ordinary file.
+.IP
+FTW_SL: A symbolic link.
+Unless FTW_FOLLOW (below) is issued by the user function,
+this object is terminal.
+.IP
+FTW_NS: \fIStat\fR failed on this object.
+The stat buffer \fIstatb\fR is undefined.
+This object is terminal.
+.PP
+The \fIstatus\fR field of \fIstruct FTW\fR is used to communicate information
+between \fIftwalk\fR and \fIuserf\fR. On calls to \fIuserf\fR, it has one of
+two values:
+.IP
+FTW_NAME: The name of the object as defined in \fIftw->name\fR should be used for
+accessing its file information. This is because \fIchdir\fR(2) has been used
+to set the current directory to a suitable place (see FTW_CHDIR).
+.IP
+FTW_PATH: The argument \fIpath\fR of \fIuserf\fR should be used
+for accessing the file information of the object.
+.PP
+Upon returning, \fIuserf\fR may set the \fIstatus\fR field
+to one of the following values:
+.IP
+FTW_AGAIN: If this is a directory object being visited in postorder,
+it will be processed \fIagain\fR as if it had not been visited.
+.IP
+FTW_NOPOST: If this is a directory object being visited in preorder,
+the user function will not be called on its postorder visit.
+.IP
+FTW_SKIP: This object and its descendants are pruned from the search.
+.IP
+FTW_FOLLOW: If this object is a symbolic link,
+follow the link to its physical counterpart.
+.PP
+\fIComparf\fR, if not NULL, is a pointer to a function
+used to define a search ordering for children of a directory.
+If FTW_CHILDREN is turned on, the ordering of the children of
+a directory is done before the preorder call to \fIuserf\fR on that directory.
+Therefore, in that case, \fIftw->link\fR will point to the smallest child.
+.PP
+The \fIcomparf\fP prototype is:
+.PP
+.nf
+ int comparf(struct FTW* ftw1, struct FTW* ftw2)
+.fi
+.PP
+\fIComparf\fR should return a value <0, 0, or >0 to indicate whether
+\fIftw1\fR is considered smaller, equal, or larger than \fIftw2\fR.
+.PP
+\fIFtwalk\fR normally returns 0.
+On hard errors such as running out of memory, it returns -1.
+\fIFtwalk\fR may also return other values as discussed with respect
+to \fIuserf\fR.
+.PP
+\fIFtwflags\fR returns a combination of \fB0, FTW_META, FTW_PHYSICAL\fR
+according to the
+preferences specified by
+\fBastconf("PATH_RESOLVE",0,0)\fR:
+.TP
+.B logical
+0
+.TP
+.B metaphysical
+.B "FTW_META|FTW_PHYSICAL"
+.TP
+.B physical
+.B FTW_PHYSICAL
+.SH HISTORY
+\fIFtwalk\fR performs similar functions as that of
+the routine \fIftw\fR provided in System V.
+However, it is more general than \fIftw\fR
+and suitable for use as a base in implementing
+popular tools such as \fIls, find, tar, du,\fR and \fIrm\fR.
+\fIFtwalk\fR also handles symbolic links and hard links gracefully.
+.SH AUTHORS
+Phong Vo, Glenn Fowler, Dave Korn
+.SH SEE ALSO
+find(1), rm(1), du(1), ls(1), tar(1), stat(2), symlink(2),
+astfeature(3), ftw(3), pathcd(3)
diff --git a/src/lib/libast/man/getcwd.3 b/src/lib/libast/man/getcwd.3
new file mode 100644
index 0000000..3403296
--- /dev/null
+++ b/src/lib/libast/man/getcwd.3
@@ -0,0 +1,67 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH GETCWD 3
+.SH NAME
+getcwd \- return absolute path to current directory
+.SH SYNOPSIS
+.EX
+#include <ast.h>
+
+char* getcwd(char* \fIbuf\fP, size_t \fIlen\fP);
+.EE
+.SH DESCRIPTION
+.L getcwd
+copies the absolute path name of the current directory info into
+.I buf
+of length
+.IR len .
+The return path may be longer than
+.LR PATH_MAX .
+If
+.I "buff == 0"
+then space is allocated via
+.IR malloc (3)
+and
+.I len
+extra characters are reserved after the generated path name.
+A pointer to the path name is returned,
+.L 0
+on error.
+.SH "SEE ALSO"
+pathcd(3)
diff --git a/src/lib/libast/man/hash.3 b/src/lib/libast/man/hash.3
new file mode 100644
index 0000000..162d62d
--- /dev/null
+++ b/src/lib/libast/man/hash.3
@@ -0,0 +1,644 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH HASH 3
+.SH NAME
+hash \- hash table support (obsolete: use \fBcdt\fP instead)
+.SH SYNOPSIS
+.L "#include <hash.h>"
+.SH DESCRIPTION
+The
+.I hash
+routines manipulate collections of dynamic, scoped hash tables.
+.PP
+A hash table provides an association between a
+.I key
+and its
+.IR value .
+A
+.I key
+is a sequence of
+.L char
+elements and a
+.I value
+is a user supplied pointer to the value.
+Each hash table has a dynamic number of slots,
+each pointing to the head of a forward linked
+.IR "collision chain" .
+.PP
+Hashing occurs as follows:
+a
+.I "hash function"
+takes a
+.I key
+as an argument and returns a non-negative index.
+The index modulo the table size produces a
+slot that points to a
+.IR "collision chain" .
+The collision chain is sequentially searched until a match is found for
+.IR key .
+The hash tables are automatically resized as new entries are added.
+.PP
+Each hash table has one key type.
+The default key type is a pointer to a null-terminated string.
+The alternate key type is a pointer to a fixed length byte buffer,
+declared for a given table by the
+.L hashalloc()
+function described below.
+.PP
+Hash table information is partitioned into two parts for efficient scoping.
+The
+.I root
+part contains fixed information that is shared among a set of related
+hash tables.
+The remaining information is maintained on a per-table basis.
+.PP
+These basic types are defined in the header file
+.B hash.h
+(alternate names are listed in parenthesis):
+.TP
+.L "Hash_table_t (HASHTABLE)"
+The per-table information.
+The readonly public elements are:
+.RS
+.TP
+.L "int buckets"
+The number of table entries.
+.TP
+.L "char* name"
+The hash table name.
+.TP
+.L "root"
+The root information.
+The public elements are:
+.RS
+.TP
+.L "int root->accesses"
+The number of lookups.
+.TP
+.L "int root->collisions"
+The number of lookup collisions.
+.RE
+.TP
+.L "Hash_table_t* scope"
+The table that this scope covers,
+.L NULL
+if the table is not a scope.
+.TP
+.L "int size"
+The current hash table size.
+.RE
+.TP
+.L "Hash_bucket_t (HASHBUCKET)"
+A collision chain hash bucket.
+The public structure elements are:
+.RS
+.TP
+.L "char* hashname(Hash_bucket_t*)"
+Returns a pointer to the hash bucket key given the bucket pointer.
+.TP
+.L "char* value"
+The value associated with the key.
+.RE
+.TP
+.L "Hash_header_t (HASHHEADER)"
+The hash bucket header that must be the first element in all user defined
+buckets.
+.L HASH_VALUE
+may not be used with user defined buckets.
+.TP
+.L "Hash_position_t (HASHPOSITION)"
+Stores the hash table position for
+.LR hashscan .
+The public elements are:
+.RS
+.TP
+.L "Hash_bucket_t* bucket"
+The current hash bucket pointer.
+.RE
+.PP
+The routines are:
+.TP
+.L "Hash_table_t* hashalloc(Hash_table_t* ref, int op, ...)"
+Creates a new hash table and returns a pointer to the table.
+.IR malloc (3)
+is used to allocate space for the table.
+.L NULL
+is returned if the table cannot be created.
+.L ref
+is a pointer to a reference hash table that provides
+default values for unspecified information.
+The new hash table and
+.L ref
+share the same root information.
+If
+.L ref
+is
+.L NULL
+then new root information is created for the new table.
+The remaining arguments appear in
+.I op-arg
+pairs, followed by a final
+.L 0
+argument.
+The
+.I op-arg
+pairs are:
+.RS
+.TP
+.L "HASH_alloc, (char(*)()) alloc"
+.L alloc
+is a function that is called to process
+.L Hash_bucket_t
+.L value
+assignments.
+The single argument is
+.L "char* value"
+and the processed
+.L char*
+value is returned.
+.TP
+.L "HASH_clear, int flags"
+.L flags
+are the
+.L ref
+flags to be cleared in the new hash table.
+See
+.L HASH_set
+below.
+.TP
+.L "HASH_compare, (int(*)()) compare"
+Specifies an alternate
+.I key
+comparison function.
+The arguments and return value for
+.L compare
+are the same as for
+.IR strncmp (3)
+if
+.L HASH_namesize
+is specified and
+.IR strcmp (3)
+otherwise.
+The first argument is the
+.I key
+from the current hash bucket on the
+.I "collision chain"
+and the second argument is the user supplied
+.IR key .
+.TP
+.L "HASH_free, (int(*)()) free"
+.L free
+is a function that is called when a hash bucket is freed.
+If
+.L HASH_BUCKET
+was set in
+.L hashalloc
+then the hash bucket pointer is passed, otherwise the bucket
+.L value
+pointer is passed.
+.TP
+.L "HASH_hash, (int(*)()) hash"
+Specifies an alternate
+.I key
+hash function.
+A
+.L char*
+key argument (and, if
+.L HASH_namesize
+is specified, an
+.L int
+key size argument) is passed to
+.LR hash .
+The return value must be a non-negative
+.LR int .
+.TP
+.L "HASH_meanchain, int meanchain"
+Specifies the mean collision chain length.
+The hash table is automatically resized when this value is exceeded.
+The default mean chain length is 2.
+.TP
+.L "HASH_name, char* name"
+Associates
+.L name
+with the hash table.
+Used by
+.LR hashdump) .
+.TP
+.L "HASH_namesize, int namesize"
+The fixed size in bytes for
+.I keys
+in the table.
+If
+.L namesize
+is 0 (the default) then the
+.I keys
+are interpreted as null-terminated strings.
+.TP
+.L "HASH_set, int flags"
+Changes the hash table flags by
+.IR or ing
+in
+.LR flags .
+The flags, which may be
+.IR or ed
+together, are:
+.RS
+.TP
+.L HASH_ALLOCATE
+Keys for new hash table entries are to be copied to data areas obtained from
+.IR malloc (3).
+.TP
+.L HASH_FIXED
+Fixes the hash table size, disabling any automatic table resizing.
+.TP
+.L HASH_SCOPE
+The new hash table is a scope that is to be pushed on top of
+.LR ref .
+.L ref
+must be
+.RL non- NULL .
+.RE
+.TP
+.L "HASH_va_list, va_list ap"
+.L ap
+is a
+.L va_list
+variable argument list pointer
+(see
+.LR <stdarg.h> ).
+.RE
+.TP
+.L "Hash_table_t* hashfree(Hash_table_t* tab)"
+The hash table
+.L tab
+is freed.
+The scope covered table pointer is returned,
+.L NULL
+if
+.L tab
+is not a scope.
+.TP
+.L "char* hashlook(Hash_table_t* tab, char* name, int flags, char* value)"
+Operates on the key
+.L name
+in the hash table
+.L tab
+according to
+.L flags
+and
+.LR value .
+A
+.L Hash_bucket_t
+pointer is returned unless otherwise noted.
+There are three basic lookup operations:
+.RS
+.TP
+.L HASH_CREATE
+.L name
+is entered into the top level scope if it does not already exist.
+If
+.L name
+also appears in a lower scope and
+.L HASH_ALLOC
+is set for the table then the new bucket will share the
+.L name
+field value with the lower scope.
+.TP
+.L HASH_DELETE
+.L name
+is deleted from the top level scope if it exists.
+.L NULL
+is returned.
+.TP
+.L HASH_LOOKUP
+The scopes are searched in order from top to bottom for
+.L name .
+The bucket pointer for the first occurrence is returned.
+.L NULL
+is returned if
+.L name
+is not found.
+.RE
+The basic operations may be qualified by the following
+(the qualifiers are restricted to the basic operations in
+the parenthesized list):
+.RS
+.TP
+.L "HASH_BUCKET (HASH_CREATE,HASH_DELETE,HASH_LOOKUP)"
+.L name
+is a pointer to a bucket that has already been entered into the table.
+.TP
+.L "HASH_FIXED (HASH_CREATE)"
+.L value
+is taken to be the size of the hash bucket to be created for
+.L name
+in the top level scope.
+The minimum bucket size is silently restricted to
+.LR sizeof(Hash_header_t) .
+.TP
+.L "HASH_INSTALL (HASH_CREATE)"
+.L name
+is a pointer to a bucket that has not been entered into the table.
+.TP
+.L "HASH_NOSCOPE (HASH_LOOKUP)"
+The lookup is restricted to the top level scope.
+.TP
+.L "HASH_OPAQUE (HASH_CREATE,HASH_DELETE)"
+Sets
+.L (HASH_CREATE)
+or clears
+.L (HASH_DELETE)
+the
+.I opaque
+property for the bucket.
+An opaque bucket is not visible in lower scopes.
+.TP
+.L "HASH_SCOPE (HASH_CREATE,HASH_DELETE)"
+All scopes are searched for the bucket.
+If the bucket is not found for
+.L HASH_CREATE
+then a new bucket is created in the lowest scope.
+.TP
+.L "HASH_VALUE (HASH_CREATE,HASH_LOOKUP)"
+For
+.L HASH_CREATE
+the bucket
+.L value
+field is set to
+.L value
+and the bucket
+.L name
+value is returned.
+For
+.L HASH_LOOKUP
+the bucket
+.L value
+field is returned,
+.L NULL
+if the bucket is not found.
+.RE
+If
+.L name
+.L NULL
+then the name from the most recent
+.L hashlook()
+is used, avoiding recomputation of some internal parameters.
+.TP
+.L "char* hashget(Hash_table_t* tab, char* name)"
+Returns the value
+associated with the key
+.L name
+in the hash table
+.LR tab .
+If
+.L name
+is
+.L NULL
+then the name from the most recent
+.L hashget()
+is used, avoiding recomputation of some internal parameters.
+.L NULL
+is returned if
+.L name
+is not in the table.
+All scope covered tables are searched.
+.TP
+.L "Hash_bucket_t* hashlast(Hash_table_t* tab)"
+Returns a pointer to the most recent hash bucket for
+.LR tab .
+The value is set by
+.LR hashlook() ,
+.L hashscan()
+and
+.LR hashwalk() .
+.TP
+.L "char* hashput(Hash_table_t* tab, char* name, char* value)"
+Set the value of the key
+.L name
+to
+.L value
+in the top level scope of the hash table
+.LR tab .
+.L name
+is entered into the top level scope if necessary.
+The (possibly re-allocated) key name pointer is returned
+(see
+.LR HASH_ALLOCATE ).
+If
+.L name
+is 0 then the most recent lookup
+.L name
+to
+.L hashlook()
+or
+.L hashget()
+is used.
+This eliminates a re-hash and re-lookup of
+.LR name .
+.TP
+.L "int hashwalk(Hash_table_t* tab, int flags, (int(*)()) walker, char* handle)"
+The function
+.L walker
+is applied to each entry (not covered by a scope starting at
+.LR tab )
+in the hash table
+.LR tab .
+If
+.L flags
+is
+.L HASH_NOSCOPE
+then only the top level hash table is used, otherwise the walk includes
+all scope covered tables.
+.L walker
+is called with
+.L char*
+.I key
+as the first argument,
+.L char*
+.I value
+as the second argument, and
+.L char*
+.I handle
+as the third argument.
+.I handle
+may be
+.LR 0 .
+The walk terminates after the last entry or when
+.L walker
+returns a negative value.
+The return value of the last call to
+.L walker
+is returned.
+Only one walk may be active within a collection of scoped tables.
+.TP
+.L "Hash_position_t* hashscan(Hash_table_t* tab, int flags)"
+Returns a
+.L Hash_position_t
+pointer for a sequential scan on the hash table
+.LR tab .
+If
+.L flags
+is
+.L HASH_NOSCOPE
+then only the top level hash table is used, otherwise the scan includes
+all scope covered tables.
+Only one scan may be active within a collection of scoped tables.
+.L hashdone()
+must be called to terminate the scan.
+.L 0
+is returned on error.
+.TP
+.L "Hash_bucket_t* hashnext(Hash_position_t* pos)"
+Returnes a pointer to the next bucket in the sequential scan set up by
+.L hashscan()
+on
+.LR pos .
+If no elements remain then
+.L 0
+is returned.
+.TP
+.L "void hashdone(Hash_position_t* pos)"
+Completes a scan initiated by
+.L hashscan()
+on
+.LR pos .
+.TP
+.L "int hashset(Hash_table_t* tab, int flags)"
+Sets the flags for the hash table
+.L tab
+by
+.IR or ing
+in
+.LR flags .
+Only
+.L HASH_ALLOCATE
+and
+.L HASH_FIXED
+may be set.
+.TP
+.L "int hashclear(Hash_table_t* tab, int flags)"
+Clears the flags for the hash table
+.L tab
+by masking out
+.LR flags .
+Only
+.L HASH_ALLOCATE
+and
+.L HASH_FIXED
+may be cleared.
+.TP
+.L "void hashdump(Hash_table_t* tab, int flags)"
+Dumps hash table accounting info to standard error.
+If
+.L tab
+is
+.L NULL
+then all allocated hash tables are dumped, otherwise only information on
+.L tab
+is dumped.
+If
+.L flags
+is
+.L HASH_BUCKET
+then the hash bucket
+.I key-value
+pairs for each collision chain are also dumped.
+.TP
+.L "void hashsize(Hash_table_t* tab, int size)"
+Changes the size of the hash table
+.L tab
+to
+.L size
+where
+.L size
+must be a power of 2.
+Explicit calls to this routine are not necessary as hash tables
+are automatically resized.
+.TP
+.L "int strhash(char* name)"
+Hashes the null terminated character string
+.L name
+using a linear congruent pseudo-random number generator algorithm
+and returns a non-negative
+.L int
+hash value.
+.TP
+.L "int memhash(char* buf, int siz)"
+Hashes the buffer
+.L buf
+of
+.L siz
+bytes using a linear congruent pseudo-random number generator algorithm
+and returns a non-negative
+.L int
+hash value.
+.TP
+.L "long strsum(char* name, long sum)"
+Returns a running 31-bit checksum of the string
+.L name
+where
+.L sum
+is
+.L 0
+on the first call and
+the return value from a previous
+.L memsum
+or
+.L strsum
+call otherwise.
+The checksum value is consistent across all implementations.
+.TP
+.L "long memsum(char* buf, int siz, long sum)"
+Returns a running 31-bit checksum of buffer
+.L buf
+of
+.L siz
+bytes where
+.L sum
+is
+.L 0
+on the first call and
+the return value from a previous
+.L memsum
+or
+.L strsum
+call otherwise.
+The checksum value is consistent across all implementations.
+.SH "SEE ALSO"
+sum(1)
diff --git a/src/lib/libast/man/iblocks.3 b/src/lib/libast/man/iblocks.3
new file mode 100644
index 0000000..0c615f8
--- /dev/null
+++ b/src/lib/libast/man/iblocks.3
@@ -0,0 +1,62 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH IBLOCKS 3
+.SH NAME
+iblocks \- compute number file blocks used
+.SH SYNOPSIS
+.EX
+#include <ls.h>
+
+long _iblocks(struct stat* \fIst\fP);
+.EE
+.SH DESCRIPTION
+.L _iblocks
+returns the number of blocks used by the file whose
+.IR stat (2)
+information is pointed to by
+.IR st .
+The count includes both data and indirect blocks.
+.PP
+This routine is used by
+.B <ls.h>
+on system without the
+.LI "struct stat" st_blocks
+field.
+.SH "SEE ALSO"
+ls(1), stat(2)
diff --git a/src/lib/libast/man/int.3 b/src/lib/libast/man/int.3
new file mode 100644
index 0000000..8d457c0
--- /dev/null
+++ b/src/lib/libast/man/int.3
@@ -0,0 +1,68 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH INT 3
+.SH NAME
+int \- integral type macros
+.SH SYNOPSIS
+.EX
+#include <int.h>
+.EE
+.SH DESCRIPTION
+This header defines macros for the local integral types.
+.LR int_1 ,
+.LR int_2
+and
+.L int_4
+are always defined to integral types with a size of
+1, 2 and 4 bytes respectively.
+The macros
+.LI int_ n
+where
+.I n
+is a power of 2 greater than 4 are defined if the type is supported.
+.L int_max
+is defined to be the largest support integral type.
+.L int_swap
+is the
+.IR swap (3)
+operation that converts a local
+.L int
+to canonical big-endian representation.
+.SH "SEE ALSO"
+swap(3)
diff --git a/src/lib/libast/man/ip6.3 b/src/lib/libast/man/ip6.3
new file mode 100644
index 0000000..1dadb05
--- /dev/null
+++ b/src/lib/libast/man/ip6.3
@@ -0,0 +1,85 @@
+.fp 5 B
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH IP6 3
+.SH NAME
+ip6 \- IP V6 address support
+.SH SYNOPSIS
+.EX
+#include <ip6.h>
+
+char* fmtip6(unsigned char* addr, int bits);
+int strtoip6(const char* str, char** end, unsigned char* addr, unsigned char* bits);
+.EE
+
+.SH DESCRIPTION
+.L fmtip6()
+formats the IPV6 address
+.L addr
+with optional prefix bits
+.L bits
+(0 if not a prefix) into a thread-specific 0-terminated temporary buffer and returns a pointer
+to the formatted value.
+
+.PP
+.L strtoip6()
+converts a formatted IPV6 address from the 0-terminated string
+.L str
+into a host order IPV6 address in
+.L addr
+which must be a buffer of at least
+.L IP6ADDR
+bytes.
+If
+.L bits
+is not 0 then an optional
+.BI / bits
+(prefix size in bits) is parsed and
+.L *bits
+is set to the number of prefix bits.
+If
+.L end
+is not 0 then
+.L *end
+will point to the first unparsed character in
+.L str
+on return.
+0 is returned on success, -1 on failure.
+
+.SH "SEE ALSO"
+dss(1)
diff --git a/src/lib/libast/man/magic.3 b/src/lib/libast/man/magic.3
new file mode 100644
index 0000000..e8bf0e3
--- /dev/null
+++ b/src/lib/libast/man/magic.3
@@ -0,0 +1,493 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH MAGIC 3
+.SH NAME
+magic \- magic file interface
+.SH SYNOPSIS
+.EX
+#include <magic.h>
+
+Magic_t
+{
+ unsigned long flags;
+};
+
+Magic_t* magicopen(unsigned long \fIflags\fP);
+void magicclose(Magic_t* \fImagic\fP);
+
+int magicload(Magic_t* \fImagic\fP, const char* \fIpath\fP, unsigned long \fIflags\fP);
+int magiclist(Magic_t* \fImagic\fP, Sfio_t* \fIsp\fP);
+
+char* magictype(Magic_t* \fImagic\fP, const char* \fIpath\fP, struct stat* \fIst\fP);
+.EE
+.SH DESCRIPTION
+These routines provide an interface to the
+.IR file (1)
+command magic file.
+.L magicopen
+returns a magic session handle that is passed to all of the other routines.
+.I flags
+may be
+.TP
+.L MAGIC_MIME
+Return the MIME type string rather than the magic file description.
+.TP
+.L MAGIC_PHYSICAL
+Don't follow symbolic links.
+.TP
+.L MAGIC_STAT
+The stat structure
+.I st
+passed to
+.I magictype
+will contain valid
+.I stat (2)
+information.
+See
+.L magictype
+below.
+.TP
+.L MAGIC_VERBOSE
+Enable verbose error messages.
+.PP
+.L magicclose
+closes the magic session.
+.PP
+.L magicload
+loads the magic file named by
+.I path
+into the magic session.
+.I flags
+are the same as with
+.LR magicopen .
+More than one magic file can be loaded into a session;
+the files are searched in load order.
+If
+.I path
+is
+.L 0
+then the default magic file is loaded.
+.PP
+.L magiclist
+lists the magic file contents on the
+.IR sfio (3)
+stream
+.IR sp .
+This is used for debugging magic entries.
+.PP
+.L magictype
+returns the type string for
+.I path
+with optional
+.IR stat (2)
+information
+.IR st .
+If
+.I "st == 0"
+then
+.L magictype
+calls
+.L stat
+on a private stat buffer,
+else if
+.L magicopen
+was called with the
+.L MAGIC_STAT
+flag then
+.I st
+is assumed to contain valid stat information, otherwise
+.L magictype
+calls
+.L stat
+on
+.IR st .
+.L magictype
+always returns a non-null string.
+If errors are encounterd on
+.I path
+then the return value will contain information on those errors, e.g.,
+.LR "cannot stat" .
+.SH FORMAT
+The magic file format is a backwards compatible extension of an
+ancient System V file implementation.
+However, with the extended format it is possible to write a single
+magic file that works on all platforms.
+Most of the net magic files floating around work with
+.LR magic ,
+but they usually double up on
+.I le
+and
+.I be
+entries that are automatically handled by
+.LR magic .
+.PP
+A magic file entry describes a procedure for determining a single file type
+based on the file pathname,
+.I stat (2)
+information, and the file data.
+An entry is a sequence of lines, each line being a record of
+.I space
+separated fields.
+The general record format is:
+.EX
+[op]offset type [mask]expression description [mimetype]
+.EE
+.L #
+in the first column introduces a comment.
+The first record in an entry contains no
+.LR op ;
+the remaining records for an entry contain an
+.LR op .
+Integer constants are as in C:
+.L 0x*
+or
+.L 0X*
+for hexadecimal,
+.L 0*
+for octal and decimal otherwise.
+.PP
+The
+.L op
+field may be one of:
+.TP
+.L +
+The previous records must match but the current record is optional.
+.L >
+is an old-style synonym for
+.LR + .
+.TP
+.L &
+The previous and current records must match.
+.TP
+.L {
+Starts a nesting block that is terminated by
+.LR } .
+A nesting block pushes a new context for the
+.L +
+and
+.L &
+ops.
+The
+.L {
+and
+.L }
+records have no other fields.
+.TP
+\fIid\f5{\fR
+A function declaration and call for the single character identifier
+.IR id .
+The function return is a nesting block end record
+.LR } .
+Function may be redefined.
+Functions have no arguments or return value.
+.TP
+\fIid\f5()\fR
+A call to the function
+.IR id .
+.PP
+The
+.L offset
+field is either the offset into the data upon which the current entry operates
+or a file metadata identifier.
+Offsets are either integer constants or offset expressions.
+An offset expression is contained in (...) and is a combination of
+integral arithmetic operators and the
+.L @
+indirection operator.
+Indirections take the form
+.LI @ integer
+where integer is the data offset for the indirection value.
+The size of the indirection value is taken either from one of the suffixes
+.LR B (byte, 1 char),
+.LR H (short, 2 chars),
+.LR L (long, 4 chars),
+pr
+.LR Q (quead, 8 chars),
+or from the
+.L type
+field.
+Valid file metadata identifiers are:
+.TP
+.L atime
+The string representation of
+.LR stat.st_atime .
+.TP
+.L blocks
+.LR stat.st_blocks .
+.TP
+.L ctime
+The string representation of
+.LR stat.st_ctime .
+.TP
+.L fstype
+The string representation of
+.LR stat.st_fstype .
+.TP
+.L gid
+The string representation of
+.LR stat.st_gid .
+.TP
+The
+.L stat.st_mode
+file mode bits in
+.IR modecanon (3)
+canonical representation (i.e., the good old octal values).
+.TP
+.L mtime
+The string representation of
+.LR stat.st_mtime .
+.TP
+.L nlink
+.LR stat.st_nlink .
+.TP
+.L size
+.LR stat.st_size .
+.TP
+.L name
+The file path name sans directory.
+.TP
+.L uid
+The string representation of
+.LR stat.st_uid .
+.PP
+The
+.L type
+field specifies the type of the data at
+.LR offset .
+Integral types may be prefixed by
+.L le
+or
+.L be
+for specifying exact little-endian or big-endian representation,
+but the internal algorithm automatically loops through the
+standard representations to find integral matches,
+so representation prefixes are rarely used.
+However, this looping may cause some magic entry conflicts; use the
+.L le
+or
+.L be
+prefix in these cases.
+Only one representation is used for all the records in an entry.
+Valid types are:
+.TP
+.L byte
+A 1 byte integer.
+.TP
+.L short
+A 2 byte integer.
+.TP
+.L long
+A 4 byte integer.
+.TP
+.L quad
+An 8 byte integer.
+Tests on this type may fail is the local compiler does not support
+an 8 byte integral type and the corresponding value overflows 4 bytes.
+.TP
+.L date
+The data at
+.L offset
+is interpreted as a 4 byte seconds-since-the-epoch date and
+converted to a string.
+.TP
+.L edit
+The
+.L expression
+field is an
+.IR ed (1)
+style substitution expression
+\fIdel old del new del \fP [ \fI flags \fP ]
+where the substituted value is made available to the
+.L description
+field
+.L %s
+format.
+In addition to the
+.I flags
+supported by
+.IR ed (3)
+are
+.L l
+that converts the substituted value to lower case and
+.L u
+that converts the substituted value to upper case.
+If
+.I old
+does not match the string data at
+.L offset
+then the entry record fails.
+.TP
+.L match
+.L expression
+field is a
+.IR strmatch (3)
+pattern that is matched against the string data at
+.LR offset .
+.TP
+.L string
+The
+.L expression
+field is a string that is compared with the string data at
+.LR offset .
+.PP
+The optional
+.L mask
+field takes the form
+.LI & number
+where
+.I number
+is
+.I anded
+with the integral value at
+.L offset
+before the
+.L expression
+is applied.
+.PP
+The contents of the expression field depends on the
+.LR type .
+String type expression are described in the
+.L type
+field entries above.
+.L *
+means any value and applies to all types.
+Integral
+.L type
+expression take the form [\fIoperator\fP] \fIoperand\P where
+.I operand
+is compared with the data value at
+.L offset
+using
+.IR operator .
+.I operator
+may be one of
+.LR < .
+.LR <= ,
+.LR == ,
+.LR >=
+or
+.LR > .
+.I operator
+defaults to
+.L ==
+if omitted.
+.I operand
+may be an integral constant or one of the following builtin function calls:
+.TP
+.L magic()
+A recursive call to the magic algorithm starting with the data at
+.LR offset .
+.TP
+\f5loop(\fIfunction\fP,\fIoffset\fP,\fIincrement\fP)\fR
+Call
+.I function
+starting at
+.I offset
+and increment
+.I offset
+by
+.I increment
+after each iteration.
+Iteration continues until the description text does not change.
+.PP
+The
+.L description
+field is the most important because it is this field that is presented
+to the outside world.
+When constructing description
+fields one must be very careful to follow the style layed out in the
+magic file, lest yet another layer of inconsistency creep into the system.
+The description for each matching record in an entry are concatenated
+to form the complete magic type.
+If the previous matching description in the current entry does not end with
+.I space
+and the current description is not empty and does not start with
+.I comma ,
+.I dot
+or
+.I backspace
+then a
+.I space
+is placed between the descriptions
+(most optional descriptions start with
+.IR comma .)
+The data value at
+.L offset
+can be referenced in the description using
+.L %s
+for the string types and
+.L %ld
+or
+.L %lu
+for the integral types.
+.PP
+The
+.L mimetype
+field specifies the MIME type, usually in the form
+.IR a / b .
+.SH FILES
+.L ../lib/file/magic
+located on
+.L $PATH
+.SH EXAMPLES
+.EX
+0 long 0x020c0108 hp s200 executable, pure
+o{
++36 long >0 , not stripped
++4 short >0 , version %ld
+}
+
+0 long 0x020c0107 hp s200 executable
+o()
+
+0 long 0x020c010b hp s200 executable, demand-load
+o()
+.EE
+The function
+.LR o() ,
+shared by 3 entries,
+determines if the executable is stripped and also extracts the version number.
+.EX
+0 long 0407 bsd 386 executable
+&mode long &0111!=0
++16 long >0 , not stripped
+.EE
+This entry requires that the file also has execute permission.
+.SH "SEE ALSO"
+file(1), mime(4), tw(1), modecanon(3)
diff --git a/src/lib/libast/man/mem.3 b/src/lib/libast/man/mem.3
new file mode 100644
index 0000000..70da0db
--- /dev/null
+++ b/src/lib/libast/man/mem.3
@@ -0,0 +1,98 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH MEM 3
+.SH NAME
+mem \- fixed string routines
+.SH SYNOPSIS
+.EX
+#include <ast.h>
+
+void mematoe(void* \fIout\fP, const void* \fIin\fP, size_t \fIn\fP);
+void* memdup(const void* \fIbuf\fP, size_t \fIn\fP)
+void memetoa(void* \fIout\fP, const void* \fIin\fP, size_t \fIn\fP);
+void* memzero(void* \fIbuf\fP, size_t \fIn\fP);
+.EE
+.SH DESCRIPTION
+.L mematoe
+converts
+.I n
+ASCII characters in
+.I in
+to EBCDIC characters in
+.IR out .
+.I in
+and
+.I out
+may be the same.
+.PP
+.L memdup
+copies the
+.I n
+byte buffer
+.I buf
+to a new location provided by
+.IR malloc (3)
+and returns a pointer to the new copy.
+0 is returned if
+.IR malloc (3)
+fails.
+.PP
+.L memetoa
+converts
+.I n
+EBCDIC characters in
+.I in
+to ASCII characters in
+.IR out .
+.I in
+and
+.I out
+may be the same.
+.PP
+.L memzero
+sets the first
+.I n
+bytes in
+.I buf
+to
+.IR 0 .
+.SH "SEE ALSO"
+Proposed Bell Laboratories ASCII/EBCDIC standard, April 16, 1979.
+.br
+str(3), vmalloc(3)
diff --git a/src/lib/libast/man/mime.3 b/src/lib/libast/man/mime.3
new file mode 100644
index 0000000..f540b2e
--- /dev/null
+++ b/src/lib/libast/man/mime.3
@@ -0,0 +1,117 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH MIME 3
+.SH NAME
+mime \- mime/mailcap interface
+.SH SYNOPSIS
+.EX
+#include <mime.h>
+
+Mime_t
+{
+ unsigned long flags;
+};
+
+Mime_t* mimeopen(unsigned long \fIflags\fP);
+void mimeclose(Mime_t* \fImime\fP);
+
+int mimeload(Mime_t* \fImime\fP, const char* \fIpath\fP, unsigned long \fIflags\fP);
+int mimelist(Mime_t* \fImime\fP, Sfio_t* \fIsp\fP, const char* \fIpattern\fP);
+
+char* mimeview(Mime_t* \fImime\fP, const char* \fIview\fP, const char* \fIname\fP, const char* \fItype\fP, const char* \fIopts\fP);
+int mimeset(Mime_t* \fImime\fP, char* \fIline\fP, unsigned long \fIflags\fP);
+.EE
+.SH DESCRIPTION
+These routines provide an interface to the MIME type database.
+.L mimeopen
+returns a mime session handle that is passed to all of the other routines.
+The
+.I flags
+argument is currently unused.
+.PP
+.L mimeclose
+closes the mime session.
+.PP
+.L mimeload
+loads the mime file named by
+.I path
+into the mime session.
+.I flags
+may be one of:
+.TP
+.L MIME_LIST
+The
+.I path
+argument is a
+.B :
+separated list of pathnames, each of which is loaded.
+Non-existent files are ignored
+.L MIME_LIST
+set.
+.TP
+.L MIME_REPLACE
+Replace existing entries by new entries with the same type.
+Otherwise original entries take precedence.
+.PP
+More than one mime file can be loaded into a session;
+the files are searched in load order.
+If
+.I path
+is
+.L 0
+then the default mime file is loaded.
+.PP
+.L mimelist
+lists the mime file contents on the
+.IR sfio (3)
+stream
+.IR sp .
+This is used for debugging mime entries.
+.PP
+.L mimetype
+returns the type string for
+.IR path .
+.L mimetype
+always returns a non-null string.
+If errors are encounterd on
+.I path
+then the return value will be
+.LR "error" .
+.SH "SEE ALSO"
+file(1), mime(4)
diff --git a/src/lib/libast/man/modecanon.3 b/src/lib/libast/man/modecanon.3
new file mode 100644
index 0000000..4a5d128
--- /dev/null
+++ b/src/lib/libast/man/modecanon.3
@@ -0,0 +1,104 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH MODECANON 3
+.SH NAME
+modecanon \- canonical file mode representation
+.SH SYNOPSIS
+#include <modex.h>
+
+int modei(int \fIexternal\fP);
+int modex(int \fIinternal\fP);
+.EE
+.SH DESCRIPTION
+POSIX threw out the file type bit macros and replaced them with
+function-like macros that test file type.
+This is bad in many ways, the worst of which is that it provides
+no way for a user program to synthesize file types in the mode bits.
+.IR pax (1),
+.IR tar (1)
+and
+.IR cpio (1)
+are examples of user programs that must convert between the internal mode
+representation and a private external representation.
+These routines provide a canonical external representation
+with macros to access and synthesize the bits in the external
+representation.
+.PP
+.L modei
+takes an external mode representation
+.I external
+and returns the equivalent internal representation.
+.PP
+.L modex
+takes an internal mode representation
+.I internal
+and returns the equivalent external representation.
+.PP
+The traditional bit access macro (\f5S_\fP prefix changes to \f5X_\fP) are:
+.L X_IFMT ,
+.L X_IFSOCK ,
+.L X_IFLNK ,
+.L X_IFCTG ,
+.L X_IFREG ,
+.L X_IFBLK ,
+.L X_IFDIR ,
+.L X_IFCHR ,
+.L X_IFIFO ,
+.L X_IPERM ,
+.L X_ISUID ,
+.L X_ISGID ,
+.L X_ISVTX ,
+.L X_IRUSR ,
+.L X_IWUSR ,
+.L X_IXUSR ,
+.L X_IRGRP ,
+.L X_IWGRP ,
+.L X_IXGRP ,
+.L X_IROTH ,
+.L X_IWOTH ,
+.L X_IXOTH ,
+.L X_IRWXU ,
+.L X_IRWXG
+and
+.L X_IRWXO .
+.LI X_ITYPE( mode )
+returns the type bits for
+.IR mode .
+.SH "SEE ALSO"
+pax(1), stat(2)
diff --git a/src/lib/libast/man/optget.3 b/src/lib/libast/man/optget.3
new file mode 100644
index 0000000..90afcb8
--- /dev/null
+++ b/src/lib/libast/man/optget.3
@@ -0,0 +1,68 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH OPTGET 3
+.SH NAME
+optget \- option parse assist
+.SH SYNOPSIS
+.EX
+#include <option.h>
+
+Opt_t
+{
+};
+
+Optdisc_t
+{
+ unsigned long version;
+ unsigned long flags;
+ char* catalog;
+ Optinfo_f infof;
+};
+
+Opt_t opt_info;
+
+void optinit(Optdisc_t* \fIdisc\fP, Error_f \fIerrorf\fP);
+int optget(char** \fIargv\fP, const char* \fIusage\fP);
+int optstr(const char* \fIstring\fP, const char* \fIusage\fP);
+int optjoin(char** \fIargv\fP, ... [int (*\fIoptfun\fP)(char** \fIargv\fP, int \fIlast\fP)]);
+char* optusage(const char* \fIopts\fP);
+int optesc(Sfio_t* \fIsp\fP, const char* \fIstring\fP, int \fIflags\fP);
+.EE
+.SH DESCRIPTION
+.SH "SEE ALSO"
diff --git a/src/lib/libast/man/path.3 b/src/lib/libast/man/path.3
new file mode 100644
index 0000000..8721888
--- /dev/null
+++ b/src/lib/libast/man/path.3
@@ -0,0 +1,391 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH PATH 3
+.SH NAME
+path \- file path routines
+.SH SYNOPSIS
+.EX
+#include <ast.h>
+
+char* pathaccess(char* \fIpath\fP, const char* \fIdirs\fP, const char* \fIa\fP, const char* \fIb\fP, int \fImode\fP);
+char* pathbin(void);
+char* pathcanon(char* \fIpath\fP, int \fIflags\fP);
+char* pathcat(char* \fIpath\fP, const char* \fIdirs\fP, int \fIsep\fP, const char* \fIa\fP, const char* \fIb\fP);
+char* pathcd(char* \fIpath\fP, const char* \fIhome\fP);
+int pathcheck(const char* \fIpackage\fP, const char* \fItool\fP, Pathcheck_t* \fIpc\fP);
+int pathgetlink(const char* \fIname\fP, char* \fIbuf\fP, int \fIsiz\fP);
+char* pathkey(char* \fIkey\fP, char* \fIattr\fP, const char* \fIlang\fP, const char* \fIpath\fP);
+char* pathnext(char* \fIpath\fP, char* \fIextra\fP, long* \fIvisits\fP);
+char* pathpath(char* \fIpath\fP, const char* \fIp\fP, const char* \fIa\fP, int \fImode\fP);
+char* pathprobe(char* \fIpath\fP, char* \fIattr\fP, const char* \fIlang\fP, const char* \fItool\fP, const char* \fIproc\fP, int \fIop\fP);
+char* pathrepl(char* \fIpath\fP, const char* \fImatch\fP, const char* \fIreplace\fP);
+int pathsetlink(const char* \fItext\fP, char* \fIname\fP);
+char* pathshell(void);
+int pathstat(const char* \fIpath\fP, struct stat* \fIst\fP);
+char* pathtemp(char* \fIpath\fP, const char* \fIdir\fP, const char* \fIpfx\fP);
+.EE
+.SH DESCRIPTION
+These routines operate on file path names.
+Path buffers are assumed to be of size
+.LR PATH_MAX .
+.L <ast.h>
+always defines
+.LR PATH_MAX ,
+even if it indeterminant on the local system.
+Yes, this was probably a bad choice, but it was made about 10 years ago.
+We will probably move to a <stk.h> based implementation.
+.PP
+.L pathaccess
+constructs a path in
+.L path
+to the file
+.L a/b
+with access
+.L mode
+using the
+.L :
+separated directories in
+.IR dirs .
+Both
+.I a
+and
+.I b
+may be
+.LR 0 .
+.L mode
+is the inclusive-or of:
+.TP
+.L F_OK
+File exists.
+.TP
+.L R_OK
+Read permission on file.
+.TP
+.L W_OK
+Write permission on file.
+.TP
+.L X_OK
+Execute permission on file.
+.TP
+.L PATH_REGULAR
+A regular file.
+.TP
+.L PATH_ABSOLUTE
+Generated path name is rooted at
+.LR / .
+.I path
+is returned, 0 on error.
+.PP
+.L pathbin
+returns a pointer to the
+.L :
+separated list of directories to search for executable commands.
+The
+.L PATH
+environment variable is first consulted.
+If not defined then
+.L confstr(_CS_PATH,...)
+is used.
+A valid string is always returned.
+.PP
+.L pathcanon
+canonicalizes the path
+.I path
+in place.
+A pointer to the trailing 0 in the canonicalized path is returned.
+A canonical path has:
+redundant
+.L .
+and
+.L /
+removed;
+.L ..
+moved to the front;
+.L /..
+preserved for super root hacks;
+.L ...
+resolved if
+.IR fs3d (3)
+is enabled.
+.I flags is the inclusive-or of:
+.TP
+.L PATH_DOTDOT
+Each
+.L ..
+is checked for access.
+.TP
+.L PATH_EXISTS
+Path must exist at each component.
+.TP
+.L PATH_PHYSICAL
+Symbolic links are resolved at each component.
+.PP
+0 is returned on error.
+If an error occurs and either of
+.L PATH_DOTDOT
+or
+.L PATH_EXISTS
+is set then
+.I path
+will contain the components following the failure point.
+.PP
+.L pathcat
+concatenates the first
+.I sep
+separated path component in
+.I dirs
+with the path components
+.I a
+and
+.I b
+into
+.LR path .
+The path is constructed in
+.I path
+by separating each path component with
+.IR / .
+Both
+.I a
+and
+.I b
+may be
+.LR 0 .
+A pointer to the next
+.I sep
+separated component in
+.I dirs
+is returned,
+.L 0
+when there are no more components.
+.L pathcat
+is used by
+.LR pathaccess .
+.PP
+.L pathcd
+sets the current working directory to
+.I path
+via
+.IR chdir (2).
+If
+.I path
+is longer than
+.L PATH_MAX
+then it is split up into a sequence of relative paths and
+.I chdir
+is called on each of these.
+For any given system, if you got to a directory, then
+.L pathcd
+can get you back, modulo permission and link changes.
+.PP
+.L pathcheck
+is a stub for license libraries.
+See
+.IR license (3).
+.PP
+.L pathgetlink
+returns the 0-terminated symbolic link text for
+.I path
+in the buffer
+.I bu
+of size
+.IR siz .
+The link text length is returned on success, \-1 on error.
+Weird
+.I universe (1)
+interactions with dynamic symbolic links are handled
+by converting non-standard dynamic link text to
+.LI .../$( UNIVERSE )/...
+.L pathsetsymlink
+converts in the other direction.
+.PP
+.L pathkey
+generates in
+.I key
+a 14 character lookup key (plus terminating 0) for the language
+.I lang
+processor in
+.IR path .
+A poihter to the key is returned, 0 on error.
+If
+.I "key == 0"
+then space is allocated via
+.IR malloc (3).
+Key specific attribute
+.I name=value
+pairs are copied into
+.I attr
+if
+.IR "attr != 0" .
+.PP
+.L pathpath
+constructs in
+.I path
+a path to
+.I p
+with
+.IR access (2)
+mode
+.I mode
+using the directories from
+.LR pathbin() .
+If \fIa != 0\fP then
+.IR a ,
+.IR argv [0]
+(if available via
+.IR optget (3)),
+and the
+.L _
+environment variable (set by
+.IR ksh (1) )
+are used for related root searching.
+If
+.I p
+also contains a
+.L /
+then
+.I ../p
+is searched for.
+.PP
+.L pathprobe
+generates in
+.I path
+the full path name of the
+.I tool
+specific
+.IR probe (1)
+information file for the
+.I lang
+langauge processor
+.IR proc .
+If
+.I "path == 0"
+then space is allocated via
+.IR malloc (3).
+Probe attribute
+.I name=value
+pairs are copied into
+.I attr
+if
+.IR "attr != 0" .
+.I op
+may be one of:
+.TP
+.B \-1
+return the path name with no access checks or generation
+.TP
+.B 0
+message emitted information must be generated via
+.IR probe (1)
+.TP
+.B 1
+no message emitted information must be probed via
+.IR probe (1)
+.PP
+0 is returned if the information does not exist and cannot be generated.
+.PP
+.L pathrepl
+does an in-place replacement of the first occurrence of
+.I /match/
+with
+.I /replace/
+in
+.IR path .
+.PP
+.L pathsetlink
+creates a symbolic link
+.I text
+in the path
+.IR name .
+See
+.L pathgetlink
+above for weird
+.IR universe (1)
+interactions hidden by this routine.
+.PP
+.L pathshell
+returns a pointer to the pathname for the shell for the current process.
+The
+.L SHELL
+environment variable is first consulted, but is rejected under suspicious
+ownership/setuid conditions of if it seems to point to
+.IR csh (1) ;
+otherwise
+.L confstr(_CS_SHELL,...)
+is used.
+A valid string is always returned.
+.PP
+.L pathstat
+first tries
+.LI stat( path,st )
+and if that fails it tries
+.LI lstat( path,st ).
+The
+.L stat
+or
+.L lstat
+return value is returned.
+.PP
+.L pathtemp
+generates in
+.I path
+a temporary file path name of the form
+.I dir/pfx<pid>.<suf>
+where the length of
+.IR pfx ,
+if !=0, is limited to 5, the length of
+.I <pid>
+(the base 64 representation of the current process id)
+is limited to 3, and
+.I <suf>
+(an internally generated suffix that avoid file confilicts)
+is limited to 3.
+The generated path name conforms to the classic UNIX 14 char and the DOS
+.LR 8.3
+limitations.
+Both
+.I dir
+and
+.I pfx
+may be
+.LR 0 .
+.IR access (2)
+is used to avoid file conflicts but the generated path name is not created,
+so you could lose in a race.
+.SH "SEE ALSO"
+3d(1), access(2), confstr(3), fs3d(3), lstat(2), stat(2)
diff --git a/src/lib/libast/man/preroot.3 b/src/lib/libast/man/preroot.3
new file mode 100644
index 0000000..025fc22
--- /dev/null
+++ b/src/lib/libast/man/preroot.3
@@ -0,0 +1,151 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH PREROOT 3
+.SH NAME
+preroot \- preroot support
+.SH SYNOPSIS
+.EX
+#include <preroot.h>
+
+char* getpreroot(char* \fIpath\fP, char* \fIcmd\fP);
+int ispreroot(char* \fIdir\fP);
+int realopen(char* \fIpath\fP, int \fImode\fP, int \fIperm\fP);
+void setpreroot(char** \fIargv\fP, char* \fIdir\fP);
+.EE
+.SH DESCRIPTION
+The
+.I preroot
+routines manipulate the process preroot.
+.I preroot
+is a kernel supported per-process two level viewpath.
+All pathnames rooted at
+.L /
+are first searched for in the process preroot directory
+and then in the system root directory.
+Setting the process preroot is a priveleged operation controlled by the
+.IR /etc/preroot (1)
+command.
+.PP
+.L <preroot.h>
+defines the symbol
+.B FS_PREROOT
+for those systems that support preroot.
+The following routines are valid only when
+.B FS_PREROOT
+is defined:
+.TP
+.L getpreroot
+returns a pointer to the absolute pathname of the preroot directory
+for the executable
+.IR cmd .
+The result is placed in
+.IR path .
+If
+.I path
+is
+.B 0
+then
+.IR malloc (3)
+is used to allocate the pathname space.
+.B 0
+is returned if
+.I cmd
+has no preroot or if an error was encountered.
+In this case
+.I errno
+is set to indicate the error.
+.TP
+.L ispreroot
+Non-zero is returned if
+.I dir
+is the current process preroot.
+If
+.I dir
+is
+.B 0
+then non-zero is returned if the current process has a preroot.
+.TP
+.L realopen
+temporarily disables the process preroot and does an
+.IR open (3)
+relative to the system root directory.
+The return value from
+.I open
+is returned.
+If there is no preroot then
+.I realopen
+is equivalent to
+.IR open .
+.TP
+.L setpreroot
+calls
+.IR execvp (3)
+as
+.L "execvp(a\fIrgv\fP[0],\fIargv\fP)"
+with the process preroot set to
+.IR dir .
+.I argv
+must be a
+.BR 0 -terminated
+argument array.
+If
+.I argv
+is
+.B 0
+then the value of
+.I opt_argv
+from
+.IR optget (3)
+is used.
+.L setpreroot
+returns immediately if
+.I dir
+is already the process preroot.
+.SH "SEE ALSO"
+/etc/preroot(1)
+.SH BUGS
+Preroot semantics should be preserved when reading directories.
+The
+.I ast
+.IR directory (3)
+routines do this.
+.IR 3d (1)
+viewpathing does
+.I preroot
+the right way.
diff --git a/src/lib/libast/man/proc.3 b/src/lib/libast/man/proc.3
new file mode 100644
index 0000000..64c1a6e
--- /dev/null
+++ b/src/lib/libast/man/proc.3
@@ -0,0 +1,319 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH PROC 3
+.SH NAME
+proc \- process control routines
+.SH SYNOPSIS
+.EX
+#include <proc.h>
+
+Proc_t* procopen(const char* \fIcommand\fP, char** \fIargv\fP, char** \fIenvv\fP, long* \fIopv\fP, long \fIflags\fP);
+int procfree(Proc_t* \fIproc\fP);
+int procclose(Proc_t* \fIproc\fP);
+int procrun(const char* \fIcommand\fP, char** \fIargv\fP);
+.EE
+.SH DESCRIPTION
+These routines provide a portable interface to process creation and execution.
+They work on systems with
+.IR fork (2)
+and
+.IR exec (2)
+as well as on systems with only
+.IR spawnve (2)
+or
+.IR spanwveg (3).
+.PP
+.L procopen
+runs
+.I command
+with arguments
+.IR argv ,
+environment modifications in
+.IR envv ,
+file descriptor, signal and process group operations in
+.I opv
+and flags in
+.IR flags .
+.PP
+.I command
+is searched for using the
+.L PATH
+environment variable from the calling environment.
+If
+.I command
+is
+.L 0
+then the current shell is used (see
+.IR pathshell (3)).
+If
+.I envv
+is not
+.L 0
+then it is a
+.L 0
+terminated vector of
+\fIname\fP[=\fIvalue\fP]
+strings that are added to the
+.I command
+environment using
+.IR setenviron (3).
+If
+.I name
+appears in the parent environment then its value is replaced with the new
+.IR value .
+If
+.RI = value
+is omitted then
+.I name
+is removed from the child environment.
+The
+.L _
+environment variable is set to contain the pathname for
+.I command
+and will appear at the top of the child environment.
+.PP
+If
+.I opv
+is not
+.L 0
+then it is a 0 terminaled vector of operations to perform.
+In the following
+.I context
+is a combination of
+.L PROC_FD_CHILD
+and
+.L PROC_FD_PARENT
+for the child and parent process context respectively.
+Valid operations are:
+.TP
+\f5PROC_FD_CLOSE(\fIfd\fP,\fIcontext\fP)\fR
+The file descriptor
+.I fd
+is closed in
+.IR context .
+.TP
+\f5PROC_FD_DUP(\fIfrom\fP,\fIto\fP,\fIcontext\fP)\fR
+The file descriptor
+.I from
+is
+.IR dup (2)'d
+into the file descriptor
+.I to
+in
+.IR context .
+.TP
+\f5PROC_SIG_DFL(\fIsig\fP)\fR
+The signal handler for
+.I sig
+is set to
+.L SIG_DFL
+in the child context.
+.TP
+\f5PROC_SIG_IGN(\fIsig\fP)\fR
+The signal handler for
+.I sig
+is set to
+.L SIG_IGN
+in the child context.
+.TP
+\f5PROC_SYS_PGRP(\fIpgid\fP)\fR
+The child process group is set to
+.IR pgid .
+.I pgid
+may have the following values:
+.TP
+.L <0
+The child process becomes a session leader.
+.TP
+.L 0
+The child process is in the parent process group.
+.TP
+.L 1
+The child process becomes a process group leader.
+.TP
+.L >1
+The child process joins the process group
+.IR pgid .
+.TP
+\f5PROC_SYS_UMASK(\fImask\fP)\fR
+The child process group file creation mask is set to
+.IR mask .
+.PP
+.I flags
+is the inclusive-or of the following:
+.TP
+.L PROC_ARGMOD
+.I "argv[-1]"
+and
+.I "argv[0]"
+may be modified.
+This is an optimization that avoids an environment vector
+.I realloc(3)
+when
+.I command
+is a shell script.
+.TP
+.L PROC_BACKGROUND
+Standard shell
+.L &
+setup is done for the child process.
+.TP
+.L PROC_CLEANUP
+Parent process redirection file discriptors are closed on error.
+.TP
+.L PROC_DAEMON
+Standard daemon setup is done for the child process.
+.TP
+.L PROC_ENVCLEAR
+The child environment is cleared before
+.I envv
+is added.
+.TP
+.L PROC_GID
+The child effective group id is set to the real group id.
+.TP
+.L PROC_IGNORE
+Parent pipe errors are ignored.
+.TP
+.L PROC_OVERLAY
+The current process is overlayed by
+.I command
+if possible
+(i.e., the
+.IR fork (2)
+call is omitted).
+.TP
+.L PROC_PARANOID
+Paranoid:
+.I command
+is searched using the default standard
+.LR PATH ;
+the child environment variable
+.L PATH
+is set to the default standard;
+the
+.L PROC_GID
+and
+.L PROC_UID
+modes are set;
+only
+.L /bin/sh
+is used to execute
+.I command
+if it is a shell script.
+.TP
+.L PROC_PRIVELEGED
+If the effective user id is
+.L 0
+then the child real user id is set to
+.L 0
+and the child real group id is set to the effective group id.
+.TP
+.L PROC_READ
+.I proc.rfd
+is connected to
+.IR command 's
+standard output.
+.TP
+.L PROC_SESSION
+The child process becomes a session group leader.
+(Equivalent to the
+.I opv
+entry
+.LR PROC_SYS_PGRP(-1) .)
+.TP
+.L PROC_UID
+The child effective user id is set to the real user id.
+.TP
+.L PROC_WRITE
+.I proc.wfd
+is connected to
+.IR commands 's
+standard input.
+.PP
+The return value is a pointer to a structure with the following members:
+.TP
+.L "pid_t \fIpid\fP"
+The child process id.
+.TP
+.L "pid_t \fIpgrp\fP"
+The child process group.
+.TP
+.L "int \fIrfd\fP"
+A read file descriptor connected to
+.IR command 's
+standard output.
+.TP
+.L "int \fIwfd\fP"
+A write file descriptor connected to
+.IR command 's
+standard input.
+.PP
+If an error occurs then
+.L 0
+is returned.
+.PP
+.L procclose
+waits for the process
+.I proc
+to complete and then closes the command stream
+.IR proc .
+The command exit status is returned.
+.L -1
+is returned if the child portion of
+.L procopen
+failed.
+.PP
+.L procfree
+frees the process stream without waiting for
+.I command
+to complete.
+Presumably some other mechanism will be used to wait for
+.IR proc.pid .
+.PP
+.L procrun
+combines
+.L procopen
+and
+.L procclose
+with the flags
+.L PROC_GID|PROC_UID
+and returns the command exit status.
+.SH "SEE ALSO"
+popen(3), sfpopen(3), spawnveg(3), system(3)
diff --git a/src/lib/libast/man/re.3 b/src/lib/libast/man/re.3
new file mode 100644
index 0000000..2e1010e
--- /dev/null
+++ b/src/lib/libast/man/re.3
@@ -0,0 +1,214 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH RE 3
+.SH NAME
+recomp, reexec, ressub, refree, reerror \(mi regular expression library
+.SH SYNOPSIS
+.EX
+#include <re.h>
+
+Re_program_t* recomp(char* \fIpattern\fP, int \fIflags\fP);
+int reexec(Re_program_t* \fIre\fP, char* \fIsource\fP);
+void ressub(Re_program_t* \fIre\fP, Sfio_t* \fIsp\fP, char* \fIold\fP, char* \fInew\fP, int \fIflags\fP);
+void reerror(char* \fImessage\fP);
+void refree(Re_program_t* \fIre\fP);
+.EE
+.SH DESCRIPTION
+.L recomp
+compiles a regular expression in
+.I pattern
+and returns a pointer to the compiled regular expression.
+The space is allocated by
+.IR malloc (3)
+and may be released by
+.LR refree .
+Regular expressions are as in
+.IR egrep (1)
+except that newlines are treated as ordinary
+characters and
+.L $
+matches the end of a null-terminated string.
+.I flags
+may be
+.L RE_EDSTYLE
+which specifies
+.IR ed (1)
+style special characters,
+.LR \e( ,
+.LR \e) ,
+.LR \e? ,
+.L \e+
+and
+.L \e|
+for the
+.IR egrep (1)
+.LR ( ,
+.LR ) ,
+.LR ? ,
+.L +
+and
+.LR | ,
+respectively.
+.PP
+.L reexec
+matches the null-terminated
+.I source
+string against the compiled regular expression
+.I re
+from a previous call to
+.LR recomp .
+If it matches,
+.L reexec
+returns a non-zero value.
+If
+.I flags
+is
+.L RE_MATCH
+then the array
+.I re\->match
+is filled with character pointers to the substrings of
+.I source
+that correspond to the
+parenthesized subexpressions of
+.IR pattern :
+.I re\->match[i].sp
+points to the beginning and
+.I re\->match[i].ep
+points just beyond
+the end of substring
+.IR i .
+(Subexpression
+.I i
+begins at the
+.IR i th
+matched left parenthesis, counting from 1.)
+Pointers in
+.I re\->match[0]
+pick out the substring that corresponds to
+the entire regular expression.
+Unused elements of
+.I re\->match
+are filled with zeros.
+Matches involving
+.LR * ,
+.LR + ,
+and
+.L ?
+are extended as far as possible.
+A maximum of 9 subexpressions will be matched.
+The structure of elements of
+.I re\->match
+is:
+.nf
+.ta 8n
+ typedef struct
+ {
+ char* sp;
+ char* ep;
+ } rematch;
+.fi
+.LP
+.L ressub
+places in the
+.IR sfio (3)
+stream
+.I sp
+a substitution instance of
+.I old
+to
+.I new
+in
+.I source
+in the context of the last
+.L reexec
+performed on
+.IR re\->match .
+Each instance of
+.LI \e n ,
+where
+.I n
+is a digit, is replaced by the
+string delimited by
+.LI re\->match[ n ].sp
+and
+.LI re\->match[ n ].ep .
+Each instance of
+.L &
+is replaced by the string delimited by
+.I re\->match[0].sp
+and
+.IR re\->match[0].ep .
+If
+.L RE_ALL
+is set in
+.I flags
+then all occurrences of
+.I old
+are replaced by
+.IR new .
+If
+.L RE_LOWER
+.RL [ RE_UPPER ]
+is set in
+.I flags
+then
+.I old
+is converted to lower [upper] case.
+.LP
+.L reerror,
+called whenever an error is detected in
+.L recomp,
+.L reexec,
+or
+.L ressub,
+writes the string
+.I msg
+on the standard error file and exits.
+.L reerror
+may be replaced to perform
+special error processing.
+.SH DIAGNOSTICS
+.L recomp
+returns 0 for an invalid expression or other failure.
+.L reexec
+returns 1 if
+.I source
+is accepted, 0 otherwise.
+.SH "SEE ALSO"
+ed(1), grep(1), expr(1)
diff --git a/src/lib/libast/man/regex.3 b/src/lib/libast/man/regex.3
new file mode 100644
index 0000000..7c15d21
--- /dev/null
+++ b/src/lib/libast/man/regex.3
@@ -0,0 +1,163 @@
+.fp 5 B
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH REGEX 3
+.SH NAME
+regex \- regular expression interface
+.SH SYNOPSIS
+.EX
+#include <regex.h>
+
+int regcomp(regex_t* \fIre\fP, const char* \fIregex\fP, int \fIcflags\fP);
+int regexec(const regex_t* \fIre\fP, const char* \fIstring\fP, size_t \fInmatch\fP, regmatch_t \fIpmatch\fP[], int \fIeflags\fP);
+size_t regerror(int \fIcode\fP, const regex_t* \fIre\fP, char* \fIerrbuf\fP, size_t \fIerrbuf_size\fP);
+void regfree(regex_t* \fIre\fP);
+
+regclass_t regclass(const char* \fIstr\fP, char** \fIend\fP);
+int regaddclass(const char* \fIname\fP, regclass_t \fIclassf\fP);
+int regcollate(const char* \fIstr\fP, char** \fIend\fP, char* \fIbuf\fP, int \fIsize\fP);
+
+int regcomb(regex_t* \fIre_1\fP, regex_t* \fIre_2\fP);
+size_t regdecomp(regex_t* \fIre\fP, regflags_t \fIflags\fP, char* \fIbuf\fP, size_t \fIsize\fP);
+int regdup(regex_t* \fIre_old\fP, regex_t* \fIre_new\fP);
+regstat_t* regstat(const regex_t* \fIre\fP);
+
+regex_t* regcache(const char* \fIpattern\fP, regflags_t \fIflags\fP, int* \fIpcode\fP);
+
+int regncomp(regex_t* \fIre\fP, const char* \fIpattern\fP, size_t \fIsize\fP, regflags_t \fIflags\fP);
+int regnexec(const regex_t* \fIre\fP, const char* \fIsubject\fP, size_t \fIsize\fP, size_t \fInmatch\fP, regmatch_t* \fImatch\fP, regflags_t \fIflags\fP);
+int regrecord(const regex_t* \fIre\fP);
+int regrexec(const regex_t* \fIre\fP, const char* \fIbuf\fP, size_t \fIsize\fP, size_t \fInmatch\fP, regmatch_t* \fImatch\fP, regflags_t \fIflags\fP, int \fIsep\fP, void* \fIhandle\fP, regrecord_t \fIrecordf\fP);
+void regfatal(regex_t* \fIre\fP, int \fIlevel\fP, int \fIcode\fP);
+void regfatalpat(regex_t* \fIre\fP, int \fIlevel\fP, int \fIcode\fP, const char* \fIpattern\fP);
+
+int regsubcomp(regex_t* \fIre\fP, const char* \fIstr\fP, const regflags_t* \fImap\fP, int \fIminmatch\fP, regflags_t \fIflags\fP);
+int regsubexec(const regex_t* \fIre\fP, const char* \fIsubject\fP, size_t \fInmatch\fP, regmatch_t* match);
+int regsubflags(regex_t* \fIre\fP, const char* \fIstr\fP, char** \fIend\fP, int \fIdelim\fP, const regflags_t* \fImap\fP, int* \fIpm\fP, regflags_t* \fIpf\fP);
+void regsubfree(regex_t* \fIre\fP);
+.EE
+
+.SH DESCRIPTION
+.LR regcomp() ,
+.LR regexec() ,
+.LR regerror() ,
+and
+.L regfree()
+are the POSIX regular expression functions.
+The remaining functions are
+.B ast
+extensions.
+.B ast
+also provides
+.I flags
+extensions to the
+.LR regcomp() ,
+.LR regexec()
+functions and
+.I code
+extensions to the
+.L regerror()
+function.
+
+.PP
+.L regcache()
+maintains a cache of compiled regular expressions for patterns of size
+255 bytes or less.
+The initial cache size is 8.
+.L pattern
+and
+.L flags
+are passed to
+.L regcomp()
+with an
+.L re
+pointer maintained by
+.LR regcache() .
+.LR pcode ,
+if not 0, points to the return value of the
+.L regcomp()
+call.
+If the
+.L regcomp()
+call fails,
+.L regcache()
+returns 0 and
+.L pcode
+will point to the non-zero error code.
+Do not call
+.L regfree()
+on the
+.L re
+returned by
+.LR regcache() .
+Both
+.L pattern
+and
+.L flags
+are used to match entries in the cache.
+When the cache is full the least recently used
+.L re
+is freed (via
+.LR regfree() )
+to make space for the new pattern.
+Any
+.L re
+previously returned by
+.L regcache()
+may be freed (invalidated) on the next call to
+.LR regcache() .
+If
+.L pattern
+is longer that 255 bytes then it is still passed on to
+.LR regcomp() ,
+but it will not be cached.
+If
+.L pattern
+is 0 then the cache is flushed.
+In addition, if the integer value of
+.L flags
+is greater than the current cache size, the cache size is increased
+to that integer value.
+0 is always returned when
+.L pattern
+is 0;
+.L pcode
+will point to a non-zero value on error.
+
+.SH "SEE ALSO"
+strmatch(3)
diff --git a/src/lib/libast/man/setenviron.3 b/src/lib/libast/man/setenviron.3
new file mode 100644
index 0000000..818f7fc
--- /dev/null
+++ b/src/lib/libast/man/setenviron.3
@@ -0,0 +1,79 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH LIBAST 3
+.SH NAME
+setenviron \- set environment value
+.SH SYNOPSIS
+.EX
+#include <ast.h>
+
+char* setenviron(const char* \fIkey\fP);
+.EE
+.SH DESCRIPTION
+.L setenviron
+controls environment
+.I name=value
+pairs.
+.L setenviron("\fIname=value\fP")
+adds
+.I name
+to the environment and returns a pointer to a
+.IR strdup (3)
+copy of
+.IR name=value .
+.L setenviron("\fIname\fP")
+removes
+.I name
+from the environment and returns the empty string.
+.L setenviron(0)
+reserves a few slots in an internal array and is usually called by
+a parent process that expects many children.
+0 is returned on error.
+.L setenviron
+preserves the
+.IR ksh (1)
+convention of
+.L _
+as the first environment variable name.
+.SH "SEE ALSO"
+env(1), exec(2)
+.SH BUGS
+POSIX will eventually settle on an interface.
+It has already picked a few of the names we did in .2 drafts.
+This is about the third name change for ours.
diff --git a/src/lib/libast/man/sfdisc.3 b/src/lib/libast/man/sfdisc.3
new file mode 100644
index 0000000..f0ce5b0
--- /dev/null
+++ b/src/lib/libast/man/sfdisc.3
@@ -0,0 +1,118 @@
+.fp 5 CW
+.TH SFDISC 3 "16 June 1993"
+.SH NAME
+\fBsfdisc\fR \- \fBsfio\fP disciplines
+.SH SYNOPSIS
+.de Tp
+.fl
+.ne 2
+.TP
+..
+.de Ss
+.fl
+.ne 2
+.SS "\\$1"
+..
+.ta 1.0i 2.0i 3.0i 4.0i 5.0i
+.nf
+.ft 5
+#include <sfdisc.h>
+
+extern Sfdisc_t* dcnewskable(Sfio_t* f);
+extern int dcdelskable(Sfdisc_t* disc);
+
+extern Sfdisc_t* dcnewtee(Sfio_t* tee);
+extern int dcdeltee(Sfdisc_t* disc);
+
+extern Sfdisc_t* dcnewfilter(char* cmd);
+extern int dcdelfilter(Sfdisc_t* disc);
+
+extern Sfdisc_t* dcnewsubstream(Sfio_t* f, long offset, long extent);
+extern int dcdelsubstream(Sfdisc_t* disc);
+
+extern Sfdisc_t* dcnewlzw(void);
+extern int dcdellzw(Sfdisc_t* disc);
+
+extern Sfdisc_t* dcnewunion(Sfio_t** flist, int n);
+extern int dcdelunion(Sfdisc_t* disc);
+.ft 1
+.fi
+.SH DESCRIPTION
+.PP
+I/O disciplines are used to extend the data processing power of
+\fIsfio\fP streams. The convention for using the disciplines
+in this package is to use the call \f5dcnewXXX()\fP to create
+a discipline of the type \f5XXX\fP and to use \f5dcdelXXX()\fP
+to destroy it.
+A discipline is enable by inserting it into the desired
+stream using the \f5sfdisc()\fP call. A discipline can be used on only
+one stream. It is unsafe to share a discipline on two or more streams
+since the discipline may maintain states between successive IO calls.
+For multiple uses, \f5dcnewXXX()\fP should be used
+to create a distinct discipline for each stream.
+Each discipline structure is equipped with an exception handler
+that causes self-destruction when the associated stream is closed.
+.PP
+.Ss " Sfdisc_t* dcnewskable(Sfio_t* f);"
+.Ss " int dcdelskable(Sfdisc_t* disc);"
+\f5dcnewskable()\fP creates a discipline that when inserted
+on the stream \f5f\fP will ensure that \f5f\fP is seekable.
+If \f5f\fP is originally unseekable, data will be shadowed
+in a temporary file stream to allow seekability.
+\f5dcnewskable()\fP returns the discipline on success and \f5NULL\fP on failure.
+
+.Ss " Sfdisc_t* dcnewtee(Sfio_t* tee);"
+.Ss " int dcdeltee(Sfdisc_t* disc);"
+\f5dcnewtee()\fP creates a discipline that
+when inserted into a stream \f5f\fP will duplicate to the stream \f5tee\fP
+any data written to \f5f\fP.
+\f5dcnewtee()\fP returns the discipline on success and \f5NULL\fP on failure.
+
+.Ss " Sfdisc_t* dcnewfilter(char* cmd);"
+.Ss " int dcdelfilter(Sfdisc_t* disc);"
+\f5dcnewfilter()\fP creates a discipline that
+when inserted into a stream \f5f\fP will run the command \f5cmd\fP
+to process any input data before making it available to the application.
+For example, \f5dcnewfilter("uncompress")\fP is an equivalent but slower
+alternative to the lzw discipline below.
+\f5dcnewfilter()\fP returns the discipline on success and \f5NULL\fP on failure.
+
+.Ss " Sfdisc_t* dcnewsubstream(Sfio_t* base, long offset, long extent);"
+.Ss " int dcdelsubstream(Sfdisc_t* disc);"
+\f5dcnewsubstream()\fP creates a discipline that
+reserves a portion of the stream \f5base\fP starting at \f5offset\fP
+with length \f5extent\fP and makes this portion appear as if it is
+a stream. When this discipline is inserted into a stream, it will make
+cause all IO operations on this stream to take place in the reserved
+portion of the \f5base\fP stream.
+\f5dcnewsubstream()\fP returns the discipline on success and \f5NULL\fP on failure.
+
+.Ss " Sfdisc_t* dcnewlzw(void);
+.Ss " int dcdellzw(Sfdisc_t* disc);"
+\f5dcnewlzw()\fP creates a discipline that when inserted into
+a stream \f5f\fP will run the \fBuncompress\fP algorithm
+on input data from \f5f\fP before making it available to the
+application. This is useful to allow applications to process
+data from a file packed with the UNIX \fBcompress\fP utility
+as if the data is in plain text.
+\f5dcnewlzw()\fP returns the discipline on success and \f5NULL\fP on failure.
+
+.Ss " Sfdisc_t* dcnewunion(Sfio_t** list, int n);
+.Ss " int dcdelunion(Sfdisc_t* disc);"
+\f5dcnewunion()\fP creates a discipline that concatenates
+input data from all \f5n\fP streams in \f5list\fP.
+When inserted into a stream \f5f\fP, this discipline will cause
+all input operations on \f5f\fP to come from the merged data stream.
+\f5dcnewunion()\fP returns the discipline on success and \f5NULL\fP on failure.
+
+.SH ACKNOWLEDGMENTS
+Dave Korn contributed the substream discipline.
+Jim Arnold contributed the lzw discipline.
+
+.SH NOTES
+Since we are not sure of the legal responsibilities concerning the lzw patent,
+the lzw discipline is not currently distributed with any release of sfio
+outside of AT&T.
+
+.SH AUTHOR
+Kiem-Phong Vo, kpv@research.att.com.
diff --git a/src/lib/libast/man/sfio.3 b/src/lib/libast/man/sfio.3
new file mode 100644
index 0000000..f22d0b7
--- /dev/null
+++ b/src/lib/libast/man/sfio.3
@@ -0,0 +1,2373 @@
+.fp 5 CW
+.TH SFIO 3 "01 June 2008"
+.SH NAME
+\fBsfio\fR \- safe/fast string/file input/output
+.SH SYNOPSIS
+.de Tp
+.fl
+.ne 3
+.TP
+..
+.de Ss
+.fl
+.ne 3
+.SS "\\$1"
+..
+.ta 1.0i 2.0i 3.0i 4.0i 5.0i
+.Ss "LIBRARIES"
+.nf
+.ft 5
+#include <sfio.h>
+
+libsfio.a -lsfio
+libstdio.a -lstdio
+libsfio-mt.a -lsfio-mt
+libstdio-mt.a -lstdio-mt
+.ft 1
+.fi
+.Ss "DATA TYPES"
+.nf
+.ft 5
+Void_t;
+Sfoff_t;
+Sflong_t;
+Sfulong_t;
+Sfdouble_t;
+
+Sfio_t;
+
+Sfdisc_t;
+ssize_t (*Sfread_f)(Sfio_t*, Void_t*, size_t, Sfdisc_t*);
+ssize_t (*Sfwrite_f)(Sfio_t*, const Void_t*, size_t, Sfdisc_t*);
+Sfoff_t (*Sfseek_f)(Sfio_t*, Sfoff_t, int, Sfdisc_t*);
+int (*Sfexcept_f)(Sfio_t*, int, Void_t*, Sfdisc_t*);
+
+Sffmt_t;
+int (*Sffmtext_f)(Sfio_t*, Void_t*, Sffmt_t*);
+int (*Sffmtevent_f)(Sfio_t*, int, Void_t*, Sffmt_t*);
+
+SFIO_VERSION
+.ft 1
+.fi
+.Ss "BIT FLAGS"
+.nf
+.ft 5
+SF_STRING
+SF_READ
+SF_WRITE
+SF_APPENDWR (SF_APPEND)
+SF_LINE
+SF_SHARE
+SF_PUBLIC
+SF_MALLOC
+SF_STATIC
+SF_IOCHECK
+SF_WHOLE
+SF_MTSAFE
+SF_IOINTR
+.ft 1
+.fi
+.Ss "OPENING/CLOSING STREAMS"
+.nf
+.ft 5
+Sfio_t* sfnew(Sfio_t* f, Void_t* buf, size_t size, int fd, int flags);
+Sfio_t* sfopen(Sfio_t* f, const char* string, const char* mode);
+Sfio_t* sfpopen(Sfio_t* f, const char* cmd, const char* mode);
+Sfio_t* sftmp(size_t size);
+int sfclose(Sfio_t* f);
+
+
+.ft 1
+.fi
+.Ss "THREAD SAFETY"
+.nf
+.ft 5
+int sfmutex(Sfio_t* f, int type);
+
+SFMTX_LOCK
+SFMTX_TRYLOCK
+SFMTX_UNLOCK
+SFMTX_CLRLOCK
+.ft 1
+.fi
+.Ss "INPUT/OUTPUT OPERATIONS"
+.nf
+.ft 5
+int sfgetc(Sfio_t* f);
+int sfputc(Sfio_t* f, int c);
+int sfnputc(Sfio_t* f, int c, int n);
+int sfungetc(Sfio_t* f, int c);
+
+Sfulong_t sfgetm(Sfio_t* f, Sfulong_t max);
+int sfputm(Sfio_t* f, Sfulong_t v, Sfulong_t max);
+Sfulong_t sfgetu(Sfio_t* f);
+int sfputu(Sfio_t* f, Sfulong_t v);
+Sflong_t sfgetl(Sfio_t* f);
+int sfputl(Sfio_t* f, Sflong_t v);
+Sfdouble_t sfgetd(Sfio_t* f);
+int sfputd(Sfio_t* f, Sfdouble_t v);
+
+char* sfgetr(Sfio_t* f, int rsc, int type);
+ssize_t sfputr(Sfio_t* f, const char* s, int rsc);
+Sfoff_t sfmove(Sfio_t* fr, Sfio_t* fw, Sfoff_t n, int rsc);
+
+ssize_t sfread(Sfio_t* f, Void_t* buf, size_t n);
+ssize_t sfwrite(Sfio_t* f, const Void_t* buf, size_t n);
+Sfoff_t sfseek(Sfio_t* f, Sfoff_t offset, int type);
+Void_t* sfreserve(Sfio_t* f, ssize_t n, int type);
+.ft 1
+.fi
+.Ss "DATA FORMATTING"
+.nf
+.ft 5
+int sfscanf(Sfio_t* f, const char* format, ...);
+int sfsscanf(const char* s, const char* format, ...);
+int sfvsscanf(const char* s, const char* format, va_list args);
+int sfvscanf(Sfio_t* f, const char* format, va_list args);
+
+int sfprintf(Sfio_t* f, const char* format, ...);
+char* sfprints(const char* format, ...);
+char* sfvprints(const char* format, va_list args);
+ssize_t sfaprints(char** sp, const char* format, ...);
+ssize_t sfvaprints(char** sp, const char* format, va_list args);
+int sfsprintf(char* s, int n, const char* format, ...);
+int sfvsprintf(char* s, int n, const char* format, va_list args);
+int sfvprintf(Sfio_t* f, const char* format, va_list args);
+
+Sffmt_t;
+
+SFFMT_LEFT
+SFFMT_SIGN
+SFFMT_BLANK
+SFFMT_ZERO
+SFFMT_THOUSAND
+SFFMT_LONG
+SFFMT_LLONG
+SFFMT_SHORT
+SFFMT_LDOUBLE
+SFFMT_IFLAG
+SFFMT_JFLAG
+SFFMT_CENTER
+SFFMT_CHOP
+SFFMT_ALTER
+SFFMT_SKIP
+SFFMT_ARGPOS
+SFFMT_VALUE
+
+int (*Sffmtext_f)(Sfio_t* f, Void_t* v, Sffmt_t* fe);
+int (*Sffmtevent_f)(Sfio_t* f, int type, Void_t* v, Sffmt_t* fe);
+void va_copy(va_list to, va_list fr);
+long sffmtversion(Sffmt_t* fe, type);
+.ft 1
+.fi
+.Ss "BUFFERING, SYNCHRONIZATION"
+.nf
+.ft 5
+Void_t* sfsetbuf(Sfio_t* f, Void_t* buf, size_t size);
+int sfsync(Sfio_t* f);
+int sfpoll(Sfio_t** flist, int n, int timeout);
+Sfio_t* sfpool(Sfio_t* f, Sfio_t* poolf, int mode);
+int sfpurge(Sfio_t* f);
+.ft 1
+.fi
+.Ss "DISCIPLINE, EVENT HANDLING"
+.nf
+.ft 5
+Sfdisc_t* sfdisc(Sfio_t* f, Sfdisc_t* disc);
+int sfraise(Sfio_t* f, int type, Void_t* data);
+ssize_t sfrd(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc);
+ssize_t sfwr(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc);
+Sfoff_t sfsk(Sfio_t* f, Sfoff_t offset, int type, Sfdisc_t* disc);
+
+SF_NEW
+SF_READ
+SF_WRITE
+SF_SEEK
+SF_CLOSING (SF_CLOSE)
+SF_DPUSH
+SF_DPOP
+SF_DPOLL
+SF_DBUFFER
+SF_SYNC
+SF_PURGE
+SF_FINAL
+SF_READY
+SF_LOCKED
+SF_ATEXIT
+SF_EVENT
+.ft 1
+.fi
+.Ss "STREAM CONTROL"
+.nf
+.ft 5
+int sfresize(Sfio_t* f, Sfoff_t size);
+int sfset(Sfio_t* f, int flags, int i);
+int sfsetfd(Sfio_t* f, int fd);
+Sfio_t* sfstack(Sfio_t* base, Sfio_t* top);
+Sfio_t* sfswap(Sfio_t* f1, Sfio_t* f2);
+.ft 1
+.fi
+.Ss "STREAM INFORMATION"
+.nf
+.ft 5
+Sfoff_t sfsize(Sfio_t* f);
+Sfoff_t sftell(Sfio_t* f);
+ssize_t sfvalue(Sfio_t* f);
+int sffileno(Sfio_t* f);
+
+int sfstacked(Sfio_t* f);
+int sfeof(Sfio_t* f);
+int sferror(Sfio_t* f);
+int sfclrerr(Sfio_t* f);
+int sfclrlock(Sfio_t* f);
+
+int sfnotify(void (*notify)(Sfio_t* f, int type, Void_t* data));
+
+int sfwalk(Sfwalk_f walkf, Void_t* data, int type);
+.ft 1
+.fi
+.Ss "MISCELLANEOUS FUNCTIONS"
+.nf
+.ft 5
+ssize_t sfmaxr(ssize_t maxr, int s);
+ssize_t sfslen();
+int sfulen(Sfulong_t v);
+int sfllen(Sflong_t v);
+int sfdlen(Sfdouble_t v);
+ssize_t sfpkrd(int fd, Void_t* buf, size_t n,
+ int rsc, long tm, int action);
+.ft 1
+.fi
+.Ss "FULL STRUCTURE SFIO_T"
+.nf
+.ft 5
+#include <sfio_t.h>
+#define SFNEW(buf,size,file,flags,disc)
+.ft 1
+.fi
+.Ss "EXAMPLE DISCIPLINES"
+.nf
+.ft 5
+#include <sfdisc.h>
+
+int sfdcdio(Sfio_t* f, size_t bufsize);
+int sfdcdos(Sfio_t* f);
+int sfdcfilter(Sfio_t* f, const char* cmd);
+int sfdcseekable(Sfio_t* f);
+int sfdcslow(Sfio_t* f);
+int sfdcsubstream(Sfio_t* f, Sfio_t* parent,
+ Sfoff_t offset, Sfoff_t extent);
+int sfdctee(Sfio_t* f, Sfio_t* tee);
+int sfdcunion(Sfio_t* f, Sfio_t** array, int n);
+int sfdclzw(Sfio_t* f);
+int sfdcgzip(Sfio_t* f, int flags);
+.ft 1
+.fi
+.Ss "STDIO-COMPATIBILITY"
+.nf
+.ft 5
+#include <stdio.h>
+cc ... -lstdio -lsfio
+cc ... -lstdio-mt -lsfio-mt
+.ft 1
+.fi
+.SH DESCRIPTION
+.PP
+Sfio provides I/O functions to manage buffered streams.
+Each Sfio stream is a \fIfile stream\fP, representing a file (see \f5open(2)\fP),
+or a \fIstring stream\fP, representing a memory segment.
+Beyond the usual I/O operations on streams,
+Sfio provides I/O disciplines for extended data processing,
+stream stacks for recursive stream processing, and
+stream pools for automatic data synchronization.
+Applications can extend the \f5sfprintf()/sfscanf()\fP functions
+to define their own conversion patterns as well as redefine existing ones.
+.PP
+A discipline defines analogues of
+the system calls \f5read(2), write(2)\fP and \f5lseek(2)\fP.
+Such system calls or their discipline replacements are used to process stream data.
+Henceforth, ``\fIsystem call\fP'' will refer to either a system call
+or its discipline replacement.
+.PP
+A system call is said to cause an exception if its return value is non-positive.
+Unless overridden by exception handlers (see \f5sfdisc()\fP),
+an interrupted system call (\f5errno == EINTR\fP on UNIX systems)
+will be automatically reinvoked to continue the ongoing operation.
+.PP
+The buffer of a stream is typically a memory segment allocated via \f5malloc(3)\fP
+or supplied by the application.
+File streams may also use memory mapping (\f5mmap(2)\fP) if that is more efficient.
+When memory mapping is used,
+the underlying file should not be truncated while the stream is active.
+Memory mapping can be turned off using \f5sfsetbuf()\fP.
+.PP
+There are three \fIstandard streams\fP:
+\f5sfstdin\fP for input (file descriptor \f50\fP on UNIX systems),
+\f5sfstdout\fP for normal output (file descriptor \f51\fP), and
+\f5sfstderr\fP for error output (file descriptor \f52\fP).
+
+.PP
+.Ss "LIBRARIES"
+.PP
+This version of Sfio can be built and used for both uni-threaded and multi-threaded
+environments. In the former case, streams are not protected from
+simultaneous accesses by different threads. In the latter case, a stream
+is typically locked with a mutex during access so that another thread
+trying to access the same stream will block until the mutex is released.
+
+A program that does not use multiple threads can link with \fBlibsfio.a\fP
+while a program that uses multiple threads should link with \fBlibsfio-mt.a\fP.
+The libraries \fBlibstdio.a\fP and \fBlibstdio-mt.a\fP provide
+corresponding Stdio functions to link with code already compiled using the
+native header \fBstdio.h\fP instead of the one provided by Sfio.
+
+.PP
+.Ss "DATA TYPES"
+.PP
+.Ss " Void_t*"
+This defines a type suitable to exchange
+data of unknown types between application and Sfio.
+\f5Void_t\fP is a macro defined as \f5void\fP for ANSI-C and C++ and
+\f5char\fP for other compilation environments.
+.PP
+.Ss " Sfoff_t"
+This defines an integral type suitable to address
+the largest possible file extent.
+.PP
+.Ss " Sfulong_t, Sflong_t, Sfdouble_t"
+These are respectively the largest
+unsigned integer, signed integer, and floating point value types on the local platform.
+.PP
+.Ss " Sfio_t"
+This defines the type of a stream handle.
+.PP
+.Ss " Sfdisc_t"
+.Ss " ssize_t (*Sfread_f)(Sfio_t*, Void_t*, size_t, Sfdisc_t*)"
+.Ss " ssize_t (*Sfwrite_f)(Sfio_t*, const Void_t*, size_t, Sfdisc_t*)"
+.Ss " Sfoff_t (*Sfseek_f)(Sfio_t*, Sfoff_t, int, Sfdisc_t*)"
+.Ss " int (*Sfexcept_f)(Sfio_t*, int, Void_t*, Sfdisc_t*)"
+\f5Sfdisc_t\fP defines a stream discipline structure.
+\f5Sfread_f\fP, \f5Sfwrite_f\fP and \f5Sfseek_f\fP are the types
+of discipline functions to replace the system calls:
+\f5read(2)\fP, \f5write(2)\fP and \f5lseek(2)\fP.
+\f5Sfexcept_f\fP is the type of an event-handling function.
+See \f5sfdisc()\fP for more details.
+.PP
+.Ss " Sffmt_t"
+.Ss " int (*Sffmtext_f)(Sfio_t*, Void_t*, Sffmt_t*)"
+.Ss " int (*Sffmtevent_f)(Sfio_t*, int, Void_t*, Sffmt_t*)"
+\f5Sffmt_t\fP defines a formatting environment that can be used
+to extend scanning and printing in the \f5sfprint()/sfscanf()\fP
+functions. \f5Sffmtext_f\fP and \f5Sffmtevent_f\fP define the types
+of extension functions definable in \f5Sffmt_t\fP.
+See \f5Sffmt_t\fP below for more details.
+.PP
+.Ss " SFIO_VERSION"
+This is a macro value of type \f5long int\fP that defines
+the current version number of Sfio. For example, the Sfio2000's
+version number is \f520000515L\fP
+(which also indicates its latest version date: 05/15/2000).
+
+.Ss "BIT FLAGS"
+A number of bit flags control stream operations.
+They are set either at stream initialization or by calling \f5sfset()\fP.
+Following are the flags:
+.Tp
+\f5SF_STRING\fP:
+The stream is memory-based.
+.Tp
+\f5SF_READ\fP, \f5SF_WRITE\fP, \f5SF_APPENDWR\fP (\f5SF_APPEND\fP):
+Flags \f5SF_READ\fP and \f5SF_WRITE\fP indicate readability and writability.
+Flag \f5SF_APPENDWR\fP asserts that the stream is a file opened in append mode
+(see \f5open(2)\fP and \f5fcntl(2)\fP)
+so that data is always output at the end of file.
+On systems without direct support for append mode,
+Sfio uses \f5lseek(2)\fP or its discipline replacement
+to approximate this behavior.
+.Tp
+\f5SF_LINE\fP:
+The stream is line-oriented.
+For a \f5SF_WRITE\fP stream,
+this means that buffered data is flushed
+whenever a new-line character, \f5\en\fP, is output.
+For a \f5SF_READ\fP stream, \f5SF_LINE\fP is only
+significant during calls to functions in the \f5sfscanf()\fP family.
+\f5SF_LINE\fP is set on initialization of
+any stream representing a terminal device.
+.Tp
+\f5SF_SHARE\fP, \f5SF_PUBLIC\fP:
+Flag \f5SF_SHARE\fP means that the underlying file descriptor
+is shared by independent entities (for example, multiple processes).
+
+For a seekable file stream, \f5SF_SHARE\fP means that
+the logical stream and the physical file positions will be made the same
+before a system call to perform physical I/O.
+There are different possibilities.
+If \f5SF_PUBLIC\fP is not set,
+the physical file position is made equal to the logical stream position.
+If \f5SF_PUBLIC\fP is set, there are two cases.
+If the physical file position has changed from its last known position,
+the logical stream position is made equal to the new physical file position.
+Finally, if the physical file location remains the same as its last known position,
+the physical file position is made the same as the logical stream position.
+
+For an unseekable stream (e.g., pipes or terminal devices), if possible,
+\f5SF_SHARE\fP means that
+the block and record I/O operations (\f5sfread()\fP, \f5sfwrite()\fP, \f5sfmove()\fP,
+\f5sfgetr()\fP, \f5sfputr()\fP, \f5sfreserve()\fP, \f5sfscanf()\fP
+and \f5sfvprintf()\fP) will ensure:
+(1) after each writing operation, the stream is synchronized and
+(2) each reading operation only reads the requested amount.
+Note, however, that (2) is not always possible
+without proper OS facilities such as \f5recv(2)\fP or \f5streamio(4)\fP.
+
+A standard stream that is seekable will be initialized with \f5SF_SHARE|SF_PUBLIC\fP.
+.Tp
+\f5SF_MALLOC\fP:
+The stream buffer was obtained via \f5malloc(3)\fP
+and can be reallocated or freed.
+.Tp
+\f5SF_STATIC\fP:
+The stream structure should not be freed when closed (\f5sfclose()\fP).
+This flag is used by an applications that allocate their own
+stream structures. Such applications must use the header file \f5sfio_t.h\fP
+instead of \f5sfio.h\fP.
+.Tp
+\f5SF_IOCHECK\fP:
+If the stream has a discipline exception handler,
+exceptions will be raised in \f5sfsync()\fP, \f5sfpurge()\fP
+or before a system call \f5read(2)\fP or \f5write(2)\fP (see \f5sfdisc()\fP).
+.Tp
+\f5SF_WHOLE\fP:
+This flag guarantees that data written in any single \f5sfwrite()\fP or
+\f5sfputr()\fP call will always be output as a whole to the output device.
+This is useful in certain applications (e.g., networking) where a complex object
+must be output without being split in different system calls.
+Note that the respective stream still buffers data as much as the buffer can accomodate.
+.Tp
+\f5SF_MTSAFE\fP:
+This flag indicates that the respective stream may be accessed by more than one threads.
+A mutex lock will be used to ensure that only one thread at a time can access
+the stream. Note that this flag can only be set at stream opening time
+(see \f5sfopen()\fP, \f5sfpopen()\fP and \f5sfnew()\fP).
+Certain fast macro functions such as \f5sfgetc()\fP and \f5sfputc()\fP will
+no longer behave as macros. Thus, an application that requires such fast macro functions
+should leave \f5SF_MTSAFE\fP off and performs explicit locking with \f5sfmutex()\fP.
+.Tp
+\f5SF_IOINTR\fP:
+This flag indicates that I/O system calls should not be resumed
+after being interrupted by signals. It is useful for
+aborting I/O operations on such interruptions. Note, however,
+than certain operating systems (e.g., BSD Unix systems) may automatically
+resume interrupted system calls outside the scope of the library. On such systems,
+\f5SF_IOINTR\fP will be ineffective.
+
+.PP
+.Ss "OPENING/CLOSING STREAMS"
+.PP
+.Ss " Sfio_t* sfnew(Sfio_t* f, Void_t* buf, size_t size, int fd, int flags)"
+This function creates or renews a stream.
+It returns the new stream on success and \f5NULL\fP on error.
+.Tp
+\f5f\fP:
+If \f5f\fP is \f5NULL\fP, a new stream is created.
+Otherwise, \f5f\fP is reused.
+In this case, if \f5flags\fP does not have \f5SF_EOF\fP,
+\f5f\fP shall be closed via \f5sfclose()\fP before being reused.
+During a stream renewal, buffer, pool and discipline stack are preserved.
+Note that, except for \f5SF_STATIC\fP streams,
+renewing a stream already closed will result in undefined behavior.
+.Tp
+\f5buf\fP, \f5size\fP:
+These determine a buffering scheme.
+See \f5sfsetbuf()\fP for more details.
+.Tp
+\f5fd\fP:
+If \f5SF_STRING\fP is specified in \f5flags\fP, this is ignored.
+Otherwise, \f5fd\fP is a file descriptor (e.g., from \f5open(2)\fP)
+to use for raw data I/O.
+Note that Sfio supports unseekable file descriptors
+opened for both read and write, e.g., sockets.
+.Tp
+\f5flags\fP:
+This is composed from \f5SF_EOF\fP and
+bit values defined in the \fBBIT FLAGS\fP section.
+Note, in particular, that a multi-threaded application should
+set the bit \f5SF_MTSAFE\fP to protect the new stream from
+being simultaneously accessed by multiple threads.
+
+.Ss " Sfio_t* sfopen(Sfio_t* f, const char* string, const char* mode)"
+
+If \f5string\fP is \f5NULL\fP,
+\f5f\fP is a file stream and
+\f5mode\fP does not imply a string stream,
+\f5sfopen()\fP changes the modes of \f5f\fP according to \f5mode\fP.
+In this case, \f5sfopen()\fP returns \f5f\fP on success and \f5NULL\fP on error.
+This somewhat unusual usage of \f5sfopen()\fP is good for
+resetting certain predefined modes in standard streams including
+\fItext/binary\fP and \fIappend\fP that are inherited from some parent process.
+Note also that \f5SF_READ\fP and \f5SF_WRITE\fP can only be reset if the stream
+is not yet initialized.
+
+\f5sfopen()\fP is normally used to create a new stream or renew a stream.
+In this case, it returns the new stream on success and \f5NULL\fP on error.
+Below are the meanings of the arguments:
+.Tp
+\f5f\fP:
+This is treated as in \f5sfnew()\fP.
+.Tp
+\f5string\fP:
+This is a file name or a string to perform I/O on.
+See above for when this is \f5NULL\fP.
+.Tp
+\f5mode\fP:
+This is composed from the set of letters \f5{s, r, w, +, a, b, t, x, m, u}\fP.
+When conflicting options are present in the same \f5mode\fP string,
+the last one will take effect.
+
+\f5s\fP specifies opening a string stream.
+\f5string\fP can be a null-terminated string or \f5NULL\fP.
+Specifying \f5s\fP alone is equivalent to specifying \f5sr\fP.
+If \f5s\fP is not specified, \f5string\fP defines a file name.
+
+\f5r\fP and \f5w\fP specify read and write modes.
+Write mode creates and/or truncates the given file to make an empty file.
+The \f5+\fP modifier indicates that the stream is opened for both read and write.
+
+\f5a\fP specifies append mode, i.e., data is always output at end of file.
+
+\f5b\fP and \f5t\fP specify binary and text modes.
+
+\f5x\fP specifies exclusive mode, i.e.,
+a file opened for writing should not already exist.
+
+\f5m\fP specifies that the stream needs to be protected from
+simultaneous accesses by multiple threads.
+This turns on the bit flag \f5SF_MTSAFE\fP.
+
+\f5u\fP specifies that the stream is guaranteed to be accessed
+by only one thread at a time. The bit flag \f5SF_MTSAFE\fP is left off.
+The absence of option \f5m\fP is the same as the presence of option \f5u\fP.
+
+.Ss " Sfio_t* sfpopen(Sfio_t* f, const char* cmd, const char* mode)"
+This function opens a stream that corresponds to the coprocess \f5cmd\fP.
+The argument \f5mode\fP should be composed from \f5r\fP, \f5w\fP, and \f5+\fP.
+The argument \f5f\fP, if not \f5NULL\fP, is a stream to be renewed (see \f5sfnew()\fP).
+\f5sfpopen()\fP returns the new stream or \f5NULL\fP on error.
+
+The standard input/output of \f5cmd\fP
+is connected to the application via a pipe if the stream is opened for writing/reading.
+If the stream is opened for both reading and writing,
+there will be two different associated file descriptors, one for each type of I/O
+(note the effect on \f5sffileno()\fP).
+
+On opening a coprocess for writing (i.e., \f5mode\fP contains \f5w\fP or \f5+\fP),
+the signal handler for \f5SIGPIPE\fP in the parent application
+will be set to \f5SIG_IGN\fP if it is \f5SIG_DFL\fP at that time.
+This protects the parent application from being accidentally killed
+on writing to a coprocess that closes its reading end.
+Applications that need to detect such write errors should use
+disciplines and exception handlers (see \f5sfdisc()\fP).
+
+The command \f5cmd\fP
+is executed by an \fIinterpreter\fP which is either \f5/bin/sh\fP
+or an executable command defined by the environment variable \f5SHELL\fP.
+In either case, the interpreter is invoked with 2 arguments, respectively \f5-c\fP
+and the given command \f5cmd\fP. When the interpreter is \f5/bin/sh\fP or
+\f5/bin/ksh\fP, \f5sfpopen()\fP may execute the command \f5cmd\fP itself
+if there are no shell meta-characters in \f5cmd\fP.
+
+.Ss " Sfio_t* sftmp(size_t size)"
+This function creates a stream for temporary data.
+It returns the new stream or \f5NULL\fP on error.
+
+A stream created by \f5sftmp()\fP can be completely or partially memory-resident.
+If \f5size\fP is \f5SF_UNBOUND\fP, the stream is a pure string stream.
+If \f5size\fP is zero, the stream is a pure file stream.
+Otherwise, the stream is first created as a string stream but when
+its buffer grows larger than \f5size\fP or on any attempt to change disciplines,
+a temporary file is created.
+Two environment variables, \f5TMPPATH\fP and \f5TMPDIR\fP,
+direct where temporary files are created.
+\f5TMPPATH\fP, if defined,
+specifies a colon-separated set of directories to be
+used in a round-robin fashion to create files.
+If \f5TMPPATH\fP is undefined,
+\f5TMPDIR\fP can be used to specify a single directory to create files.
+If neither of \f5TMPPATH\fP and \f5TMPDIR\fP are defined, \f5/tmp\fP is used.
+
+.Ss " int sfclose(Sfio_t* f)"
+This function closes the stream \f5f\fP and frees its resources.
+\f5SF_STATIC\fP should be used if the stream space is to be preserved.
+If \f5f\fP is the base of a stream stack (see \f5sfstack()\fP),
+all streams on the stack are closed.
+If \f5f\fP is a \f5sfpopen\fP-stream,
+\f5sfclose()\fP waits until the associated command terminates
+and returns its exit status.
+\f5sfclose()\fP returns \f5-1\fP for failure and \f50\fP for success.
+
+\f5SF_READ|SF_SHARE\fP and \f5SF_WRITE\fP streams
+are synchronized before closing (see \f5sfsync()\fP).
+If \f5f\fP has disciplines,
+their exception handlers will be called twice.
+The first exception handler call has the \f5type\fP argument as one of
+\f5SF_CLOSING\fP or \f5SF_NEW\fP (see \f5sfdisc()\fP.)
+The latter, \f5SF_NEW\fP is used when a stream is being closed via \f5sfnew()\fP
+so that it can be renewed.
+The second call uses \f5type\fP as \f5SF_FINAL\fP
+and is done after all closing operations have succeeded but before
+the stream itself is deallocated.
+In either case, if the exception handler returns a negative value,
+\f5sfclose()\fP will immediately return this value.
+If the exception handler returns a positive value,
+\f5sfclose()\fP will immediately return a zero value.
+
+.PP
+.Ss "THREAD SAFETY"
+.PP
+The libraries \f5libsfio.a\fP and \f5libstdio.a\fP (providing binary
+compatibility to Stdio-based code) only support uni-threaded code.
+Multi-threaded applications should link with
+\f5libsfio-mt.a\fP and \f5libstdio-mt.a\fP.
+When this is done, certain platforms may require additional
+thread libraries for linkage. For example, Linux, Irix and Solaris
+require \f5-lpthread\fP while HPUX requires \f5-lcma\fP.
+Aside from linkage differences, the Sfio API remains identical in all cases.
+
+Note that unlike Stdio streams which are in thread-safe mode by default.
+Sfio streams can be opened in either uni-threaded or multi-threaded mode.
+A uni-threaded stream is more efficient than a multi-threaded one.
+For example, functions such as \f5sfgetc()\fP and \f5sfputc()\fP
+remain as macro or inline functions for a uni-threaded stream while
+they will act as full function calls in a multi-threaded case.
+The three standard streams \f5sfstdin/sfstdout/sfstderr\fP
+are in multi-threaded mode by default
+(however, see \f5sfopen()\fP for how this may be changed).
+Other Sfio streams are normally opened uni-threaded unless
+the flag \f5SF_MTSAFE\fP or the option \f5m\fP were specified.
+Stdio-based code can also make a Stdio stream uni-threaded by
+using the option \f5u\fP when opening a file.
+
+.PP
+.Ss "int sfmutex(Sfio_t* f, int type)"
+This function acquires or releases a mutex
+(mutually exclusive) lock on the stream \f5f\fP.
+It can be used by a thread to serialize a sequence of I/O operations
+executed together in some critical section.
+\f5sfmutex()\fP is implicitly used by
+all Sfio operations on a stream with the flag \f5SF_MTSAFE\fP to
+protect it from concurrent accesses via multiple threads.
+\f5sfmutex()\fP returns \f50\fP on success and some non-zero value on failure.
+
+Each stream has a lock count which starts at \f50\fP.
+When the count is positive, a single thread holds the stream.
+Only this thread can further lock or unlock the stream.
+A different thread attempting to acquire such a locked stream will suspend
+until the lock count returns to \f50\fP.
+Each successful locking operation increases the lock count
+while each successful unlocking operation decreases it,
+thus, allowing nesting of matching lock/unlock operations.
+
+The \f5type\fP argument of \f5sfmutex()\fP takes on the below values:
+.Tp
+\f5SFMTX_LOCK\fP:
+Locking a stream if it is unlocked or increasing the lock count of the stream
+if it is already locked by the same thread. This call will block until it is
+possible to lock the stream.
+.Tp
+\f5SFMTX_TRYLOCK\fP:
+This is the non-blocking version of \f5SFMTX_LOCK\fP.
+If the stream is already locked by a different thread, \f5sfmutex()\fP will
+immediately return with an error status.
+.Tp
+\f5SFMTX_UNLOCK\fP:
+Decreasing the lock count and releasing the stream when the lock count reaches 0.
+An attempt to unlock a stream without a previously successful lock may
+result in undefined behavior in certain implementations.
+The current Sfio implementation returns an error status.
+.Tp
+\f5SFMTX_CLRLOCK\fP:
+Resetting the lock count to \f50\fP and releasing the stream.
+As with \f5SFMTX_LOCK\fP,
+an attempt to clear the lock count without a previously successful lock
+may result in undefined behavior.
+.PP
+.Ss "INPUT/OUPUT OPERATIONS"
+.PP
+.Ss " int sfgetc(Sfio_t* f)"
+.Ss " int sfputc(Sfio_t* f, int c)"
+These functions read/write a byte from/to stream \f5f\fP.
+\f5sfgetc()\fP returns the byte read or \f5-1\fP on error.
+\f5sfputc()\fP returns \f5c\fP on success and \f5-1\fP on error.
+
+.Ss " ssize_t sfnputc(Sfio_t* f, int c, size_t n)"
+This function attempts to write the byte \f5c\fP to \f5f\fP \f5n\fP times.
+It returns the number of bytes actually written or \f5-1\fP on failure.
+
+.Ss " int sfungetc(Sfio_t* f, int c)"
+This function pushes the byte \f5c\fP back into \f5f\fP.
+If \f5c\fP matches the byte immediately before the current position in buffered data,
+the current position is simply backed up (note the effect on \f5sftell()\fP and
+\f5sfseek()\fP). There is no theoretical limit on the number of bytes that
+can be pushed back into a stream. Pushed back bytes not part of
+buffered data will be discarded on any operation that implies
+buffer synchronization.
+\f5sfungetc()\fP returns \f5c\fP on success and \f5-1\fP on failure.
+
+.Ss " Sfulong_t sfgetm(Sfio_t* f, Sfulong_t max)"
+.Ss " int sfputm(Sfio_t* f, Sfulong_t v, Sfulong_t max)"
+These functions read and write \f5Sfulong_t\fP values
+encoded in a portable format given that the values are at most \f5max\fP.
+Portability across a write architecture and a read architecture
+requires that the bit order in a byte is the same on both architectures and
+the written value is storable in an \f5Sfulong_t\fP on the read architecture.
+\f5sfgetm()\fP returns the value read or \f5-1\fP on error.
+\f5sfputm()\fP returns the number of bytes written or \f5-1\fP on error.
+
+.Ss " Sfulong_t sfgetu(Sfio_t* f)"
+.Ss " int sfputu(Sfio_t* f, Sfulong_t v)"
+These functions read and write \f5Sfulong_t\fP values
+in a compact variable-length portable format.
+Portability across a write architecture and a read architecture
+requires that the bit order in a byte is the same on both architectures and
+the written value is storable in an \f5Sfulong_t\fP on the read architecture.
+\f5sfgetu()\fP returns the value read or \f5-1\fP on error.
+\f5sfputu()\fP returns the number of bytes written or \f5-1\fP on error.
+See also \f5sfulen()\fP.
+
+.Ss " Sflong_t sfgetl(Sfio_t* f)"
+.Ss " int sfputl(Sfio_t* f, Sflong_t v)"
+These functions are similar to \f5sfgetu()\fP and \f5sfputu()\fP
+but for reading and writing (signed) \f5Sflong_t\fP values.
+See also \f5sfllen()\fP.
+
+.Ss " Sfdouble_t sfgetd(Sfio_t* f)"
+.Ss " int sfputd(Sfio_t* f, Sfdouble_t v)"
+These functions read and write \f5Sfdouble_t\fP values.
+In this case, portability depends on the input and output architectures
+having the same floating point value representation.
+Values are coded and decoded using \f5ldexp(3)\fP and \f5frexp(3)\fP
+so they are constrained to the sizes supported by these functions.
+See also \f5sfdlen()\fP.
+
+.Ss " char* sfgetr(Sfio_t* f, int rsc, int type)"
+This function reads a record of data ending in the record separator \f5rsc\fP.
+After \f5sfgetr()\fP returns, the length of the record even if it is incomplete
+can be retrieved with \f5sfvalue()\fP.
+\f5sfgetr()\fP returns the record on success and \f5NULL\fP on error.
+See also \f5sfmaxr()\fP for limiting the amount of data read to construct a record.
+
+The \f5type\fP argument is composed of some subset of the below bit flags:
+.Tp
+\f5SF_STRING\fP:
+A null byte will replace the record separator to make the record into a C string.
+Otherwise, the record separator is left alone.
+.Tp
+\f5SF_LOCKR\fP:
+Upon successfully obtaining a record \f5r\fP,
+the stream will be locked from further access until it is released with
+a call \f5sfread(f,r,0)\fP.
+.Tp
+\f5SF_LASTR\fP:
+This should be used only after a failed \f5sfgetr()\fP to retrieve
+the last incomplete record. In this case, \f5rsc\fP is ignored.
+
+.Ss " ssize_t sfputr(Sfio_t* f, const char* s, int rsc)"
+This function writes the null-terminated string \f5s\fP to \f5f\fP.
+If \f5rsc\fP is non-negative, \f5(unsigned char)rsc\fP is output after the string.
+\f5sfputr()\fP returns the number of bytes written or \f5-1\fP on failure.
+
+.Ss " Sfoff_t sfmove(Sfio_t* fr, Sfio_t* fw, Sfoff_t n, int rsc)"
+This function moves objects
+from input stream \f5fr\fP to output stream \f5fw\fP.
+\f5sfmove()\fP returns the number of objects moved or \f5-1\fP on failure.
+
+An object can be either a byte if the record separator argument
+\f5rsc\fP is negative or a record of \f5rsc\fP is non-negative.
+In the latter case, a record is incomplete if it does not end in \f5rsc\fP.
+Generally speaking, a stream can have at most one incomplete record.
+If \f5n\fP is negative, all complete objects of \f5fr\fP will be moved.
+Otherwise, \f5n\fP indicates the number of objects to move.
+If either \f5fr\fP or \f5fw\fP is \f5NULL\fP, it acts
+as if it is a stream corresponding to \f5/dev/null\fP,
+the UNIX device that has no read data and throws away any write data.
+For example, the call \f5sfmove(f,(Sfio_t*)0,(Sfoff_t)(-1),'\en')\fP
+counts the number of complete lines in stream \f5f\fP.
+
+.Ss " ssize_t sfread(Sfio_t* f, Void_t* buf, size_t n)"
+This function reads up to \f5n\fP bytes from \f5f\fP into buffer \f5buf\fP.
+It returns the number of bytes actually read or \f5-1\fP on error.
+
+.Ss " ssize_t sfwrite(Sfio_t* f, const Void_t* buf, size_t n)"
+This function writes \f5n\fP bytes from \f5buf\fP to \f5f\fP.
+If \f5f\fP is \f5SF_STRING\fP, and the buffer is not large enough,
+an \f5SF_WRITE\fP exception shall be raised.
+\f5sfwrite()\fP returns the number of bytes written or \f5-1\fP on failure.
+
+.Ss " Sfoff_t sfseek(Sfio_t* f, Sfoff_t offset, int type)"
+This function sets a new I/O position for \f5f\fP.
+It returns the new position or \f5-1\fP on failure.
+
+If the stream is a \f5SF_STRING\fP stream and the new
+address is beyond the current buffer extent,
+an \f5SF_SEEK\fP exception will be raised (see \f5sfdisc()\fP).
+
+The new position is determined based on \f5offset\fP and
+\f5type\fP which is composed from the bit flags:
+.Tp
+\f50\fP or \f5SEEK_SET\fP:
+\f5offset\fP is the desired position.
+.Tp
+\f51\fP or \f5SEEK_CUR\fP:
+\f5offset\fP is relative to the current position (see \f5SF_PUBLIC\fP below).
+.Tp
+\f52\fP or \f5SEEK_END\fP:
+\f5offset\fP is relative to the physical end of file.
+.Tp
+\f5SF_SHARE\fP:
+The stream is treated as if it has the control bit \f5SF_SHARE\fP on.
+This implies that a system call seek will be done to ensure that the
+location seeking to is valid.
+.Tp
+\f5SF_PUBLIC\fP:
+The stream is treated as if it has the control bit \f5SF_PUBLIC\fP on.
+If the physical file position has changed from its last known location,
+the current position is taken as the new physical position.
+Otherwise, the current position is the logical stream position.
+
+.Ss " Void_t* sfreserve(Sfio_t* f, ssize_t n, int type)"
+This function reserves a data block from the stream \f5f\fP.
+It returns the reserved data block on success and \f5NULL\fP on failure.
+
+If \f5f\fP is a \f5SF_READ\fP stream, the data block is a segment of input data.
+If \f5f\fP is a \f5SF_WRITE\fP stream, the data block is a buffer
+suitable for writing output data.
+For consistency, if \f5f\fP is opened with \f5SF_READ|SF_WRITE\fP,
+it will normally be treated as if it is a \f5SF_READ\fP stream
+(see \f5sfset()\fP for forcing a particular mode) but the returned
+buffer can also be written into (more below).
+However, it is possible to bias to \f5SF_WRITE\fP when the \f5type\fP
+argument is non-negative by adding the \f5SF_WRITE\fP bit \f5type\fP.
+In any case, a reserved data block is guaranteed to be valid only until
+a future access to the stream \f5f\fP.
+
+When \f5f\fP is \f5SF_READ\fP, \f5SF_SHARE\fP and unseekable,
+\f5sfreserve()\fP will attempt to peek at input data without
+consuming it. This enables separate processes to share in reading
+input from unseekable file descriptors (e.g., pipes or devices).
+However, this use of \f5sfreserve()\fP may fail
+on certain platforms that do not properly support
+peeking on unseekable file descriptors.
+
+After a \f5sfreserve()\fP call, whether or not it succeeds,
+\f5sfvalue(f)\fP gives the size of the available data block.
+Any partially reserved data block after a failed \f5sfreserve()\fP
+call can be obtained in another \f5sfreserve()\fP call with the argument
+\f5type\fP being \f5SF_LASTR\fP. The second argument \f5n\fP
+to \f5sfreserve()\fP will be ignored in this case.
+
+A \f5sfreserve()\fP call is successful if it can obtain a data block
+of size at least the absolute value of \f5n\fP.
+For a \f5SF_READ\fP atream, the argument \f5n\fP is treated as follows:
+.Tp
+\f5n < 0\fP:
+\f5sfreserve()\fP attempts to get \fIat least\fP \f5|n|\fP bytes
+into the buffer.
+.Tp
+\f5n == 0\fP:
+If the argument \f5type\fP is \f50\fP,
+\f5sfreserve()\fP attempts to get \fIat least\fP \f51\fP byte into the buffer
+but does not consume it (as consistent with \f5n == 0\fP).
+If \f5type != 0\fP, no attempt will be made to read data into the buffer.
+For example, the call \f5sfreserve(f, 0, -1)\fP only returns the buffer status,
+i.e., size of existing buffered data and pointer to such data, if any.
+The call \f5sfreserve(f, 0, SF_LOCKR)\fP is similar but also locks the stream.
+.Tp
+\f5n > 0\fP:
+\f5sfreserve()\fP will use attempt to get \fIat most\fP \f5n\fP bytes into
+the buffer. Further, if \f5type == \f5SF_LOCKR\fP (see below), read attempts
+end on a positive amount.
+
+For a successful reservation, the argument \f5type\fP dictates treatment
+as follows:
+.Tp
+\f5type == SF_LASTR\fP:
+After a \f5sfreserve()\fP call with \f5type != SF_LOCKR\fP fails,
+there may be some left over data not accessible via conventional Sfio calls.
+Immediately after such a failed call,
+another call to \f5sfreserve\fP with \f5type == SF_LASTR\fP will return any left over
+data and also advance the stream I/O position by the amount of returned data.
+.Tp
+\f5type < 0\fP:
+If \f5n > 0\fP, the stream I/O position is advanced by \f5n\fP.
+If \f5n < 0\fP, the stream I/O position is advanced by the amount
+of available data.
+For example, a successful \f5sfreserve(f, -1, -1)\fP call will return a
+buffer of data and simultanously advance the stream I/O position by the amount
+indicated by \f5sfvalue(f)\fP.
+.Tp
+\f5type == SF_LOCKR\fP:
+The stream I/O position remains unchanged.
+In addition, \f5f\fP will be locked from further access.
+As appropriate to the stream type (\f5SF_READ\fP, \f5SF_WRITE\fP or both),
+\f5f\fP can be unlocked later
+with one of \f5sfread(f,rsrv,size)\fP or \f5sfwrite(f,rsrv,size)\fP
+where \f5rsrv\fP is the reserved data block and \f5size\fP is the amount of
+data to be consumed. For example, if \f5f\fP is a locked \f5SF_READ\fP stream,
+the call \f5sfread(f,rsrv,1)\fP will reopen the stream and simultaneously
+advance the stream I/O position by \f51\fP.
+Finally, a stream opened for both reading and writing
+can release the lock with either call (with associated operational semantics!)
+For example, the below code reads 10 bytes of data from a stream
+opened with both \f5SF_READ\fP and \f5SF_WRITE\fP, modifies the data in place,
+then rewrites the new data back to the stream:
+
+.nf
+.ft 5
+ rsrv = sfreserve(f, 10, 1);
+ for(i = 0; i < 10; ++i)
+ rsrv[i] = toupper(rsrv[i]);
+ sfwrite(f, rsrv, 10);
+.ft 1
+.fi
+
+.ne 6
+.PP
+.Ss "DATA FORMATTING"
+.PP
+Data printing and scanning are done via the
+\f5sfprintf()\fP and \f5sfscanf()\fP family of functions.
+These functions are similar to their
+ANSI-C \f5fprintf()\fP and \f5fscanf()\fP counterparts.
+However, the Sfio versions have been extended for both portability and generality.
+In particular, a notion of a formatting environment stack is introduced.
+Each formatting element on the stack
+defines a separate \fIformatting pair\fP of a format specification string,
+\f5char* format\fP (the usual second argument in the formatting
+functions), and an argument list, \f5va_list args\fP (the third argument
+in functions \f5sfvprintf()\fP and \f5sfvscanf()\fP).
+A formatting environment element may also specify extension functions
+to obtain or assign arguments and to provide new semantics for pattern processing.
+To simplify the description below, whenever we talk
+about an argument list, unless noted otherwise,
+it is understood that this means either the true
+argument list when there is no extension function or the action to be taken
+by such a function in processing arguments.
+The manipulation of the formatting environment stack is done
+via the pattern \f5!\fP discussed below.
+
+.Ss "%! and Sffmt_t"
+The pattern \f5%!\fP manipulates the formatting environment stack to
+(1) change the top environment to a new environment,
+(2) stack a new environment on top of the current top,
+or (3) pop the top environment.
+The bottom of the environment stack always contains a virtual environment with the
+original formatting pair and without any extension functions.
+
+The top environment of a stack, say \f5fe\fP, is automatically popped whenever
+its format string is completely processed.
+In this case, its event-handling function (if any) is called
+as \f5(*eventf)(f,SF_FINAL,NIL(Void_t*),fe)\fP.
+The top environment
+can also be popped by giving an argument \f5NULL\fP to \f5%!\fP
+or by returning a negative value in an extension function.
+In these cases, the event-handling function is called
+as \f5(*eventf)(f,SF_DPOP,form,fe)\fP where \f5form\fP is the remainder
+of the format string. A negative return value from the event handling function
+will prevent the environment from being popped.
+
+A formatting environment is a structure of type \f5Sffmt_t\fP
+which contains the following elements:
+
+.nf
+.ft 5
+ Sffmtext_f extf; /* extension processor */
+ Sffmtevent_f eventf; /* event handler */
+
+ char* form; /* format string to stack */
+ va_list args; /* corresponding arg list */
+
+ int fmt; /* pattern being processed */
+ ssize_t size; /* object size */
+ int flags; /* formatting control flags */
+ int width; /* width of field */
+ int precis; /* precision required */
+ int base; /* conversion base */
+
+ char* t_str; /* extfdata string */
+ int n_str; /* length of t_str */
+.ft 1
+.fi
+
+The first four elements of \f5Sffmt_t\fP must be defined by the application
+before the structure is passed to a formatting function.
+The two function fields should not be changed during processing.
+Other elements of \f5Sffmt_t\fP are set by the respective formatting function
+before it calls the extension function \f5Sffmt_t.extf\fP and, subsequently,
+can be modified by this function to redirect formatting or scanning.
+For example, consider a call from a \f5sfprintf()\fP function to process an
+unknown pattern \f5%t\fP (which we may take to mean ``time'') based on a
+formatting environment \f5fe\fP.
+\f5fe->extf\fP may reset \f5fe->fmt\fP to `\f5d\fP' upon returing
+to cause \f5sfprintf()\fP to process the value being formatted as an integer.
+
+Below are the fields of \f5Sffmt_t\fP:
+.Tp
+\f5extf\fP:
+\f5extf\fP is a function to extend scanning and formatting patterns.
+Its usage is discussed below.
+.Tp
+\f5eventf\fP:
+This is a function to process events as discussed earlier.
+.Tp
+\f5form\fP and \f5args\fP:
+This is the formatting pair of a specification string and corresponding argument list.
+When an environment \f5fe\fP is being inserted into the stack,
+if \f5fe->form\fP is \f5NULL\fP, the top environment is changed to \f5fe\fP
+and its associated extension functions
+but processing of the current formatting pair continues.
+On the other hand, if \f5fe->form\fP is not \f5NULL\fP,
+the new environment is pushed onto the stack
+so that pattern processing will start with the new formatting pair as well as
+any associated extension functions.
+During processing, whenever \f5extf\fP is called,
+\f5form\fP and \f5args\fP will be set to the current values of
+the formatting pair in use.
+.Tp
+\f5fmt\fP:
+This is set to the pattern being processed or one of '.', 'I', '('.
+.Tp
+\f5size\fP:
+This is the size of the object being processed.
+.Tp
+\f5flags\fP:
+This is a collection of bits defining the formatting flags specified for the pattern.
+The bits are:
+
+\f5SFFMT_LEFT\fP: Flag \f5-\fP in \f5sfprintf()\fP.
+
+\f5SFFMT_SIGN\fP: Flag \f5+\fP in \f5sfprintf()\fP.
+
+\f5SFFMT_BLANK\fP: Flag \fIspace\fP in \f5sfprintf()\fP.
+
+\f5SFFMT_ZERO\fP: Flag \f50\fP in \f5sfprintf()\fP.
+
+\f5SFFMT_THOUSAND\fP: Flag \f5'\fP in \f5sfprintf()\fP.
+
+\f5SFFMT_LONG\fP: Flag \f5l\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
+
+\f5SFFMT_LLONG\fP: Flag \f5ll\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
+
+\f5SFFMT_SHORT\fP: Flag \f5h\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
+
+\f5SFFMT_LDOUBLE\fP: Flag \f5L\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
+
+\f5SFFMT_IFLAG\fP: flag \f5I\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
+
+\f5SFFMT_JFLAG\fP: flag \f5j\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
+
+\f5SFFMT_CENTER\fP: flag \f5=\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
+
+\f5SFFMT_CHOP\fP: flag \f5-\fP in \fIprecis\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
+
+\f5SFFMT_ALTER\fP: Flag \f5#\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
+
+\f5SFFMT_SKIP\fP: Flag \f5*\fP in \f5sfscanf()\fP.
+
+\f5SFFMT_ARGPOS\fP: This indicates argument processing for \f5pos$\fP.
+
+\f5SFFMT_VALUE\fP: This is set by \f5fe->extf\fP
+to indicate that it is returning a value to be formatted or
+the address of an object to be assigned.
+
+.Tp
+\f5width\fP:
+This is the field width.
+.Tp
+\f5precis\fP:
+This is the precision.
+.Tp
+\f5base\fP:
+This is the conversion base.
+.Tp
+\f5t_str\fP and \f5n_str\fP:
+This is the type string and its size.
+
+.Ss " int (*Sffmtext_f)(Sfio_t* f, Void_t* v, Sffmt_t* fe)"
+This is the type of the extension function \f5fe->extf\fP to process
+patterns and arguments.
+Arguments are always processed in order and
+\f5fe->extf\fP is called exactly once per argument.
+Note that, when \f5pos$\fP (below) is not used anywhere in a format string,
+each argument is used exactly once per a corresponding pattern.
+In that case, \f5fe->extf\fP is called
+as soon as the pattern is recognized and before any scanning or formatting.
+On the other hand, when \f5pos$\fP is used in a format string,
+an argument may be used multiple times.
+In this case, all arguments shall be processed in order
+by calling \f5fe->extf\fP exactly once per argument before any pattern processing.
+This case is signified by the flag \f5SFFMT_ARGPOS\fP in \f5fe->flags\fP.
+
+In addition to the predefined formatting patterns and other application-defined
+patterns, \f5fe->extf\fP may be called with \f5fe->fmt\fP being one
+of `\f5(\fP' (left parenthesis), `\f5.\fP' (dot), and `\f5I\fP'.
+
+The left parenthesis requests a string to be used as the \f5extfdata\fP string discussed below.
+In this case, upon returning, \f5fe->extf\fP should set the \f5fe->size\fP field
+to be the length of the string or a negative value to indicate a null-terminated string.
+
+The `\f5I\fP' requests an integer to define the object size.
+
+The dot requests an integer for width, precision, base, or a separator.
+In this case, the \f5fe->size\fP field will indicate how many dots have appeared
+in the pattern specification. Note that, if the actual conversion pattern is 'c' or 's',
+the value \f5*form\fP will be one of these characters.
+.Tp
+\f5f\fP:
+This is the input/output stream in the calling formatting function.
+During a call to \f5fe->extf\fP, the stream shall be unlocked
+so that \f5fe->extf\fP can read from or write to it as appropriate.
+.Tp
+\f5v\fP:
+For both \f5sfscanf()\fP and \f5sfprintf()\fP functions,
+\f5v\fP points to a location suitable for storing any scalars or pointers.
+On return, \f5fe->extf\fP treats \f5v\fP as discussed below.
+.Tp
+\f5fe\fP:
+This is the current formatting environment.
+.PP
+The return value \f5rv\fP of \f5fe->extf\fP directs further processing.
+There are two cases.
+When \f5pos$\fP is present, a negative return value means to ignore \f5fe\fP
+in further argument processing while a non-negative return value is treated
+as the case \f5rv == 0\fP below.
+When \f5pos$\fP is not present, \f5fe->extf\fP is called per argument
+immediately before pattern processing and its return values are treated
+as below:
+.Tp
+\f5rv < 0:\fP
+The environment stack is immediately popped.
+.Tp
+\f5rv == 0:\fP
+The extension function has not consumed (in a scanning case) or
+output (in a printing case) data out of or into the given stream \f5f\fP.
+The fields \f5fmt\fP, \f5flags\fP, \f5size\fP,
+\f5width\fP, \f5precis\fP and \f5base\fP of \f5fe\fP
+shall direct further processing.
+
+For \f5sfprintf()\fP functions, if \f5fe->flags\fP
+has the bit \f5SFFMT_VALUE\fP,
+\f5fe->extf\fP should have set \f5*v\fP to the value to be processed;
+otherwise, a value should be obtained from the argument list.
+Likewise, for \f5sfscanf()\fP functions,
+\f5SFFMT_VALUE\fP means that
+\f5*v\fP should have a suitable address; otherwise,
+an address to assign value should be obtained from the argument list.
+
+When \f5pos$\fP is present,
+if \f5fe->extf\fP changes \f5fe->fmt\fP, this pattern shall be used regardless of
+the pattern defined in the format string. On the other hand, if \f5fe->fmt\fP
+is unchanged by \f5fe->extf\fP, the pattern in the format string is used.
+In any case, the effective pattern should be one of the standardly defined pattern.
+Otherwise, it shall be treated as unmatched.
+.Tp
+\f5rv > 0:\fP
+The extension function has accessed the stream \f5f\fP
+to the extent of \f5rv\fP bytes.
+Processing of the current pattern ceases except that,
+for scanning functions, if \f5fe->flags\fP does not contain
+the bit \f5SFFMT_SKIP\fP, the assignment count shall increase by 1.
+
+.Ss "void va_copy(va_list to, va_list fr)"
+This macro function portably copies the argument list \f5fr\fP to
+the argument list \f5to\fP. It should be used to set the field \f5Sffmt_t.args\fP.
+
+.Ss "long sffmtversion(Sffmt_t* fe, int type)"
+This macro function initializes
+the formatting environment \f5fe\fP with a version number if \f5type\fP is
+non-zero. Otherwise, it returns the current value of the version number of \f5fe\fP.
+This is useful for applications to find out
+when the format of the structure \f5Sffmt_t\fP changes.
+Note that the version number corresponds to the Sfio version number
+which is defined in the macro value \f5SFIO_VERSION\fP.
+
+.Ss " int sfprintf(Sfio_t* f, const char* format, ...);"
+.Ss " char* sfprints(const char* format, ...);"
+.Ss " char* sfvprints(const char* format, va_list args);"
+.Ss " ssize_t sfaprints(char** sp, const char* format, ...);"
+.Ss " ssize_t sfvaprints(char** sp, const char* format, va_list args);"
+.Ss " int sfsprintf(char* s, int n, const char* format, ...)"
+.Ss " int sfvsprintf(char* s, int n, const char* format, va_list args);"
+.Ss " int sfvprintf(Sfio_t* f, const char* format, va_list args);"
+These functions format output data.
+\f5sfprintf()\fP and \f5sfvprintf()\fP write to output stream \f5f\fP.
+\f5sfsprintf()\fP and \f5sfvsprintf()\fP write to buffer \f5s\fP
+which is of size \f5n\fP.
+\f5sfprints()\fP and \f5sfvprints()\fP construct data in some Sfio-defined buffer.
+\f5sfaprints()\fP and \f5sfvaprints()\fP are similar to \f5sfprints()\fP
+and \f5sfvprints()\fP
+but they return a string constructed via \f5malloc()\fP in \f5*sp\fP
+and expect this string to be freed by the caller when no longer needed.
+\f5sfvprintf()\fP is the underlying primitive for the other functions.
+Except for \f5sfprints()\fP and \f5sfvprints()\fP
+which return a null-terminated string or \f5NULL\fP,
+other functions return the number of output bytes or \f5-1\fP on failure.
+
+The length of string constructed by \f5sfprints()\fP, \f5sfsprintf()\fP, or
+\f5sfvsprintf()\fP can be retrieved by \f5sfslen()\fP.
+.PP
+The standard patterns are:
+\f5n, s, c, %, h, i, d, p, u, o, x, X, g, G, e, E, f\fP and \f5!\fP.
+Except for \f5!\fP which shall be described below,
+see the ANSI-C specification of \f5fprintf(3)\fP for details on the other patterns.
+Let \f5z\fP be some pattern type. A formatting pattern is defined as below:
+
+.nf
+.ft 5
+ %[pos$][flag][width][.precision[.base]][(extfdata)]z
+.ft 1
+.fi
+
+.Tp
+\f5pos$\fP:
+A pattern can specify which argument in the argument list to use.
+This is done via \f5pos$\fP where \f5pos\fP is the argument position.
+Arguments are numbered so that the first argument after \f5format\fP is at position 1.
+If \f5pos\fP is not specified, the argument following the most recently used one
+will be used.
+The pattern \f5%!\fP (see below) cannot be used subsequent to a usage of \f5pos$\fP.
+Doing so may cause unexpected behaviors.
+.Tp
+\f5flag\fP:
+The flag characters are
+\f5h\fP, \f5hh\fP, \f5l\fP, \f5ll\fP, \f5L\fP, \f5I\fP, \f5j\fP, \f5t\fP, \f5z\fP,
+\f5\-\fP, \f5+\fP, \fIspace\fP, \f50\fP, \f5'\fP, \f5=\fP and \f5#\fP.
+
+Flag \f5I\fP defines the size or type of the object being formatted.
+There are two cases: (1) \f5I\fP by itself and (2) \f5I\fP
+followed by either a decimal number or `*'.
+
+In the first case, for integer and floating point patterns,
+the object type is taken to be the largest appropriate type
+(i.e., one of \f5Sflong_t\fP, \f5Sfulong_t\fP or \f5Sfdouble_t\fP).
+For conversion specifiers \f5s\fP and \f5c\fP, the flag is ignored.
+
+In the second case, a given decimal value would define a size while
+`*' would cause the size to be obtained from the argument list.
+Then, if the conversion specifier is \f5s\fP, this size defines the
+length of the string or strings being formatted (see the discussion of \f5base\fP below).
+For integer and floating point patterns,
+the size is used to select a type from one of the below lists as
+indicated by the conversion specifier:
+
+.nf
+.ft 5
+ Sflong_t, long, int, short
+ Sfulong_t, unsigned long, unsigned int, unsigned short
+ Sfdouble_t, double, float
+.ft 1
+.fi
+
+The selection algorithm always matches types from left to right in any given list.
+Although selection is generally based on sizes in bytes,
+for compatibility with Microsoft-C, the size 64
+is matched with an appropriate type with the same number of bits, if any.
+If the given size does not match any of the listed types,
+it shall match one of \f5int\fP, \f5unsigned int\fP, and \f5double\fP
+as defined by the formatting pattern.
+
+Below are a few examples of using the \f5I\fP flag.
+The first example prints an \f5Sflong_t\fP integer.
+This example is actually not portable and
+only works on platforms where \f5sizeof(Sflong_t)\fP is 8.
+The second example shows how to that portably.
+The third example specifies printing a string of length 16.
+This length shall be used regardless of whether or not the given string
+is shorter or longer than 16.
+The last example shows the use of the pattern \f5%n\fP to assign the amount
+of data already output into a \f5short\fP integer \f5n_output\fP.
+
+.nf
+.ft 5
+ sfprintf(sfstdout,"%I8d", Sflong_obj);
+ sfprintf(sfstdout,"%I*d", sizeof(Sflong_obj), Sflong_obj);
+ sfprintf(sfstdout,"%I*s", 16, s);
+ sfprintf(sfstdout,"%d%I*n", 1001, sizeof(short), &n_output);
+.ft 1
+.fi
+
+Flags \f5h\fP, \f5l\fP, \f5j\fP and \f5L\fP are the ANSI-C conventions to
+select the types of input objects.
+For example, \f5%hd\fP indicates a \f5short int\fP,
+while \f5%ld\fP indicates a \f5long int\fP.
+
+Flag \f5hh\fP addresses the byte value types, i.e., \f5char\fP and \f5unsigned char\fP.
+
+Flags \f5z\fP, \f5t\fP and \f5j\fP address respectively
+the types \f5size_t\fP, \f5ptrdiff_t\fP and \f5Sflong_t\fP.
+
+Flags \f5ll\fP and \f5L\fP address respectively
+the largest integer and floating value types, i.e.,
+\f5Sfulong_t\fP, \f5Sflong_t\fP, and \f5Sfdouble_t\fP.
+
+Flag \f5-\fP left-justifies data within the field (otherwise, right-justification).
+
+Flag \f5+\fP means that a signed conversion will always begin with a plus or minus sign.
+
+Flag \fIspace\fP is ignored if \f5+\fP is specified; otherwise,
+it means that if the first character of a signed conversion
+is not a sign or if the result is empty, a space will be prepended.
+
+Flag \f50\fP means padding with zeros on the left.
+
+Flag \f5'\fP outputs thousands-separator used by the current locale.
+\f5setlocale(3)\fP should have been used to set the desired locale.
+
+Flag \f5=\fP centers data within the field.
+
+Flag \f5#\fP indicates an alternative format processing.
+For \f5%o\fP, the first digit is always a zero.
+For \f5%x\fP and \f5%X\fP, a non-zero result will have a prefix
+\f50x\fP or \f50X\fP. For \f5%e\fP, \f5%E\fP, \f5%f\fP, \f5%g\fP, and \f5%G\fP,
+the result always contains a decimal point. For \f5%g\fP and \f5%G\fP,
+trailing zeros will not be removed. For \f5%d\fP, \f5%i\fP and \f5%u\fP,
+the form is \fIbase#number\fP where \fIbase\fP is the conversion base
+and \fInumber\fP is represented by digits for this \fIbase\fP.
+For example, a base \f52\fP conversion with \f5%#..2d\fP for \f510\fP
+is \f52#1010\fP instead of \f51010\fP as printed with \f5%..2d\fP.
+Finally, for \f5%c\fP, bytes will be printed in the C format.
+For example, when the ASCII character set is used,
+the byte value 10 will be printed as \f5\\n\fP while 255 is printed
+as \f5\\377\fP.
+.Tp
+\f5width\fP:
+This defines the width of the printing field. A value to be printed will
+be justified and padded if necessary to fill out the field width.
+.Tp
+\f5precis\fP:
+After a first dot appears, an integral value defines a precision.
+For floating point value patterns, precision is the number of precision digits.
+For \f5%c\fP, precision defines the number of times to repeat the
+character being formatted.
+For \f5%s\fP, precision defines the maximum number of characters to output;
+-\f5precis\fP also defines the maximum number of characters to output, but
+retains the rightmost \f5precis\fP characters.
+.Tp
+\f5base\fP:
+This is defined after exactly two dots have appeared.
+
+For \f5%i\fP, \f5%d\fP, and \f5%u\fP,
+\f5base\fP should be an integer value in the inclusive range \f5[2,64]\fP
+and defines a conversion base.
+If \f5base\fP is not in this range, it is defined to be \f510\fP.
+The digits to represent numbers are:
+
+.nf
+.ft 5
+ 01234567890
+ abcdefghijklmnopqrstuvwxyz
+ ABCDEFGHIJKLMNOPQRSTUVWXYZ @_
+.ft 1
+.fi
+
+For \f5%s\fP and \f5%c\fP, \f5base\fP defines a separator.
+Then, for \f5%s\fP, the input argument is taken to be a NULL-terminated array of strings
+while, for \f5%c\fP, this is a null-terminated array of characters.
+The strings or characters will be formatted one of a time based
+on the usual width and precision rules.
+After each formatted string or character, except for the last one,
+the separator \f5base\fP is output if it is a non-zero.
+
+There are further restrictions on the syntax of \f5%s\fP and \f5%c\fP when
+a separator is defined.
+Below are the legitimate sequences for \f5%s\fP and \f5%c\fP after the second dot:
+
+.nf
+\f5 s c\fP
+\f5 *s *c\fP
+\f5 \fP\fIz\fP\f5s \fP\fIz\fP\f5c\fP
+.fi
+
+In the first case, no separator is defined so \f5base\fP is set to zero.
+In the second case, \f5base\fP is obtained from the argument list.
+In the third case, the character \fIz\fP
+must be non-alphanumeric and \f5base\fP will be set to this character.
+
+The below example shows both the call and the result
+of printing a \f5NULL\fP-terminated array
+of three strings \f5apple\fP, \f5orange\fP, and \f5grape\fP:
+
+.nf
+.ft 5
+ sfprintf(sfstdout,"|%8..:s|",list);
+ | apple: orange: grape|
+.ft 1
+.fi
+
+.Tp
+\f5(extfdata)\fP:
+This defines a string \f5extfdata\fP
+to be passed to the extension function \f5Sffmt_t.extf\fP.
+Parentheses shall be balanced.
+If \f5extfdata\fP is \f5*\fP, the string is obtained from the argument list.
+
+.PP
+.Ss " int sfscanf(Sfio_t* f, const char* format, ...)"
+.Ss " int sfsscanf(const char* s, const char* format, ...)"
+.Ss " int sfvsscanf(const char* s, const char* format, va_list args)"
+.Ss " int sfvscanf(Sfio_t* f, const char* format, va_list args)"
+These functions scan data items.
+\f5sfscanf()\fP scans from the input stream \f5f\fP
+while \f5sfsscanf()\fP and \f5sfvsscanf()\fP
+scan from the null-terminated string \f5s\fP.
+\f5sfvscanf()\fP is the underlying primitive that performs the actual scanning.
+Item types are determined from patterns in string \f5format\fP.
+These functions return
+the number of items successfully scanned or \f5-1\fP on error.
+.PP
+A white space character (blank, tab, or new-line) in \f5format\fP
+normally matches a maximal sequence of input white space characters.
+However, if the input stream is in \f5SF_LINE\fP mode (see \f5sfset()\fP),
+a new-line character only matches white spaces up to an input new-line character.
+This is useful to avoid blocking when scanning typed inputs.
+.PP
+The standard scan patterns are:
+\f5i, d, u, o, x, X, p, n, f, e, E, g, G, c, %, s, []\fP and \f5!\fP.
+Except for \f5!\fP which shall be described below,
+see the ANSI-C specification of \f5fscanf(3)\fP for details on other patterns.
+Let \f5z\fP be some pattern type. A formatting pattern is specified as below:
+
+.nf
+.ft 5
+ %[*][pos$][width][.width.base][(extfdata)][flag]z
+.ft 1
+.fi
+
+.Tp
+\f5pos$\fP:
+A pattern can specify which argument in the argument list to use.
+This is done via \f5pos$\fP where \f5pos\fP is the argument position.
+Arguments are numbered so that the first argument after \f5format\fP is at position 1.
+If \f5pos\fP is not specified, the argument following the most recently used one
+will be used.
+The pattern \f5%!\fP (see below) cannot be used subsequent to a usage of \f5pos$\fP.
+.Tp
+\f5*:\fP
+This discards the corresponding scanned item.
+.Tp
+\f5width\fP and \f5base\fP:
+\f5width\fP defines the maximum number of bytes to scan
+and \f5base\fP defines the base of an integral value being scanned.
+The `.' (dot) notation also allows specifying a `*' (star) to obtain
+the value from the argument list. The below example specifies scanning
+4 bytes to obtain the value of an integer in base 10. At the end of scanning,
+the variable \f5v\fP should have the value \f51234\fP.
+
+.nf
+.ft 5
+ sfsscanf("12345678","%.*.*d", 4, 10, &v);
+.ft 1
+.fi
+
+.Tp
+\f5(extfdata)\fP:
+This defines a string \f5extfdata\fP
+to be passed to the extension function \f5Sffmt_t.extf\fP.
+Parentheses shall be balanced.
+If \f5extfdata\fP is \f5*\fP, the string is obtained from the argument list.
+.Tp
+\f5flag:\fP
+This is \f5#\fP, \f5I\fP, or some sequence of \f5h\fP, \f5l\fP, and \f5L\fP.
+
+Flag \f5#\fP is significant for pattern \f5%i\fP and \f5%[\fP.
+For \f5%i\fP, it means that the \f5#\fP symbol does not have its usual
+meaning in an input sequence \f5base#value\fP.
+For example, the scanning result of \f5%#i\fP on input \f52#1001\fP is \f52\fP
+and the next \f5sfgetc()\fP call will return \f5#\fP.
+For \f5%[\fP, if the next character in the input stream does not match
+the given scan set of characters, \f5#\fP causes a match to a null string
+instead of a failure.
+
+Flag \f5I\fP defines the size or type of the object being formatted.
+There are two cases: (1) \f5I\fP by itself and (2) \f5I\fP
+followed by either a decimal number or `*'.
+
+In the first case, for integer and floating point patterns,
+the object type is taken to be the largest appropriate type
+(i.e., one of \f5Sflong_t\fP, \f5Sfulong_t\fP or \f5Sfdouble_t\fP).
+For string patterns such as \f5%s\fP, the flag is ignored.
+
+In the second case, a given decimal value would define a size while
+`*' would cause the size to be obtained from the argument list.
+For string patterns such as \f5%s\fP or \f5%[\fP, this size defines the
+length of the buffer to store scanned data.
+Specifying a buffer size only limits the amount of data copied into the buffer.
+Scanned data beyond the buffer limit will be discarded.
+For integer and floating point patterns,
+the size is used to select a type from one of the below lists as
+indicated by the conversion specifier:
+
+.nf
+.ft 5
+ Sflong_t, long, int, short
+ Sfulong_t, unsigned long, unsigned int, unsigned short
+ Sfdouble_t, double, float
+.ft 1
+.fi
+
+The selection algorithm always matches types from left to right in any given list.
+Although selection is generally based on sizes in bytes,
+for compatibility with Microsoft-C, the size 64
+is matched with an appropriate type with the same number of bits, if any.
+If the given size does not match any of the listed types,
+it shall match one of \f5int\fP, \f5unsigned int\fP, and \f5double\fP
+as indicated by the formatting pattern.
+
+Below are examples of using the \f5I\fP flag.
+The first example scans a 64-bit integer.
+The second scans some floating point value
+whose size is explicitly computed and given.
+The last example scans a string into a buffer with the given size 128.
+Note that if the scanned string is longer than 127, only the first 127
+bytes shall be copied into the buffer. The rest of the scanned data
+shall be discarded.
+
+.nf
+.ft 5
+ sfscanf(sfstdin,"%I64d", &int64_obj);
+ sfscanf(sfstdin,"%I*f", sizeof(float_obj), &float_obj);
+ sfscanf(sfstdin,"%I*s", 128, buffer);
+.ft 1
+.fi
+
+Flags \f5h\fP, \f5l\fP, and \f5L\fP are the ANSI-C conventions
+for indicating the type of a scanned element.
+For example, \f5%hd\fP means scanning a \f5short int\fP.
+The flags \f5ll\fP and \f5L\fP mean respectively scanning an
+integer or a floating point value with largest size
+(i.e, \f5Sflong_t\fP or \f5Sfdouble_t\fP).
+.PP
+The \f5%i\fP, \f5%d\fP and \f5%u\fP patterns scan numbers in bases
+from \f52\fP to \f564\fP.
+\f5%i\fP scans integral values in self-describing formats.
+Except for octal, decimal and hexadecimal numbers with the usual formats,
+numbers in general bases are assumed to be of the form: \fIbase#value\fP
+where \fIbase\fP is a number in base 10 and \fIvalue\fP
+is a number in the given base.
+For example, \f52#1001\fP is the binary representation of the decimal value \f59\fP.
+If \fIbase\fP is \f536\fP or less,
+the digits for \fIvalue\fP can be any combination of \f5[0-9], [a-z], [A-Z]\fP
+where upper and lower case digits are not distinguishable.
+If \fIbase\fP is larger than \f536\fP, the set of digits is:
+
+.nf
+.ft 5
+ 0123456789
+ abcdefghijklmnopqrstuvwxyz
+ ABCDEFGHIJKLMNOPQRSTUVWXYZ @_
+.ft 1
+.fi
+
+.PP
+.Ss "BUFFERING, SYNCHRONIZATION"
+.PP
+.Ss " Void_t* sfsetbuf(Sfio_t* f, Void_t* buf, size_t size)"
+This function changes the buffering scheme for the stream \f5f\fP.
+The stream will be synchronized before any buffer modification.
+If a new buffer is successfully set and the old buffer has not been freed,
+\f5sfsetbuf()\fP returns the old buffer. Otherwise, it returns \f5NULL\fP.
+After a \f5sfsetbuf()\fP call,
+\f5sfvalue()\fP returns the size of the returned buffer.
+
+Sfio attempts to read data in blocks likely to be serviced fast by the file system.
+This means block sizes being multiples of a suitable alignment value
+(e.g., 512, 1024 or 8192). By default, the alignment value
+is computed via some internal mechanism depending on the local platform but
+it can also be explicitly set via the call \f5sfsetbuf(f, (Void_t*)f, size)\fP.
+
+In invocations of \f5sfsetbuf()\fP other than the above case,
+the \f5size\fP argument is treated as follows:
+.Tp
+\f5size == SF_UNBOUND\fP:
+Sfio will pick a suitable buffer size.
+If \f5buf\fP is \f5NULL\fP,
+Sfio will also pick a suitable buffering scheme (such as memory mapping.)
+If \f5buf\fP is not \f5NULL\fP, its actual value is ignored
+but the buffer will be allocated via \f5malloc(3)\fP.
+This can be used to avoid memory mapping.
+.Tp
+\f5size > 0\fP:
+This is the suggested size to use for buffering or memory mapping.
+If \f5buf\fP is \f5NULL\fP,
+Sfio will pick a suitable buffering scheme as discussed above.
+If \f5buf\fP is not \f5NULL\fP, then \f5buf\fP and \f5size\fP determine
+a buffer of the given size.
+.Tp
+\f5size == 0\fP:
+If \f5buf\fP is \f5NULL\fP, the stream will be unbuffered.
+If \f5buf\fP is not \f5NULL\fP,
+\f5sfsetbuf()\fP simply returns the stream buffer.
+In this case, no attempt will be made to synchronize the stream.
+
+.Ss " int sfsync(Sfio_t* f)"
+This function synchronizes the logical and physical views of stream \f5f\fP.
+It returns a negative value for failure and \f50\fP for success.
+
+For a \f5SF_WRITE\fP stream, synchronization means to write out any buffered data.
+For a seekable \f5SF_READ\fP file stream,
+the physical file position is aligned with the logical stream position and,
+if \f5SF_SHARE\fP is on, buffered data is discarded.
+If \f5f\fP is \f5NULL\fP, all streams are synchronized.
+If \f5f\fP is the base of a stream stack (see \f5sfstack()\fP),
+all stacked streams are synchronized.
+Note that a stacked stream can only be synchronized this way.
+If \f5f\fP is in a pool (see \f5sfpool()\fP) but not being the head,
+the pool head is synchronized.
+
+If \f5f\fP has flag \f5SF_IOCHECK\fP, the \f5SF_SYNC\fP event is raised
+before and after synchronization. See \f5sfdisc()\fP for details.
+
+.Ss " int sfpoll(Sfio_t** flist, int n, int timeout)"
+This function polls a set of streams to see if I/O operations
+can be performed on them without blocking.
+This is useful for multiplexing I/O over a set of streams.
+If a stream has a discipline, the exception function may be called
+before and after the stream is polled (see \f5sfdisc()\fP for details).
+After a successful \f5sfpoll()\fP call,
+for each ready stream \f5f\fP, \f5sfvalue(f)\fP returns
+a bit combination of \f5SF_READ\fP and \f5SF_WRITE\fP to tell which I/O
+mode is available. If \f5SF_READ\fP is available, an attempt to read
+a byte will not block. If \f5SF_WRITE\fP is available,
+an attempt to flush will not block.
+\f5sfpoll()\fP returns the number of ready streams or \f5-1\fP on failure.
+.Tp
+\f5flist\fP and \f5n\fP:
+\f5flist\fP is an array of \f5n\fP streams to be polled.
+Upon return, ready streams are moved to the front
+of \f5flist\fP in the same relative order.
+.Tp
+\f5timeout\fP:
+This defines an elapse time in milliseconds
+to wait to see if any stream is ready for I/O.
+If \f5timeout\fP is negative, \f5sfpoll()\fP will block until some stream become ready.
+Note that \f5SF_STRING\fP and normal file streams never block
+and are always ready for I/O.
+If a stream with discipline is being polled and
+its readiness is as yet undetermined (e.g., empty buffer,)
+the discipline exception function will be called with \f5SF_DPOLL\fP
+before querying the operating system.
+
+.Ss " Sfio_t* sfpool(Sfio_t* f, Sfio_t* poolf, int mode)"
+This function manipulates pools of streams.
+In a pool, only one stream is at the head and can have buffered data.
+All other streams in the pool will be synchronized.
+A stream becomes head when it is used for some I/O operation.
+\f5sfpool()\fP returns \f5NULL\fP on failure.
+.Tp
+\f5f\fP and \f5poolf\fP:
+If \f5f\fP is \f5NULL\fP,
+\f5sfpool()\fP simply returns the head of the pool containing \f5poolf\fP.
+If \f5f\fP is not \f5NULL\fP and \f5poolf\fP is \f5NULL\fP,
+\f5f\fP is deleted from its pool.
+In this case, if no other stream from the same pool can become head,
+\f5sfpool()\fP will return \f5NULL\fP; otherwise, it returns some stream
+from the remainder of the pool.
+If both \f5f\fP and \f5poolf\fP are not \f5NULL\fP,
+\f5f\fP is moved from its current pool (if any)
+into the same pool with \f5poolf\fP.
+In this case, \f5poolf\fP is returned.
+.Tp
+\f5mode\fP:
+If \f5poolf\fP is already in a pool, \f5mode\fP is ignored.
+Otherwise, \f5mode\fP should be \f50\fP or \f5SF_SHARE\fP.
+A \f5SF_SHARE\fP pool contains streams with \f5SF_WRITE\fP mode.
+In addition, on change to a new head stream,
+buffered write data of the current head
+is transferred to the new head.
+
+.Ss " int sfpurge(Sfio_t* f)"
+This function discards all buffered data
+unless \f5f\fP is a \f5SF_STRING\fP stream.
+Note that if \f5f\fP is a \f5SF_READ\fP stream based on an unseekable device,
+purged data will not be recoverable.
+If \f5f\fP is a \f5sfpopen\fP-stream opened for both read and write,
+data of both the read and write pipe ends will be purged
+(see \f5sfset()\fP to selectively turn off read or write mode
+if one set of data is to be preserved.)
+After purging, if \f5f\fP has flag \f5SF_IOCHECK\fP,
+the event \f5SF_PURGE\fP is raised.
+\f5sfpurge()\fP returns \f5-1\fP for failure and \f50\fP for success.
+
+.PP
+.Ss "DISCIPLINE, EVENT-HANDLING"
+.PP
+A file stream uses the system calls \f5read(2)\fP, \f5write(2)\fP
+and \f5lseek(2)\fP to read, write and position in the underlying file.
+Disciplines enable application-defined I/O methods including exception handling and
+data pre/post-processing.
+
+.Ss " Sfdisc_t* sfdisc(Sfio_t* f, Sfdisc_t* disc)"
+Each stream has a discipline stack whose bottom is a virtual discipline
+representing the actual system calls.
+\f5sfdisc()\fP manipulates the discipline stack of stream \f5f\fP.
+\f5f\fP will be synchronized before any discipline stack manipulation.
+After a successful discipline stack manipulation,
+the stream I/O position (see \f5sfseek()\fP and \f5sftell()\fP)
+and extent (see \f5sfsize()\fP) are updated
+to reflect that defined by the top discipline.
+\f5sfdisc()\fP returns \f5NULL\fP on failure.
+
+If the value of \f5disc\fP is identical to the value of \f5f\fP,
+then the top discipline on the discipline
+stack is returned without any further action.
+An application can then use this feature of \f5sfdisc()\fP
+and the field \f5disc\fP (below) of the discipline structure
+to traverse the entire discipline stack of a stream \f5f\fP as follows:
+
+.nf
+.ft 5
+ for(disc = sfdisc(f, (Sfdisc_t*)f); disc; disc = disc->disc)
+.ft 1
+.fi
+
+If \f5disc\fP is \f5SF_POPDISC\fP or \f5(Sfdisc_t*)0\fP,
+the top element of the stack, if any, is popped and its address is returned.
+Otherwise, \f5disc\fP is pushed onto the discipline stack.
+In this case, if successful, \f5sfdisc()\fP returns
+the discipline that was pushed down.
+
+Note that a discipline can be used on only one stream at a time.
+An application should take care to allocate different discipline
+structures for use with different streams.
+A discipline structure is of the type \f5Sfdisc_t\fP which
+contains the following public fields:
+
+.nf
+.ft 5
+ Sfread_f readf;
+ Sfwrite_f writef;
+ Sfseek_f seekf;
+ Sfexcept_f exceptf;
+ Sfdisc_t* disc;
+.ft 1
+.fi
+
+.PP
+The first three fields of \f5Sfdisc_t\fP specify alternative I/O functions.
+If any of them is \f5NULL\fP, it is inherited
+from a discipline pushed earlier on the stack.
+Note that a file stream always
+has \f5read(2)\fP, \f5write(2)\fP, \f5lseek(2)\fP and \f5NIL(Sfexcept_f)\fP
+as the \fIlogical bottom discipline\fP.
+Arguments to I/O discipline functions
+have the same meaning as that of the
+functions \f5sfrd()\fP, \f5sfwr()\fP and \f5sfsk()\fP described below.
+.PP
+The exception function, \f5(*exceptf)()\fP announces exceptional events during
+I/O operations.
+It is called as \f5(*exceptf)(Sfio_t* f, int type, Void_t* value, Sfdisc_t* disc)\fP.
+Unless noted otherwise, the return value of \f5(*exceptf)()\fP is used as follows:
+.Tp
+\f5<0\fP:
+The on-going operation shall terminate.
+.Tp
+\f5>0\fP:
+If the event was raised due to an I/O error,
+the error has been repaired and the on-going operation shall continue normally.
+For some events, e.g., \f5SF_DPOLL\fP, the return value may also have
+additional meanings.
+.Tp
+\f5=0\fP:
+The on-going operation performs default actions with respect to the raised event.
+For example, on a reading error or reaching end of file, the top stream of a stack
+will be popped and closed and the on-going operation continue with the new top
+stream.
+.PP
+The argument \f5type\fP of \f5(*exceptf)()\fP
+identifies the particular exceptional event:
+.Tp
+\f5SF_LOCKED\fP:
+The stream cannot be accessed.
+Note that this lock state is not related to the mutex lock
+that protects a stream from multiple accesses by different threads
+(see section THREAD SAFETY). Rather, the stream was frozen by
+certain operations such as \f5sfreserve()\fP or \f5sfstack()\fP.
+Thus, a stream can be in this state even if the application is uni-threaded.
+.Tp
+\f5SF_READ\fP, \f5SF_WRITE\fP:
+These events are raised around reading and writing operations.
+
+If \f5SF_IOCHECK\fP is on, \f5SF_READ\fP and \f5SF_WRITE\fP
+are raised immediately before \f5read(2) and write(2)\fP calls.
+In this case, \f5*((ssize_t*)value)\fP is the amount of data to be processed.
+The return value of \f5(*exceptf)()\fP, if negative,
+indicates that the stream is not ready for I/O
+and the calling operation will abort with failure.
+If it is positive, the stream is ready for I/O
+but the amount should be restricted to the amount specified by this value.
+If the return value is zero, the I/O operation is carried out normally.
+
+\f5SF_READ\fP and \f5SF_WRITE\fP are also raised on operation failures.
+In such a case, \f5*((ssize_t*)value)\fP
+is the return value from the failed operation.
+.Tp
+\f5SF_SEEK\fP:
+This event is raised when a seek operation fails.
+.Tp
+\f5SF_NEW\fP, \f5SF_CLOSING\fP (\f5SF_CLOSE\fP), \f5SF_FINAL\fP:
+These events are raised during a stream closing.
+\f5SF_NEW\fP is raised for a stream about to be closed to be renewed (see \f5sfnew()\fP).
+\f5SF_CLOSING\fP is raised for a stream about to be closed.
+\f5SF_FINAL\fP is raised after a stream has been closed and before
+its space is to be destroyed (see \f5sfclose()\fP).
+For these events, a non-zero return value from \f5(*exceptf)()\fP causes
+\f5sfclose()\fP to return immediately with the same value.
+.Tp
+\f5SF_DPUSH\fP, \f5SF_DPOP\fP, \f5SF_DBUFFER\fP:
+Events \f5SF_DPUSH\fP and \f5SF_DPOP\fP are raised when a
+discipline is about to be pushed or popped.
+\f5(Sfdisc_t*)value\fP is the to-be top discipline, if any.
+
+A stream buffer is always synchronized before pushing or popping a discipline.
+If this synchronization fails, \f5SF_DBUFFER\fP will be raised with
+\f5*((size_t*)value)\fP being the amount of data still in the buffer.
+If the return value of \f5exceptf\fP is non-negative,
+the push or pop operation will continue normally;
+otherwise, \f5sfdisc()\fP returns failure.
+.Tp
+\f5SF_DPOLL\fP:
+This event is raised by
+\f5sfpoll()\fP to see if the stream is ready for I/O.
+\f5*((int*)value)\fP indicates a time-out interval to wait.
+A negative return value from the exception function means blocking.
+A zero return value means that \f5sfpoll()\fP should
+query the underlying file descriptor.
+A positive return value means non-blocking. In addition,
+this value will be a bit combination of \f5SF_READ\fP and \f5SF_WRITE\fP
+to indicate what I/O modes are ready.
+.Tp
+\f5SF_READY\fP:
+This event is raised by \f5sfpoll()\fP for each ready stream.
+The third argument to the event handler is an integer composed with
+the two bits \f5SF_READ\fP and \f5SF_WRITE\fP to indicate which
+I/O modes are ready.
+.Tp
+\f5SF_SYNC\fP, \f5SF_PURGE\fP:
+If \f5SF_IOCHECK\fP is set,
+these events are raised respectively for a \f5sfsync()\fP or \f5sfpurge()\fP call.
+In each case, the respective event is raised once before the appropriate
+operation (synchronization or purging) with \f5((int)value)\fP being \f51\fP
+and once after with \f5((int)value)\fP being \f50\fP.
+Note that \f5sfsync()\fP is called for each
+\f5SF_WRITE\fP or \f5SF_SHARE|SF_READ\fP stream on closing.
+
+.Tp
+\f5SF_ATEXIT\fP:
+This event is raised for each open stream before the process exits.
+
+.Ss " int sfraise(Sfio_t* f, int type, Void_t* data)"
+If \f5f\fP is non-\f5NULL\fP, \f5sfraise()\fP calls all exception handlers
+of \f5f\fP with the event \f5type\fP and associated \f5data\fP.
+If an exception handler returns a non-zero value,
+\f5sfraise()\fP immediate returns the same value.
+Application-defined events should start from the value \f5SF_EVENT\fP
+so as to avoid confusion with system-defined events,
+\f5sfraise()\fP returns \f50\fP on success and \f5-1\fP on failure.
+
+If \f5f\fP is \f5NULL\fP, \f5sfraise()\fP iterates over all streams
+and raise events as described above. In this case,
+\f5sfraise()\fP returns \f50\fP on success and a negative value
+on failure. The absolute value of the return value tells how many
+streams failed on raising the given event.
+
+.Ss " ssize_t sfrd(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc)"
+.Ss " ssize_t sfwr(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc)"
+.Ss " Sfoff_t sfsk(Sfio_t* f, Sfoff_t offset, int type, Sfdisc_t* disc)"
+These functions provides safe methods for a discipline I/O function to invoke
+earlier discipline I/O functions and to properly handle exceptions.
+They should not be used in any other context.
+\f5sfrd()\fP and \f5sfwr()\fP return the number of bytes read or written.
+\f5sfsk()\fP returns the new seek position.
+On error, all three functions return a negative value which should be \f5-1\fP
+or the value returned by the exception handler.
+
+.PP
+.Ss "STREAM CONTROL"
+.PP
+.Ss " int sfresize(Sfio_t* f, Sfoff_t size)"
+This function resizes the stream \f5f\P so that its extent is \f5size\fP.
+If the stream corresponds to a file, the file size is set to \f5size\fP
+via the system call \f5ftruncate()\fP.
+When a stream is made larger, the new data space is filled with zero's.
+\f5sfresize()\fP returns \f50\fP on success and a negative value on failure.
+
+.Ss " int sfset(Sfio_t* f, int flags, int set)"
+This function sets control flags for the stream \f5f\fP.
+It returns the previous set of flags or \f50\fP on error.
+
+Settable flags are:
+\f5SF_READ\fP, \f5SF_WRITE\fP, \f5SF_IOCHECK\fP,
+\f5SF_LINE\fP, \f5SF_SHARE\fP, \f5SF_PUBLIC\fP, \f5SF_MALLOC\fP and
+\f5SF_STATIC\fP.
+Note that \f5SF_READ\fP and \f5SF_WRITE\fP can be turned on or off only
+if the stream was opened as \f5SF_READ|SF_WRITE\fP.
+Turning off one of them means that the stream is to be treated exclusively
+in the other mode. It is not possible to turn off both.
+If legal, an attempt to turn on either \f5SF_READ\fP or \f5SF_WRITE\fP
+will cause the stream to be in the given I/O mode.
+.Tp
+\f5set == 0:\fP
+If \f5flags\fP is zero, the current set of flags is simply returned.
+Note that when a stream is first opened, not
+all of its flags are initialized yet (more below). If \f5flags\fP is
+non-zero, an attempt is made to turn off the specified flags.
+.Tp
+\f5set != 0:\fP
+If \f5flags\fP is zero, the stream is initialized if not yet done so.
+Then the current set of flags is returned.
+If \f5flags\fP is non-zero, an attempt is made to turn on the
+specified flags.
+
+.Ss " int sfsetfd(Sfio_t* f, int fd)"
+This function changes the file descriptor of \f5f\fP.
+Before a change is realized,
+\f5(*notify)(f,SF_SETFD,newfd)\fP (see \f5sfnotify()\fP) is called.
+\f5sfsetfd()\fP returns \f5-1\fP on failure and the new file descriptor on success.
+.Tp
+\f5fd >= 0\fP:
+If the current file descriptor is non-negative,
+it will be changed using \f5dup(3)\fP to a value larger or equal to \f5fd\fP.
+Upon a successful change, the previous file descriptor will be closed.
+If the current file descriptor is negative, it will be set to \f5fd\fP and
+the stream will be reinitialized.
+.Tp
+\f5fd < 0\fP:
+The stream is synchronized (see \f5sfsync()\fP) and its
+file descriptor will be set to this value.
+Then, except for \f5sfclose()\fP, the stream will be inaccessible
+until a future \f5sfsetfd()\fP call resets the file descriptor to a non-negative value.
+Thus, \f5sfsetfd(f,-1)\fP can be used to avoid closing the file descriptor
+of \f5f\fP when \f5f\fP is closed.
+
+.Ss " Sfio_t* sfstack(Sfio_t* base, Sfio_t* top)"
+This function stacks or unstacks stream.
+Every stream stack is identified by a base stream
+via which all I/O operations are performed.
+However, an I/O operation always takes effect on the top stream.
+If the top stream reaches the end of file or
+has an unrecoverable error condition,
+it is automatically popped and closed
+(see also \f5sfdisc()\fP for alternative handling of these conditions).
+.Tp
+\f5base\fP:
+This is the base stream of the stack.
+If it is \f5NULL\fP, \f5sfstack()\fP does nothing and returns \f5top\fP.
+.Tp
+\f5top\fP:
+If this is \f5SF_POPSTACK\fP or \f5(Sfio_t*)0\fP,
+the stack is popped and \f5sfstack()\fP returns the popped stream.
+Otherwise, \f5top\fP is pushed on top of the stack identified by \f5base\fP
+and \f5sfstack()\fP returns the \f5base\fP stream.
+
+.Ss " Sfio_t* sfswap(Sfio_t* f1, Sfio_t* f2)"
+This function swaps contents of \f5f1\fP and \f5f2\fP.
+This fails if either stream is in a stream stack but not being a base stream.
+If \f5f2\fP is \f5NULL\fP, a new stream is constructed as a duplicate of \f5f1\fP.
+\f5sfswap()\fP returns \f5f2\fP or \f5f1\fP duplicate on success and
+\f5NULL\fP on failure.
+
+.PP
+.Ss "STREAM INFORMATION"
+.PP
+.Ss " Sfoff_t sfsize(Sfio_t* f)"
+This function returns the size of stream \f5f\fP (see \f5sfnew()\fP).
+If \f5f\fP is not seekable or if its size is not determinable,
+\f5sfsize()\fP returns \f5-1\fP.
+
+.Ss " Sfoff_t sftell(Sfio_t* f)"
+This function returns the current I/O position in stream \f5f\fP.
+Note that if \f5f\fP is \f5SF_APPEND\fP
+and a writing operation was just performed,
+the current I/O position is at the physical end of file.
+If \f5f\fP is unseekable, \f5sftell\fP returns the number of bytes
+read from or written to \f5f\fP.
+See also \f5sfungetc()\fP.
+
+.Ss " ssize_t sfvalue(Sfio_t* f)"
+This function returns the string or buffer length
+for \f5sfreserve()\fP, \f5sfsetbuf()\fP, and \f5sfgetr()\fP.
+
+.Ss " int sffileno(Sfio_t* f)"
+This function returns the file descriptor of stream \f5f\fP.
+
+.Ss " int sfstacked(Sfio_t* f)"
+This function returns a non-zero value
+if stream \f5f\fP has been stacked.
+
+.Ss " int sfeof(Sfio_t* f)"
+.Ss " int sferror(Sfio_t* f)"
+.Ss " int sfclrerr(Sfio_t* f)"
+\f5sfeof()\fP tells whether or not the stream has an end-of-file condition.
+\f5sferror()\fP tells whether or not the stream has an error condition.
+\f5sfclrerr()\fP clears both end-of-file and error conditions.
+The end-of-file and error conditions are also cleared on an I/O operation.
+
+.Ss " int sfclrlock(Sfio_t* f)"
+This function restores the stream back to a normal state.
+This means clearing locks and possibly throwing away unprocessed data.
+As such, this operation is unsafe and should be used with care.
+For example, it may be used before a long jump (\f5longjmp(3)\fP)
+out of some discipline I/O function to restore the internal stream states.
+\f5sfclrlock()\fP returns the current set of flags.
+
+.Ss " int sfnotify((void(*)notify)(Sfio_t*, int, void*) )"
+This sets a function \f5(*notify)()\fP to be called
+as \f5(*notify)(f, type, data)\fP on various stream events.
+Arguments \f5type\fP and \f5data\fP indicate the reason for the call and accompanying data:
+.Tp
+\f5SF_NEW\fP:
+\f5f\fP is being opened and \f5data\fP is the underlying file descriptor.
+.Tp
+\f5SF_CLOSING\fP (\f5SF_CLOSE\fP):
+\f5f\fP is the stream being closed and \f5data\fP is the underlying file descriptor.
+.Tp
+\f5SF_SETFD\fP:
+The file descriptor of \f5f\fP is being changed to the one
+defined by \f5data\fP (see \f5sfsetfd()\fP.)
+.Tp
+\f5SF_READ\fP:
+An attempt to change \f5f\fP to read mode failed.
+\f5data\fP is the file descriptor of the stream.
+.Tp
+\f5SF_WRITE\fP:
+An attempt to change \f5f\fP to write mode failed.
+\f5data\fP is the file descriptor of the stream.
+.Tp
+\f5SF_MTACCESS\fP:
+When a notifying function was registered (see \f5sfnotify()\fP),
+every Sfio call on a stream with flag \f5SF_MTSAFE\fP will
+invoke the notifying function
+once on entry after the stream is locked
+as \f5(*notify)(f, SF_MTACCESS, Sfio_t** fp), and
+once on return before unlocking as
+as \f5(*notify)(f, SF_MTACCESS, (Sfio_t**)0).
+In the call entry case,
+the notification function could use the argument \f5fp\fP
+to set a stream that would be used for performing the actual I/O operation.
+In this way, certain global streams such as the standard streams \f5sfstdin\fP,
+\f5sfstdout\fP and \f5sfstderr\fP could be made to act differently when used
+in different streams.
+
+.Ss " int sfwalk(Sfwalk_f walkf, Void_t* data, int type)"
+This function invokes \f5(*walkf)(f, data)\fP on every open stream \f5f\fP
+whose flags as defined by \f5sfset()\fP contains all bit flags given in \f5type\fP.
+On such a call, if the return value is negative, \f5sfwalk()\fP will terminate.
+\f5sfwalk()\fP returns 0 if no stream was processed.
+Otherwise, it returns the return value from the last invocation of \f5walkf()\fP.
+
+As an example, the call \f5sfwalk(walkf, data, SF_READ)\fP will iterate over all streams
+opened for reading. Similarly, \f5sfwalk(walkf, data, SF_READ|SF_WRITE)\fP
+iterates over all streams opened for both reading and writing.
+Lastly, \f5sfwalk(walkf, data, 0)\fP iterates over all streams.
+
+.PP
+.Ss "MISCELLANEOUS FUNCTIONS"
+.PP
+.Ss " ssize_t sfmaxr(ssize_t maxr, int set)"
+Certain records may require too much memory for storage, thus, causing
+undesirable side effects. Therefore, the library normally bounds the amount
+of memory used by \f5sfgetr()\fP. A different memory bound
+can be set via \f5sfmaxr()\fP. While a positive \f5maxr\fP hints to \f5sfgetr()\fP
+to use only about that much memory to construct a record, a non-positive bound
+allows \f5sfgetr()\fP to use as much memory as necessary.
+\f5sfmaxr()\fP sets the value only if \f5set\fP is non-zero.
+It returns the value before setting or the current value if not setting.
+
+.Ss " ssize_t sfslen()"
+This function returns the length of a string just constructed
+by \f5sfsprintf()\fP or \f5sfprints()\fP. See also \f5sfvalue()\fP.
+
+.Ss " int sfulen(Sfulong_t v)"
+.Ss " int sfllen(Sflong_t v)"
+.Ss " int sfdlen(Sfdouble_t v)"
+These functions return respectively the number of bytes required to code the
+\f5Sfulong_t\fP, \f5Sflong_t\fP or \f5Sfdouble_t\fP value \f5v\fP by \f5sfputu()\fP,
+\f5sfputl()\fP or \f5sfputd()\fP.
+
+.Ss " ssize_t sfpkrd(int fd, char* buf, size_t n, int rsc, long tm, int action)"
+This function acts directly on the file descriptor \f5fd\fP.
+It does a combination of peeking on incoming data and a time-out read.
+Upon success, it returns the number of bytes received.
+A return value of \f50\fP means that the end-of-file condition has been detected.
+A negative value represents an error.
+.Tp
+\f5buf\fP, \f5n\fP:
+These define a buffer and its size to read data into.
+.Tp
+\f5rsc\fP:
+If \f5>=0\fP, this defines a record separator.
+If the last returned byte is not the record separator, then
+the read data did not contain a complete record. Otherwise,
+it contains one or more records.
+See also \f5action\fP below.
+.Tp
+\f5tm\fP:
+If \f5>=0\fP, this defines a time interval in milliseconds to wait for incoming data.
+.Tp
+\f5action\fP:
+If \f5action > 0\fP, \f5sfpkrd()\fP will peek on incoming data but
+will not read past it. Therefore, a future \f5sfpkrd()\fP or \f5read(2)\fP will see
+the same data again.
+If \f5action <= 0\fP, \f5sfpkrd()\fP will not peek and there are two cases.
+If \f5rsc < 0\fP, an attempt is made to read \f5n\fP bytes.
+If \f5rsc >= 0\fP, an attempt is made to read one record.
+
+.PP
+.Ss "FULL STRUCTURE SFIO_T"
+.PP
+.Ss " #include <sfio_t.h>"
+Most applications based on Sfio only need to include
+the header file \f5sfio.h\fP which defines an abbreviated \f5Sfio_t\fP
+structure without certain fields private to Sfio.
+However, there are times (e.g., debugging)
+when an application may require more details about the full \f5Sfio_t\fP structure.
+In such cases, the header file \f5sfio_t.h\fP can be used in place of \f5sfio.h\fP.
+Note that an application doing this will become sensitive to changes
+in the internal architecture of Sfio.
+
+.Ss " #define SFNEW(buf,size,file,flags,disc)"
+This macro function is defined in \f5sfio_t.h\fP for
+use in static initialization of an \f5Sfio_t\fP structure.
+It requires five arguments:
+.Tp
+\f5buf, size\fP:
+These define a buffer and its size.
+.Tp
+\f5file\fP:
+This defines the underlying file descriptor if any.
+.Tp
+\f5flags\fP:
+This is composed from bit flags described above.
+.Tp
+\f5disc\fP:
+This defines a discipline if any.
+
+.PP
+.Ss "EXAMPLE DISCIPLINES"
+.PP
+The below functions create disciplines and insert them into
+the given streams \f5f\fP. These functions return \f50\fP
+on success and \f5-1\fP on failure.
+
+.Ss "int sfdcdio(Sfio_t* f, size_t bufsize)"
+This creates a discipline that uses the direct IO feature
+available on file systems such as SGI's XFS to speed up IO.
+The argument \f5bufsize\fP suggests a buffer size to use for data transfer.
+
+.Ss "int sfdcdos(Sfio_t* f)"
+This creates a discipline to read DOS text files.
+It basically transforms pairs of \er\en to \en.
+
+.Ss "int sfdcfilter(Sfio_t* f, const char* cmd)"
+This creates a discipline that sends data from \f5f\fP
+to the given command \f5cmd\fP to process, then reads back the processed data.
+
+.Ss "int sfdcseekable(Sfio_t* f)"
+This creates a discipline that makes an unseekable reading stream seekable.
+
+.Ss "int sfdcslow(Sfio_t* f)"
+This creates a discipline that makes all Sfio operations return immediately
+on interrupts. This is useful for dealing with slow devices.
+
+.Ss "int sfdcsubstream(Sfio_t* f, Sfio_t* parent, Sfoff_t offset, Sfoff_t extent)"
+This creates a discipline that makes \f5f\fP acts as if it
+corresponds exactly to the subsection of \f5parent\fP
+starting at \f5offset\fP with size \f5extent\fP.
+
+.Ss "int sfdctee(Sfio_t* f, Sfio_t* tee)"
+This creates a discipline that copies to the stream \f5tee\fP
+any data written to \f5f\fP.
+
+.Ss "int sfdcunion(Sfio_t* f, Sfio_t** array, int n)"
+This creates a discipline that makes \f5f\fP act as if it is
+the concatenation of the \f5n\fP streams given in \f5array\fP.
+
+.Ss "int sfdclzw(Sfio_t* f)"
+This creates a discipline that would decompress data in \f5f\fP.
+The stream \f5f\fP should have data from a source compressed by
+the Unix \fBcompress\fP program.
+
+.Ss "int sfdcgzip(Sfio_t* f, int opt)"
+This creates a discipline for reading/writing data compressed by zlib.
+The argument \f5opt\fP defines the optimization level.
+
+.PP
+.Ss "STDIO-COMPATIBILITY"
+.PP
+Sfio provides compatibility functions for all various popular
+Stdio implementations at source and binary level.
+The source Stdio-compatibility interface
+provides the header file \f5stdio.h\fP that defines
+a set of macros or inlined functions to map Stdio calls to Sfio ones.
+This mapping may benignly extend or change the meaning of certain
+original Stdio operations. For example, the Sfio's version of
+\f5popen()\fP allows a coprocess to be opened for both reading and writing
+unlike the original call which only allows a coprocess to be opened for a single mode.
+Similarly, the Sfio's \f5fopen()\fP call can be used to create
+string streams in addition to file streams.
+.PP
+The standard streams \f5stdin\fP, \f5stdout\fP and \f5stderr\fP
+are mapped via \f5#define\fP to \f5sfstdin\fP, \f5sfstdout\fP and \f5sfstderr\fP.
+The latter are typically declared of the type \f5Sfio_t*\fP.
+Certain older Stdio applications require these to be declared
+as addresses of structures so that static initializations of
+the sort ``\f5FILE*\ f\ =\ stdin;\fP'' would work.
+Such applications should use the compile time flag \f5SF_FILE_STRUCT\fP
+to achieve the desired effect.
+.PP
+The binary Stdio-compatibility libraries, \f5libstdio.a\fP and \f5libstdio-mt.a\fP,
+provide complete implementations of Stdio functions suitable
+for linking applications already compiled with native header \f5stdio.h\fP.
+These functions are also slightly altered or extended
+as discussed above.
+.PP
+Below are the supported Stdio functions:
+.PP
+.nf
+.ft 5
+FILE* fopen(const char* file, const char* mode);
+FILE* freopen(const char* file, const char* mode, FILE* stream);
+FILE* fdopen(int filedesc, const char* mode);
+FILE* popen(const char* command, const char* mode);
+FILE* tmpfile();
+int fclose(FILE* stream);
+int pclose(FILE* stream);
+
+void flockfile(FILE* stream)
+int ftrylockfile(FILE* stream)
+void funlockfile(FILE* stream)
+
+void setbuf(FILE* stream, char* buf);
+int setvbuf(FILE* stream, char* buf, int mode, size_t size);
+void setbuffer(FILE* stream, char* buf, size_t size);
+int setlinebuf(FILE* stream);
+int fflush(FILE* stream);
+int fpurge(FILE* stream);
+
+int fseek(FILE* stream, long offset, int whence);
+void rewind(FILE* stream);
+int fgetpos(FILE* stream, fpos_t* pos);
+int fsetpos(FILE* stream, fpos_t* pos);
+long ftell(FILE* stream);
+
+int getc(FILE* stream);
+int fgetc(FILE* stream);
+int getchar(void);
+int ungetc(int c, FILE* stream);
+int getw(FILE* stream);
+char* gets(char* s);
+char* fgets(char* s, int n, FILE* stream);
+size_t fread(Void_t* ptr, size_t size, size_t nelt, FILE* stream);
+
+int putc(int c, FILE* stream);
+int fputc(int c, FILE* stream);
+int putchar(int c);
+int putw(int w, FILE* stream);
+int puts(const char* s, FILE* stream);
+int fputs(const char* s, FILE* stream);
+size_t fwrite(const Void_t* ptr, size_t size, size_t nelt, FILE* stream);
+
+int fscanf(FILE* stream, const char* format, ...);
+int vfscanf(FILE* stream, const char* format, va_list args);
+int _doscan(FILE* stream, const char* format, va_list args);
+int scanf(const char* format, ...);
+int vscanf(const char* format, va_list args);
+int sscanf(const char* s, const char* format, ...);
+int vsscanf(const char* s, const char* format, va_list args);
+
+int fprintf(FILE* stream, const char* format, ...);
+int vfprintf(FILE* stream, const char* format, va_list args);
+int _doprnt(FILE* stream, const char* format, va_list args);
+int printf(const char* format, ...);
+int vprintf(const char* format, va_list args);
+int sprintf(const char* s, const char* format, ...);
+int snprintf(const char* s, int n, const char* format, ...);
+int vsprintf(const char* s, const char* format, va_list args);
+int vsnprintf(const char* s, int n, const char* format, va_list args);
+
+int feof(FILE* stream);
+int ferror(FILE* stream);
+int clearerr(FILE* stream);
+.ft 1
+.fi
+
+.PP
+.Ss "RECENT CHANGES"
+.PP
+A few exception types have been added. In particular, exception handlers shall
+be raised with \f5SF_LOCKED\fP on accessing a stream frozen either by
+an ongoing operation or a previous operation (e.g., \f5sfgetr()\fP).
+Before a process exits, the event \f5SF_ATEXIT\fP is raised for each open stream.
+.PP
+A number of disciplines were added for various processing functions.
+Of interests are disciplines to use the direct I/O feature on IRIX6.2,
+read DOS text files, and decompress files compressed by Unix \fIcompress\fP.
+.PP
+Various new stream and function flags have been added. For example,
+the third argument of \f5sfgetr()\fP is now a set of bit flags and not
+just a three-value object. However, the old semantics of this argument
+of \f5sfgetr()\fP is still supported.
+.PP
+The \f5sfopen()\fP call has been extended so that sfopen(f,NULL,mode) can be
+used to changed the mode of a file stream before any I/O operations.
+This is most useful for changing the modes of the standard streams.
+.PP
+The buffering strategy has been significantly enhanced for streams
+that perform many seek operations. Also, the handling of stream and
+file positions have been better clarified so that applications that
+share file descriptors across streams and/or processes can be sure that
+the file states will be consistent.
+.PP
+The strategy for mapping between Sfio and Stdio streams in the binary
+compatibility package has been significantly enhanced for efficiency.
+For most platforms, the mapping is now constant time per look-up.
+.PP
+The \f5SF_BUFCONST\fP flag was deleted. This is largely unused anyway.
+.PP
+The library can be built for thread-safety. This is based largely on
+Posix pthread mutexes except for on UWIN where native Windows APIs
+are used.
+.PP
+The functions \f5sfgetm()\fP and \f5sfputm()\fP were added to encode
+unsigned integer values with known ranges.
+.PP
+The flag \f5SF_APPEND\fP is identical to \f5SF_APPENDWR\fP.
+However it conflicts with a different token of the same name
+defined in the system header \f5stat.h\fP of BSDI Unix systems.
+On such systems, we shall not define \f5SF_APPEND\fP and this
+symbol may be removed in a future release.
+.PP
+Similarly, the exception \f5SF_CLOSE\fP is identical to \f5SF_CLOSING\fP.
+However it conflicts with a different token of the same name
+defined in the system header \f5socket.h\fP of AIX Unix systems.
+On such systems, we shall not define \f5SF_CLOSE\fP and this
+symbol may be removed in a future release.
+.PP
+The printing and scanning functions were extended to handle multibyte characters
+and to conform to the C99 standard.
+.PP
+The function \f5sfpoll()\fP was rehauled to make it useful
+for writing servers that must commnunicate with multiple streams
+without blocking.
+.PP
+The formatting pattern \f5%c\fP for \f5sf*printf\fP was extended
+to allow the flag \f5#\fP to print unprintable character values
+using the C convention. For example, \f5%#c\fP prints the octal value 012
+as \f5\\n\fP.
+
+.SH AUTHORS
+Kiem-Phong Vo, kpv@research.att.com,
+.br
+David G. Korn, dgk@research.att.com, and
+.br
+Glenn S. Fowler, gsf@research.att.com.
diff --git a/src/lib/libast/man/sig.3 b/src/lib/libast/man/sig.3
new file mode 100644
index 0000000..db41a2b
--- /dev/null
+++ b/src/lib/libast/man/sig.3
@@ -0,0 +1,75 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH SIG 3
+.SH NAME
+sig \- signal interface routines
+.SH SYNOPSIS
+.L "#include <ast.h>"
+.L "#include <sig.h>"
+.sp
+.L "int sigunblock(int sig);"
+.L "int sigcritical(int op);"
+.SH DESCRIPTION
+.L sigunblock
+is called to
+unblocks the signal
+.L sig
+from within a handler currently servicing
+.LR sig .
+.PP
+.L sigcritical
+controls a critical region for the
+.LR SIGINT ,
+.L SIGQUIT
+and
+.L SIGHUP
+signals.
+.L "op > 0"
+pushes the region,
+.L "op == 0"
+pops the region, and
+.L "op < 0"
+returns non-zero if any signals are being held in the current
+critical region.
+Signal critical regions may be nested.
+The current critical region level is returned,
+.L \-1
+on error.
+.SH "SEE ALSO"
+signal(2)
diff --git a/src/lib/libast/man/spawnveg.3 b/src/lib/libast/man/spawnveg.3
new file mode 100644
index 0000000..3dfd424
--- /dev/null
+++ b/src/lib/libast/man/spawnveg.3
@@ -0,0 +1,97 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH SPAWNVEG 3
+.SH NAME
+spawnveg \- process spawn with process group and session control
+.SH SYNOPSIS
+.L "#include <ast.h>"
+.sp
+.L "int spawnveg(const char* command, char** argv, char** envv, pid_t pgid);"
+.SH DESCRIPTION
+.L spwanveg
+combines
+.IR fork (2),
+.IR exec (2),
+.IR setpgid (2)
+and
+.IR setsid (2)
+into a single call.
+.PP
+.LR command ,
+.L argv
+and
+.L envv
+are as in
+.IR execve (2).
+.L pgid
+controls the new process group and session:
+.TP
+.L <0
+The new process becomes a session leader.
+is called in the child context.
+.TP
+.L 0
+The new process is in the callers process group.
+.TP
+.L 1
+The new process becomes a process group leader.
+.TP
+.L >1
+The new process joins the process group
+.IR pgid .
+.SH COMMENTS
+It is possible to code all process creation (except for
+.IR vfork (2)
+hack like in
+.IR csh (1))
+using
+.LR spawnveg .
+The
+.IR proc (3)
+routines and
+.IR ksh (1)
+do this on systems that don't support
+.IR fork (2).
+This makes porting to NT and Windows a snap: a simple
+.IR iffe (1)
+probe provides a
+.L spawnveg
+implementation using the NT or Windows process primitives.
+.SH "SEE ALSO"
+fork(2), exec(2), setpgid(2), setsid(2), spawnve(2)
diff --git a/src/lib/libast/man/stak.3 b/src/lib/libast/man/stak.3
new file mode 100644
index 0000000..5feac69
--- /dev/null
+++ b/src/lib/libast/man/stak.3
@@ -0,0 +1,169 @@
+.fp 5 CW
+.TH STAK 3
+.SH NAME
+\fBstak\fR \- data stack storage library (obsolete: use \fBstk\fR instead)
+.SH SYNOPSIS
+.ta .75i 1.5i 2.25i 3i 3.75i 4.5i 5.25i 6i
+.PP
+.nf
+\f5
+#include <stak.h>
+
+Stak_t *stakcreate(int \fIflags\fP);
+Stak_t *stakinstall(Stak_t *\fIstack\fP, char *(\fIoverflow\fP)(int));
+int stakdelete(Stak_t *\fIstack\fP);
+void staklink(Stak_t *\fIstack\fP)
+
+char *stakalloc(unsigned \fIsize\fP);
+char *stakcopy(const char *\fIstring\fP);
+char *stakset(char *\fIaddress\fP, unsigned \fIoffset\fP);
+
+char *stakseek(unsigned \fIoffset\fP);
+int stakputc(int \fIc\fP);
+int stakputs(const char *\fIstring\fP);
+int stakwrite(const char *\fIaddress\fP, unsigned \fIsize\fP);
+int staktell(void);
+char *stakptr(unsigned \fIoffset\fP);
+char *stakfreeze(unsigned \fIextra\fP);
+\fR
+.fi
+.SH DESCRIPTION
+.PP
+\f5stak\fP is a package of routines designed to provide efficient
+stack oriented dynamic storage.
+A stack abstraction consists of an ordered list of contiguous
+memory regions, called stack frames, that can hold objects of
+arbitrary size.
+A stack is represented by the type \f5Stak_t\fP
+defined in header \f5<stak.h>\fP.
+At any instant there is one active stack.
+Variable size objects can be
+added to the active stack
+and programs can reference these objects directly with pointers.
+In addition, the last object on the stack
+(referred to here as the current object)
+can be built incrementally.
+The current object has an associated offset that determines its
+current size.
+While the current object is being built incrementally,
+its location might
+change so that it is necessary to reference the object with
+relative offsets ranging from zero to the current offset of the object.
+.PP
+There is a preset initial active stack.
+To use an additional stack, it is necessary to create it and to
+install it as the active stack.
+A stack is created with the \f5stakcreate\fP() function.
+A \fIflags\fP argument of \f5STAK_SMALL\fP indicates that unused
+space on the stack should be freed whenever this stack ceases
+to be the active stack.
+If successful,
+\f5stakcreate\fP() returns a pointer to a stack whose reference
+count is 1.
+Otherwise, \f5stakcreate\fP() returns a null pointer.
+The \f5staklink\fP() function increases the reference count for the
+given \fIstack\fP.
+The \f5stakinstall\fP() function
+makes the specified \fIstack\fP the active stack and returns a pointer
+to the previous active stack.
+When the \fIoverflow\fP argument is not null,
+it specifies a function that will
+be called whenever \f5malloc\fP(3) fails while trying to grow the
+stack.
+The \fIoverflow\fP function will be called with the size that was passed
+to \f5malloc\fP(3).
+The \fIoverflow\fP function can call \f5exit\fP(3), call \f5longjmp\fP(3)
+or return.
+If the \f5overflow\fP function returns,
+it must return a pointer to a memory region of the given size.
+The default action is to write an error to standard error and to
+call \f5exit\fP(2) with a non-zero exit value.
+When \fIstack\fP is a null pointer,
+the active stack is not changed
+but the \fIoverflow\fP function for the active stack can be changed
+and a pointer to the active stack is returned.
+The \f5stakdelete\fP() function decrements the reference count and
+frees the memory associated with
+the specified stack
+when the reference count is zero.
+The effect of subsequent references to objects
+on the stack are undefined.
+.PP
+The
+\f5stakalloc\fP() function returns an aligned pointer to space on the
+active stack that can be used to hold any object of the given \fIsize\fP.
+\f5stakalloc\fP() is similar to \f5malloc\fP(3) except that individual
+items returned by \f5stakalloc\fP() can not be freed.
+\f5stakalloc\fP() causes the offset of the current object to be set to
+zero.
+.PP
+The
+\f5stakcopy\fP() function copies the given string onto the stack
+and returns a pointer to the \fIstring\fP on the stack.
+\f5stakcopy\fP() causes the offset of the current object to be set to
+zero.
+.PP
+The \f5stakset\fP() function finds the frame containing the given
+\fIaddress\fP, frees all frames that were created after the one containing
+the given \fIaddress\fP, and sets the current object to the given
+\fIaddress\fP.
+The top of the current object is set to \fIoffset\fP bytes from
+current object.
+If \fIaddress\fP is not the address of an object on the
+stack the result is undefined.
+.PP
+The remaining functions are used to build the current object incrementally.
+An object that is built incrementally on the stack will
+always occupy contiguous memory within a stack frame but
+until \f5stakfreeze\fP() is called,
+the location in memory for the object can change.
+There is a current offset associated with the current object that
+determines where subsequent operations apply.
+Initially, this offset is zero, and the offset changes as a result
+of the operations you specify.
+The \f5stakseek\fP() function is used set the offset for the
+current object.
+The \fIoffset\fP argument to \f5stakseek\fP() specifies the new
+offset for the current object.
+The frame will be extended or moved
+if \f5offset\fP causes the new current offset to extend beyond the
+current frame.
+\f5stakseek\fP() returns a pointer to the beginning of the current object.
+The \f5staktell\fP() function gives the offset of the current object.
+.PP
+The \f5stakputc\fP() function adds a given character to the current object
+on the stack.
+The current offset is advanced by 1.
+The \f5stakputs\fP() function appends the given \fIstring\fP onto the current
+object in the stack and returns the length of the string.
+The current offset is advanced by the length of the string.
+The \f5stakwrite\fP() function appends the given \fIsize\fP byte memory
+region starting at \fIaddress\fP onto the current
+object in the stack and advances the current offset by \fIsize\fP.
+The current offset is returned.
+.PP
+The \f5stakptr\fP() function converts the given \f5offset\fP
+for the current object into a memory address on the stack.
+This address is only valid until another stack operation is given.
+The result is not defined if \fIoffset\fP exceeds the size of the current
+object.
+The \f5stakfreeze\fP()
+function terminates the current object on the
+stack and returns a pointer to the beginning of this object.
+If \fIextra\fP is non-zero, \fIextra\fP bytes are added to the stack
+before the current object is terminated. The first added byte will
+contain zero and the contents of the remaining bytes are undefined.
+.PP
+.SH HISTORY
+The
+\f5stak\fP
+interface was derived from similar routines in the KornShell code
+that is used for building parse trees and carrying out expansions.
+It provides an efficient mechanism for grouping dynamically allocated
+objects so that they can be freed all at once rather than individually.
+.SH AUTHOR
+ David Korn
+.SH SEE ALSO
+\f5exit(2)\fP
+\f5longjmp(3)\fP
+\f5malloc(3)\fP
diff --git a/src/lib/libast/man/stk.3 b/src/lib/libast/man/stk.3
new file mode 100644
index 0000000..3e65821
--- /dev/null
+++ b/src/lib/libast/man/stk.3
@@ -0,0 +1,165 @@
+.fp 5 CW
+.TH STK 3
+.SH NAME
+\fBstk\fR \- data stack storage library
+.SH SYNOPSIS
+.ta .75i 1.5i 2.25i 3i 3.75i 4.5i 5.25i 6i
+.PP
+.nf
+\f5
+#include <stk.h>
+
+Stk_t *stkopen(int \fIflags\fP);
+Stk_t *stkinstall(Stk_t *\fIstack\fP, char *(\fIoverflow\fP)(int));
+int stkclose(Stk_t *\fIstack\fP);
+void stklink(Stk_t *\fIstack\fP)
+
+char *stkalloc(Stk_t *\fIstack\fP, unsigned \fIsize\fP);
+char *stkcopy(Stk_t *\fIstack\fP, const char *\fIstring\fP);
+char *stkset(Stk_t *\fIstack\fP, char *\fIaddress\fP, unsigned \fIoffset\fP);
+
+char *stkseek(Stk_t *\fIstack\fP, unsigned \fIoffset\fP);
+int stktell(Stk_t *\fIstack\fP);
+char *stkptr(Stk_t *\fIstack\fP, unsigned \fIoffset\fP);
+char *stkfreeze(Stk_t *\fIstack\fP, unsigned \fIextra\fP);
+int stkon(Stk *\fIstack\fP, char* \fIaddr\fP)
+\fR
+.fi
+.SH DESCRIPTION
+.PP
+\f5stk\fP is a package of routines designed to provide efficient
+stack oriented dynamic storage.
+A stack abstraction consists of an ordered list of contiguous
+memory regions, called stack frames, that can hold objects of
+arbitrary size.
+A stack is represented by the type \f5Stk_t\fP
+defined in header \f5<stk.h>\fP.
+The type \f5Stk_t\fP is compatible with the type \f5Sfio_t\fP
+defined by the \f5sfio\fP(3) library.
+At any instant there is one active stack which can be referenced
+by the constant \f5stkstd\fP.
+Variable size objects can be
+added to the active stack
+and programs can reference these objects directly with pointers.
+In addition, the last object on the stack
+(referred to here as the current object)
+can be built incrementally.
+The current object has an associated offset that determines its
+current size.
+While the current object is being built incrementally,
+its location might
+change so that it is necessary to reference the object with
+relative offsets ranging from zero to the current offset of the object.
+.PP
+There is a preset initial active stack.
+To use an additional stack, it is necessary to create it and to
+install it as the active stack.
+A stack is created with the \f5stkopen\fP() function.
+A \fIflags\fP argument of \f5STK_SMALL\fP indicates that unused
+space on the stack should be freed whenever this stack ceases
+to be the active stack.
+If successful,
+\f5stkopen\fP() returns a pointer to a stack whose reference
+count is 1.
+Otherwise, \f5stkopen\fP() returns a null pointer.
+The \f5stklink\fP() function increases the reference count for the
+given \fIstack\fP.
+The \f5stkinstall\fP() function
+makes the specified \fIstack\fP the active stack and returns a pointer
+to the previous active stack.
+When the \fIoverflow\fP argument is not null,
+it specifies a function that will
+be called whenever \f5malloc\fP(3) fails while trying to grow the
+stack.
+The \fIoverflow\fP function will be called with the size that was passed
+to \f5malloc\fP(3).
+The \fIoverflow\fP function can call \f5exit\fP(3), call \f5longjmp\fP(3)
+or return.
+If the \f5overflow\fP function returns,
+it must return a pointer to a memory region of the given size.
+The default action is to write an error to standard error and to
+call \f5exit\fP(2) with a non-zero exit value.
+When \fIstack\fP is a null pointer,
+the active stack is not changed
+but the \fIoverflow\fP function for the active stack can be changed
+and a pointer to the active stack is returned.
+The \f5stkclose\fP() function decrements the reference count and
+frees the memory associated with
+the specified stack
+when the reference count is zero.
+The effect of subsequent references to objects
+on the stack are undefined.
+.PP
+The
+\f5stkalloc\fP() function returns an aligned pointer to space on the
+active stack that can be used to hold any object of the given \fIsize\fP.
+\f5stkalloc\fP() is similar to \f5malloc\fP(3) except that individual
+items returned by \f5stkalloc\fP() can not be freed.
+\f5stkalloc\fP() causes the offset of the current object to be set to
+zero.
+.PP
+The
+\f5stkcopy\fP() function copies the given string onto the stack
+and returns a pointer to the \fIstring\fP on the stack.
+\f5stkcopy\fP() causes the offset of the current object to be set to
+zero.
+.PP
+The \f5stkset\fP() function finds the frame containing the given
+\fIaddress\fP, frees all frames that were created after the one containing
+the given \fIaddress\fP, and sets the current object to the given
+\fIaddress\fP.
+The top of the current object is set to \fIoffset\fP bytes from
+current object.
+If \fIaddress\fP is not the address of an object on the
+stack the result is undefined.
+.PP
+The \f5sfio\fP(3) output functions can be used to build
+current object incrementally.
+An object that is built incrementally on the stack will
+always occupy contiguous memory within a stack frame but
+until \f5stkfreeze\fP() is called,
+the location in memory for the object can change.
+There is a current offset associated with the current object that
+determines where subsequent operations apply.
+Initially, this offset is zero, and the offset changes as a result
+of the operations you specify.
+The \f5stkseek\fP() function is used set the offset for the
+current object.
+The \fIoffset\fP argument to \f5stkseek\fP() specifies the new
+offset for the current object.
+The frame will be extended or moved
+if \f5offset\fP causes the new current offset to extend beyond the
+current frame.
+\f5stkseek\fP() returns a pointer to the beginning of the current object.
+The \f5stktell\fP() function gives the offset of the current object.
+.PP
+The \f5stkptr\fP() function converts the given \f5offset\fP
+for the current object into a memory address on the stack.
+This address is only valid until another stack operation is given.
+The result is not defined if \fIoffset\fP exceeds the size of the current
+object.
+The \f5stkfreeze\fP()
+function terminates the current object on the
+stack and returns a pointer to the beginning of this object.
+If \fIextra\fP is non-zero, \fIextra\fP bytes are added to the stack
+before the current object is terminated. The first added byte will
+contain zero and the contents of the remaining bytes are undefined.
+.PP
+The \f5stkon\fP()
+function returns non-zero if the address given by \fIaddr\fP is
+on the stack \fIstack\fP and \f50\fP otherwise.
+.PP
+.SH HISTORY
+The
+\f5stk\fP
+interface was derived from similar routines in the KornShell code
+that is used for building parse trees and carrying out expansions.
+It provides an efficient mechanism for grouping dynamically allocated
+objects so that they can be freed all at once rather than individually.
+.SH AUTHOR
+ David Korn
+.SH SEE ALSO
+\f5exit(2)\fP
+\f5longjmp(3)\fP
+\f5malloc(3)\fP
+\f5sfio(3)\fP
diff --git a/src/lib/libast/man/strcopy.3 b/src/lib/libast/man/strcopy.3
new file mode 100644
index 0000000..c08d885
--- /dev/null
+++ b/src/lib/libast/man/strcopy.3
@@ -0,0 +1,54 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STRCOPY 3
+.SH NAME
+strcopy \- copy strings
+.SH SYNOPSIS
+.L "char* strcopy(char* a, char* b)"
+.SH DESCRIPTION
+.I strcopy
+copies the nul-terminated string
+.I b
+into
+.IR a .
+A pointer to the 0 character in
+.I a
+is returned.
+.SH "SEE ALSO"
+strcpy(3)
diff --git a/src/lib/libast/man/strdup.3 b/src/lib/libast/man/strdup.3
new file mode 100644
index 0000000..3b26ec4
--- /dev/null
+++ b/src/lib/libast/man/strdup.3
@@ -0,0 +1,55 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STRDUP 3
+.SH NAME
+strdup \- duplicate nul-terminated string
+.SH SYNOPSIS
+.L "char* strdup(char* s)"
+.SH DESCRIPTION
+.I strdup
+copies the nul-terminated string
+.I s
+to a new location provided by
+.IR malloc (3)
+and returns a pointer to the new copy.
+0 is returned if
+.IR malloc (3)
+failed.
+.SH "SEE ALSO"
+malloc(3), memdup(3)
diff --git a/src/lib/libast/man/strelapsed.3 b/src/lib/libast/man/strelapsed.3
new file mode 100644
index 0000000..8c3fa4a
--- /dev/null
+++ b/src/lib/libast/man/strelapsed.3
@@ -0,0 +1,77 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STRELAPSED 3
+.SH NAME
+strelapsed \- parse elapsed time expression
+.SH SYNOPSIS
+.L "unsigned long strelapsed(char* buf, char** next, int persec)"
+.SH DESCRIPTION
+.I strelapsed
+returns a pointer to a string representation of the elapsed time for
+.L (count/persec)
+seconds.
+The two largest time units are used, limiting the return value length
+to at most 6 characters.
+The units are:
+.TP
+.B s
+seconds
+.TP
+.B m
+minutes
+.TP
+.B h
+hours
+.TP
+.B days
+.TP
+.B weeks
+.TP
+.B M
+months
+.TP
+.B Y
+years
+.TP
+.B S
+scores
+.SH "SEE ALSO"
+strelapsed(3)
+.SH CAVEATS
+The return value points to a static area that is overwritten on each call.
diff --git a/src/lib/libast/man/strerror.3 b/src/lib/libast/man/strerror.3
new file mode 100644
index 0000000..0084e3a
--- /dev/null
+++ b/src/lib/libast/man/strerror.3
@@ -0,0 +1,53 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STRERROR 3
+.SH NAME
+strerror \- return error message string given error number
+.SH SYNOPSIS
+.L "char* strerror(int err)"
+.SH DESCRIPTION
+.I strerror
+returns the error message string corresponding to the error message number
+.IR err .
+.BI "Error " nnn
+is returned if
+.I err
+is invalid.
+.SH "SEE ALSO"
+error(3)
diff --git a/src/lib/libast/man/stresc.3 b/src/lib/libast/man/stresc.3
new file mode 100644
index 0000000..c09a0e9
--- /dev/null
+++ b/src/lib/libast/man/stresc.3
@@ -0,0 +1,53 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STRESC 3
+.SH NAME
+stresc \- convert character constants in string
+.SH SYNOPSIS
+.L "int stresc(char* s)"
+.SH DESCRIPTION
+.I stresc
+converts
+.L \e
+character constant expressions in the nul-terminated string
+.I s
+in place and returns the length of the converted
+.IR s .
+.SH "SEE ALSO"
+chresc(3), ctoi(3)
diff --git a/src/lib/libast/man/streval.3 b/src/lib/libast/man/streval.3
new file mode 100644
index 0000000..2b491c8
--- /dev/null
+++ b/src/lib/libast/man/streval.3
@@ -0,0 +1,83 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STREVAL 3
+.SH NAME
+streval \- long integer arithmetic expression evaluator
+.SH SYNOPSIS
+.L "long streval(char* s, char** e, long (*conv)(char* cs, char** ce))"
+.SH DESCRIPTION
+.I streval
+evaluates the long integer arithmetic expression in the nul-terminated string
+.I s
+and returns the result.
+If
+.I e
+is not 0 then
+.I *e
+is set to point to the first unknown character in the expression.
+.PP
+If
+.I conv
+is not 0 then it is called when an unknown token is encountered in
+.IR s .
+.I cs
+points to the beginning of the unknown token.
+The return value is the long integer value of the unknown token and
+.I ce
+must be set to point to the first character after the unknown token.
+If an expression syntax error is encountered the
+.I conv
+is called with
+.I cs
+set to 0 and
+.I *ce
+pointing to the error message text.
+.PP
+In addition to the normal C expressions and integer constant styles,
+numbers in any base
+.I b
+<= 2 <=36
+may be represented as
+.IR b # nnnn ,
+where the extra digits in
+.I nnnn
+are taken from
+.BR [A-Z] .
+.SH "SEE ALSO"
+strtol(3)
diff --git a/src/lib/libast/man/strgid.3 b/src/lib/libast/man/strgid.3
new file mode 100644
index 0000000..d7a2663
--- /dev/null
+++ b/src/lib/libast/man/strgid.3
@@ -0,0 +1,53 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STRGID 3
+.SH NAME
+strgid \- return group name given group number
+.SH SYNOPSIS
+.L "char* strgid(int gid)"
+.SH DESCRIPTION
+.I strgid
+returns the group id name string given the group number
+.IR gid .
+.I strgid
+maintains an internal cache to avoid repeated password database scans
+by the low level
+.IR getgrgid (3).
+.SH "SEE ALSO"
+getgrent(3)
diff --git a/src/lib/libast/man/strmatch.3 b/src/lib/libast/man/strmatch.3
new file mode 100644
index 0000000..5f5af89
--- /dev/null
+++ b/src/lib/libast/man/strmatch.3
@@ -0,0 +1,101 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STRMATCH 3
+.SH NAME
+strmatch \- match shell file patterns
+.SH SYNOPSIS
+.L "int strmatch(char* s, char* p)"
+.br
+.L "char* submatch(char* s, char* p, int m)"
+.SH DESCRIPTION
+.I strmatch
+compares the string
+.I s
+with the shell pattern
+.I p
+and returns 1 for match and 0 otherwise.
+.I submatch
+does a leading substring match of the shell pattern
+.I p
+with the string
+.IR s .
+If
+.I m
+is 0 then the match is minimal, otherwise a maximal match is done.
+A pointer to the first character after the matched substring is returned,
+.I 0
+if there is no match.
+.PP
+Except for
+.I &
+and
+.IR ! ,
+each shell pattern has an equivalent
+.IR egrep (1)
+construct.
+.EX
+ \fBsh pattern egrep RE description\fP
+ * .* 0 or more chars
+ ? . any single char
+ [.] [.] char class
+ [!.] [^.] negated char class
+ *(.) (.)* 0 or more of
+ +(.) (.)+ 1 or more of
+ ?(.) (.)? 0 or 1 of
+ (.) (.) 1 of
+ @(.) (.) 1 of
+ a|b a|b a or b
+ a&b a and b
+ !(.) none of
+.EE
+.L \e
+is used to escape *, ?, (, |, &, ), [, and \e
+outside of [...].
+.SH "SEE ALSO"
+grep(1)
+.SH BUGS
+An unbalanced
+.L )
+terminates the top level pattern.
+.br
+Nested
+.L &
+and
+.L !
+constructs are non-intuitive and are computationally intensive.
diff --git a/src/lib/libast/man/stropt.3 b/src/lib/libast/man/stropt.3
new file mode 100644
index 0000000..f2a8dae
--- /dev/null
+++ b/src/lib/libast/man/stropt.3
@@ -0,0 +1,130 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STROPT 3
+.SH NAME
+stropt \- table driven option expression evaluator
+.SH SYNOPSIS
+.L "#include <namval.h>"
+.br
+.L "int stropt(char* s, struct namval* tab,
+.br
+.L " int (*fun)(void* a, struct namval* p, int n, char* v),"
+.br
+.L " void* a)"
+.SH DESCRIPTION
+.I stropt
+parses option expressions in the nul-terminated string
+.I s
+using the option names in
+.IR tab .
+.I tab
+is an array of
+.B "struct namval"
+name value pairs:
+.EX
+char* name;
+int value;
+.EE
+The last entry must be followed by a sentinel with
+.B name
+set to 0.
+.PP
+An option expression contains 0 or more of [\fBno\fP]\fIname\fP[=\fIvalue\fP]
+separate by
+.B space
+or
+.BR tab ,
+where
+.I name
+must be one of the option names in
+.IR tab ,
+.I value
+is an optional value, and
+.B no
+is for Boolean options.
+Each option is passed to
+.I fun
+for processing.
+.I a
+is the
+.L void*
+pointer that is passed from the
+.I stropt
+call but is otherwise not interpreted.
+.I p
+points to the option name value pair from
+.IR tab .
+.I n
+is 0 if
+.B no
+preceded the option
+.I name
+and
+.I v
+points to the beginning of the option
+.I value
+in
+.IR s .
+and
+If
+.I name
+is not found in
+.I tab
+then
+.I fun
+is called with
+.I p
+pointing to an internal
+.I namval
+entry with
+.I p\->name
+pointing to the unknown option and
+.I p\->value
+set to the
+.I value
+of the sentinel entry in
+.IR tab .
+.PP
+If
+.I fun
+returns non-zero then this value is returned and no further
+options are processed.
+Otherwise
+.I stropt
+returns 0 after processing all options.
diff --git a/src/lib/libast/man/strperm.3 b/src/lib/libast/man/strperm.3
new file mode 100644
index 0000000..9b68946
--- /dev/null
+++ b/src/lib/libast/man/strperm.3
@@ -0,0 +1,109 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STRPERM 3
+.SH NAME
+strperm \- evaluate file permission expression
+.SH SYNOPSIS
+.L "int strperm(char* s, char** e, int p)"
+.SH DESCRIPTION
+.I strperm
+applies a file permission expression in the nul-terminated string
+.I s
+to the initial file permission mask
+.IR p .
+The new permission mask is returned.
+If
+.I e
+not 0 then
+.I *e
+is set to point to the first unrecognized character in
+.IR s .
+.PP
+A tape device specification is composed of one or more
+.I who-op-permission
+terms separated by
+.BR , .
+.I who
+selects portions of the permission bits and may be any combination of:
+.TP 3
+.B u
+the user permission bits;
+.TP
+.B g
+the group permission bits;
+.TP
+.B o
+the `other' permission bits;
+.TP
+.B a
+all permission bits.
+.PP
+If omitted, all permission bits are selected.
+.I op
+specifies how the original permission
+.I p
+is to be modified:
+.TP 3
+.B +
+.br
+.ns
+.B |
+the new bits are set in
+.IR p ;
+.TP 3
+.B \-
+the new bits are cleared in
+.IR p ;
+.TP
+.B &
+the new bits are and'd with
+.IR p ;
+.TP
+.B =
+the select bits in
+.I p
+are set equal to the new bits
+.PP
+A permission expression term may also be an octal number.
+Octal specifications are inherently non-portable.
+Refer to
+.IR chmod (1)
+for an explanation of this form.
+.SH "SEE ALSO"
+chmod(1), ls(1), strmode(3)
diff --git a/src/lib/libast/man/strsignal.3 b/src/lib/libast/man/strsignal.3
new file mode 100644
index 0000000..4141980
--- /dev/null
+++ b/src/lib/libast/man/strsignal.3
@@ -0,0 +1,53 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STRSIGNAL 3
+.SH NAME
+strsignal \- return signal description string given signal number
+.SH SYNOPSIS
+.L "char* strsignal(int sig)"
+.SH DESCRIPTION
+.I strsignal
+returns the signal description string corresponding to the signal number
+.IR sig .
+.BI "Signal " nnn
+is returned if
+.I sig
+is invalid.
+.SH "SEE ALSO"
+signal(2), sigvec(2)
diff --git a/src/lib/libast/man/strsort.3 b/src/lib/libast/man/strsort.3
new file mode 100644
index 0000000..c48cfc2
--- /dev/null
+++ b/src/lib/libast/man/strsort.3
@@ -0,0 +1,73 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH HSORT 3
+.SH NAME
+hsort \- array heap sort
+.SH SYNOPSIS
+.EX
+#include <ast.h>
+
+void strsort(char** \fIarray\fP, int \fIelements\fP, int (*\fIcompare\fP)(const char* \fIa\fP, const char* \fIb\fP));
+.EE
+.SH DESCRIPTION
+.L strsort
+does a heap sort on the array of pointers
+.I array
+with
+.I elements
+elements using the comparison function
+.IR compare .
+.I compare
+returns
+.L \-1
+if
+.I a
+is lexicographically less than
+.IR b ,
+.L 0
+if
+.I a
+is equal to
+.IR b ,
+and
+.L 1
+if
+.I a
+is lexicographically greater than
+.IR b .
diff --git a/src/lib/libast/man/strtape.3 b/src/lib/libast/man/strtape.3
new file mode 100644
index 0000000..06c33ba
--- /dev/null
+++ b/src/lib/libast/man/strtape.3
@@ -0,0 +1,86 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STRTAPE 3
+.SH NAME
+strtape \- convert string to tape device pathname
+.SH SYNOPSIS
+.L "char* strtape(char* s, char** e)"
+.SH DESCRIPTION
+.I strtape
+converts the generic tape device specification in the nul-terminated string
+.I s
+to a local tape device pathname.
+A pointer to the device pathname is returned.
+If
+.I e
+not 0 then
+.I *e
+is set to point to the first unrecognized character in
+.IR s .
+.PP
+A tape device specification is composed of
+.IR unit-density-rewind .
+All are optional.
+.I unit
+is a unit number in the range
+.BR [0-7] .
+The default unit is
+.BR 1 .
+Density may be one of:
+.TP 3
+.B l
+for low;
+.TP 3
+.B m
+for medium, and
+.TP
+.B h
+for high.
+.PP
+The default is
+.BR m .
+.I rewind
+is
+.B n
+for no-rewind on device close.
+The default is to rewind on device close.
+.SH "SEE ALSO"
+pax(1), tar(1)
+.SH CAVEATS
+The return value points to a static area that is overwritten on each call.
diff --git a/src/lib/libast/man/strton.3 b/src/lib/libast/man/strton.3
new file mode 100644
index 0000000..bfcf891
--- /dev/null
+++ b/src/lib/libast/man/strton.3
@@ -0,0 +1,97 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STRTON 3
+.SH NAME
+strton \- convert string to long integer
+.SH SYNOPSIS
+.L "long strton(char* s, char** e)"
+.SH DESCRIPTION
+.I strton
+converts the nul-terminated string
+.I s
+to a long integer.
+If
+.I e
+not 0 then
+.I *e
+is set to point to the first unrecognized character in
+.IR s .
+Leading spaces in
+.I s
+are ignored.
+.PP
+A number is composed of
+.IR sign-base-number-suffix .
+All but
+.I number
+are optional.
+.I sign
+may be \+ or \-.
+.I base
+may be:
+.TP
+.B 0x
+for hexadecimal;
+.TP
+.B 0
+for octal, or
+.TP
+.IR nn #
+for base
+2 \(le
+.I nn
+\(le 36.
+.PP
+For bases greater than 10 the additional digits are take from the set
+.BR [a-zA-Z] .
+The suffix multiplies the converted number and may be:
+.TP
+.B b
+block (512)
+.TP
+.B g
+giga (1024 * 1024 * 1024)
+.TP
+.B k
+kilo (1024)
+.TP
+.B m
+mega (1024 * 1024)
+.SH "SEE ALSO"
+atoi(3), scanf(3), strtod(3)
diff --git a/src/lib/libast/man/struid.3 b/src/lib/libast/man/struid.3
new file mode 100644
index 0000000..522deb5
--- /dev/null
+++ b/src/lib/libast/man/struid.3
@@ -0,0 +1,53 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH STRUID 3
+.SH NAME
+struid \- return user name given user number
+.SH SYNOPSIS
+.L "char* struid(int uid)"
+.SH DESCRIPTION
+.I struid
+returns the user id name string given the user number
+.IR uid .
+.I struid
+maintains an internal cache to avoid repeated password database scans
+by the low level
+.IR getpwuid (3).
+.SH "SEE ALSO"
+getpwent(3)
diff --git a/src/lib/libast/man/swap.3 b/src/lib/libast/man/swap.3
new file mode 100644
index 0000000..82176de
--- /dev/null
+++ b/src/lib/libast/man/swap.3
@@ -0,0 +1,138 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH SWAP 3
+.SH NAME
+swap \- integral representation conversion routines
+.SH SYNOPSIS
+.L "#include <swap.h>"
+.sp
+.L "int swapop(const void* internal, const void* external, int width);
+.L "int_max swapget(int op, const void* from, int width);"
+.L "void* swapput(int op, void* to, int width, int_max value);"
+.L "void* swapmem(int op, const void* from, void* to, size_t n);"
+.SH DESCRIPTION
+These routines convert integral constants between internal and
+external representations.
+They are used to handle binary data generated by foreign programs.
+New binary data representations should use the compact canonical form
+provided by the
+.IR sfio (3)
+routines
+.L sfputu
+and
+.LR sgetu .
+.PP
+.L swapop
+returns the swap operation required to convert the
+.L width
+byte integer
+.L external
+to the
+.L width
+byte integer
+.LR internal .
+The swap operation is a bit mask:
+.TP
+.L 0
+No swapping necessary.
+.TP
+.L 1
+Swap byte
+.L 0
+with byte
+.LR 1 .
+.TP
+.L 2
+Swap bytes
+.L 0
+and
+.L 1
+with bytes
+.L 2
+and
+.LR 3 .
+.TP
+.L 4
+Swap bytes
+.L 0-3
+with bytes
+.LR 4-7 ,
+and so on.
+The largest native integral type is defined by the macro
+.L int_max
+in the header
+.L <int.h>
+described in
+.IR int (3).
+.PP
+.L swapget
+returns the
+.L width
+byte integer in the buffer
+.LR from ,
+swapped according to
+.LR op .
+.PP
+.L swapput
+copies the
+.L width
+byte integer
+.L value
+into the buffer
+.LR to ,
+swapped according to
+.LR op .
+.L to
+is returned.
+.PP
+.L swapmem
+swaps
+.L n
+bytes from the buffer
+.L from
+to the buffer
+.L to
+according to
+.LR op .
+.L to
+and
+.L from
+may be the same.
+.SH "SEE ALSO"
+int(3)
diff --git a/src/lib/libast/man/tab.3 b/src/lib/libast/man/tab.3
new file mode 100644
index 0000000..e1c76f3
--- /dev/null
+++ b/src/lib/libast/man/tab.3
@@ -0,0 +1,74 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH TAB 3
+.SH NAME
+tab \- simple table lookup routines
+.SH SYNOPSIS
+.L "#include <ast.h>"
+.sp
+.L "int tabindex(const void* tab, int size, const char* name);"
+.L "void* tablook(const void* tab, int size, const char* name);"
+.SH DESCRIPTION
+These routines do linear lookups in
+.I small
+tables (on the order of 32 elements).
+Each table element has a size of
+.L size
+bytes and the beginning of the element points to a name that is
+matched by the lookup routines.
+.PP
+.L tabindex
+returns the index of the table element in
+.L tab
+that matches
+.LR name .
+If there is no match then
+.L \-1
+is returned.
+.PP
+.L tablook
+returns a pointer to the table element in
+.L tab
+that matches
+.LR name .
+If there is no match then
+.L 0
+is returned.
+.SH "SEE ALSO"
+hash(3)
diff --git a/src/lib/libast/man/tm.3 b/src/lib/libast/man/tm.3
new file mode 100644
index 0000000..12eb4ec
--- /dev/null
+++ b/src/lib/libast/man/tm.3
@@ -0,0 +1,775 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH TM 3
+.SH NAME
+tm \- seconds resolution time conversion support
+.SH SYNOPSIS
+.L "#include <tm.h>"
+.SH DESCRIPTION
+The
+.I tm
+library supports conversion between
+string date specifications,
+seconds reolution
+.L time_t
+clock values and
+.LR Tm_t .
+.L Tm_t
+contains the elements of
+.L "struct tm"
+along with these additions:
+.TP
+.L "unsigned _ast_int4_t tm_nsec"
+The subsecond portion of the time in nanoseconds.
+.TP
+.L "Tm_zone_t* tm_zone"
+The time zone name.
+.PP
+.L localtime()
+and
+.L gmtime()
+(see
+.BR ctime (3))
+are used to determine local time zone and savings time information.
+.PP
+.L time_t
+values are the number of seconds since the epoch,
+.BR "Jan 1 00:00:00 GMT 1970" ,
+with leap seconds omitted.
+.PP
+The global variable
+.L "int tm_info.flags"
+contains flags that allow all programs using the library
+to be controlled in a consistent manner.
+.L tm_info.flags
+is initialized by the
+.L tminit()
+routine described below, and may be explicitly reset after
+.L tminit()
+is called.
+The flags are:
+.TP
+.L TM_ADJUST
+Set by
+.L tminit()
+if
+.L localtime()
+and
+.L gmtime()
+do not compensate for leap seconds.
+.TP
+.L TM_LEAP
+.L time_t
+values are interpreted as if they include leap seconds.
+Set by
+.L tminit()
+if the
+.L leap
+option is set in the
+.L TM_OPTIONS
+environment variable.
+.TP
+.L TM_UTC
+Times are relative to
+.B UTC
+(universal coordinated time, i.e.,
+.BR GMT .)
+Otherwise times are relative to the local time zone.
+Set by
+.L tminit()
+if the time zone name matches one of
+.L tm_info.format[43]
+through
+.L tm_info.format[46]
+described below.
+If the time zone name is not determined by
+.L localtime()
+then the environment variables
+.L TZNAME
+(as described in BSD 4.3) and
+.L TZ
+(as described in System V)
+are checked, in order.
+If this fails then the time zone name is constructed using
+the local time zone offset.
+.PP
+The routines are:
+.TP
+.L "time_t tmdate(const char* date, char** end, time_t* clock)"
+Parses the date specification
+.L date
+using the
+.L tm_info.format
+string table (described below)
+and returns the equivalent
+.L time_t
+value.
+If
+.RL non- NULL ,
+.L end
+is set to the position of the first unrecognized character in
+.LR date .
+.L clock
+is used to provide default values for omitted components in
+.LR date .
+If
+.L clock
+is
+.L NULL
+then the current time is used.
+.TP
+.L "Tm_t* tmfix(Tm_t* tp)"
+Corrects any out of bounds fields in
+.L tp
+and returns
+.L tp
+as its value.
+The corrections start with
+.L tp->tm_sec
+and propagate down to
+.LR tp->tm_year .
+For example, if
+.L tp->tm_sec
+were 61 then it would change to 1 and
+.L tp->tm_min
+would be incremented by 1, and so on.
+.L tp->tm_isdst
+is not changed -- call
+.L tmtime()
+to determine its proper value after the
+.L tmfix()
+adjustments.
+.TP
+.L "char* tmfmt(char* buf, size_t len, const char* format, time_t* clock)"
+Formats the date pointed to by
+.L clock
+into the buffer
+.L buf
+with size
+.L len
+bytes according to the format specification
+.LR format .
+If
+.L format
+is
+.L NULL
+or empty then the string
+.L tm_info.format[40]
+is used.
+If
+.L clock
+is
+.L NULL
+then the current time is used.
+A pointer to the end of
+.L buf
+(i.e., the terminating
+.LR "'\e0'" )
+is returned.
+.RS
+.PP
+.L format
+is in
+.BR printf (3)
+style, where
+.RI % field
+names a fixed size field, zero padded if necessary,
+and
+.I \ec
+and
+.I \ennn
+sequences are as in C. Invalid
+.RI % field
+specifications and all other characters are copied
+without change.
+.I field
+may be preceded by
+.B %-
+to turn off padding or
+.B %_
+to pad with space, otherwise numeric fields
+are padded with
+.B 0
+and string fields are padded with space.
+.I field
+may also be preceded by
+.B E
+for alternate era representation or
+.B O
+for alternate digit representation (if supported by the current locale.)
+Finally, an integral
+.I width
+preceding
+.I field
+truncates the field to
+.I width
+characters.
+sequences are interpreted as in the C language.
+String field values are taken from the
+.L tm_info.format
+string table.
+The
+.I fields
+are:
+.TP
+.PD 0
+.B %
+.B %
+character.
+.TP
+.B a
+Abbreviated weekday name.
+.TP
+.B A
+Full weekday name.
+.TP
+.B b
+Abbreviated month name.
+.TP
+.B c
+.BR ctime (3)
+style date without the trailing
+.BR newline .
+.TP
+.B C
+.BR date (1)
+style date.
+.TP
+.B d
+Day of month number.
+.TP
+.B D
+Date as
+.IR mm / dd / yy .
+.TP
+.B e
+Blank padded day of month number.
+.TP
+.B E
+Unpadded day of month number.
+.TP
+.B f
+Locale default override date format.
+.TP
+.B F
+Locale default date format
+.RL ( tm_info.format[40] .)
+.TP
+.B h
+Abbreviated month name.
+.TP
+.B H
+24-hour clock hour.
+.TP
+.B i
+International
+.BR date (1)
+date that includes the time zone type name
+.RL ( tm_info.format[107] .)
+.TP
+.B I
+12-hour clock hour.
+.TP
+.B j
+1-offset Julian date.
+.TP
+.B J
+0-offset Julian date.
+.TP
+.B k
+.BR date (1)
+style date
+.RL ( tm_info.format[106] .)
+.TP
+.B K
+Language neutral, all numeric, no embedded space date
+with larger to smaller time units from left to right,
+suitable for sorting:
+.LR '"%Y-%m-%d+%H:%M:%S"' .
+.TP
+.B l
+.BR ls (1)
+.B \-l
+date that lists recent dates with
+.L %g
+and distant dates with
+.BR %G .
+.TP
+.B m
+Month number.
+.TP
+.B M
+Minutes.
+.TP
+.B n
+.B newline
+character.
+.TP
+.B N
+The time zone type or nation code.
+.TP
+.B p
+Meridian (e.g.,
+.B AM
+or
+.BR PM .)
+.TP
+.B q
+The nanosecond part of the time.
+.TP
+\fB%Q\fP\fI<delim>recent<delim>distant<delim>\fP
+Recent dates are formatted with
+.I recent
+and distand dates are formatted with
+.IR distant ,
+where
+.I <delim>
+is any character not appearing in
+.I recent
+or
+.IR distant .
+.TP
+.B r
+12-hour time as
+.IR hh : mm : ss
+.IR meridian .
+.TP
+.B R
+24-hour time as
+.IR hh : mm .
+.TP
+.B s
+Seconds since the epoch.
+.RI . prec
+preceding
+.B s
+appends
+.I prec
+nanosecond digits,
+.B 9
+if
+.I prec
+is omitted.
+.TP
+.B S
+.I seconds.subseconds
+since the epoch.
+.TP
+.B t
+.B tab
+character.
+.TP
+.B T
+24-hour time as
+.IR hh : mm : ss .
+.TP
+.B u
+Weeday number with 1 for Monday, 7 for Sunday.
+.TP
+.B U
+Week number with Sunday as the first day.
+.TP
+.B V
+ISO week number (i18n is \fIfun\fP.)
+.TP
+.B w
+Weekday number with 0 for Sunday, 6 for Saturday.
+.TP
+.B W
+Week number with Monday as the first day.
+.TP
+.B x
+Local date style, using
+.LR tm_info.format[39] ,
+that includes the month, day and year.
+.TP
+.B X
+Local time style, using
+.LR tm_info.format[38] ,
+that includes the hours and minutes.
+.TP
+.B y
+2-digit year (you'll be sorry.)
+.TP
+.B Y
+4-digit year.
+.TP
+.B z
+Time zone
+.I SHHMM
+west of GMT offset where
+.I S
+is
+.B +
+or
+.BR - .
+.TP
+.B Z
+Time zone name.
+.TP
+=[=]][-+]]\fIflag\fP
+Set (default or +) or clear (-)
+.I flag
+in
+.L tm_info.flags
+for the remainder of
+.IR format ,
+or for the remainder of the process if
+.B ==
+is specified.
+.I flag
+may be:
+.RS
+.TP
+.B l
+.L (TM_LEAP)
+Enable leap second adjustments.
+.TP
+.B s
+.L (TM_SUBSECOND)
+Append nanosecond
+.B .%N
+to
+.BR %S .
+.TP
+.B u
+.L (TM_UTC)
+UTC time zone.
+.RE
+.TP
+.B #
+Equivalent to
+.BR %s .
+.TP
+\fP?\fP\fIalternate\fP
+Use
+.I alternate
+format is a default format override has not been specified.
+e.g.,
+.BR ls (1)
+uses
+.BR %?%l .
+Export
+\f5TM_OPTIONS="format='\fP\fIoverride\fP\f5'"\fP
+to override the default.
+.PD
+.RE
+.TP
+.L "void tminit(Tm_zone_t* zone)"
+Implicitly called by the other
+.I tm
+library routines to initialize global data, including the
+.L tm_info.format
+table and the
+.L tm_info.flags
+global flags.
+Global data should only be modified after an explicit call to
+.LR tminit .
+If
+.L "zone != 0"
+then it specifies a time zone other that the local time zone.
+.TP
+.L "void tmset(Tm_zone_t* zone);"
+.L tmset
+sets the reference timezoe to
+.LR zone .
+.L tm_info.local
+points to the local timezone and
+.L tm_info.zone
+points to the current reference timezone.
+.TP
+.L "time_t tmleap(time_t* clock)"
+Returns a
+.L time_t
+value for the time pointed to by
+.L clock
+with leap seconds adjusted for external
+routines that do not handle leap seconds.
+If
+.L clock
+is
+.L NULL
+then the current time is used.
+Adjustments are only done if the
+.L TM_ADJUST
+flag is set in
+.LR tm_info.flags .
+.TP
+.L "Tm_t* tmmake(time_t* clock)"
+Returns a pointer to the
+.L Tm_t
+struct corresponding to the time pointed to by
+.LR clock .
+If
+.L clock
+is
+.L NULL
+then the current time is used.
+.TP
+.L "time_t tmtime(Tm_t* tp, int west)"
+Returns the
+.L time_t
+value corresponding to
+.LR tp .
+If
+.L west
+is
+.L TM_LOCALZONE
+then
+.L tm
+is relative to the local time zone,
+otherwise
+.L west
+is the number of minutes west of
+.B UTC
+with daylight savings time taken into account.
+.LR tp->tm_wday ,
+.LR tp->tm_yday
+and
+.L tp->tm_isdst
+are ignored in the conversion.
+.PP
+The library routines use a table of date strings pointed to by
+.LR "char** tm_info.format" .
+The indices in
+.L tm_info.format
+are fixed by category.
+.L tm_info.format
+may be changed to point to other tables
+according to local language and date conventions.
+The contents by index (showing the USA English values) are:
+.RS
+.TP
+.PD 0
+.B 0-11
+3-character abbreviated month names.
+.TP
+.B 12-23
+Full month names.
+.TP
+.B 24-30
+3-character abbreviated weekday names.
+.TP
+.B 31-37
+Full weekday names.
+.TP
+.B 38
+.L tmfmt()
+local time format used by the
+.B %X
+field.
+.TP
+.B 39
+.L tmfmt()
+local date format used by the
+.B %x
+field.
+.TP
+.B 40
+.L tmfmt()
+format used if the
+.L format
+argument is
+.L NULL
+or empty.
+.TP
+.B 41-42
+Meridian names: AM, PM.
+.TP
+.B 43-46
+.B UTC
+time zone names: GMT, UTC, UCT, CUT.
+.TP
+.B 47-50
+Daylight savings time suffix names: DST.
+.TP
+.B 51-54
+Suffixes to be ignored when matching strings in
+.LR tmfmt() .
+.TP
+.B 55-61
+Time part names: second, hour, minute, day, week, month, year.
+.TP
+.B 62-65
+Hours of the day names: midnight, morning, noon, evening.
+.TP
+.B 66-68
+Relative day names: yesterday, today, tomorrow.
+.TP
+.B 69-71
+Past relative time references: last, ago, past.
+.TP
+.B 72-75
+Current relative time references: this, now, current.
+.TP
+.B 75-77
+Future relative time references: next, hence, coming.
+.TP
+.B 78-80
+Exact relative time references: exactly.
+.TP
+.B 81-84
+Noise words to be ignored: at, in, on.
+.TP
+.B 85-94
+Ordinal suffixes: st, nd, rd, th, th, th, th, th, th, th.
+.TP
+.B 95-104
+Digit names.
+.TP
+.B 105
+The
+.L tmfmt()
+format equivalent for
+.BR ctime (3):
+.LR '"%a %b %e %T %Y"' .
+.TP
+.B 106
+The
+.L tmfmt()
+.BR date (1)
+default format:
+.LR '"%a %b %e %T %Z %Y"' .
+.TP
+.B 107
+The
+.L tmfmt()
+.BR date (1)
+international format:
+.LR '"%a %b %e %T %z %Z %Y"' .
+.TP
+.B 108
+The
+.L tmfmt()
+.BR ls (1)
+recent date format:
+.LR '"%b %e %H:%M"' .
+.TP
+.B 109
+The
+.L tmfmt()
+.BR ls (1)
+distant date format:
+.LR '"%b %e %Y"' .
+.TP
+.B 110
+The
+.L tmfmt()
+.BR date (1)
+meridian date format:
+.LR '"%I:%M:%S %p"' .
+.TP
+.B 111
+The ERA name.
+.TP
+.B 112
+ERA alternative for
+.BR 39 .
+.TP
+.B 113
+ERA alternative for
+.BR 38 .
+.TP
+.B 114
+ERA alternative for
+.BR 40 .
+.TP
+.B 115
+The ERA year.
+.TP
+.B 116-125
+Ordinal names: first, \fIno second!\fP, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth.
+.TP
+.B 126-128
+Final time references, as in \fIthe last in the list\fP: final, ending, nth.
+.PD
+.RE
+.PP
+Low level support functions and data are described in
+.LR <tm.h> .
+.SH EXAMPLES
+.EX
+#include <tm.h>
+main() {
+ int i;
+ time_t t;
+ char buf[128];
+ struct {
+ char* date;
+ char* format;
+ } x[] = {
+ "now", "%i",
+ "2 months ago", "%C",
+ "this Wednesday noon", "%x %I:%M %p",
+ "last December 25", "%A",
+ 0, 0
+ };
+ for (i = 0; x[i].date; i++) {
+ t = tmdate(x[i].date, (char*)0, (time_t*)0);
+ (void)tmfmt(buf, sizeof(buf), x[i].format, &t);
+ puts(buf);
+ }
+}
+.EE
+produces
+.EX
+Fri Sep 30 12:10:14 USA EDT 1988
+Fri Jul 1 00:00:00 EDT 1988
+10/05/88 12:00 PM
+Friday
+.EE
+.SH "SEE ALSO"
+.BR date (1),
+.BR time (2),
+.BR ctime (3)
+.SH BUGS
+The C library static
+.L "struct tm"
+values may get clobbered by
+.I tm
+library routines as the
+.BR ctime (3)
+and
+.BR localtime (3)
+routines typically return pointers to a single static
+.L "struct tm"
+area.
+.L tmdate()
+uses an internal international time zone name table that will
+probably always be incomplete.
diff --git a/src/lib/libast/man/tmx.3 b/src/lib/libast/man/tmx.3
new file mode 100644
index 0000000..268d40a
--- /dev/null
+++ b/src/lib/libast/man/tmx.3
@@ -0,0 +1,576 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH TM 3
+.SH NAME
+tm \- time conversion support
+.SH SYNOPSIS
+.L "#include <tm.h>"
+.SH DESCRIPTION
+The
+.I tm
+library supports conversion between
+string date specifications,
+.L time_t
+clock values and
+.L "struct tm"
+values.
+.L localtime()
+and
+.L gmtime()
+(see
+.IR ctime (3))
+are used to determine local time zone information.
+.PP
+.L time_t
+values are the number of seconds since the epoch,
+.BR "Jan 1 00:00:00 GMT 1970" ,
+with leap seconds omitted.
+.PP
+The global variable
+.L "int tm_info.flags"
+contains flags that allow all programs using the library
+to be controlled in a consistent manner.
+.L tm_info.flags
+is initialized by the
+.L tminit()
+routine described below, and may be explicitly reset after
+.L tminit()
+is called.
+The flags are:
+.TP
+.L TM_ADJUST
+Set by
+.L tminit()
+if
+.L localtime()
+and
+.L gmtime()
+do not compensate for leap seconds.
+.TP
+.L TM_LEAP
+.L time_t
+values are interpreted as if they include leap seconds.
+Set by
+.L tminit()
+if the
+.L leap
+option is set in the
+.L TM_OPTIONS
+environment variable.
+.TP
+.L TM_UTC
+Times are relative to
+.B UTC
+(universal coordinated time, i.e.,
+.BR GMT ).
+Otherwise times are relative to the local time zone.
+Set by
+.L tminit()
+if the time zone name matches one of
+.L tm_info.format[43]
+through
+.L tm_info.format[46]
+described below.
+If the time zone name is not determined by
+.L localtime()
+then the environment variables
+.L TZNAME
+(as described in BSD 4.3) and
+.L TZ
+(as described in System V)
+are checked, in order.
+If this fails then the time zone name is constructed using
+the local time zone offset.
+.PP
+The routines are:
+.TP
+.L "time_t tmdate(const char* date, char** end, time_t* clock)"
+Parses the date specification
+.L date
+using the
+.L tm_info.format
+string table (described below)
+and returns the equivalent
+.L time_t
+value.
+If
+.RL non- NULL ,
+.L end
+is set to the position of the first unrecognized character in
+.LR date .
+.L clock
+is used to provide default values for omitted components in
+.LR date .
+If
+.L clock
+is
+.L NULL
+then the current time is used.
+.TP
+.L "struct tm* tmfix(struct tm* tp)"
+Corrects any out of bounds fields in
+.L tp
+and returns
+.L tp
+as its value.
+The corrections start with
+.L tp->tm_sec
+and propagate down to
+.LR tp->tm_year .
+For example, if
+.L tp->tm_sec
+were 61 then it would change to 1 and
+.L tp->tm_min
+would be incremented by 1, and so on.
+.LR tp->tm_wday ,
+.LR tp->tm_yday
+and
+.L tp->tm_isdst
+are not changed as these can be computed from the other fields.
+.TP
+.L "char* tmfmt(char* buf, size_t len, const char* format, time_t* clock)"
+Formats the date pointed to by
+.L clock
+into the buffer
+.L buf
+with size
+.L len
+bytes according to the format specification
+.LR format .
+If
+.L format
+is
+.L NULL
+or empty then the string
+.L tm_info.format[40]
+is used.
+If
+.L clock
+is
+.L NULL
+then the current time is used.
+A pointer to the end of
+.L buf
+(i.e., the terminating
+.LR "'\e0'" )
+is returned.
+.RS
+.PP
+.L format
+is in the style of
+.IR printf (3),
+where
+.BI % field
+causes the corresponding fixed size field to be placed in
+.LR buf ,
+zero padded if necessary, and \e\fIc\fP and \e\fInnn\fP
+sequences are interpreted as in the C language.
+Otherwise invalid
+.BI % field
+specifications and all other characters in
+.L format
+are copied into
+.L buf
+without change.
+String field values are taken from the
+.L tm_info.format
+string table.
+The
+.I fields
+are:
+.TP
+.PD 0
+.B %
+.B %
+character.
+.TP
+.B a
+Abbreviated weekday name.
+.TP
+.B A
+Full weekday name.
+.TP
+.B b
+Abbreviated month name.
+.TP
+.B c
+.IR ctime (3)
+style date without the trailing
+.BR newline .
+.TP
+.B C
+.IR date (1)
+style date.
+.TP
+.B d
+Day of month number.
+.TP
+.B D
+Date as
+.IR mm / dd / yy .
+.TP
+.B e
+Blank padded day of month number.
+.TP
+.B E
+Unpadded day of month number.
+.TP
+.B h
+Abbreviated month name.
+.TP
+.B H
+24-hour clock hour.
+.TP
+.B i
+International
+.IR date (1)
+date that includes the time zone type name.
+.TP
+.B I
+12-hour clock hour.
+.TP
+.B j
+1-offset Julian date.
+.TP
+.B J
+0-offset Julian date.
+.TP
+.B l
+.IR ls (1)
+.B \-l
+date that lists recent dates with
+.IR hh : mm
+and distant dates with
+.IR yyyy .
+.TP
+.B m
+Month number.
+.TP
+.B M
+Minutes.
+.TP
+.B n
+.B newline
+character.
+.TP
+.B p
+Meridian (e.g.,
+.B AM
+or
+.BR PM ).
+.TP
+.B r
+12-hour time as
+.IR hh : mm : ss
+.IR meridian .
+.TP
+.B R
+24-hour time as
+.IR hh : mm .
+.TP
+.B S
+Seconds.
+.TP
+.B t
+.B tab
+character.
+.TP
+.B T
+24-hour time as
+.IR hh : mm : ss .
+.TP
+.B U
+Week number with Sunday as the first day.
+.TP
+.B w
+Weekday number.
+.TP
+.B W
+Week number with Monday as the first day.
+.TP
+.B x
+Local date style, using
+.LR tm_info.format[39] ,
+that includes the month, day and year.
+.TP
+.B X
+Local time style, using
+.LR tm_info.format[38] ,
+that includes the hours and minutes.
+.TP
+.B y
+2-digit year.
+.TP
+.B Y
+4-digit year.
+.TP
+.B z
+Time zone type name.
+.TP
+.B Z
+Time zone name.
+.TP
+.BI + flag
+.TP
+.BI \- flag
+Temporarily (until
+.L tmform()
+returns) sets (+) or clears (\-) the
+.L tm_info.flags
+flags specified by
+.IR flag :
+.RS
+.TP
+.B l
+.L TM_LEAP
+.TP
+.B u
+.L TM_UTC
+.RE
+.TP
+.B #
+Number of seconds since the epoch.
+.PD
+.RE
+.TP
+.L "void tminit(Tm_zone_t* zone)"
+Implicitly called by the other
+.I tm
+library routines to initialize global data, including the
+.L tm_info.format
+table and the
+.L tm_info.flags
+global flags.
+Global data should only be modified after an explicit call to
+.LR tminit .
+If
+.L "zone != 0"
+then it specifies a time zone other that the local time zone.
+.TP
+.L "void tmset(Tm_zone_t* zone);"
+.L tmset
+sets the reference timezoe to
+.LR zone .
+.L tm_info.local
+points to the local timezone and
+.L tm_info.zone
+points to the current reference timezone.
+.TP
+.L "time_t tmleap(time_t* clock)"
+Returns a
+.L time_t
+value for the time pointed to by
+.L clock
+with leap seconds adjusted for external
+routines that do not handle leap seconds.
+If
+.L clock
+is
+.L NULL
+then the current time is used.
+Adjustments are only done if the
+.L TM_ADJUST
+flag is set in
+.LR tm_info.flags .
+.TP
+.L "struct tm* tmmake(time_t* clock)"
+Returns a pointer to the
+.L tm
+struct corresponding to the time pointed to by
+.LR clock .
+If
+.L clock
+is
+.L NULL
+then the current time is used.
+.TP
+.L "time_t tmtime(struct tm* tp, int west)"
+Returns the
+.L time_t
+value corresponding to
+.LR tp .
+If
+.L west
+is
+.L TM_LOCALZONE
+then
+.L tm
+is relative to the local time zone,
+otherwise
+.L west
+is the number of minutes west of
+.B UTC
+with daylight savings time taken into account.
+.LR tp->tm_wday ,
+.LR tp->tm_yday
+and
+.L tp->tm_isdst
+are ignored in the conversion.
+.PP
+The library routines use a table of date strings pointed to by
+.LR "char** tm_info.format" .
+The indices in
+.L tm_info.format
+are fixed by category.
+.L tm_info.format
+may be changed to point to other tables
+according to local language and date conventions.
+The contents by index (showing the USA English values) are:
+.RS
+.TP
+.PD 0
+.B 0-11
+3-character abbreviated month names.
+.TP
+.B 12-23
+Full month names.
+.TP
+.B 24-30
+3-character abbreviated weekday names.
+.TP
+.B 31-37
+Full weekday names.
+.TP
+.B 38
+.L tmform()
+local time format used by the
+.B %X
+field.
+.TP
+.B 39
+.L tmform()
+local date format used by the
+.B %x
+field.
+.TP
+.B 40
+.L tmform()
+format used if the
+.L format
+argument is
+.L NULL
+or empty.
+.TP
+.B 41-42
+Meridian names: AM, PM.
+.TP
+.B 43-46
+.B UTC
+time zone names: GMT, UTC, UCT, CUT.
+.TP
+.B 47-50
+Daylight savings time suffix names: DST.
+.TP
+.B 51-54
+Suffixes to be ignored when matching strings in
+.LR tmform() .
+.TP
+.B 55-61
+Time part names: second, hour, minute, day, week, month, year.
+.TP
+.B 62-65
+Hours of the day names: midnight, morning, noon, evening.
+.TP
+.B 66-68
+Relative day names: yesterday, today, tomorrow.
+.TP
+.B 69-71
+Past relative time references: last, ago, past.
+.TP
+.B 72-75
+Current relative time references: this, now, current.
+.TP
+.B 75-77
+Future relative time references: next, hence, coming.
+.TP
+.B 78-80
+Exact relative time references: exactly.
+.TP
+.B 81-85
+Noise words to be ignored: at, in, on.
+.PD
+.RE
+.PP
+Low level support functions and data are described in
+.LR <tm.h> .
+.SH EXAMPLES
+.EX
+#include <tm.h>
+main() {
+ int i;
+ time_t t;
+ char buf[128];
+ struct {
+ char* date;
+ char* format;
+ } x[] = {
+ "now", "%i",
+ "2 months ago", "%C",
+ "this Wednesday noon", "%x %I:%M %p",
+ "last December 25", "%A",
+ 0, 0
+ };
+ for (i = 0; x[i].date; i++) {
+ t = tmdate(x[i].date, (char*)0, (time_t*)0);
+ (void)tmform(buf, x[i].format, &t);
+ puts(buf);
+ }
+}
+.EE
+produces
+.EX
+Fri Sep 30 12:10:14 USA EDT 1988
+Fri Jul 1 00:00:00 EDT 1988
+10/05/88 12:00 PM
+Friday
+.EE
+.SH "SEE ALSO"
+date(1), time(2), ctime(3)
+.SH BUGS
+.L "struct tm"
+values may get clobbered by the
+.I tm
+library routines as the
+.IR ctime (3)
+routines typically return pointers to a single static
+.L "struct tm"
+area.
+.L tmdate()
+uses an internal international time zone name table that will
+probably always be incomplete.
diff --git a/src/lib/libast/man/tok.3 b/src/lib/libast/man/tok.3
new file mode 100644
index 0000000..46fbff9
--- /dev/null
+++ b/src/lib/libast/man/tok.3
@@ -0,0 +1,217 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH TOK 3
+.SH NAME
+tok \- space separated token stream routines
+.SH SYNOPSIS
+.L "#include <ast.h>"
+.sp
+.L "void* tokopen(char* string)"
+.L "char* tokread(void* tok)"
+.L "void tokclose(void* tok)"
+.sp
+.L "int tokscan(char* string, char** next, const char* format, ...);"
+.sp
+.L "Sfio_t* tokline(const char* input, int flags, int* line);"
+.SH DESCRIPTION
+.L tokopen
+returns a pointer to a space separated token stream on the 0 terminated
+string
+.LR string .
+.L tokread
+returns a pointer to the next
+space separated token in the token stream
+.L tok
+as returned by
+.LR tokopen .
+0 is returned when no tokens remain.
+.L tokread
+temporarily modifies
+.L string
+by inserting 0's to terminate each token.
+.L tokclose
+closes the token stream and restores
+.L string
+to its original state.
+.PP
+.L tokscan
+scans the string
+.L string
+for tokens specified in
+.LR format .
+It is a more forgiving
+.IR sscanf (3).
+If
+.L "next != 0"
+then it will point to the next unread character in
+.L string
+on return.
+The number of scanned tokens is returned.
+.L \-1
+is returned if
+.L string
+was not empty and
+.L format
+failed to match and tokens.
+.PP
+.I space
+in
+.L format
+matches 0 or more
+.I space
+or
+.I tab
+characters.
+.I newline
+in format eats the remainder of the current line in
+.LR string .
+"...", '...' and \e\fIcharacter\fP quotes are interpreted.
+A quoted
+.I carriage-return
+is converted to
+.IR newline .
+.I newline
+in
+.L string
+is equivalent to end of string except when quoted.
+.I \enewline
+is a line splice.
+.PP
+.L %
+in
+.L format
+prefixes format conversion characters; each conversion character
+corresponds to a
+.L tokscan
+argument following the
+.L format
+argument.
+The format conversions are:
+.TP
+.L %c
+A single
+.LR char .
+.TP
+.L "%hd %d %ld"
+[short, int, long] base 10 integer.
+.TP
+.L "%hn %n %ln"
+[short, int, long] C-style base integer.
+.TP
+.L "%ho %o %lo"
+[short, int, long] base 8 integer.
+.TP
+.L %s
+String.
+.TP
+.L "%hu %u %lu"
+[short, int, long] C-style base unsigned integer.
+.TP
+.L %v
+The next two arguments are a pointer to a
+.L char**
+argument vector and the maximum number of elements in the vector.
+.TP
+.L "%hx %x %lx"
+[short, int, long] base 16 integer.
+.PP
+.L %s
+and
+.L %v
+data may also be counted length strings of the form
+\f5(\fIcount\fP:\fIdata\fP)\fR
+where
+.I count
+is the number of characters in
+.I data
+and the terminating
+.L )
+may also be a
+.IR tab ,
+or the data may be
+.L (null)
+which represents the
+.L NULL
+string.
+.PP
+.L tokline
+returns an
+.IR sfio (3)
+stream to a file or string that splices
+.I \enewline
+into single lines,
+allows "..." and '...' to quotes to span
+.I newlines
+(done by translating quoted
+.I newline
+to
+.IR carriage-return ;
+.L tokscan
+above converts quoted
+.I carriage-return
+back to
+.IR newline ),
+and deletes
+.I "# ... newline"
+comments.
+This is done by pushing an
+.I sfio
+discipline onto a string or file stream.
+Seeks are disabled on the resulting stream.
+If
+.L "flags == SF_READ"
+then
+.L input
+is a file name;
+If
+.L "flags == SF_STRING"
+then
+.L input
+is a 0 terminated string;
+otherwise
+.L input
+is an open
+.L Sfio_t*
+stream.
+If
+.L "line != 0"
+then it points to a line count that is initialized to 0
+and is incremented for each input line.
+.SH "SEE ALSO"
+sfio(3)
diff --git a/src/lib/libast/man/touch.3 b/src/lib/libast/man/touch.3
new file mode 100644
index 0000000..908a8b1
--- /dev/null
+++ b/src/lib/libast/man/touch.3
@@ -0,0 +1,68 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH TOUCH 3
+.SH NAME
+touch \- set file access and modify times
+.SH SYNOPSIS
+.L "#include <ast.h>"
+.sp
+.L "int touch(const char* path, time_t atime, time_t mtime, int force);"
+.SH DESCRIPTION
+.L touch
+sets the access and modify times of the file named by
+.LR path .
+If
+.L "force != 0"
+then the file is created if it doesn't exist;
+otherwise the file is not created and
+.L \-1
+is returned.
+If
+.L "force < 0"
+then
+.L atime
+and
+.L mtime
+are taken verbatim; otherwise
+.L "(time_t)(-1)"
+retains the current value for the file and
+.L "(time_t)(0)"
+uses the current time.
+.SH CAVEATS
+By default the change time is always changed to the current time.
diff --git a/src/lib/libast/man/tv.3 b/src/lib/libast/man/tv.3
new file mode 100644
index 0000000..b90a559
--- /dev/null
+++ b/src/lib/libast/man/tv.3
@@ -0,0 +1,173 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH TM 3
+.SH NAME
+tv \- high resolution time support
+.SH SYNOPSIS
+.L "#include <tv.h>"
+.SH DESCRIPTION
+The
+.I tv
+library supports high resolution
+.B Tv_t
+time specifications.
+.SS Tv_t
+contains these elements:
+.TP
+.L unsigned
+.L _ast_int4_t
+.L tv_sec
+Seconds since the epoch.
+.TP
+.L unsigned
+.L _ast_int4_t
+.L tv_nsec
+Nanosecond resolution.
+.PP
+In practice resolution is much coarser than 1 nanosecond.
+Systems that only support 1 second resolution always set
+.L tv_nsec
+to 0.
+.SS "int tvgettime(Tv_t* tv)"
+Sets
+.L tv
+to the current time.
+.L 0
+is returned on success,
+.L -1
+on error.
+.SS "int tvsettime(const Tv_t* tv)"
+Sets the system time to
+.LR tv .
+The caller must have sufficient privilege.
+.L 0
+is returned on success,
+.L -1
+on error.
+.SS "int tvcmp(const Tv_t* av, const Tv_t* bv)"
+Compares the times
+.L av
+and
+.L bv
+and returns
+.L -1
+if
+.L av
+is less than
+.LR bv ,
+.L 0
+if
+.L av
+is equal to
+.LR bv ,
+and
+.L 1
+if
+.L av
+is greater than
+.LR bv .
+.SS "time_t tvgetatime(Tv_t* tv, const struct stat* st)"
+.SS "time_t tvgetmtime(Tv_t* tv, const struct stat* st)"
+.SS "time_t tvgetctime(Tv_t* tv, const struct stat* st)"
+These macros set
+.L tv
+to the
+.L st
+the access, modify, or change time, respectively.
+The seconds portion of
+.L tv
+is returned.
+.SS "time_t tvsetatime(Tv_t* tv, struct stat* st)"
+.SS "time_t tvsetmtime(Tv_t* tv, struct stat* st)"
+.SS "time_t tvsetctime(Tv_t* tv, struct stat* st)"
+These macros set the
+.L st
+access, modify, or change time, respectively, to
+.LR tv .
+The seconds portion of
+.L tv
+is returned.
+.SS "int tvtouch(const char* path, const Tv_t* av, const Tv_t* mv, const Tv_t* cv, int copy)"
+Sets the file
+.L path
+access time from
+.LR av ,
+modify time from
+.LR mv ,
+and change time from
+.LR cv .
+Any of
+.LR av ,
+.LR mv ,
+and
+.L cv
+may be 0; the corresponding file time will retain the previous value if
+.L path
+exists and
+.L copy
+is
+.L 1 ;
+otherwise the corresponding file time will be set to the current time.
+.L 0
+is returned on success,
+.L -1
+on error.
+.SS "int tvsleep(const Tv_t* tv, Tv_t* rv)"
+Pauses execution for
+.L tv
+time.
+.L 0
+is returned if the full
+.L tv
+amount has expired.
+Otherwise
+.L -1
+is returned and
+.LR rv ,
+if not 0, is set to the sleep time remaining.
+.SH "RETURN VALUE"
+Except for
+.LR tvcmp() ,
+an error return of
+.L -1
+also sets
+.L errno
+to the corresponding error code.
+.SH "SEE ALSO"
+tm(3)
diff --git a/src/lib/libast/man/vecargs.3 b/src/lib/libast/man/vecargs.3
new file mode 100644
index 0000000..29e492b
--- /dev/null
+++ b/src/lib/libast/man/vecargs.3
@@ -0,0 +1,126 @@
+.fp 5 CW
+.de Af
+.ds ;G \\*(;G\\f\\$1\\$3\\f\\$2
+.if !\\$4 .Af \\$2 \\$1 "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+..
+.de aF
+.ie \\$3 .ft \\$1
+.el \{\
+.ds ;G \&
+.nr ;G \\n(.f
+.Af "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7" "\\$8" "\\$9"
+\\*(;G
+.ft \\n(;G \}
+..
+.de L
+.aF 5 \\n(.f "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de LR
+.aF 5 1 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de RL
+.aF 1 5 "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6" "\\$7"
+..
+.de EX \" start example
+.ta 1i 2i 3i 4i 5i 6i
+.PP
+.RS
+.PD 0
+.ft 5
+.nf
+..
+.de EE \" end example
+.fi
+.ft
+.PD
+.RE
+.PP
+..
+.TH VECARGS 3
+.SH NAME
+vecargs \- command argument vector insertion routines
+.SH SYNOPSIS
+.L "#include <vecargs.h>"
+.sp
+.L "char** vecload(char* string);"
+.L "char** vecfile(const char* path);"
+.L "char** vecstring(const char* string);"
+.L "void vecfree(char**, int);"
+.L "int vecargs(char** vec, int* argcp, char*** argvp);"
+.SH DESCRIPTION
+.L vecload
+loads a string vector from lines in
+.LR string .
+.L string
+may be modified upon return.
+Each line in
+.L string
+is treated as a new vector element.
+Lines with
+.L #
+as the first character are comments.
+.I \enewline
+joins consecutive lines.
+A string vector pointer is returned, 0 on error.
+.PP
+.L vecfile
+constructs a string vector by calling
+.L vecload
+on the contents of the file named by
+.LR path .
+The string vector pointer is returned, 0 on error.
+.PP
+.L vecstring
+constructs a string vector by calling
+.L vecload
+on a copy of
+.LR string .
+The string vector pointer is returned, 0 on error.
+.PP
+.L vecfree
+frees a string vector allocated by
+.LR vecfile ,
+.L vecload
+or
+.LR vecstring .
+.PP
+.L vecargs
+inserts the string vector
+.L vec
+(as returned by
+.LR vecfile ,
+.L vecload
+or
+.LR vecstring )
+between
+.L "(*argvp)[0]"
+and
+.LR "(*argvp)[1]" ,
+sliding
+.L "(*argvp)[1] ..."
+over.
+NULL and empty string args in
+.L vec
+are not copied.
+.L "vecfree(vec)"
+is called before the return.
+.L \-1
+is returned if the insertion failed.
+.SH EXAMPLES
+.L vecargs
+is commonly used to modify command
+.L argv
+from fixed files.
+For example,
+.IR make (1)
+checks for the files
+.L ./Makeargs
+and
+.L ./makeargs
+to modify its arguments on startup.
+Its a handy way to override default options on a directory by directory basis
+without modify the standard control files
+(\f5Makefile\fP in this case.)
+.SH CAVEATS
+This paradigm is not recommended for all commands; only a few exceptions
+make sense.
diff --git a/src/lib/libast/man/vmalloc.3 b/src/lib/libast/man/vmalloc.3
new file mode 100644
index 0000000..3bc6413
--- /dev/null
+++ b/src/lib/libast/man/vmalloc.3
@@ -0,0 +1,640 @@
+.fp 5 CW
+.de MW
+\f5\\$1\fP
+..
+.TH VMALLOC 3 "1 May 1998"
+.SH NAME
+vmalloc \- virtual memory allocation
+.SH SYNOPSIS
+.MW "#include <vmalloc.h>"
+.SS Regions
+.nf
+.MW "Vmalloc_t* vmopen(Vmdisc_t* disc, Vmethod_t* meth, int flags);"
+.MW "int vmclose(Vmalloc_t*);"
+.MW "int vmclear(Vmalloc_t*);"
+.MW "int vmcompact(Vmalloc_t* region);"
+.MW "int vmset(Vmalloc_t* region, int flags, int type);"
+.MW "Vmalloc_t* Vmheap;"
+.MW "Vmdisc_t* vmdisc(Vmalloc_t* region, Vmdisc_t* disc);"
+.MW "Vmalloc_t* vmmopen(char* file, int project, ssize_t size);"
+.MW "Void_t* vmmvalue(Vmalloc_t* vm, int key, Void_t* value, int op);"
+.MW "Void_t* vmmcleanup(Vmalloc_t* vm);"
+.MW "Void_t* vmmaddress(size_t size);"
+.fi
+.SS "Allocation functions"
+.nf
+.MW "Void_t* vmalloc(Vmalloc_t* region, size_t size);"
+.MW "Void_t* vmalign(Vmalloc_t* region, size_t size, size_t align);"
+.MW "Void_t* vmresize(Vmalloc_t* region, Void_t* addr, size_t size, int type);"
+.MW "int vmfree(Vmalloc_t* region, Void_t* addr);"
+.MW "Void_t* vmnewof(Vmalloc_t* region, Void_t* addr, type, size_t n, size_t x);"
+.MW "Void_t* vmoldof(Vmalloc_t* region, Void_t* addr, type, size_t n, size_t x);"
+.MW "Void_t* vmgetmem(Vmalloc_t* region, Void_t* addr, size_t size);"
+.fi
+.SS "Debugging"
+.nf
+.MW "int vmdebug(int);"
+.MW "int vmdbcheck(Vmalloc_t* vm);"
+.MW "int vmdbwatch(Void_t* addr);"
+.MW "static void vmdbwarn(Vmalloc_t*, char* mesg, int n);"
+.fi
+.SS "Profiling"
+.nf
+.MW "void vmprofile(Vmalloc_t* vm, int fd);"
+.fi
+.SS "Information and statistics"
+.nf
+.MW "int vmbusy(Vmalloc_t* region);"
+.MW "Vmalloc_t* vmregion(Void_t* addr);"
+.MW "Void_t* vmsegment(Vmalloc_t* region, Void_t* addr);"
+.MW "int vmwalk(Vmalloc_t* region, int(*walkf)(Vmalloc_t*, Void_t*, size_t, Vmdisc_t*);"
+.MW "long vmaddr(Vmalloc_t* region, Void_t* addr);"
+.MW "long vmsize(Vmalloc_t* region, Void_t* addr);"
+.MW "int vmstat(Vmalloc_t* vm, Vmstat_t* statb);"
+.MW "int vmtrace(int fd);"
+.MW "int vmtrbusy(Vmalloc_t* vm);"
+.MW "Void_t* vmdata(Vmalloc_t* vm);"
+.fi
+.SS "Malloc-compatible functions"
+.nf
+.MW "Void_t* malloc(size_t size);"
+.MW "Void_t* realloc(Void_t* addr, size_t size);"
+.MW "Void_t* calloc(size_t n_obj, size_t s_obj);"
+.MW "int cfree(Void_t* addr);"
+.MW "void free(Void_t* addr);"
+.MW "Void_t* memalign(size_t align, size_t size);"
+.MW "Void_t* valloc(size_t size);"
+.MW "int setregmax(int regmax);"
+.fi
+.SH DESCRIPTION
+These functions for dynamic storage allocation work in
+\fIregions\fP of memory.
+Each region has an \fIallocation method\fP
+for parceling out blocks of storage and a
+\fImemory discipline\fP for obtaining raw space.
+Automatic locking prevents interference by reentrant
+access to a region.
+.PP
+Pointers to space have type \f5Void_t*\fP
+where \f5Void_t\fP is \f5#define\fPd as \f5void\fP if possible, otherwise \f5char\fP.
+Space is counted in type \f5size_t\fP.
+
+.ne 4
+.SS Regions
+Regions have type \f5Vmalloc_t\fP.
+Two predefined regions are pointed to by:
+.TP
+.MW Vmheap
+A general-purpose region, with best-fit
+allocation, and system memory discipline \f5Vmdcsystem\fP.
+.PP
+These functions manipulate regions:
+.PP
+.I vmopen
+creates a region with memory discipline \fIdisc\fP,
+allocation method \fImeth\fP,
+and a setting for control \fIflags\fP.
+It returns a pointer to the region on success and \f5NULL\fP on failure.
+The flags, represented by bit values or-ed together, are:
+.TP
+.MW VM_SHARE
+This region may be accessed concurrently by multiple threads or processes.
+.TP
+.MW VM_TRACE
+Place tracing messages for each allocation event
+on the tracing file established by \fIvmtrace\fP.
+.TP
+\f5VM_DBCHECK\fP, \f5VM_DBABORT\fP
+.br
+See \fBDebugging\fP below.
+.PP
+.I vmclose
+closes a \fIregion\fP and releases all associated memory
+according to the region's discipline.
+The first segment obtained from the discipline's
+\f5memoryf\fP function (see `Disciplines' below) will be the last released.
+\fIvmclose\fP returns \-1 on failure and a non-negative value otherwise.
+.PP
+.I vmclear
+frees all allocated blocks in \fIregion\fP regardless of methods.
+It returns \-1 on failure and a non-negative value otherwise.
+.PP
+.I vmcompact
+releases as much of a \fIregion\fP's
+free space to its discipline's \f5memoryf\fP
+function as possible.
+It returns a nonnegative value on success and \-1 on failure.
+.PP
+.I vmset
+adjusts and queries a \fIregion\fP's \fIflags\fP.
+The indicated flags are turned on if \fItype\fP is nonzero, off if zero.
+\fIvmset\fP returns the previous value of all flags.
+Thus, \f5vmset(region,0,0)\fP queries the flags without changing them.
+In addition to the settable flags, one of
+\f5VM_MTBEST\fP, \f5VM_MTDEBUG\fP, \f5VM_MTPROFILE\fP,
+\f5VM_MTPOOL\fP, or \f5VM_MTLAST\fP
+is returned to indicate the method used in creating the \fIregion\fP.
+.PP
+.I vmdisc
+changes the discipline of \fIregion\fP to the given new discipline
+\fIdisc\fP if \fIdisc\fP is not \f5NULL\fP and its \f5memoryf\fP function
+is the same as the current discipline. If the current discipline
+has an \f5exceptf\fP function, it will be called with event \f5VM_DISC\fP.
+This function always returns the current discipline.
+.PP
+.I vmmopen
+creates a region to allocate memory obtained via either
+\fImmap(2)\fP when \fIproject < 0\fP or \fIshmget(2)\fP when \fIproject >= 0\fP.
+The region is built from a single memory segment
+guaranteed to be at least as large as \fIsize\fP.
+When \fIproject >= 0\fP,
+\fIfile\fP and \fIproject\fP are used in a call to \fIftok(3)\fP
+to get a key suitable for getting a shared memory segment via \fIshmget(2)\fP.
+Otherwise, \fIfile\fP is the backing store for the mapped data.
+In this case, not only the region may be used concurrently by different processes,
+it is also persistent. That is, process could even exit, move the file to
+a different but similar machine then restart and open the same
+region to continue working.
+.PP
+Note that Vmalloc can protect concurrent accesses only on region entry and exit
+for memory allocation operations.
+This means that at the time when regions are being opened or closed, there will be no
+protection for the memory segments being attached into or detached from process memory space.
+This limitation has a special impact on \fIvmmopen()\fP as follows.
+.PP
+A shared memory segment opened via \fIvmmopen()\fP corresponds uniquely
+to a combination of the \fIfile\fP and \fIproject\fP parameters.
+Thus, if multiple \fIvmmopen()\fP calls are done in the same process using a
+same combination of \fIfile\fP and \fIproject\fP,
+the joined behavior of such regions will be unpredictable when opening and closing
+are done concurrently with other memory allocation operations.
+Beware that this effect can be subtle with library functions that may attempt
+to create their own memory allocation regions.
+.PP
+.I vmmvalue
+manages pairs of \fIkey\fP and \fIvalue\fP in a region opened via \fIvmopen()\fP.
+If \fIop\fP is \f5VM_MMGET\fP, the value associated with \f5key\fP is returned.
+If \fIop\fP is \f5VM_MMSET\fP, the value associated with \f5key\fP will be
+set to \fIvalue\fP.
+If \fIop\fP is \f5VM_MMADD\fP, the value associated with \f5key\fP will be
+treated as a signed long value to which \f5val\fP (also treated as a signed long value)
+will be added.
+The call always returns the updated data value associated with \fIkey\fP.
+.PP
+.I vmmcleanup
+sets region up to remove backing store or \fIshmid\fP on closing.
+.PP
+.I vmmaddress
+computes an address suitable for attaching a shared memory segment or
+memory mapping a segment of file data of the given \fIsize\fP.
+The address is chosen with hope to minimize collision with other activities
+related to memory such as growth of stack space or space used
+for dynamically linked libraries, etc.
+
+.SS "Allocation functions"
+.I vmalloc
+returns a pointer to a block of the requested \fIsize\fP
+in a \fIregion\fP, aligned to the \fIstrictest alignment\fP
+that is suitable for the needs of any basic data type.
+It returns \f5NULL\fP on failure.
+.PP
+.I vmalign
+works like \fIvmalloc\fP, but returns a block aligned to a common
+multiple of \fIalign\fP and the \fIstrictest alignment\fP.
+.PP
+.I vmresize
+attempts to change the length of the block pointed to by
+\fIaddr\fP to the specified \fIsize\fP.
+If that is impossible and \fItype\fP has
+at least one of \f5VM_RSMOVE\fP and \f5VM_RSCOPY\fP,
+a new block is allocated and the old block is freed.
+The bit \f5VM_RSCOPY\fP also causes
+the new block to be initialized with
+as much of the old contents as will fit.
+When a resized block gets larger, the new space will be cleared
+if \fItype\fP has the bit \f5VM_RSZERO\fP.
+\fIvmresize\fP
+returns a pointer to the final block, or \f5NULL\fP on failure.
+If \fIaddr\fP is \f5NULL\fP, \fIvmresize\fP behaves like \fIvmalloc\fP;
+otherwise, if \fIsize\fP is 0, it behaves like \fIvmfree\fP.
+.PP
+.I vmfree
+makes the currently allocated block pointed to by
+\fIaddr\fP available for future allocations in its \fIregion\fP.
+If \fIaddr\fP is \f5NULL\fP, \fIvmfree\fP does nothing.
+It returns \-1 on error, and nonnegative otherwise.
+.PP
+.I vmnewof
+is a macro function that attempts to change the length of
+the block pointed to by \fIaddr\fP to the size \f5n*sizeof(type)+x\fP.
+If the block is moved, new space will be initialized with as much of the
+old content as will fit.
+Additional space will be set to zero.
+.PP
+.I vmoldof
+is similar to \fIvmnewof\fP but it neither copies data nor clears space.
+.PP
+.I vmgetmem
+provides a handy function to creat/close regions and allocate/free memory
+based on chunks of memory obtained from the heap region \fIVmheap\fP.
+.TP
+.MW "vmgetmem(0,0,0)"
+This call opens a new region.
+.TP
+.MW "vmgetmem(region, 0, 0)"
+This call closes the given \f5region\fP.
+.TP
+.MW "vmgetmem(region,0,n)"
+This call allocates a block of length \f5n\fP and clears it to zeros.
+.TP
+.MW "vmgetmem(region,p,0)"
+This call frees the block \f5p\fP.
+.TP
+.MW "vmgetmem(region,p,n)"
+This call resizes the block \f5p\fP to length \f5n\fP
+and clears the new memory to zeros if the block grows.
+The block may be moved as deemed necessary by the allocator.
+.PP
+.SS "Memory disciplines"
+Memory disciplines have type \f5Vmdisc_t\fP,
+a structure with these members:
+.in +.5i
+.nf
+.MW "Void_t* (*memoryf)(Vmalloc_t *region, Void_t* obj,"
+.ti +.5i
+.MW "size_t csz, size_t nsz, Vmdisc_t *disc);"
+.MW "int (*exceptf)(Vmalloc_t *region, int type, Void_t* obj, Vmdisc_t *disc);"
+.MW "int round;"
+.fi
+.in -.5i
+.TP
+.MW round
+If this value is positive, all size arguments to the
+\f5memoryf\fP function will be multiples of it.
+.TP
+.MW memoryf
+Points to a function to get or release segments of space for the
+\fIregion\fP.
+.TP
+.MW exceptf
+If this pointer is not \f5NULL\fP,
+the function it points to is called to announce
+events in a \fIregion\fP.
+.PP
+There are two standard disciplines, both with \f5round\fP being 0 and \f5exceptf\fP being \f5NULL\fP.
+.TP
+.MW Vmdcsystem
+A discipline whose \f5memoryf\fP function gets space from the operation system
+via different available methods which include \fImmap(2)\fP, \fIsbrk(2)\fP and
+functions from the WIN32 API.
+For historical reason, \fIVmdcsbrk\fP is also available and functions like \fIVmdcsystem\fP.
+.TP
+.MW Vmdcheap
+A discipline whose \f5memoryf\fP function gets space from the region \f5Vmheap\fP.
+A region with \f5Vmdcheap\fP discipline and \f5Vmlast\fP
+allocation is good for building throwaway data structures.
+.PP
+A \fImemoryf\fP
+function returns a pointer to a memory segment on success, and \f5NULL\fP on failure.
+When \fInsz >= 0\fP and \fIcsz > 0\fP,
+the function first attempts to change the current segment \fIaddr\fP to fit \fInsz\fP
+(for example, \fInsz == 0\fP means deleting the segment \fIaddr\fP).
+If this attempt is successful, it should return \fIaddr\fP.
+Otherwise, if \fInsz > csz\fP, the function may try to allocate a new segment
+of size \fInsz-csz\fP. If successful, it should return the address of the new segment.
+In all other cases, it should return NULL.
+.PP
+An \fIexceptf\fP
+function is called for events identified by \fItype\fP, which is coded thus:
+.TP
+.MW VM_OPEN
+This event is raised at the start of the process to open a new region.
+Argument \fIobj\fP will be a pointer to an object of type \f5Void_t*\fP
+initialized to NULL before the call. The return value of \fIexceptf\fP
+is significant as follows:
+
+On a negative return value, \fIvmopen\fP will terminate with failure.
+
+On a zero return value, \fIexceptf\fP may set \f5*((Void_t**)obj)\fP
+to some non-NULL value to tell \fIvmopen\fP
+to allocate the region handle itself via \fImemoryf\fP. Otherwise,
+the region handle will be allocated from the \f5Vmheap\fP region.
+
+On a positive return value,
+the new region is being reconstructed
+based on existing states of some previous region.
+In this case, \fIexceptf\fP should set \f5*(Void_t**)\fP\fIobj\fP to point to
+the field \f5Vmalloc_t.data\fP of the corresponding previous region
+(see \f5VM_CLOSE\fP below).
+If the handle of the previous region was allocated
+via \fImemoryf\fP as discussed above in the case of the zero return value,
+then it will be exactly restored. Otherwise, a new handle will be allocated from \f5Vmheap\fP.
+The ability to create regions sharing the same states allows for
+managing shared and/or persistent memory.
+.TP
+.MW VM_ENDOPEN
+This event is raised at the end of the process to open a new region.
+The return value of \fIexceptf\fP will be ignored.
+.TP
+.MW VM_CLOSE
+This event is raised at the start of the process to close a region,
+The return value of \fIexceptf\fP is significant as follows:
+
+On a negative return value, \fIvmclose\fP immediately returns with failure.
+
+On a zero return value, \fIvmclose\fP proceeds normally by calling \f5memoryf\fP to free
+all allocated memory segments and also freeing the region itself.
+
+On a positive return value, \fIvmclose\fP will only free the region
+without deallocating the associated memory segments. That is,
+the field \fIVmalloc_t.data\fP of the region handle remains intact.
+This is useful for managing shared and/or persistent memory (see \f5VM_OPEN\fP above).
+.TP
+.MW VM_ENDCLOSE
+This event is raised at the end of the process to close a region.
+The return value of \fIexceptf\fP will be ignored.
+.TP
+.MW VM_NOMEM
+An attempt to extend the region by the amount
+\f5(size_t)\fP\fIobj\fP failed. The region is unlocked, so the
+\fIexceptf\fP function may free blocks.
+If the function returns a positive value the memory
+request will be repeated.
+.TP
+.MW VM_DISC
+The discipline structure is being changed.
+
+.SS "Allocation methods"
+Methods are of type \f5Vmethod_t*\fP.
+.TP
+.MW Vmbest
+An approximately best-fit allocation strategy.
+.TP
+.MW Vmlast
+A strategy for building structures that are only deleted in whole.
+Only the latest allocated block can be freed.
+This means that as soon as a block \f5a\fP is allocated,
+\fIvmfree\fP calls on blocks other than \c5a\fP are ignored.
+.TP
+.MW Vmpool
+A strategy for blocks of one size,
+set by the first \fIvmalloc\fP call after \fIvmopen\fP or \fIvmclear\fP.
+.TP
+.MW Vmdebug
+An allocation strategy with extra-stringent checking and locking.
+It is useful for finding misuses of dynamically allocated
+memory, such as writing beyond the boundary of a block, or
+freeing a block twice.
+.ne 3
+.TP
+.MW Vmprofile
+An allocation method that records and prints summaries of memory usage.
+
+.SS Debugging
+The method \f5Vmdebug\fP is used to debug common memory violation problems.
+When a problem is found,
+a warning message is written to file descriptor 2 (standard error).
+In addition, if flag \f5VM_DBABORT\fP is on,
+the program is terminated by calling \fIabort\fP(2).
+Each message is a line of self-explanatory fields separated by colons.
+The optional flag \f5-DVMFL\fP, if used during compilation,
+enables recording of file names and line numbers.
+The following functions work with method \f5Vmdebug\fP.
+.PP
+.I vmdebug
+resets the file descriptor to write out warnings to the given argument.
+By default, this file descriptor is 2, the standard error.
+\fIvmdebug\fP returns the previous file descriptor.
+.PP
+.I vmdbcheck
+checks a region using \f5Vmdebug\fP or \f5Vmbest\fP for integrity.
+If \f5Vmdebug\fP, this also checks for block overwriting errors.
+On errors, \fIvmdbwarn\fP is called.
+If flag \f5VM_DBCHECK\fP is on,
+\fIvmdbcheck\fP is called at each invocation of
+\fIvmalloc\fP, \fIvmfree\fP, or \fIvmresize\fP.
+.PP
+.I vmdbwatch
+causes address \fIaddr\fP
+to be watched, and reported whenever met in
+\fIvmalloc\fP, \fIvmresize\fP or \fIvmfree\fP.
+The watch list has finite size and if it becomes full,
+watches will be removed in a first-in-first-out fashion.
+If \fIaddr\fP is \f5NULL\fP,
+all current watches are canceled.
+\fIvmdbwatch\fP returns the watch bumped out due to an insertion
+into a full list or \f5NULL\fP otherwise.
+.PP
+.I vmdbwarn
+is an internal function that processes
+warning messages for discovered errors.
+It can't be called from outside the \fIvmalloc\fP package,
+but is a good place to plant debugger traps because
+control goes there at every trouble.
+
+.SS "Profiling"
+The method \f5Vmprofile\fP is used to profile memory usage.
+Profiling data are maintained in private memory of a process so
+\f5Vmprofile\fP should be avoided from regions manipulating
+persistent or shared memory.
+The optional flag \f5-DVMFL\fP, if used during compilation,
+enables recording of file names and line numbers.
+.PP
+.I vmprofile
+prints memory usage summary.
+The summary is restricted to region \fIvm\fP if \fIvm\fP is not \f5NULL\fP;
+otherwise, it is for all regions created with \f5Vmprofile\fP.
+Summary records are written to file descriptor \fIfd\fP as lines with
+colon-separated fields. Here are some of the fields:
+.TP
+.I n_alloc,n_free:
+Number of allocation and free calls respectively. Note that a resize
+operation is coded as a free and an allocation.
+.TP
+.I s_alloc,s_free:
+Total amounts allocated and freed. The difference between these numbers
+is the amount of space not yet freed.
+.TP
+.I max_busy, extent:
+These fields are only with the summary record for region.
+They show the maximum busy space at any time and the extent of the region.
+
+.SS "Information and statistics"
+.I vmbusy
+returns the busy status of a region.
+A region is busy if some allocation operation is accessing it.
+.PP
+.I vmregion
+returns the region to which the block pointed to by
+\fIaddr\fP belongs.
+This works only in regions that allocate with
+\f5Vmbest\fP, \f5Vmdebug\fP or \f5Vmprofile\fP.
+.PP
+.I vmsegment
+finds if some segment of memory in \fIregion\fP
+contains the address \fIaddr\fP.
+It returns the address of a found segment or \f5NULL\fP if none found.
+.PP
+.I vmwalk
+walks all segments in \fIregion\fP or if \fIregion\fP is \f5NULL\fP,
+all segments in all regions.
+At each segment, \fI(*walkf)(vm,addr,size,disc)\fP
+is called where \fIvm\fP is the region, \fIaddr\fP is the segment,
+\fIsize\fP is the size of the segment, and \fIdisc\fP is the region's discipline.
+If \fIwalkf\fP returns a negative value, the walk stops and returns the same value.
+On success, \fIvmwalk\fP returns 0; otherwise, it returns \-1.
+.PP
+.I vmaddr
+checks whether \fIaddr\fP
+points to an address within some allocated block of the given region.
+If not, it returns \-1.
+If so, it returns the offset from the beginning of the block.
+The function does not work for a \f5Vmlast\fP region except
+on the latest allocated block.
+.PP
+.I vmsize
+returns the size of the allocated block pointed to by \fIaddr\fP.
+It returns \-1 if \fIaddr\fP
+does not point to a valid block in the region.
+Sizes may be padded beyond that requested; in
+particular no block has size 0.
+The function does not work for a \f5Vmlast\fP region except
+on the latest allocated block.
+.PP
+.I vmstat
+gathers statistics on the given \fIregion\fP.
+If \f5region\fP is NULL, it computes statistics for the \fIMalloc\fP calls.
+This may include summing statistics from more than one regions constructed to avoid blocking
+due to parallel or asynchronous operations.
+If \fIstatb\fP is not NULL, \fIvmstat\fP computes and stores the statistics in \fIstatb\fP then returns 0.
+If \fIstatb\fP is NULL, no statistics will be computed and
+the returned value is either 1 if the region is busy, i.e.,
+being accessed by some allocation call or 0 otherwise.
+
+A \f5Vmstat_t\fP structure has at least these members:
+.in +.5i
+.nf
+.ta \w'\f5size_t \fP'u +\w'\f5extent \fP'u
+.MW "int n_busy; /* # of busy blocks */
+.MW "int n_free; /* # of free blocks */
+.MW "size_t s_busy; /* total busy space */
+.MW "size_t s_free; /* total free space */
+.MW "size_t m_busy; /* maximum busy block size */
+.MW "size_t m_free; /* maximum free block size */
+.MW "int n_seg; /* count of segments */
+.MW "size_t extent; /* memory extent of region */
+.MW "int n_region; /* total Malloc regions */
+.MW "int n_open; /* non-blocked operations */
+.MW "int n_lock; /* blocked operations */
+.MW "int n_probe; /* region searches */
+.fi
+.in -.5i
+.PP
+Bookeeping overhead is counted in \f5extent\fP,
+but not in \f5s_busy\fP or \f5s_free\fP.
+.PP
+.I vmtrace
+establishes file descriptor \fIfd\fP
+as the trace file and returns
+the previous value of the trace file descriptor.
+The trace descriptor is initially invalid.
+Output is sent to the trace file by successful allocation
+events when flag \f5VM_TRACE\fP is on.
+.PP
+Tools for analyzing traces are described in \fImtreplay\fP(1).
+The trace record for an allocation event
+is a line with colon-separated fields, four numbers and one string.
+.TP
+.I old
+Zero for a fresh allocation;
+the address argument for freeing and resizing.
+.TP
+.I new
+Zero for freeing;
+the address returned by allocation or resizing.
+.TP
+.I size
+The size argument for allocation or resizing;
+the size freed by freeing.
+Sizes may differ due to padding for alignment.
+.TP
+.I region
+The address of the affected region.
+.TP
+.I method
+A string that tells the region's method:
+\f5best\fP, \f5last\fP, \f5pool\fP, \f5profile\fP, or \f5debug\fP.
+.PP
+.I vmtrbusy
+outputs a trace of all currently busy blocks in region \f5vm\fP.
+This only works with the \f5Vmbest\fP, \f5Vmdebug\fP and \f5Vmprofile\fP methods.
+.PP
+.I vmdata
+returns the core data of the given region.
+The core data hold the data structures for allocated and free blocks.
+Depending on the region discipline,
+the core data of a region may be in shared or persistent memory even
+if the region pointer created with \fIvmopen\fP is always in private process memory.
+
+.SS "Malloc-compatible functions"
+This set of functions implement \fImalloc\fP(3).
+They allocate via the \fIVmregion\fP region which is initially set
+to be \fIVmheap\fP.
+
+Concurrent accesses are supported unless an application
+change \fIVmregion\fP to something other than \fIVmheap\fP.
+New regions may be created on the fly to avoid blocking.
+The maximum number of regions that can be created
+this way is set to 64 by default. An application could
+reduce this number by calling \fIsetregmax(regmax)\fP to
+set the maximum number of these extra regions to \fIregmax\fP.
+\fIsetregmax()\fP always returns the previous value.
+.PP
+These functions are instrumented for run-time debugging, profiling and tracing.
+For accurate reporting of files and line numbers,
+application code should include \f5vmalloc.h\fP and compile with \f5-DVMFL\fP.
+The following environment variables can be set before any memory allocation
+(e.g., before a process starts) to drive different modes:
+.TP
+.I VMETHOD
+This defines the method to use for allocation.
+Its value should be one of the strings:
+\fIVmbest, Vmdebug, Vmprofile, Vmlast, Vmpool\fP.
+The 'V' can be in lower case.
+.TP
+.I VMDEBUG
+This is ignored if
+a method other than \f5Vmdebug\fP has been selected with \fIVMETHOD\fP.
+\fIVMDEBUG\fP can be any combination of `a',
+a decimal number and a list of hexadecimal numbers.
+`a' causes the program to abort on any discovered allocation error.
+A hexadecimal number starts with either \fI0x\fP or \fI0X\fP
+and defines an address to watch (see \fIvmdbwatch\fP).
+Any other number is taken to be decimal and defines a period \fIp\fP
+to check the arena for integrity. The default period is 1, ie, the
+arena is checked on every call to a \fImalloc\fP function.
+Other letters not part of the defined set are ignored.
+.TP
+.I VMPROFILE
+This is ignored if a method other than \f5Vmprofile\fP
+has been selected by \fIVMETHOD\fP or \fIVMDEBUG\fP.
+\fIVMPROFILE\fP defines a file name to store profile data.
+Each instance of the pattern `%p' found in \fIVMPROFILE\fP
+is transformed to the process id of the running process.
+If the file cannot be created, file descriptor 2 (standard error)
+is used for output.
+.TP
+.I VMTRACE
+If this defines a valid writable file, trace messages of all allocation calls
+are written to the given file (see \fIvmopen()\fP and \fIvmtrace()\fP).
+Similar to \fIVMPROFILE\fP, each instance of the pattern `%p' found
+in \fIVMTRACE\fP is turned to the process id of the running process.
+
+.SH RECENT CHANGES
+\f5Vmlast\fP: allocated blocks are now allowed to be resized (09/1998).
+
+.SH SEE ALSO
+\fImtreplay\fP(1), \fImalloc\fP(3).
+
+.SH AUTHOR
+Kiem-Phong Vo, kpv@research.att.com
diff --git a/src/lib/libast/misc/astintercept.c b/src/lib/libast/misc/astintercept.c
new file mode 100644
index 0000000..c4e84cb
--- /dev/null
+++ b/src/lib/libast/misc/astintercept.c
@@ -0,0 +1,53 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "intercepts.h"
+
+/*
+ * NOTE: the "intercepts" definition is in getenv.c because some static linkers
+ * miss lone references to "intercepts" without "astintercept()"
+ */
+
+/*
+ * set/clear ast intercept callouts
+ */
+
+int
+astintercept(Shbltin_t* call, int set)
+{
+ if (call->shgetenv)
+ {
+ if (set)
+ intercepts.intercept_getenv = call->shgetenv;
+ else
+ intercepts.intercept_getenv = 0;
+ }
+ if (call->shsetenv)
+ {
+ if (set)
+ intercepts.intercept_setenviron = call->shsetenv;
+ else
+ intercepts.intercept_setenviron = 0;
+ }
+ return 0;
+}
diff --git a/src/lib/libast/misc/cmdarg.c b/src/lib/libast/misc/cmdarg.c
new file mode 100644
index 0000000..38d247b
--- /dev/null
+++ b/src/lib/libast/misc/cmdarg.c
@@ -0,0 +1,382 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * xargs/tw command arg list support
+ */
+
+#define _AST_API_H 1
+
+#include <ast.h>
+#include <cmdarg.h>
+
+Cmdarg_t*
+cmdopen(char** argv, int argmax, int size, const char* argpat, int flags)
+{
+ Error_f ef;
+
+ if (flags & CMD_SILENT)
+ ef = 0;
+ else
+ {
+ ef = errorf;
+ flags |= CMD_EXIT;
+ }
+ return cmdopen_20110505(argv, argmax, size, argpat, flags, ef);
+}
+
+#undef _AST_API_H
+
+#include <ast_api.h>
+
+#include <ctype.h>
+#include <proc.h>
+
+#ifndef ARG_MAX
+#define ARG_MAX (64*1024)
+#endif
+#ifndef EXIT_QUIT
+#define EXIT_QUIT 255
+#endif
+
+static const char* echo[] = { "echo", 0 };
+
+/*
+ * open a cmdarg stream
+ * initialize the command for execution
+ * argv[-1] is reserved for procrun(PROC_ARGMOD)
+ */
+
+Cmdarg_t*
+cmdopen_20110505(char** argv, int argmax, int size, const char* argpat, int flags, Error_f errorf)
+{
+ register Cmdarg_t* cmd;
+ register int n;
+ register char** p;
+ register char* s;
+ char* sh;
+ char* exe;
+ int c;
+ int m;
+ int argc;
+ long x;
+
+ char** post = 0;
+
+ n = sizeof(char**);
+ if (*argv)
+ {
+ for (p = argv + 1; *p; p++)
+ {
+ if ((flags & CMD_POST) && argpat && streq(*p, argpat))
+ {
+ *p = 0;
+ post = p + 1;
+ argpat = 0;
+ }
+ else
+ n += strlen(*p) + 1;
+ }
+ argc = p - argv;
+ }
+ else
+ argc = 0;
+ for (p = environ; *p; p++)
+ n += sizeof(char**) + strlen(*p) + 1;
+ if ((x = strtol(astconf("ARG_MAX", NiL, NiL), NiL, 0)) <= 0)
+ x = ARG_MAX;
+ if (size <= 0 || size > x)
+ size = x;
+ sh = pathshell();
+ m = n + (argc + 4) * sizeof(char**) + strlen(sh) + 1;
+ m = roundof(m, sizeof(char**));
+ if (size < m)
+ {
+ if (errorf)
+ (*errorf)(NiL, sh, 2, "size must be at least %d", m);
+ return 0;
+ }
+ if ((m = x / 10) > 2048)
+ m = 2048;
+ if (size > (x - m))
+ size = x - m;
+ n = size - n;
+ m = ((flags & CMD_INSERT) && argpat) ? (strlen(argpat) + 1) : 0;
+ if (!(cmd = newof(0, Cmdarg_t, 1, n + m)))
+ {
+ if (errorf)
+ (*errorf)(NiL, sh, ERROR_SYSTEM|2, "out of space");
+ return 0;
+ }
+ cmd->errorf = errorf;
+ c = n / sizeof(char**);
+ if (argmax <= 0 || argmax > c)
+ argmax = c;
+ s = cmd->buf;
+ if (!(exe = argv[0]))
+ {
+ exe = *(argv = (char**)echo);
+ cmd->echo = 1;
+ }
+ else if (streq(exe, echo[0]))
+ {
+ cmd->echo = 1;
+ flags &= ~CMD_NEWLINE;
+ }
+ else if (!(flags & CMD_CHECKED))
+ {
+ if (!pathpath(exe, NiL, PATH_REGULAR|PATH_EXECUTE, s, n + m))
+ {
+ n = EXIT_NOTFOUND;
+ if (errorf)
+ (*cmd->errorf)(NiL, cmd, ERROR_SYSTEM|2, "%s: command not found", exe);
+ if (flags & CMD_EXIT)
+ (*error_info.exit)(n);
+ free(cmd);
+ return 0;
+ }
+ exe = s;
+ }
+ s += strlen(s) + 1;
+ if (m)
+ {
+ cmd->insert = strcpy(s, argpat);
+ cmd->insertlen = m - 1;
+ s += m;
+ }
+ s += sizeof(char**) - (s - cmd->buf) % sizeof(char**);
+ p = (char**)s;
+ n -= strlen(*p++ = sh) + 1;
+ cmd->argv = p;
+ *p++ = exe;
+ while (*p = *++argv)
+ p++;
+ if (m)
+ {
+ argmax = 1;
+ *p++ = 0;
+ cmd->insertarg = p;
+ argv = cmd->argv;
+ c = *cmd->insert;
+ while (s = *argv)
+ {
+ while ((s = strchr(s, c)) && strncmp(cmd->insert, s, cmd->insertlen))
+ s++;
+ *p++ = s ? *argv : (char*)0;
+ argv++;
+ }
+ *p++ = 0;
+ }
+ cmd->firstarg = cmd->nextarg = p;
+ cmd->laststr = cmd->nextstr = cmd->buf + n;
+ cmd->argmax = argmax;
+ cmd->flags = flags;
+ cmd->offset = ((cmd->postarg = post) ? (argc - (post - argv)) : 0) + 3;
+ return cmd;
+}
+
+/*
+ * flush outstanding command file args
+ */
+
+int
+cmdflush(register Cmdarg_t* cmd)
+{
+ register char* s;
+ register char** p;
+ register int n;
+
+ if (cmd->flags & CMD_EMPTY)
+ cmd->flags &= ~CMD_EMPTY;
+ else if (cmd->nextarg <= cmd->firstarg)
+ return 0;
+ if ((cmd->flags & CMD_MINIMUM) && cmd->argcount < cmd->argmax)
+ {
+ if (cmd->errorf)
+ (*cmd->errorf)(NiL, cmd, 2, "%d arg command would be too long", cmd->argcount);
+ return -1;
+ }
+ cmd->total.args += cmd->argcount;
+ cmd->total.commands++;
+ cmd->argcount = 0;
+ if (p = cmd->postarg)
+ while (*cmd->nextarg++ = *p++);
+ else
+ *cmd->nextarg = 0;
+ if (s = cmd->insert)
+ {
+ char* a;
+ char* b;
+ char* e;
+ char* t;
+ char* u;
+ int c;
+ int m;
+
+ a = cmd->firstarg[0];
+ b = (char*)&cmd->nextarg[1];
+ e = cmd->nextstr;
+ c = *s;
+ m = cmd->insertlen;
+ for (n = 1; cmd->argv[n]; n++)
+ if (t = cmd->insertarg[n])
+ {
+ cmd->argv[n] = b;
+ for (;;)
+ {
+ if (!(u = strchr(t, c)))
+ {
+ b += sfsprintf(b, e - b, "%s", t);
+ break;
+ }
+ if (!strncmp(s, u, m))
+ {
+ b += sfsprintf(b, e - b, "%-.*s%s", u - t, t, a);
+ t = u + m;
+ }
+ else if (b >= e)
+ break;
+ else
+ {
+ *b++ = *u++;
+ t = u;
+ }
+ }
+ if (b < e)
+ *b++ = 0;
+ }
+ if (b >= e)
+ {
+ if (cmd->errorf)
+ (*cmd->errorf)(NiL, cmd, 2, "%s: command too large after insert", a);
+ return -1;
+ }
+ }
+ cmd->nextarg = cmd->firstarg;
+ cmd->nextstr = cmd->laststr;
+ if (cmd->flags & (CMD_QUERY|CMD_TRACE))
+ {
+ p = cmd->argv;
+ sfprintf(sfstderr, "+ %s", *p);
+ while (s = *++p)
+ sfprintf(sfstderr, " %s", s);
+ if (!(cmd->flags & CMD_QUERY))
+ sfprintf(sfstderr, "\n");
+ else if (astquery(1, "? "))
+ return 0;
+ }
+ if (cmd->echo)
+ {
+ n = (cmd->flags & CMD_NEWLINE) ? '\n' : ' ';
+ for (p = cmd->argv + 1; s = *p++;)
+ sfputr(sfstdout, s, *p ? n : '\n');
+ n = 0;
+ }
+ else if ((n = procrun(*cmd->argv, cmd->argv, PROC_ARGMOD|PROC_IGNOREPATH)) == -1)
+ {
+ n = EXIT_NOTFOUND - 1;
+ if (cmd->errorf)
+ (*cmd->errorf)(NiL, cmd, ERROR_SYSTEM|2, "%s: command exec error", *cmd->argv);
+ if (cmd->flags & CMD_EXIT)
+ (*error_info.exit)(n);
+ return n;
+ }
+ else if (n >= EXIT_NOTFOUND - 1)
+ {
+ if (cmd->flags & CMD_EXIT)
+ (*error_info.exit)(n);
+ }
+ else if (!(cmd->flags & CMD_IGNORE))
+ {
+ if (n == EXIT_QUIT && (cmd->flags & CMD_EXIT))
+ (*error_info.exit)(2);
+ if (n)
+ error_info.errors++;
+ }
+ return n;
+}
+
+/*
+ * add file to the command arg list
+ */
+
+int
+cmdarg(register Cmdarg_t* cmd, const char* file, register int len)
+{
+ int i;
+ int r;
+
+ r = 0;
+ if (len)
+ {
+ while ((cmd->nextstr -= len + 1) < (char*)(cmd->nextarg + cmd->offset))
+ {
+ if (cmd->nextarg == cmd->firstarg)
+ {
+ if (cmd->errorf)
+ (*cmd->errorf)(NiL, cmd, 2, "%s: path too long for exec args", file);
+ return -1;
+ }
+ if (i = cmdflush(cmd))
+ {
+ if (r < i)
+ r = i;
+ if (!(cmd->flags & CMD_IGNORE))
+ return r;
+ }
+ }
+ *cmd->nextarg++ = cmd->nextstr;
+ memcpy(cmd->nextstr, file, len);
+ cmd->nextstr[len] = 0;
+ cmd->argcount++;
+ if (cmd->argcount >= cmd->argmax && (i = cmdflush(cmd)) > r)
+ r = i;
+ }
+ return r;
+}
+
+/*
+ * close a cmdarg stream
+ */
+
+int
+cmdclose(Cmdarg_t* cmd)
+{
+ int n;
+
+ if ((cmd->flags & CMD_EXACT) && cmd->argcount < cmd->argmax)
+ {
+ if (cmd->errorf)
+ (*cmd->errorf)(NiL, cmd, 2, "only %d arguments for last command", cmd->argcount);
+ n = -1;
+ }
+ else
+ {
+ cmd->flags &= ~CMD_MINIMUM;
+ n = cmdflush(cmd);
+ }
+ free(cmd);
+ return n;
+}
diff --git a/src/lib/libast/misc/conformance.c b/src/lib/libast/misc/conformance.c
new file mode 100644
index 0000000..12ee2ca
--- /dev/null
+++ b/src/lib/libast/misc/conformance.c
@@ -0,0 +1,151 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+#include <ctype.h>
+
+static char** ids;
+
+static const char* dflt[] = { "ast", "standard", 0 };
+
+/*
+ * initialize the conformance() id list
+ */
+
+static char**
+initconformance(void)
+{
+ char* m;
+ char** p;
+ char* t;
+ int h;
+ int i;
+ int j;
+ int c;
+ Sfio_t* sp;
+
+ static const char* conf[] = { "CONFORMANCE", "HOSTTYPE", "UNIVERSE" };
+
+ p = 0;
+ if (sp = sfstropen())
+ {
+ for (i = h = 0, j = 1; i < elementsof(conf); i++)
+ if (*(m = astconf(conf[i], NiL, NiL)) && (h |= (1<<i)) || !i && (m = "ast"))
+ {
+ t = m;
+ while ((c = *m++) && c != '.')
+ {
+ if (isupper(c))
+ c = tolower(c);
+ sfputc(sp, c);
+ }
+ sfputc(sp, 0);
+ j++;
+ if ((c = (m - t)) == 6 && strneq(t, "linux", 5))
+ {
+ sfputr(sp, "gnu", 0);
+ j++;
+ }
+ else if (c > 3 && strneq(t, "bsd", 3) || c == 7 && strneq(t, "debian", 7))
+ {
+ sfputr(sp, "bsd", 0);
+ j++;
+ }
+ if (h & 1)
+ break;
+ }
+ i = sfstrtell(sp);
+ sfstrseek(sp, 0, SEEK_SET);
+ if (p = newof(0, char*, j, i))
+ {
+ m = (char*)(p + j--);
+ memcpy(m, sfstrbase(sp), i);
+ i = 0;
+ p[i++] = m;
+ while (i < j)
+ {
+ while (*m++);
+ p[i++] = m;
+ }
+ p[i] = 0;
+ }
+ sfstrclose(sp);
+ }
+ if (!p)
+ p = (char**)dflt;
+ return ids = p;
+}
+
+/*
+ * return conformance id if s size n is in conformance
+ * prefix match of s on the conformance id table
+ * s==0 => "standard"
+ */
+
+char*
+conformance(const char* s, size_t n)
+{
+ char** p;
+ char** q;
+ char* m;
+ const char* e;
+ const char* t;
+
+ static uint32_t serial = ~(uint32_t)0;
+
+ if (!(p = ids) || serial != ast.env_serial)
+ {
+ serial = ast.env_serial;
+ if (ids)
+ {
+ if (ids != (char**)dflt)
+ free(ids);
+ ids = 0;
+ }
+ p = initconformance();
+ }
+ if (!s)
+ s = dflt[1];
+ if (!n)
+ n = strlen(s);
+ e = s + n;
+ if (*s == '(')
+ s++;
+ do
+ {
+ while (s < e && (isspace(*s) || *s == ',' || *s == '|'))
+ s++;
+ if (*s == ')')
+ break;
+ for (t = s; s < e && !isspace(*s) && *s != ',' && *s != '|' && *s != ')'; s++);
+ if (s == t)
+ break;
+ q = p;
+ while (m = *q++)
+ if (strneq(t, m, s - t))
+ return m;
+ if (s < e)
+ s++;
+ } while (s < e);
+ return 0;
+}
diff --git a/src/lib/libast/misc/debug.c b/src/lib/libast/misc/debug.c
new file mode 100644
index 0000000..791973c
--- /dev/null
+++ b/src/lib/libast/misc/debug.c
@@ -0,0 +1,66 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * <debug.h> support
+ */
+
+#include <ast.h>
+#include <error.h>
+#include <debug.h>
+
+void
+debug_fatal(const char* file, int line)
+{
+ error(2, "%s:%d: debug error", file, line);
+ abort();
+}
+
+#if _sys_times
+
+#include <times.h>
+#include <sys/resource.h>
+
+double
+debug_elapsed(int set)
+{
+ double tm;
+ struct rusage ru;
+
+ static double prev;
+
+ getrusage(RUSAGE_SELF, &ru);
+ tm = (double)ru.ru_utime.tv_sec + (double)ru.ru_utime.tv_usec/1000000.0;
+ if (set)
+ return prev = tm;
+ return tm - prev;
+}
+
+#else
+
+double
+debug_elapsed(int set)
+{
+ return 0;
+}
+
+#endif
diff --git a/src/lib/libast/misc/error.c b/src/lib/libast/misc/error.c
new file mode 100644
index 0000000..8ac8c60
--- /dev/null
+++ b/src/lib/libast/misc/error.c
@@ -0,0 +1,659 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * error and message formatter
+ *
+ * level is the error level
+ * level >= error_info.core!=0 dumps core
+ * level >= ERROR_FATAL calls error_info.exit
+ * level < 0 is for debug tracing
+ *
+ * NOTE: id && ERROR_NOID && !ERROR_USAGE implies format=id for errmsg()
+ */
+
+#include "lclib.h"
+
+#include <ctype.h>
+#include <ccode.h>
+#include <namval.h>
+#include <sig.h>
+#include <stk.h>
+#include <times.h>
+#include <regex.h>
+
+/*
+ * 2007-03-19 move error_info from _error_info_ to (*_error_infop_)
+ * to allow future Error_info_t growth
+ * by 2009 _error_info_ can be static
+ */
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+
+extern Error_info_t _error_info_;
+
+Error_info_t _error_info_ =
+{
+ 2, exit, write,
+ 0,0,0,0,0,0,0,0,
+ 0, /* version */
+ 0, /* auxilliary */
+ 0,0,0,0,0,0,0, /* top of old context stack */
+ 0,0,0,0,0,0,0, /* old empty context */
+ 0, /* time */
+ translate,
+ 0 /* catalog */
+};
+
+#undef extern
+
+__EXTERN__(Error_info_t, _error_info_);
+
+__EXTERN__(Error_info_t*, _error_infop_);
+
+Error_info_t* _error_infop_ = &_error_info_;
+
+/*
+ * these should probably be in error_info
+ */
+
+static struct State_s
+{
+ char* prefix;
+ Sfio_t* tty;
+ unsigned long count;
+ int breakpoint;
+ regex_t* match;
+} error_state;
+
+#undef ERROR_CATALOG
+#define ERROR_CATALOG (ERROR_LIBRARY<<1)
+
+#define OPT_BREAK 1
+#define OPT_CATALOG 2
+#define OPT_CORE 3
+#define OPT_COUNT 4
+#define OPT_FD 5
+#define OPT_LIBRARY 6
+#define OPT_MASK 7
+#define OPT_MATCH 8
+#define OPT_PREFIX 9
+#define OPT_SYSTEM 10
+#define OPT_TIME 11
+#define OPT_TRACE 12
+
+static const Namval_t options[] =
+{
+ "break", OPT_BREAK,
+ "catalog", OPT_CATALOG,
+ "core", OPT_CORE,
+ "count", OPT_COUNT,
+ "debug", OPT_TRACE,
+ "fd", OPT_FD,
+ "library", OPT_LIBRARY,
+ "mask", OPT_MASK,
+ "match", OPT_MATCH,
+ "prefix", OPT_PREFIX,
+ "system", OPT_SYSTEM,
+ "time", OPT_TIME,
+ "trace", OPT_TRACE,
+ 0, 0
+};
+
+/*
+ * called by stropt() to set options
+ */
+
+static int
+setopt(void* a, const void* p, register int n, register const char* v)
+{
+ NoP(a);
+ if (p)
+ switch (((Namval_t*)p)->value)
+ {
+ case OPT_BREAK:
+ case OPT_CORE:
+ if (n)
+ switch (*v)
+ {
+ case 'e':
+ case 'E':
+ error_state.breakpoint = ERROR_ERROR;
+ break;
+ case 'f':
+ case 'F':
+ error_state.breakpoint = ERROR_FATAL;
+ break;
+ case 'p':
+ case 'P':
+ error_state.breakpoint = ERROR_PANIC;
+ break;
+ default:
+ error_state.breakpoint = strtol(v, NiL, 0);
+ break;
+ }
+ else
+ error_state.breakpoint = 0;
+ if (((Namval_t*)p)->value == OPT_CORE)
+ error_info.core = error_state.breakpoint;
+ break;
+ case OPT_CATALOG:
+ if (n)
+ error_info.set |= ERROR_CATALOG;
+ else
+ error_info.clear |= ERROR_CATALOG;
+ break;
+ case OPT_COUNT:
+ if (n)
+ error_state.count = strtol(v, NiL, 0);
+ else
+ error_state.count = 0;
+ break;
+ case OPT_FD:
+ error_info.fd = n ? strtol(v, NiL, 0) : -1;
+ break;
+ case OPT_LIBRARY:
+ if (n)
+ error_info.set |= ERROR_LIBRARY;
+ else
+ error_info.clear |= ERROR_LIBRARY;
+ break;
+ case OPT_MASK:
+ if (n)
+ error_info.mask = strtol(v, NiL, 0);
+ else
+ error_info.mask = 0;
+ break;
+ case OPT_MATCH:
+ if (error_state.match)
+ regfree(error_state.match);
+ if (n)
+ {
+ if ((error_state.match || (error_state.match = newof(0, regex_t, 1, 0))) && regcomp(error_state.match, v, REG_EXTENDED|REG_LENIENT))
+ {
+ free(error_state.match);
+ error_state.match = 0;
+ }
+ }
+ else if (error_state.match)
+ {
+ free(error_state.match);
+ error_state.match = 0;
+ }
+ break;
+ case OPT_PREFIX:
+ if (n)
+ error_state.prefix = strdup(v);
+ else if (error_state.prefix)
+ {
+ free(error_state.prefix);
+ error_state.prefix = 0;
+ }
+ break;
+ case OPT_SYSTEM:
+ if (n)
+ error_info.set |= ERROR_SYSTEM;
+ else
+ error_info.clear |= ERROR_SYSTEM;
+ break;
+ case OPT_TIME:
+ error_info.time = n ? 1 : 0;
+ break;
+ case OPT_TRACE:
+ if (n)
+ error_info.trace = -strtol(v, NiL, 0);
+ else
+ error_info.trace = 0;
+ break;
+ }
+ return 0;
+}
+
+/*
+ * print a name with optional delimiter, converting unprintable chars
+ */
+
+static void
+print(register Sfio_t* sp, register char* name, char* delim)
+{
+ if (mbwide())
+ sfputr(sp, name, -1);
+ else
+ {
+#if CC_NATIVE != CC_ASCII
+ register int c;
+ register unsigned char* n2a;
+ register unsigned char* a2n;
+ register int aa;
+ register int as;
+
+ n2a = ccmap(CC_NATIVE, CC_ASCII);
+ a2n = ccmap(CC_ASCII, CC_NATIVE);
+ aa = n2a['A'];
+ as = n2a[' '];
+ while (c = *name++)
+ {
+ c = n2a[c];
+ if (c & 0200)
+ {
+ c &= 0177;
+ sfputc(sp, '?');
+ }
+ if (c < as)
+ {
+ c += aa - 1;
+ sfputc(sp, '^');
+ }
+ c = a2n[c];
+ sfputc(sp, c);
+ }
+#else
+ register int c;
+
+ while (c = *name++)
+ {
+ if (c & 0200)
+ {
+ c &= 0177;
+ sfputc(sp, '?');
+ }
+ if (c < ' ')
+ {
+ c += 'A' - 1;
+ sfputc(sp, '^');
+ }
+ sfputc(sp, c);
+ }
+#endif
+ }
+ if (delim)
+ sfputr(sp, delim, -1);
+}
+
+/*
+ * print error context FIFO stack
+ */
+
+#define CONTEXT(f,p) (((f)&ERROR_PUSH)?((Error_context_t*)&(p)->context->context):((Error_context_t*)(p)))
+
+static void
+context(register Sfio_t* sp, register Error_context_t* cp)
+{
+ if (cp->context)
+ context(sp, CONTEXT(cp->flags, cp->context));
+ if (!(cp->flags & ERROR_SILENT))
+ {
+ if (cp->id)
+ print(sp, cp->id, NiL);
+ if (cp->line > ((cp->flags & ERROR_INTERACTIVE) != 0))
+ {
+ if (cp->file)
+ sfprintf(sp, ": \"%s\", %s %d", cp->file, ERROR_translate(NiL, NiL, ast.id, "line"), cp->line);
+ else
+ sfprintf(sp, "[%d]", cp->line);
+ }
+ sfputr(sp, ": ", -1);
+ }
+}
+
+/*
+ * debugging breakpoint
+ */
+
+extern void
+error_break(void)
+{
+ char* s;
+
+ if (error_state.tty || (error_state.tty = sfopen(NiL, "/dev/tty", "r+")))
+ {
+ sfprintf(error_state.tty, "error breakpoint: ");
+ if (s = sfgetr(error_state.tty, '\n', 1))
+ {
+ if (streq(s, "q") || streq(s, "quit"))
+ exit(0);
+ stropt(s, options, sizeof(*options), setopt, NiL);
+ }
+ }
+}
+
+void
+error(int level, ...)
+{
+ va_list ap;
+
+ va_start(ap, level);
+ errorv(NiL, level, ap);
+ va_end(ap);
+}
+
+void
+errorv(const char* id, int level, va_list ap)
+{
+ register int n;
+ int fd;
+ int flags;
+ char* s;
+ char* t;
+ char* format;
+ char* library;
+ const char* catalog;
+
+ int line;
+ char* file;
+
+#if !_PACKAGE_astsa
+ unsigned long d;
+ struct tms us;
+#endif
+
+ if (!error_info.init)
+ {
+ error_info.init = 1;
+ stropt(getenv("ERROR_OPTIONS"), options, sizeof(*options), setopt, NiL);
+ }
+ if (level > 0)
+ {
+ flags = level & ~ERROR_LEVEL;
+ level &= ERROR_LEVEL;
+ }
+ else
+ flags = 0;
+ if ((flags & (ERROR_USAGE|ERROR_NOID)) == ERROR_NOID)
+ {
+ format = (char*)id;
+ id = 0;
+ }
+ else
+ format = 0;
+ if (id)
+ {
+ catalog = (char*)id;
+ if (!*catalog || *catalog == ':')
+ {
+ catalog = 0;
+ library = 0;
+ }
+ else if ((library = strchr(catalog, ':')) && !*++library)
+ library = 0;
+ }
+ else
+ {
+ catalog = 0;
+ library = 0;
+ }
+ if (catalog)
+ id = 0;
+ else
+ {
+ id = (const char*)error_info.id;
+ catalog = error_info.catalog;
+ }
+ if (level < error_info.trace || (flags & ERROR_LIBRARY) && !(((error_info.set | error_info.flags) ^ error_info.clear) & ERROR_LIBRARY) || level < 0 && error_info.mask && !(error_info.mask & (1<<(-level - 1))))
+ {
+ if (level >= ERROR_FATAL)
+ (*error_info.exit)(level - 1);
+ return;
+ }
+ if (error_info.trace < 0)
+ flags |= ERROR_LIBRARY|ERROR_SYSTEM;
+ flags |= error_info.set | error_info.flags;
+ flags &= ~error_info.clear;
+ if (!library)
+ flags &= ~ERROR_LIBRARY;
+ fd = (flags & ERROR_OUTPUT) ? va_arg(ap, int) : error_info.fd;
+ if (error_info.write)
+ {
+ long off;
+ char* bas;
+
+ bas = stkptr(stkstd, 0);
+ if (off = stktell(stkstd))
+ stkfreeze(stkstd, 0);
+ file = error_info.id;
+ if (error_state.prefix)
+ sfprintf(stkstd, "%s: ", error_state.prefix);
+ if (flags & ERROR_USAGE)
+ {
+ if (flags & ERROR_NOID)
+ sfprintf(stkstd, " ");
+ else
+ sfprintf(stkstd, "%s: ", ERROR_translate(NiL, NiL, ast.id, "Usage"));
+ if (file || opt_info.argv && (file = opt_info.argv[0]))
+ print(stkstd, file, " ");
+ }
+ else
+ {
+ if (level && !(flags & ERROR_NOID))
+ {
+ if (error_info.context && level > 0)
+ context(stkstd, CONTEXT(error_info.flags, error_info.context));
+ if (file)
+ print(stkstd, file, (flags & ERROR_LIBRARY) ? " " : ": ");
+ if (flags & (ERROR_CATALOG|ERROR_LIBRARY))
+ {
+ sfprintf(stkstd, "[");
+ if (flags & ERROR_CATALOG)
+ sfprintf(stkstd, "%s %s%s",
+ catalog ? catalog : ERROR_translate(NiL, NiL, ast.id, "DEFAULT"),
+ ERROR_translate(NiL, NiL, ast.id, "catalog"),
+ (flags & ERROR_LIBRARY) ? ", " : "");
+ if (flags & ERROR_LIBRARY)
+ sfprintf(stkstd, "%s %s",
+ library,
+ ERROR_translate(NiL, NiL, ast.id, "library"));
+ sfprintf(stkstd, "]: ");
+ }
+ }
+ if (level > 0 && error_info.line > ((flags & ERROR_INTERACTIVE) != 0))
+ {
+ if (error_info.file && *error_info.file)
+ sfprintf(stkstd, "\"%s\", ", error_info.file);
+ sfprintf(stkstd, "%s %d: ", ERROR_translate(NiL, NiL, ast.id, "line"), error_info.line);
+ }
+ }
+#if !_PACKAGE_astsa
+ if (error_info.time)
+ {
+ if ((d = times(&us)) < error_info.time || error_info.time == 1)
+ error_info.time = d;
+ sfprintf(stkstd, " %05lu.%05lu.%05lu ", d - error_info.time, (unsigned long)us.tms_utime, (unsigned long)us.tms_stime);
+ }
+#endif
+ switch (level)
+ {
+ case 0:
+ flags &= ~ERROR_SYSTEM;
+ break;
+ case ERROR_WARNING:
+ sfprintf(stkstd, "%s: ", ERROR_translate(NiL, NiL, ast.id, "warning"));
+ break;
+ case ERROR_PANIC:
+ sfprintf(stkstd, "%s: ", ERROR_translate(NiL, NiL, ast.id, "panic"));
+ break;
+ default:
+ if (level < 0)
+ {
+ s = ERROR_translate(NiL, NiL, ast.id, "debug");
+ if (error_info.trace < -1)
+ sfprintf(stkstd, "%s%d:%s", s, level, level > -10 ? " " : "");
+ else
+ sfprintf(stkstd, "%s: ", s);
+ for (n = 0; n < error_info.indent; n++)
+ {
+ sfputc(stkstd, ' ');
+ sfputc(stkstd, ' ');
+ }
+ }
+ break;
+ }
+ if (flags & ERROR_SOURCE)
+ {
+ /*
+ * source ([version], file, line) message
+ */
+
+ file = va_arg(ap, char*);
+ line = va_arg(ap, int);
+ s = ERROR_translate(NiL, NiL, ast.id, "line");
+ if (error_info.version)
+ sfprintf(stkstd, "(%s: \"%s\", %s %d) ", error_info.version, file, s, line);
+ else
+ sfprintf(stkstd, "(\"%s\", %s %d) ", file, s, line);
+ }
+ if (format || (format = va_arg(ap, char*)))
+ {
+ if (!(flags & ERROR_USAGE))
+ format = ERROR_translate(NiL, id, catalog, format);
+ sfvprintf(stkstd, format, ap);
+ }
+ if (!(flags & ERROR_PROMPT))
+ {
+ /*
+ * level&ERROR_OUTPUT on return means message
+ * already output
+ */
+
+ if ((flags & ERROR_SYSTEM) && errno && errno != error_info.last_errno)
+ {
+ sfprintf(stkstd, " [%s]", fmterror(errno));
+ if (error_info.set & ERROR_SYSTEM)
+ errno = 0;
+ error_info.last_errno = (level >= 0) ? 0 : errno;
+ }
+ if (error_info.auxilliary && level >= 0)
+ level = (*error_info.auxilliary)(stkstd, level, flags);
+ sfputc(stkstd, '\n');
+ }
+ if (level > 0)
+ {
+ if ((level & ~ERROR_OUTPUT) > 1)
+ error_info.errors++;
+ else
+ error_info.warnings++;
+ }
+ if (level < 0 || !(level & ERROR_OUTPUT))
+ {
+ n = stktell(stkstd);
+ s = stkptr(stkstd, 0);
+ if (t = memchr(s, '\f', n))
+ {
+ n -= ++t - s;
+ s = t;
+ }
+#if HUH_19980401 /* nasty problems if sfgetr() is in effect! */
+ sfsync(sfstdin);
+#endif
+ sfsync(sfstdout);
+ sfsync(sfstderr);
+ if (fd == sffileno(sfstderr) && error_info.write == write)
+ {
+ sfwrite(sfstderr, s, n);
+ sfsync(sfstderr);
+ }
+ else
+ (*error_info.write)(fd, s, n);
+ }
+ else
+ {
+ s = 0;
+ level &= ERROR_LEVEL;
+ }
+ stkset(stkstd, bas, off);
+ }
+ else
+ s = 0;
+ if (level >= error_state.breakpoint && error_state.breakpoint && (!error_state.match || !regexec(error_state.match, s ? s : format, 0, NiL, 0)) && (!error_state.count || !--error_state.count))
+ {
+ if (error_info.core)
+ {
+#ifndef SIGABRT
+#ifdef SIGQUIT
+#define SIGABRT SIGQUIT
+#else
+#ifdef SIGIOT
+#define SIGABRT SIGIOT
+#endif
+#endif
+#endif
+#ifdef SIGABRT
+ signal(SIGABRT, SIG_DFL);
+ kill(getpid(), SIGABRT);
+ pause();
+#else
+ abort();
+#endif
+ }
+ else
+ error_break();
+ }
+ if (level >= ERROR_FATAL)
+ (*error_info.exit)(level - ERROR_FATAL + 1);
+}
+
+/*
+ * error_info context control
+ */
+
+static Error_info_t* freecontext;
+
+Error_info_t*
+errorctx(Error_info_t* p, int op, int flags)
+{
+ if (op & ERROR_POP)
+ {
+ if (!(_error_infop_ = p->context))
+ _error_infop_ = &_error_info_;
+ if (op & ERROR_FREE)
+ {
+ p->context = freecontext;
+ freecontext = p;
+ }
+ p = _error_infop_;
+ }
+ else
+ {
+ if (!p)
+ {
+ if (p = freecontext)
+ freecontext = freecontext->context;
+ else if (!(p = newof(0, Error_info_t, 1, 0)))
+ return 0;
+ *p = *_error_infop_;
+ p->errors = p->flags = p->line = p->warnings = 0;
+ p->catalog = p->file = 0;
+ }
+ if (op & ERROR_PUSH)
+ {
+ p->flags = flags;
+ p->context = _error_infop_;
+ _error_infop_ = p;
+ }
+ p->flags |= ERROR_PUSH;
+ }
+ return p;
+}
diff --git a/src/lib/libast/misc/errorf.c b/src/lib/libast/misc/errorf.c
new file mode 100644
index 0000000..0a67e97
--- /dev/null
+++ b/src/lib/libast/misc/errorf.c
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * generic error discipline function
+ */
+
+#include <error.h>
+
+int
+errorf(void* handle, void* discipline, int level, ...)
+{
+ va_list ap;
+
+ va_start(ap, level);
+ errorv((discipline && handle) ? *((char**)handle) : (char*)handle, (discipline || level < 0) ? level : (level | ERROR_LIBRARY), ap);
+ va_end(ap);
+ return 0;
+}
diff --git a/src/lib/libast/misc/errormsg.c b/src/lib/libast/misc/errormsg.c
new file mode 100644
index 0000000..555d4f1
--- /dev/null
+++ b/src/lib/libast/misc/errormsg.c
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * error function with specific dictionary
+ */
+
+#include <error.h>
+
+int
+errormsg(const char* dictionary, int level, ...)
+{
+ va_list ap;
+
+ va_start(ap, level);
+ errorv(dictionary, level, ap);
+ va_end(ap);
+ return 0;
+}
diff --git a/src/lib/libast/misc/errorx.c b/src/lib/libast/misc/errorx.c
new file mode 100644
index 0000000..70466de
--- /dev/null
+++ b/src/lib/libast/misc/errorx.c
@@ -0,0 +1,50 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "lclib.h"
+
+/*
+ * low level for ERROR_translate()
+ * this fills in NiL arg defaults and calls error_info.translate
+ */
+
+char*
+errorx(const char* loc, const char* cmd, const char* cat, const char* msg)
+{
+ char* s;
+
+ if (!error_info.translate)
+ error_info.translate = translate; /* 2007-03-19 OLD_Error_info_t workaround */
+ if (ERROR_translating())
+ {
+ if (!loc)
+ loc = (const char*)locales[AST_LC_MESSAGES]->code;
+ if (!cmd)
+ cmd = (const char*)error_info.id;
+ if (!cat)
+ cat = (const char*)error_info.catalog;
+ if (s = (*error_info.translate)(loc, cmd, cat, msg))
+ return s;
+ }
+ return (char*)msg;
+}
diff --git a/src/lib/libast/misc/fastfind.c b/src/lib/libast/misc/fastfind.c
new file mode 100644
index 0000000..04d54d9
--- /dev/null
+++ b/src/lib/libast/misc/fastfind.c
@@ -0,0 +1,1282 @@
+#pragma prototyped
+/*
+ * original code
+ *
+ * James A. Woods, Informatics General Corporation,
+ * NASA Ames Research Center, 6/81.
+ * Usenix ;login:, February/March, 1983, p. 8.
+ *
+ * discipline/method interface
+ *
+ * Glenn Fowler
+ * AT&T Research
+ * modified from the original BSD source
+ *
+ * 'fastfind' scans a file list for the full pathname of a file
+ * given only a piece of the name. The list is processed with
+ * with "front-compression" and bigram coding. Front compression reduces
+ * space by a factor of 4-5, bigram coding by a further 20-25%.
+ *
+ * there are 4 methods:
+ *
+ * FF_old original with 7 bit bigram encoding (no magic)
+ * FF_gnu 8 bit clean front compression (FF_gnu_magic)
+ * FF_dir FF_gnu with sfgetl/sfputl and trailing / on dirs (FF_dir_magic)
+ * FF_typ FF_dir with (mime) types (FF_typ_magic)
+ *
+ * the bigram encoding steals the eighth bit (that's why its FF_old)
+ * maybe one day we'll limit it to readonly:
+ *
+ * 0-2*FF_OFF likeliest differential counts + offset to make nonnegative
+ * FF_ESC 4 byte big-endian out-of-range count+FF_OFF follows
+ * FF_MIN-FF_MAX ascii residue
+ * >=FF_MAX bigram codes
+ *
+ * a two-tiered string search technique is employed
+ *
+ * a metacharacter-free subpattern and partial pathname is matched
+ * backwards to avoid full expansion of the pathname list
+ *
+ * then the actual shell glob-style regular expression (if in this form)
+ * is matched against the candidate pathnames using the slower regexec()
+ *
+ * The original BSD code is covered by the BSD license:
+ *
+ * Copyright (c) 1985, 1993, 1999
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+static const char id[] = "\n@(#)$Id: fastfind (AT&T Research) 2002-10-02 $\0\n";
+
+static const char lib[] = "libast:fastfind";
+
+#include "findlib.h"
+
+#define FIND_MATCH "*/(find|locate)/*"
+
+/*
+ * this db could be anywhere
+ * findcodes[] directories are checked for findnames[i]
+ */
+
+static char* findcodes[] =
+{
+ 0,
+ 0,
+ FIND_CODES,
+ "/usr/local/share/lib",
+ "/usr/local/lib",
+ "/usr/share/lib",
+ "/usr/lib",
+ "/var/spool",
+ "/usr/local/var",
+ "/var/lib",
+ "/var/lib/slocate",
+ "/var/db",
+};
+
+static char* findnames[] =
+{
+ "find/codes",
+ "find/find.codes",
+ "locate/locatedb",
+ "locatedb",
+ "locate.database",
+ "slocate.db",
+};
+
+/*
+ * convert t to lower case and drop leading x- and x- after /
+ * converted value copied to b of size n
+ */
+
+char*
+typefix(char* buf, size_t n, register const char* t)
+{
+ register int c;
+ register char* b = buf;
+
+ if ((*t == 'x' || *t == 'X') && *(t + 1) == '-')
+ t += 2;
+ while (c = *t++)
+ {
+ if (isupper(c))
+ c = tolower(c);
+ if ((*b++ = c) == '/' && (*t == 'x' || *t == 'X') && *(t + 1) == '-')
+ t += 2;
+ }
+ *b = 0;
+ return buf;
+}
+
+/*
+ * return a fastfind stream handle for pattern
+ */
+
+Find_t*
+findopen(const char* file, const char* pattern, const char* type, Finddisc_t* disc)
+{
+ register Find_t* fp;
+ register char* p;
+ register char* s;
+ register char* b;
+ register int i;
+ register int j;
+ char* path;
+ int brace = 0;
+ int paren = 0;
+ int k;
+ int q;
+ int fd;
+ int uid;
+ Vmalloc_t* vm;
+ Type_t* tp;
+ struct stat st;
+
+
+ if (!(vm = vmopen(Vmdcheap, Vmbest, 0)))
+ goto nospace;
+
+ /*
+ * NOTE: searching for FIND_CODES would be much simpler if we
+ * just stuck with our own, but we also support GNU
+ * locate codes and have to search for the one of a
+ * bazillion possible names for that file
+ */
+
+ if (!findcodes[1])
+ findcodes[1] = getenv(FIND_CODES_ENV);
+ if (disc->flags & FIND_GENERATE)
+ {
+ if (!(fp = (Find_t*)vmnewof(vm, 0, Find_t, 1, sizeof(Encode_t) - sizeof(Code_t))))
+ goto nospace;
+ fp->vm = vm;
+ fp->id = lib;
+ fp->disc = disc;
+ fp->generate = 1;
+ if (file && (!*file || streq(file, "-")))
+ file = 0;
+ uid = geteuid();
+ j = (findcodes[0] = (char*)file) && *file == '/' ? 1 : elementsof(findcodes);
+
+ /*
+ * look for the codes file, but since it may not exist yet,
+ * also look for the containing directory if i<2 or if
+ * it is sufficiently qualified (FIND_MATCH)
+ */
+
+ for (i = 0; i < j; i++)
+ if (path = findcodes[i])
+ {
+ if (*path == '/')
+ {
+ if (!stat(path, &st))
+ {
+ if (S_ISDIR(st.st_mode))
+ {
+ for (k = 0; k < elementsof(findnames); k++)
+ {
+ sfsprintf(fp->encode.file, sizeof(fp->encode.file), "%s/%s", path, findnames[k]);
+ if (!eaccess(fp->encode.file, R_OK|W_OK))
+ {
+ path = fp->encode.file;
+ break;
+ }
+ if (strchr(findnames[k], '/') && (b = strrchr(fp->encode.file, '/')))
+ {
+ *b = 0;
+ if (!stat(fp->encode.file, &st) && st.st_uid == uid && (st.st_mode & S_IWUSR))
+ {
+ *b = '/';
+ path = fp->encode.file;
+ break;
+ }
+ }
+ }
+ if (k < elementsof(findnames))
+ break;
+ }
+ else if (st.st_uid == uid && (st.st_mode & S_IWUSR))
+ {
+ sfsprintf(fp->encode.file, sizeof(fp->encode.file), "%s", path);
+ path = fp->encode.file;
+ break;
+ }
+ }
+ else if (i < 2 || strmatch(path, FIND_MATCH))
+ {
+ sfsprintf(fp->encode.file, sizeof(fp->encode.file), "%s", path);
+ if (b = strrchr(fp->encode.file, '/'))
+ {
+ *b = 0;
+ if (!stat(fp->encode.file, &st) && st.st_uid == uid && (st.st_mode & S_IWUSR))
+ {
+ *b = '/';
+ path = fp->encode.file;
+ break;
+ }
+ }
+ }
+ }
+ else if (pathpath(path, "", PATH_REGULAR|PATH_READ|PATH_WRITE, fp->encode.file, sizeof(fp->encode.file)))
+ {
+ path = fp->encode.file;
+ break;
+ }
+ else if (b = strrchr(path, '/'))
+ {
+ sfsprintf(fp->encode.file, sizeof(fp->encode.file), "%-.*s", b - path, path);
+ if (pathpath(fp->encode.file, "", PATH_EXECUTE|PATH_READ|PATH_WRITE, fp->encode.temp, sizeof(fp->encode.temp)) &&
+ !stat(fp->encode.temp, &st) && st.st_uid == uid && (st.st_mode & S_IWUSR))
+ {
+ sfsprintf(fp->encode.file, sizeof(fp->encode.file), "%s%s", fp->encode.temp, b);
+ path = fp->encode.file;
+ break;
+ }
+ }
+ }
+ if (i >= j)
+ {
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, 2, "%s: cannot locate codes", file ? file : findcodes[2]);
+ goto drop;
+ }
+ if (fp->disc->flags & FIND_OLD)
+ {
+ /*
+ * FF_old generates temp data that is read
+ * in a second pass to generate the real codes
+ */
+
+ fp->method = FF_old;
+ if (!(fp->fp = sftmp(32 * PATH_MAX)))
+ {
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, ERROR_SYSTEM|2, "cannot create tmp file");
+ goto drop;
+ }
+ }
+ else
+ {
+ /*
+ * the rest generate into a temp file that
+ * is simply renamed on completion
+ */
+
+ if (s = strrchr(path, '/'))
+ {
+ *s = 0;
+ p = path;
+ }
+ else
+ p = ".";
+ if (!pathtemp(fp->encode.temp, sizeof(fp->encode.temp), p, "ff", &fd))
+ {
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, ERROR_SYSTEM|2, "%s: cannot create tmp file in this directory", p ? p : ".");
+ goto drop;
+ }
+ if (s)
+ *s = '/';
+ if (!(fp->fp = sfnew(NiL, NiL, (size_t)SF_UNBOUND, fd, SF_WRITE)))
+ {
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, ERROR_SYSTEM|2, "%s: cannot open tmp file", fp->encode.temp);
+ close(fd);
+ goto drop;
+ }
+ if (fp->disc->flags & FIND_TYPE)
+ {
+ fp->method = FF_typ;
+ fp->encode.namedisc.key = offsetof(Type_t, name);
+ fp->encode.namedisc.link = offsetof(Type_t, byname);
+ fp->encode.indexdisc.key = offsetof(Type_t, index);
+ fp->encode.indexdisc.size = sizeof(unsigned long);
+ fp->encode.indexdisc.link = offsetof(Type_t, byindex);
+ s = "system/dir";
+ if (!(fp->encode.namedict = dtopen(&fp->encode.namedisc, Dtoset)) || !(fp->encode.indexdict = dtopen(&fp->encode.indexdisc, Dtoset)) || !(tp = newof(0, Type_t, 1, strlen(s) + 1)))
+ {
+ if (fp->encode.namedict)
+ dtclose(fp->encode.namedict);
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, 2, "cannot allocate type table");
+ goto drop;
+ }
+
+ /*
+ * type index 1 is always system/dir
+ */
+
+ tp->index = ++fp->types;
+ strcpy(tp->name, s);
+ dtinsert(fp->encode.namedict, tp);
+ dtinsert(fp->encode.indexdict, tp);
+ }
+ else if (fp->disc->flags & FIND_GNU)
+ {
+ fp->method = FF_gnu;
+ sfputc(fp->fp, 0);
+ sfputr(fp->fp, FF_gnu_magic, 0);
+ }
+ else
+ {
+ fp->method = FF_dir;
+ sfputc(fp->fp, 0);
+ sfputr(fp->fp, FF_dir_magic, 0);
+ }
+ }
+ }
+ else
+ {
+ i = sizeof(Decode_t) + sizeof(Code_t);
+ if (!pattern || !*pattern)
+ pattern = "*";
+ i += (j = 2 * (strlen(pattern) + 1));
+ if (!(fp = (Find_t*)vmnewof(vm, 0, Find_t, 1, i)))
+ {
+ vmclose(vm);
+ return 0;
+ }
+ fp->vm = vm;
+ fp->id = lib;
+ fp->disc = disc;
+ if (disc->flags & FIND_ICASE)
+ fp->decode.ignorecase = 1;
+ j = (findcodes[0] = (char*)file) && *file == '/' ? 1 : elementsof(findcodes);
+ for (i = 0; i < j; i++)
+ if (path = findcodes[i])
+ {
+ if (*path == '/')
+ {
+ if (!stat(path, &st))
+ {
+ if (S_ISDIR(st.st_mode))
+ {
+ for (k = 0; k < elementsof(findnames); k++)
+ {
+ sfsprintf(fp->decode.path, sizeof(fp->decode.path), "%s/%s", path, findnames[k]);
+ if (fp->fp = sfopen(NiL, fp->decode.path, "r"))
+ {
+ path = fp->decode.path;
+ break;
+ }
+ }
+ if (fp->fp)
+ break;
+ }
+ else if (fp->fp = sfopen(NiL, path, "r"))
+ break;
+ }
+ }
+ else if ((path = pathpath(path, "", PATH_REGULAR|PATH_READ, fp->decode.path, sizeof(fp->decode.path))) && (fp->fp = sfopen(NiL, path, "r")))
+ break;
+ }
+ if (!fp->fp)
+ {
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, 2, "%s: cannot locate codes", file ? file : findcodes[2]);
+ goto drop;
+ }
+ if (fstat(sffileno(fp->fp), &st))
+ {
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, 2, "%s: cannot stat codes", path);
+ goto drop;
+ }
+ if (fp->secure = ((st.st_mode & (S_IRGRP|S_IROTH)) == S_IRGRP) && st.st_gid == getegid() && getegid() != getgid())
+ setgid(getgid());
+ fp->stamp = st.st_mtime;
+ b = (s = fp->decode.temp) + 1;
+ for (i = 0; i < elementsof(fp->decode.bigram1); i++)
+ {
+ if ((j = sfgetc(fp->fp)) == EOF)
+ goto invalid;
+ if (!(*s++ = fp->decode.bigram1[i] = j) && i)
+ {
+ i = -i;
+ break;
+ }
+ if ((j = sfgetc(fp->fp)) == EOF)
+ goto invalid;
+ if (!(*s++ = fp->decode.bigram2[i] = j) && (i || fp->decode.bigram1[0] >= '0' && fp->decode.bigram1[0] <= '1'))
+ break;
+ }
+ if (streq(b, FF_typ_magic))
+ {
+ if (type)
+ {
+ type = (const char*)typefix(fp->decode.bigram2, sizeof(fp->decode.bigram2), type);
+ memset(fp->decode.bigram1, 0, sizeof(fp->decode.bigram1));
+ }
+ fp->method = FF_typ;
+ for (j = 0, i = 1;; i++)
+ {
+ if (!(s = sfgetr(fp->fp, 0, 0)))
+ goto invalid;
+ if (!*s)
+ break;
+ if (type && strmatch(s, type))
+ {
+ FF_SET_TYPE(fp, i);
+ j++;
+ }
+ }
+ if (type && !j)
+ goto drop;
+ fp->types = j;
+ }
+ else if (streq(b, FF_dir_magic))
+ fp->method = FF_dir;
+ else if (streq(b, FF_gnu_magic))
+ fp->method = FF_gnu;
+ else if (!*b && *--b >= '0' && *b <= '1')
+ {
+ fp->method = FF_gnu;
+ while (j = sfgetc(fp->fp))
+ {
+ if (j == EOF || fp->decode.count >= sizeof(fp->decode.path))
+ goto invalid;
+ fp->decode.path[fp->decode.count++] = j;
+ }
+ }
+ else
+ {
+ fp->method = FF_old;
+ if (i < 0)
+ {
+ if ((j = sfgetc(fp->fp)) == EOF)
+ goto invalid;
+ fp->decode.bigram2[i = -i] = j;
+ }
+ while (++i < elementsof(fp->decode.bigram1))
+ {
+ if ((j = sfgetc(fp->fp)) == EOF)
+ goto invalid;
+ fp->decode.bigram1[i] = j;
+ if ((j = sfgetc(fp->fp)) == EOF)
+ goto invalid;
+ fp->decode.bigram2[i] = j;
+ }
+ if ((fp->decode.peek = sfgetc(fp->fp)) != FF_OFF)
+ goto invalid;
+ }
+
+ /*
+ * set up the physical dir table
+ */
+
+ if (disc->version >= 19980301L)
+ {
+ fp->verifyf = disc->verifyf;
+ if (disc->dirs && *disc->dirs)
+ {
+ for (k = 0; disc->dirs[k]; k++);
+ if (k == 1 && streq(disc->dirs[0], "/"))
+ k = 0;
+ if (k)
+ {
+ if (!(fp->dirs = vmnewof(fp->vm, 0, char*, 2 * k + 1, 0)))
+ goto drop;
+ if (!(fp->lens = vmnewof(fp->vm, 0, int, 2 * k, 0)))
+ goto drop;
+ p = 0;
+ b = fp->decode.temp;
+ j = fp->method == FF_old || fp->method == FF_gnu;
+
+ /*
+ * fill the dir list with logical and
+ * physical names since we don't know
+ * which way the db was encoded (it
+ * could be *both* ways)
+ */
+
+ for (i = q = 0; i < k; i++)
+ {
+ if (*(s = disc->dirs[i]) == '/')
+ sfsprintf(b, sizeof(fp->decode.temp) - 1, "%s", s);
+ else if (!p && !(p = getcwd(fp->decode.path, sizeof(fp->decode.path))))
+ goto nospace;
+ else
+ sfsprintf(b, sizeof(fp->decode.temp) - 1, "%s/%s", p, s);
+ s = pathcanon(b, sizeof(fp->decode.temp), 0);
+ *s = '/';
+ *(s + 1) = 0;
+ if (!(fp->dirs[q] = vmstrdup(fp->vm, b)))
+ goto nospace;
+ if (j)
+ (fp->dirs[q])[s - b] = 0;
+ q++;
+ *s = 0;
+ s = pathcanon(b, sizeof(fp->decode.temp), PATH_PHYSICAL);
+ *s = '/';
+ *(s + 1) = 0;
+ if (!strneq(b, fp->dirs[q - 1], s - b))
+ {
+ if (!(fp->dirs[q] = vmstrdup(fp->vm, b)))
+ goto nospace;
+ if (j)
+ (fp->dirs[q])[s - b] = 0;
+ q++;
+ }
+ }
+ strsort(fp->dirs, q, strcasecmp);
+ for (i = 0; i < q; i++)
+ fp->lens[i] = strlen(fp->dirs[i]);
+ }
+ }
+ }
+ if (fp->verifyf || (disc->flags & FIND_VERIFY))
+ {
+ if (fp->method != FF_dir && fp->method != FF_typ)
+ {
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, 2, "%s: %s code format does not support directory verification", path, fp->method == FF_gnu ? FF_gnu_magic : "OLD-BIGRAM");
+ goto drop;
+ }
+ fp->verify = 1;
+ }
+
+ /*
+ * extract last glob-free subpattern in name for fast pre-match
+ * prepend 0 for backwards match
+ */
+
+ if (p = s = (char*)pattern)
+ {
+ b = fp->decode.pattern;
+ for (;;)
+ {
+ switch (*b++ = *p++)
+ {
+ case 0:
+ break;
+ case '\\':
+ s = p;
+ if (!*p++)
+ break;
+ continue;
+ case '[':
+ if (!brace)
+ {
+ brace++;
+ if (*p == ']')
+ p++;
+ }
+ continue;
+ case ']':
+ if (brace)
+ {
+ brace--;
+ s = p;
+ }
+ continue;
+ case '(':
+ if (!brace)
+ paren++;
+ continue;
+ case ')':
+ if (!brace && paren > 0 && !--paren)
+ s = p;
+ continue;
+ case '|':
+ case '&':
+ if (!brace && !paren)
+ {
+ s = "";
+ break;
+ }
+ continue;
+ case '*':
+ case '?':
+ s = p;
+ continue;
+ default:
+ continue;
+ }
+ break;
+ }
+ if (s != pattern && !streq(pattern, "*"))
+ {
+ fp->decode.match = 1;
+ if (i = regcomp(&fp->decode.re, pattern, REG_SHELL|REG_AUGMENTED|(fp->decode.ignorecase?REG_ICASE:0)))
+ {
+ if (disc->errorf)
+ {
+ regerror(i, &fp->decode.re, fp->decode.temp, sizeof(fp->decode.temp));
+ (*fp->disc->errorf)(fp, fp->disc, 2, "%s: %s", pattern, fp->decode.temp);
+ }
+ goto drop;
+ }
+ }
+ if (*s)
+ {
+ *b++ = 0;
+ while (i = *s++)
+ *b++ = i;
+ *b-- = 0;
+ fp->decode.end = b;
+ if (fp->decode.ignorecase)
+ for (s = fp->decode.pattern; s <= b; s++)
+ if (isupper(*s))
+ *s = tolower(*s);
+ }
+ }
+ }
+ return fp;
+ nospace:
+ if (disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, 2, "out of space");
+ if (!vm)
+ return 0;
+ if (!fp)
+ {
+ vmclose(vm);
+ return 0;
+ }
+ goto drop;
+ invalid:
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, 2, "%s: invalid codes", path);
+ drop:
+ if (!fp->generate && fp->decode.match)
+ regfree(&fp->decode.re);
+ if (fp->fp)
+ sfclose(fp->fp);
+ vmclose(fp->vm);
+ return 0;
+}
+
+/*
+ * return the next fastfind path
+ * 0 returned when list exhausted
+ */
+
+char*
+findread(register Find_t* fp)
+{
+ register char* p;
+ register char* q;
+ register char* s;
+ register char* b;
+ register char* e;
+ register int c;
+ register int n;
+ register int m;
+ int ignorecase;
+ int t;
+ unsigned char w[4];
+ struct stat st;
+
+ if (fp->generate)
+ return 0;
+ if (fp->decode.restore)
+ {
+ *fp->decode.restore = '/';
+ fp->decode.restore = 0;
+ }
+ ignorecase = fp->decode.ignorecase ? STR_ICASE : 0;
+ c = fp->decode.peek;
+ next:
+ for (;;)
+ {
+ switch (fp->method)
+ {
+ case FF_dir:
+ t = 0;
+ n = sfgetl(fp->fp);
+ goto grab;
+ case FF_gnu:
+ if ((c = sfgetc(fp->fp)) == EOF)
+ return 0;
+ if (c == 0x80)
+ {
+ if ((c = sfgetc(fp->fp)) == EOF)
+ return 0;
+ n = c << 8;
+ if ((c = sfgetc(fp->fp)) == EOF)
+ return 0;
+ n |= c;
+ if (n & 0x8000)
+ n = (n - 0xffff) - 1;
+ }
+ else if ((n = c) & 0x80)
+ n = (n - 0xff) - 1;
+ t = 0;
+ goto grab;
+ case FF_typ:
+ t = sfgetu(fp->fp);
+ n = sfgetl(fp->fp);
+ grab:
+ p = fp->decode.path + (fp->decode.count += n);
+ do
+ {
+ if ((c = sfgetc(fp->fp)) == EOF)
+ return 0;
+ } while (*p++ = c);
+ p -= 2;
+ break;
+ case FF_old:
+ if (c == EOF)
+ {
+ fp->decode.peek = c;
+ return 0;
+ }
+ if (c == FF_ESC)
+ {
+ if (sfread(fp->fp, w, sizeof(w)) != sizeof(w))
+ return 0;
+ if (fp->decode.swap >= 0)
+ {
+ c = (int32_t)((w[0] << 24) | (w[1] << 16) | (w[2] << 8) | w[3]);
+ if (!fp->decode.swap)
+ {
+ /*
+ * the old format uses machine
+ * byte order; this test uses
+ * the smallest magnitude of
+ * both byte orders on the
+ * first encoded path motion
+ * to determine the original
+ * byte order
+ */
+
+ m = c;
+ if (m < 0)
+ m = -m;
+ n = (int32_t)((w[3] << 24) | (w[2] << 16) | (w[1] << 8) | w[0]);
+ if (n < 0)
+ n = -n;
+ if (m < n)
+ fp->decode.swap = 1;
+ else
+ {
+ fp->decode.swap = -1;
+ c = (int32_t)((w[3] << 24) | (w[2] << 16) | (w[1] << 8) | w[0]);
+ }
+ }
+ }
+ else
+ c = (int32_t)((w[3] << 24) | (w[2] << 16) | (w[1] << 8) | w[0]);
+ }
+ fp->decode.count += c - FF_OFF;
+ for (p = fp->decode.path + fp->decode.count; (c = sfgetc(fp->fp)) > FF_ESC;)
+ if (c & (1<<(CHAR_BIT-1)))
+ {
+ *p++ = fp->decode.bigram1[c & ((1<<(CHAR_BIT-1))-1)];
+ *p++ = fp->decode.bigram2[c & ((1<<(CHAR_BIT-1))-1)];
+ }
+ else
+ *p++ = c;
+ *p-- = 0;
+ t = 0;
+ break;
+ }
+ b = fp->decode.path;
+ if (fp->decode.found)
+ fp->decode.found = 0;
+ else
+ b += fp->decode.count;
+ if (fp->dirs)
+ for (;;)
+ {
+ if (!*fp->dirs)
+ return 0;
+
+ /*
+ * use the ordering and lengths to prune
+ * comparison function calls
+ * (*fp->dirs)[*fp->lens]=='/' if its
+ * already been matched
+ */
+
+ if ((n = p - fp->decode.path + 1) > (m = *fp->lens))
+ {
+ if (!(*fp->dirs)[m])
+ goto next;
+ if (!strncasecmp(*fp->dirs, fp->decode.path, m))
+ break;
+ }
+ else if (n == m)
+ {
+ if (!(*fp->dirs)[m])
+ {
+ if (!(n = strcasecmp(*fp->dirs, fp->decode.path)) && (ignorecase || !strcmp(*fp->dirs, fp->decode.path)))
+ {
+ if (m > 0)
+ {
+ (*fp->dirs)[m] = '/';
+ if ((*fp->dirs)[m - 1] != '/')
+ (*fp->dirs)[++(*fp->lens)] = '/';
+ }
+ break;
+ }
+ if (n >= 0)
+ goto next;
+ }
+ }
+ else if (!(*fp->dirs)[m])
+ goto next;
+ fp->dirs++;
+ fp->lens++;
+ }
+ if (fp->verify && (*p == '/' || t == 1))
+ {
+ if ((n = p - fp->decode.path))
+ *p = 0;
+ else
+ n = 1;
+ if (fp->verifyf)
+ n = (*fp->verifyf)(fp, fp->decode.path, n, fp->disc);
+ else if (stat(fp->decode.path, &st))
+ n = -1;
+ else if ((unsigned long)st.st_mtime > fp->stamp)
+ n = 1;
+ else
+ n = 0;
+ *p = '/';
+
+ /*
+ * n<0 skip this subtree
+ * n==0 keep as is
+ * n>0 read this dir now
+ */
+
+ /* NOT IMPLEMENTED YET */
+ }
+ if (FF_OK_TYPE(fp, t))
+ {
+ if (fp->decode.end)
+ {
+ if (*(s = p) == '/')
+ s--;
+ if (*fp->decode.pattern == '/' && b > fp->decode.path)
+ b--;
+ for (; s >= b; s--)
+ if (*s == *fp->decode.end || ignorecase && tolower(*s) == *fp->decode.end)
+ {
+ if (ignorecase)
+ for (e = fp->decode.end - 1, q = s - 1; *e && (*q == *e || tolower(*q) == *e); e--, q--);
+ else
+ for (e = fp->decode.end - 1, q = s - 1; *e && *q == *e; e--, q--);
+ if (!*e)
+ {
+ fp->decode.found = 1;
+ if (!fp->decode.match || strgrpmatch(fp->decode.path, fp->decode.pattern, NiL, 0, STR_MAXIMAL|STR_LEFT|STR_RIGHT|ignorecase))
+ {
+ fp->decode.peek = c;
+ if (*p == '/')
+ *(fp->decode.restore = p) = 0;
+ if (!fp->secure || !access(fp->decode.path, F_OK))
+ return fp->decode.path;
+ }
+ break;
+ }
+ }
+ }
+ else if (!fp->decode.match || !(n = regexec(&fp->decode.re, fp->decode.path, 0, NiL, 0)))
+ {
+ fp->decode.peek = c;
+ if (*p == '/' && p > fp->decode.path)
+ *(fp->decode.restore = p) = 0;
+ if (!fp->secure || !access(fp->decode.path, F_OK))
+ return fp->decode.path;
+ }
+ else if (n != REG_NOMATCH)
+ {
+ if (fp->disc->errorf)
+ {
+ regerror(n, &fp->decode.re, fp->decode.temp, sizeof(fp->decode.temp));
+ (*fp->disc->errorf)(fp, fp->disc, 2, "%s: %s", fp->decode.pattern, fp->decode.temp);
+ }
+ return 0;
+ }
+ }
+ }
+}
+
+/*
+ * add path to the code table
+ * paths are assumed to be in sort order
+ */
+
+int
+findwrite(register Find_t* fp, const char* path, size_t len, const char* type)
+{
+ register unsigned char* s;
+ register unsigned char* e;
+ register unsigned char* p;
+ register int n;
+ register int d;
+ register Type_t* x;
+ register unsigned long u;
+
+ if (!fp->generate)
+ return -1;
+ if (type && fp->method == FF_dir)
+ {
+ len = sfsprintf(fp->encode.mark, sizeof(fp->encode.mark), "%-.*s/", len, path);
+ path = fp->encode.mark;
+ }
+ s = (unsigned char*)path;
+ if (len <= 0)
+ len = strlen(path);
+ if (len < sizeof(fp->encode.path))
+ e = s + len++;
+ else
+ {
+ len = sizeof(fp->encode.path) - 1;
+ e = s + len;
+ }
+ p = (unsigned char*)fp->encode.path;
+ while (s < e)
+ {
+ if (*s != *p++)
+ break;
+ s++;
+ }
+ n = s - (unsigned char*)path;
+ switch (fp->method)
+ {
+ case FF_gnu:
+ d = n - fp->encode.prefix;
+ if (d >= -127 && d <= 127)
+ sfputc(fp->fp, d & 0xff);
+ else
+ {
+ sfputc(fp->fp, 0x80);
+ sfputc(fp->fp, (d >> 8) & 0xff);
+ sfputc(fp->fp, d & 0xff);
+ }
+ fp->encode.prefix = n;
+ sfputr(fp->fp, (char*)s, 0);
+ break;
+ case FF_old:
+ sfprintf(fp->fp, "%ld", n - fp->encode.prefix + FF_OFF);
+ fp->encode.prefix = n;
+ sfputc(fp->fp, ' ');
+ p = s;
+ while (s < e)
+ {
+ n = *s++;
+ if (s >= e)
+ break;
+ fp->encode.code[n][*s++]++;
+ }
+ while (p < e)
+ {
+ if ((n = *p++) < FF_MIN || n >= FF_MAX)
+ n = '?';
+ sfputc(fp->fp, n);
+ }
+ sfputc(fp->fp, 0);
+ break;
+ case FF_typ:
+ if (type)
+ {
+ type = (const char*)typefix((char*)fp->encode.bigram, sizeof(fp->encode.bigram), type);
+ if (x = (Type_t*)dtmatch(fp->encode.namedict, type))
+ u = x->index;
+ else if (!(x = newof(0, Type_t, 1, strlen(type) + 1)))
+ u = 0;
+ else
+ {
+ u = x->index = ++fp->types;
+ strcpy(x->name, type);
+ dtinsert(fp->encode.namedict, x);
+ dtinsert(fp->encode.indexdict, x);
+ }
+ }
+ else
+ u = 0;
+ sfputu(fp->fp, u);
+ /*FALLTHROUGH...*/
+ case FF_dir:
+ d = n - fp->encode.prefix;
+ sfputl(fp->fp, d);
+ fp->encode.prefix = n;
+ sfputr(fp->fp, (char*)s, 0);
+ break;
+ }
+ memcpy(fp->encode.path, path, len);
+ return 0;
+}
+
+/*
+ * findsync() helper
+ */
+
+static int
+finddone(register Find_t* fp)
+{
+ int r;
+
+ if (sfsync(fp->fp))
+ {
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, 2, "%s: write error [sfsync]", fp->encode.file);
+ return -1;
+ }
+ if (sferror(fp->fp))
+ {
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, 2, "%s: write error [sferror]", fp->encode.file);
+ return -1;
+ }
+ r = sfclose(fp->fp);
+ fp->fp = 0;
+ if (r)
+ {
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, 2, "%s: write error [sfclose]", fp->encode.file);
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * finish the code table
+ */
+
+static int
+findsync(register Find_t* fp)
+{
+ register char* s;
+ register int n;
+ register int m;
+ register int d;
+ register Type_t* x;
+ char* t;
+ int b;
+ long z;
+ Sfio_t* sp;
+
+ switch (fp->method)
+ {
+ case FF_dir:
+ case FF_gnu:
+ /*
+ * replace the real file with the temp file
+ */
+
+ if (finddone(fp))
+ goto bad;
+ remove(fp->encode.file);
+ if (rename(fp->encode.temp, fp->encode.file))
+ {
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, ERROR_SYSTEM|2, "%s: cannot rename from tmp file %s", fp->encode.file, fp->encode.temp);
+ remove(fp->encode.temp);
+ return -1;
+ }
+ break;
+ case FF_old:
+ /*
+ * determine the top FF_MAX bigrams
+ */
+
+ for (n = 0; n < FF_MAX; n++)
+ for (m = 0; m < FF_MAX; m++)
+ fp->encode.hits[fp->encode.code[n][m]]++;
+ fp->encode.hits[0] = 0;
+ m = 1;
+ for (n = USHRT_MAX; n >= 0; n--)
+ if (d = fp->encode.hits[n])
+ {
+ fp->encode.hits[n] = m;
+ if ((m += d) > FF_MAX)
+ break;
+ }
+ while (--n >= 0)
+ fp->encode.hits[n] = 0;
+ for (n = FF_MAX - 1; n >= 0; n--)
+ for (m = FF_MAX - 1; m >= 0; m--)
+ if (fp->encode.hits[fp->encode.code[n][m]])
+ {
+ d = fp->encode.code[n][m];
+ b = fp->encode.hits[d] - 1;
+ fp->encode.code[n][m] = b + FF_MAX;
+ if (fp->encode.hits[d]++ >= FF_MAX)
+ fp->encode.hits[d] = 0;
+ fp->encode.bigram[b *= 2] = n;
+ fp->encode.bigram[b + 1] = m;
+ }
+ else
+ fp->encode.code[n][m] = 0;
+
+ /*
+ * commit the real file
+ */
+
+ if (sfseek(fp->fp, (Sfoff_t)0, SEEK_SET))
+ {
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, ERROR_SYSTEM|2, "cannot rewind tmp file");
+ return -1;
+ }
+ if (!(sp = sfopen(NiL, fp->encode.file, "w")))
+ goto badcreate;
+
+ /*
+ * dump the bigrams
+ */
+
+ sfwrite(sp, fp->encode.bigram, sizeof(fp->encode.bigram));
+
+ /*
+ * encode the massaged paths
+ */
+
+ while (s = sfgetr(fp->fp, 0, 0))
+ {
+ z = strtol(s, &t, 0);
+ s = t;
+ if (z < 0 || z > 2 * FF_OFF)
+ {
+ sfputc(sp, FF_ESC);
+ sfputc(sp, (z >> 24));
+ sfputc(sp, (z >> 16));
+ sfputc(sp, (z >> 8));
+ sfputc(sp, z);
+ }
+ else
+ sfputc(sp, z);
+ while (n = *s++)
+ {
+ if (!(m = *s++))
+ {
+ sfputc(sp, n);
+ break;
+ }
+ if (d = fp->encode.code[n][m])
+ sfputc(sp, d);
+ else
+ {
+ sfputc(sp, n);
+ sfputc(sp, m);
+ }
+ }
+ }
+ sfclose(fp->fp);
+ fp->fp = sp;
+ if (finddone(fp))
+ goto bad;
+ break;
+ case FF_typ:
+ if (finddone(fp))
+ goto bad;
+ if (!(fp->fp = sfopen(NiL, fp->encode.temp, "r")))
+ {
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, ERROR_SYSTEM|2, "%s: cannot read tmp file", fp->encode.temp);
+ remove(fp->encode.temp);
+ return -1;
+ }
+
+ /*
+ * commit the output file
+ */
+
+ if (!(sp = sfopen(NiL, fp->encode.file, "w")))
+ goto badcreate;
+
+ /*
+ * write the header magic
+ */
+
+ sfputc(sp, 0);
+ sfputr(sp, FF_typ_magic, 0);
+
+ /*
+ * write the type table in index order starting with 1
+ */
+
+ for (x = (Type_t*)dtfirst(fp->encode.indexdict); x; x = (Type_t*)dtnext(fp->encode.indexdict, x))
+ sfputr(sp, x->name, 0);
+ sfputc(sp, 0);
+
+ /*
+ * append the front compressed strings
+ */
+
+ if (sfmove(fp->fp, sp, SF_UNBOUND, -1) < 0 || !sfeof(fp->fp))
+ {
+ sfclose(sp);
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, 2, "%s: cannot append codes", fp->encode.file);
+ goto bad;
+ }
+ sfclose(fp->fp);
+ fp->fp = sp;
+ if (finddone(fp))
+ goto bad;
+ remove(fp->encode.temp);
+ break;
+ }
+ return 0;
+ badcreate:
+ if (fp->disc->errorf)
+ (*fp->disc->errorf)(fp, fp->disc, 2, "%s: cannot write codes", fp->encode.file);
+ bad:
+ if (fp->fp)
+ {
+ sfclose(fp->fp);
+ fp->fp = 0;
+ }
+ remove(fp->encode.temp);
+ return -1;
+}
+
+/*
+ * close an open fastfind stream
+ */
+
+int
+findclose(register Find_t* fp)
+{
+ int n = 0;
+
+ if (!fp)
+ return -1;
+ if (fp->generate)
+ {
+ n = findsync(fp);
+ if (fp->encode.indexdict)
+ dtclose(fp->encode.indexdict);
+ if (fp->encode.namedict)
+ dtclose(fp->encode.namedict);
+ }
+ else
+ {
+ if (fp->decode.match)
+ regfree(&fp->decode.re);
+ n = 0;
+ }
+ if (fp->fp)
+ sfclose(fp->fp);
+ vmclose(fp->vm);
+ return n;
+}
diff --git a/src/lib/libast/misc/findlib.h b/src/lib/libast/misc/findlib.h
new file mode 100644
index 0000000..e42e619
--- /dev/null
+++ b/src/lib/libast/misc/findlib.h
@@ -0,0 +1,123 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * fast find private interface
+ */
+
+#ifndef _FINDLIB_H
+#define _FINDLIB_H
+
+#include <ast.h>
+#include <cdt.h>
+#include <ctype.h>
+#include <error.h>
+#include <ls.h>
+#include <regex.h>
+#include <vmalloc.h>
+
+#define FF_old 1 /* old format - 7 bit bigram */
+#define FF_gnu 2 /* gnu 8 bit no bigram */
+#define FF_dir 3 /* FF_gnu, dirs have trailing / */
+#define FF_typ 4 /* FF_dir with types */
+
+#define FF_gnu_magic "LOCATE02"
+#define FF_dir_magic "FIND-DIR-02"
+#define FF_typ_magic "FIND-DIR-TYPE-03"
+
+#define FF_ESC 0036
+#define FF_MAX 0200
+#define FF_MIN 0040
+#define FF_OFF 0016
+
+#define FF_SET_TYPE(p,i) ((p)->decode.bigram1[((i)>>3)&((1<<CHAR_BIT)-1)]|=(1<<((i)&07)))
+#define FF_OK_TYPE(p,i) (!(p)->types||((p)->decode.bigram1[((i)>>3)&((1<<CHAR_BIT)-1)]&(1<<((i)&07))))
+
+typedef struct
+{
+ char* end;
+ char* type;
+ char* restore;
+ int count;
+ int found;
+ int ignorecase;
+ int match;
+ int peek;
+ int swap;
+ regex_t re;
+ char bigram1[(1<<(CHAR_BIT-1))];
+ char bigram2[(1<<(CHAR_BIT-1))];
+ char path[PATH_MAX];
+ char temp[PATH_MAX];
+ char pattern[1];
+} Decode_t;
+
+typedef struct
+{
+ Dtdisc_t namedisc;
+ Dtdisc_t indexdisc;
+ Dt_t* namedict;
+ Dt_t* indexdict;
+ int prefix;
+ unsigned char bigram[2*FF_MAX];
+ unsigned short code[FF_MAX][FF_MAX];
+ unsigned short hits[USHRT_MAX+1];
+ char path[PATH_MAX];
+ char mark[PATH_MAX];
+ char file[PATH_MAX];
+ char temp[PATH_MAX];
+} Encode_t;
+
+typedef union
+{
+ Decode_t code_decode;
+ Encode_t code_encode;
+} Code_t;
+
+typedef struct
+{
+ Dtlink_t byname;
+ Dtlink_t byindex;
+ unsigned long index;
+ char name[1];
+} Type_t;
+
+#define _FIND_PRIVATE_ \
+ Finddisc_t* disc; \
+ Vmalloc_t* vm; \
+ char** dirs; \
+ int* lens; \
+ Sfio_t* fp; \
+ Findverify_f verifyf; \
+ int generate; \
+ int method; \
+ int secure; \
+ int types; \
+ int verify; \
+ Code_t code;
+
+#define decode code.code_decode
+#define encode code.code_encode
+
+#include <find.h>
+
+#endif
diff --git a/src/lib/libast/misc/fmtrec.c b/src/lib/libast/misc/fmtrec.c
new file mode 100644
index 0000000..36b2cd5
--- /dev/null
+++ b/src/lib/libast/misc/fmtrec.c
@@ -0,0 +1,102 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * return the record format string given a format descriptor
+ */
+
+#include <recfmt.h>
+#include <ctype.h>
+
+char*
+fmtrec(Recfmt_t f, int fs)
+{
+ char* b;
+ char* e;
+ char* s;
+ long n;
+ char del[2];
+
+ b = s = fmtbuf(n = 32);
+ e = b + n;
+ switch (RECTYPE(f))
+ {
+ case REC_delimited:
+ *s++ = 'd';
+ if ((del[0] = REC_D_DELIMITER(f)) != '\n')
+ {
+ del[1] = 0;
+ if (fs)
+ sfsprintf(s, e - s, "0x%02x", *(unsigned char*)del);
+ else
+ sfsprintf(s, e - s, "%s", fmtquote(del, NiL, NiL, 1, 0));
+ }
+ else
+ *s = 0;
+ break;
+ case REC_fixed:
+ if (!fs)
+ *s++ = 'f';
+ sfsprintf(s, e - s, "%lu", REC_F_SIZE(f));
+ break;
+ case REC_variable:
+ *s++ = 'v';
+ if (n = REC_V_SIZE(f))
+ s += sfsprintf(s, e - s, "%lu", n);
+ if (REC_V_HEADER(f) != 4)
+ s += sfsprintf(s, e - s, "h%u", REC_V_HEADER(f));
+ if (REC_V_OFFSET(f) != 0)
+ s += sfsprintf(s, e - s, "o%u", REC_V_OFFSET(f));
+ if (REC_V_LENGTH(f) != 2)
+ s += sfsprintf(s, e - s, "z%u", REC_V_LENGTH(f));
+ if (REC_V_LITTLE(f) != 0)
+ *s++ = 'l';
+ if (REC_V_INCLUSIVE(f) == 0)
+ *s++ = 'n';
+ *s = 0;
+ break;
+ case REC_method:
+ *s++ = 'm';
+ switch (n = REC_M_INDEX(f))
+ {
+ case REC_M_data:
+ sfsprintf(s, e - s, "data");
+ break;
+ case REC_M_path:
+ sfsprintf(s, e - s, "path");
+ break;
+ default:
+ sfsprintf(s, e - s, "%lu", n);
+ break;
+ }
+ break;
+ case REC_none:
+ *s++ = 'n';
+ *s = 0;
+ break;
+ default:
+ sfsprintf(s, e - s, "u%u.0x%07x", RECTYPE(f), REC_U_ATTRIBUTES(f));
+ break;
+ }
+ return b;
+}
diff --git a/src/lib/libast/misc/fs3d.c b/src/lib/libast/misc/fs3d.c
new file mode 100644
index 0000000..cc708f2
--- /dev/null
+++ b/src/lib/libast/misc/fs3d.c
@@ -0,0 +1,116 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * 3d fs operations
+ * only active for non-shared 3d library
+ */
+
+#define mount ______mount
+
+#include <ast.h>
+
+#undef mount
+
+#include <fs3d.h>
+
+int
+fs3d(register int op)
+{
+ register int cur;
+ register char* v;
+ char val[sizeof(FS3D_off) + 8];
+
+ static int fsview;
+ static char on[] = FS3D_on;
+ static char off[] = FS3D_off;
+
+ if (fsview < 0)
+ return 0;
+
+ /*
+ * get the current setting
+ */
+
+ if (!fsview && (!getenv("LD_PRELOAD") || mount("", "", 0, NiL)))
+ goto nope;
+ if (FS3D_op(op) == FS3D_OP_INIT && mount(FS3D_init, NiL, FS3D_VIEW, NiL))
+ goto nope;
+ if (mount(on, val, FS3D_VIEW|FS3D_GET|FS3D_SIZE(sizeof(val)), NiL))
+ goto nope;
+ if (v = strchr(val, ' '))
+ v++;
+ else
+ v = val;
+ if (!strcmp(v, on))
+ cur = FS3D_ON;
+ else if (!strncmp(v, off, sizeof(off) - 1) && v[sizeof(off)] == '=')
+ cur = FS3D_LIMIT((int)strtol(v + sizeof(off) + 1, NiL, 0));
+ else
+ cur = FS3D_OFF;
+ if (cur != op)
+ {
+ switch (FS3D_op(op))
+ {
+ case FS3D_OP_OFF:
+ v = off;
+ break;
+ case FS3D_OP_ON:
+ v = on;
+ break;
+ case FS3D_OP_LIMIT:
+ sfsprintf(val, sizeof(val), "%s=%d", off, FS3D_arg(op));
+ v = val;
+ break;
+ default:
+ v = 0;
+ break;
+ }
+ if (v && mount(v, NiL, FS3D_VIEW, NiL))
+ goto nope;
+ }
+ fsview = 1;
+ return cur;
+ nope:
+ fsview = -1;
+ return 0;
+}
+
+/*
+ * user code that includes <fs3d.h> will have mount() mapped to fs3d_mount()
+ * this restricts the various "standard" mount prototype conflicts to this spot
+ * this means that code that includes <fs3d.h> cannot access the real mount
+ * (at least without some additional macro hackery
+ */
+
+#undef mount
+
+extern int mount(const char*, char*, int, void*);
+
+int
+fs3d_mount(const char* source, char* target, int flags, void* data)
+{
+ return mount(source, target, flags, data);
+}
diff --git a/src/lib/libast/misc/fts.c b/src/lib/libast/misc/fts.c
new file mode 100644
index 0000000..d8bb34d
--- /dev/null
+++ b/src/lib/libast/misc/fts.c
@@ -0,0 +1,1605 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Phong Vo
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * fts implementation unwound from the kpv ftwalk() of 1988-10-30
+ */
+
+#include <ast.h>
+#include <ast_dir.h>
+#include <error.h>
+#include <fs3d.h>
+#include <ls.h>
+
+struct Ftsent;
+
+typedef int (*Compar_f)(struct Ftsent* const*, struct Ftsent* const*);
+typedef int (*Stat_f)(const char*, struct stat*);
+
+#define _fts_status status
+#define _fts_statb statb
+
+#define _FTS_PRIVATE_ \
+ FTSENT* parent; /* top parent */ \
+ FTSENT* todo; /* todo list */ \
+ FTSENT* top; /* top element */ \
+ FTSENT* root; \
+ FTSENT* bot; /* bottom element */ \
+ FTSENT* free; /* free element */ \
+ FTSENT* diroot; \
+ FTSENT* curdir; \
+ FTSENT* current; /* current element */ \
+ FTSENT* previous; /* previous current */ \
+ FTSENT* dotdot; \
+ FTSENT* link; /* real current fts_link*/ \
+ FTSENT* pwd; /* pwd parent */ \
+ DIR* dir; /* current dir stream */ \
+ Compar_f comparf; /* node comparison func */ \
+ size_t baselen; /* current strlen(base) */ \
+ size_t homesize; /* sizeof(home) */ \
+ int cd; /* chdir status */ \
+ int cpname; \
+ int flags; /* fts_open() flags */ \
+ int nd; \
+ unsigned char children; \
+ unsigned char fs3d; \
+ unsigned char nostat; \
+ unsigned char state; /* fts_read() state */ \
+ char* base; /* basename in path */ \
+ char* name; \
+ char* path; /* path workspace */ \
+ char* home; /* home/path buffer */ \
+ char* endbase; /* space to build paths */ \
+ char* endbuf; /* space to build paths */ \
+ char* pad[2]; /* $0.02 to splain this */
+
+/*
+ * NOTE: <ftwalk.h> relies on status and statb being the first two elements
+ */
+
+#define _FTSENT_PRIVATE_ \
+ int nd; /* popdir() count */ \
+ FTSENT* left; /* left child */ \
+ FTSENT* right; /* right child */ \
+ FTSENT* pwd; /* pwd parent */ \
+ FTSENT* stack; /* getlist() stack */ \
+ long nlink; /* FTS_D link count */ \
+ unsigned char must; /* must stat */ \
+ unsigned char type; /* DT_* type */ \
+ unsigned char symlink; /* originally a symlink */ \
+ char name[sizeof(int)]; /* fts_name data */
+
+#include <fts.h>
+
+#ifndef ENOSYS
+#define ENOSYS EINVAL
+#endif
+
+
+#if MAXNAMLEN > 16
+#define MINNAME 32
+#else
+#define MINNAME 16
+#endif
+
+#define drop(p,f) (((f)->fts_namelen < MINNAME) ? ((f)->fts_link = (p)->free, (p)->free = (f)) : (free(f), (p)->free))
+
+#define ACCESS(p,f) ((p)->cd==0?(f)->fts_name:(f)->fts_path)
+#define PATH(f,p,l) ((!((f)->flags&FTS_SEEDOTDIR)&&(l)>0&&(p)[0]=='.'&&(p)[1]=='/')?((p)+2):(p))
+#define SAME(one,two) ((one)->st_ino==(two)->st_ino&&(one)->st_dev==(two)->st_dev)
+#define SKIPLINK(p,f) ((f)->fts_parent->nlink == 0)
+
+#ifdef D_TYPE
+#define ISTYPE(f,t) ((f)->type == (t))
+#define TYPE(f,t) ((f)->type = (t))
+#define SKIP(p,f) ((f)->fts_parent->must == 0 && (((f)->type == DT_UNKNOWN) ? SKIPLINK(p,f) : ((f)->type != DT_DIR && ((f)->type != DT_LNK || ((p)->flags & FTS_PHYSICAL)))))
+#else
+#undef DT_UNKNOWN
+#define DT_UNKNOWN 0
+#undef DT_LNK
+#define DT_LNK 1
+#define ISTYPE(f,t) ((t)==DT_UNKNOWN)
+#define TYPE(f,d)
+#define SKIP(p,f) ((f)->fts_parent->must == 0 && SKIPLINK(p,f))
+#endif
+
+#ifndef D_FILENO
+#define D_FILENO(d) (1)
+#endif
+
+/*
+ * NOTE: a malicious dir rename() could change .. underfoot so we
+ * must always verify; undef verify to enable the unsafe code
+ */
+
+#define verify 1
+
+/*
+ * FTS_NOSTAT requires a dir with
+ * D_TYPE(&dirent_t)!=DT_UNKNOWN
+ * OR
+ * st_nlink>=2
+ */
+
+#define FTS_children_resume 1
+#define FTS_children_return 2
+#define FTS_error 3
+#define FTS_popstack 4
+#define FTS_popstack_resume 5
+#define FTS_popstack_return 6
+#define FTS_preorder 7
+#define FTS_preorder_resume 8
+#define FTS_preorder_return 9
+#define FTS_readdir 10
+#define FTS_terminal 11
+#define FTS_todo 12
+#define FTS_top_return 13
+
+typedef int (*Notify_f)(FTS*, FTSENT*, void*);
+
+typedef struct Notify_s
+{
+ struct Notify_s* next;
+ Notify_f notifyf;
+ void* context;
+} Notify_t;
+
+static Notify_t* notify;
+
+/*
+ * allocate an FTSENT node
+ */
+
+static FTSENT*
+node(FTS* fts, FTSENT* parent, register char* name, register size_t namelen)
+{
+ register FTSENT* f;
+ register size_t n;
+
+ if (fts->free && namelen < MINNAME)
+ {
+ f = fts->free;
+ fts->free = f->fts_link;
+ }
+ else
+ {
+ n = (namelen < MINNAME ? MINNAME : namelen + 1) - sizeof(int);
+ if (!(f = newof(0, FTSENT, 1, n)))
+ {
+ fts->fts_errno = errno;
+ fts->state = FTS_error;
+ return 0;
+ }
+ f->fts = fts;
+ }
+ TYPE(f, DT_UNKNOWN);
+ f->status = 0;
+ f->symlink = 0;
+ f->fts_level = (f->fts_parent = parent)->fts_level + 1;
+#if __OBSOLETE__ < 20140101
+ f->_fts_level = (short)f->fts_level;
+#endif
+ f->fts_link = 0;
+ f->fts_pointer = 0;
+ f->fts_number = 0;
+ f->fts_errno = 0;
+ f->fts_namelen = namelen;
+#if __OBSOLETE__ < 20140101
+ f->_fts_namelen = (unsigned short)f->fts_namelen;
+#endif
+ f->fts_name = f->name;
+ f->fts_statp = &f->statb;
+ memcpy(f->fts_name, name, namelen + 1);
+ return f;
+}
+
+/*
+ * compare directories by device/inode
+ */
+
+static int
+statcmp(FTSENT* const* pf1, FTSENT* const* pf2)
+{
+ register const FTSENT* f1 = *pf1;
+ register const FTSENT* f2 = *pf2;
+
+ if (f1->statb.st_ino < f2->statb.st_ino)
+ return -1;
+ if (f1->statb.st_ino > f2->statb.st_ino)
+ return 1;
+ if (f1->statb.st_dev < f2->statb.st_dev)
+ return -1;
+ if (f1->statb.st_dev > f2->statb.st_dev)
+ return 1;
+
+ /*
+ * hack for NFS where <dev,ino> may not uniquely identify objects
+ */
+
+ if (f1->statb.st_mtime < f2->statb.st_mtime)
+ return -1;
+ if (f1->statb.st_mtime > f2->statb.st_mtime)
+ return 1;
+ return 0;
+}
+
+/*
+ * search trees with top-down splaying (a la Tarjan and Sleator)
+ * when used for insertion sort, this implements a stable sort
+ */
+
+#define RROTATE(r) (t = r->left, r->left = t->right, t->right = r, r = t)
+#define LROTATE(r) (t = r->right, r->right = t->left, t->left = r, r = t)
+
+static FTSENT*
+search(FTSENT* e, FTSENT* root, int(*comparf)(FTSENT* const*, FTSENT* const*), int insert)
+{
+ register int cmp;
+ register FTSENT* t;
+ register FTSENT* left;
+ register FTSENT* right;
+ register FTSENT* lroot;
+ register FTSENT* rroot;
+
+ left = right = lroot = rroot = 0;
+ while (root)
+ {
+ if (!(cmp = (*comparf)(&e, &root)) && !insert)
+ break;
+ if (cmp < 0)
+ {
+ /*
+ * this is the left zig-zig case
+ */
+
+ if (root->left && (cmp = (*comparf)(&e, &root->left)) <= 0)
+ {
+ RROTATE(root);
+ if (!cmp && !insert)
+ break;
+ }
+
+ /*
+ * stick all things > e to the right tree
+ */
+
+ if (right)
+ right->left = root;
+ else
+ rroot = root;
+ right = root;
+ root = root->left;
+ right->left = 0;
+ }
+ else
+ {
+ /*
+ * this is the right zig-zig case
+ */
+
+ if (root->right && (cmp = (*comparf)(&e, &root->right)) >= 0)
+ {
+ LROTATE(root);
+ if (!cmp && !insert)
+ break;
+ }
+
+ /*
+ * stick all things <= e to the left tree
+ */
+
+ if (left)
+ left->right = root;
+ else
+ lroot = root;
+ left = root;
+ root = root->right;
+ left->right = 0;
+ }
+ }
+ if (!root)
+ root = e;
+ else
+ {
+ if (right)
+ right->left = root->right;
+ else
+ rroot = root->right;
+ if (left)
+ left->right = root->left;
+ else
+ lroot = root->left;
+ }
+ root->left = lroot;
+ root->right = rroot;
+ return root;
+}
+
+/*
+ * delete the root element from the tree
+ */
+
+static FTSENT*
+deleteroot(register FTSENT* root)
+{
+ register FTSENT* t;
+ register FTSENT* left;
+ register FTSENT* right;
+
+ right = root->right;
+ if (!(left = root->left))
+ root = right;
+ else
+ {
+ while (left->right)
+ LROTATE(left);
+ left->right = right;
+ root = left;
+ }
+ return root;
+}
+
+/*
+ * generate ordered fts_link list from binary tree at root
+ * FTSENT.stack instead of recursion to avoid blowing the real
+ * stack on big directories
+ */
+
+static void
+getlist(register FTSENT** top, register FTSENT** bot, register FTSENT* root)
+{
+ register FTSENT* stack = 0;
+
+ for (;;)
+ {
+ if (root->left)
+ {
+ root->stack = stack;
+ stack = root;
+ root = root->left;
+ }
+ else
+ {
+ for (;;)
+ {
+ if (*top)
+ *bot = (*bot)->fts_link = root;
+ else
+ *bot = *top = root;
+ if (root->right)
+ {
+ root = root->right;
+ break;
+ }
+ if (!(root = stack))
+ {
+ (*bot)->fts_link = 0;
+ return;
+ }
+ stack = stack->stack;
+ }
+ }
+ }
+}
+
+/*
+ * set directory when curdir is lost in space
+ */
+
+static int
+setdir(register char* home, register char* path)
+{
+ register int cdrv;
+
+ if (path[0] == '/')
+ cdrv = pathcd(path, NiL);
+ else
+ {
+ /*
+ * note that path and home are in the same buffer
+ */
+
+ path[-1] = '/';
+ cdrv = pathcd(home, NiL);
+ path[-1] = 0;
+ }
+ if (cdrv < 0)
+ pathcd(home, NiL);
+ return cdrv;
+}
+
+/*
+ * set to parent dir
+ */
+
+static int
+setpdir(register char* home, register char* path, register char* base)
+{
+ register int c;
+ register int cdrv;
+
+ if (base > path)
+ {
+ c = base[0];
+ base[0] = 0;
+ cdrv = setdir(home, path);
+ base[0] = c;
+ }
+ else
+ cdrv = pathcd(home, NiL);
+ return cdrv;
+}
+
+/*
+ * pop a set of directories
+ */
+static int
+popdirs(FTS* fts)
+{
+ register FTSENT*f;
+ register char* s;
+ register char* e;
+#ifndef verify
+ register int verify;
+#endif
+ struct stat sb;
+ char buf[PATH_MAX];
+
+ if (!(f = fts->curdir) || f->fts_level < 0)
+ return -1;
+ e = buf + sizeof(buf) - 4;
+#ifndef verify
+ verify = 0;
+#endif
+ while (fts->nd > 0)
+ {
+ for (s = buf; s < e && fts->nd > 0; fts->nd--)
+ {
+ if (fts->pwd)
+ {
+#ifndef verify
+ verify |= fts->pwd->symlink;
+#endif
+ fts->pwd = fts->pwd->pwd;
+ }
+ *s++ = '.';
+ *s++ = '.';
+ *s++ = '/';
+ }
+ *s = 0;
+ if (chdir(buf))
+ return -1;
+ }
+ return (verify && (stat(".", &sb) < 0 || !SAME(&sb, f->fts_statp))) ? -1 : 0;
+}
+
+/*
+ * initialize st from path and fts_info from st
+ */
+
+static int
+info(FTS* fts, register FTSENT* f, const char* path, struct stat* sp, int flags)
+{
+ if (path)
+ {
+#ifdef S_ISLNK
+ if (!f->symlink && (ISTYPE(f, DT_UNKNOWN) || ISTYPE(f, DT_LNK)))
+ {
+ if (lstat(path, sp) < 0)
+ goto bad;
+ }
+ else
+#endif
+ if (stat(path, sp) < 0)
+ goto bad;
+ }
+#ifdef S_ISLNK
+ again:
+#endif
+ if (S_ISDIR(sp->st_mode))
+ {
+ if ((flags & FTS_NOSTAT) && !fts->fs3d)
+ {
+ f->fts_parent->nlink--;
+#ifdef D_TYPE
+ if ((f->nlink = sp->st_nlink) < 2)
+ {
+ f->must = 2;
+ f->nlink = 2;
+ }
+ else
+ f->must = 0;
+#else
+ if ((f->nlink = sp->st_nlink) >= 2)
+ f->must = 1;
+ else
+ f->must = 2;
+#endif
+ }
+ else
+ f->must = 2;
+ TYPE(f, DT_DIR);
+ f->fts_info = FTS_D;
+ }
+#ifdef S_ISLNK
+ else if (S_ISLNK((sp)->st_mode))
+ {
+ struct stat sb;
+
+ f->symlink = 1;
+ if (flags & FTS_PHYSICAL)
+ {
+ TYPE(f, DT_LNK);
+ f->fts_info = FTS_SL;
+ }
+ else if (stat(path, &sb) >= 0)
+ {
+ *sp = sb;
+ flags = FTS_PHYSICAL;
+ goto again;
+ }
+ else
+ {
+ TYPE(f, DT_LNK);
+ f->fts_info = FTS_SLNONE;
+ }
+ }
+#endif
+ else
+ {
+ TYPE(f, DT_REG);
+ f->fts_info = FTS_F;
+ }
+ return 0;
+ bad:
+ TYPE(f, DT_UNKNOWN);
+ f->fts_info = FTS_NS;
+ return -1;
+}
+
+/*
+ * get top list of elements to process
+ * ordering delayed until first fts_read()
+ * to give caller a chance to set fts->handle
+ */
+
+static FTSENT*
+toplist(FTS* fts, register char* const* pathnames)
+{
+ register char* path;
+ register FTSENT* f;
+ register FTSENT* top;
+ register FTSENT* bot;
+ int physical;
+ int metaphysical;
+ char* s;
+ struct stat st;
+
+ if (fts->flags & FTS_NOSEEDOTDIR)
+ fts->flags &= ~FTS_SEEDOTDIR;
+ physical = (fts->flags & FTS_PHYSICAL);
+ metaphysical = (fts->flags & (FTS_META|FTS_PHYSICAL)) == (FTS_META|FTS_PHYSICAL);
+ top = bot = 0;
+ while (path = *pathnames++)
+ {
+ /*
+ * make elements
+ */
+
+ if (!(f = node(fts, fts->parent, path, strlen(path))))
+ break;
+ path = f->fts_name;
+ if (!physical)
+ f->fts_namelen = (fts->flags & FTS_SEEDOTDIR) ? strlen(path) : (pathcanon(path, strlen(path) + 1, 0) - path);
+ else if (*path != '.')
+ {
+ f->fts_namelen = strlen(path);
+ fts->flags |= FTS_SEEDOTDIR;
+ }
+ else
+ {
+ if (fts->flags & FTS_NOSEEDOTDIR)
+ {
+ fts->flags &= ~FTS_SEEDOTDIR;
+ s = path;
+ while (*s++ == '.' && *s++ == '/')
+ {
+ while (*s == '/')
+ s++;
+ if (!*s)
+ break;
+ path = f->fts_name;
+ while (*path++ = *s++);
+ path = f->fts_name;
+ }
+ }
+ else
+ fts->flags |= FTS_SEEDOTDIR;
+ for (s = path + strlen(path); s > path && *(s - 1) == '/'; s--);
+ *s = 0;
+ f->fts_namelen = s - path;
+ }
+#if __OBSOLETE__ < 20140101
+ f->_fts_namelen = (unsigned short)f->fts_namelen;
+#endif
+ if (!*path)
+ {
+ errno = ENOENT;
+ f->fts_info = FTS_NS;
+ }
+ else
+ info(fts, f, path, f->fts_statp, fts->flags);
+#ifdef S_ISLNK
+
+ /*
+ * don't let any standards committee get
+ * away with calling your idea a hack
+ */
+
+ if (metaphysical && f->fts_info == FTS_SL)
+ {
+ if (stat(path, &st) >= 0)
+ {
+ *f->fts_statp = st;
+ info(fts, f, NiL, f->fts_statp, 0);
+ }
+ else
+ f->fts_info = FTS_SLNONE;
+ }
+#endif
+ if (bot)
+ {
+ bot->fts_link = f;
+ bot = f;
+ }
+ else
+ top = bot = f;
+ }
+ return top;
+}
+
+/*
+ * order fts->todo if fts->comparf != 0
+ */
+
+static void
+order(FTS* fts)
+{
+ register FTSENT* f;
+ register FTSENT* root;
+ FTSENT* top;
+ FTSENT* bot;
+
+ top = bot = root = 0;
+ for (f = fts->todo; f; f = f->fts_link)
+ root = search(f, root, fts->comparf, 1);
+ getlist(&top, &bot, root);
+ fts->todo = top;
+}
+
+/*
+ * resize the path buffer
+ * note that free() is not used because we may need to chdir(fts->home)
+ * if there isn't enough space to continue
+ */
+
+static int
+resize(register FTS* fts, size_t inc)
+{
+ register char* old;
+ register char* newp;
+ register size_t n_old;
+
+ /*
+ * add space for "/." used in testing FTS_DNX
+ */
+
+ n_old = fts->homesize;
+ fts->homesize = ((fts->homesize + inc + 4) / PATH_MAX + 1) * PATH_MAX;
+ if (!(newp = newof(0, char, fts->homesize, 0)))
+ {
+ fts->fts_errno = errno;
+ fts->state = FTS_error;
+ return -1;
+ }
+ old = fts->home;
+ fts->home = newp;
+ memcpy(newp, old, n_old);
+ if (fts->endbuf)
+ fts->endbuf = newp + fts->homesize - 4;
+ if (fts->path)
+ fts->path = newp + (fts->path - old);
+ if (fts->base)
+ fts->base = newp + (fts->base - old);
+ free(old);
+ return 0;
+}
+
+/*
+ * open a new fts stream on pathnames
+ */
+
+FTS*
+fts_open(char* const* pathnames, int flags, int (*comparf)(FTSENT* const*, FTSENT* const*))
+{
+ register FTS* fts;
+
+ if (!(fts = newof(0, FTS, 1, sizeof(FTSENT))))
+ return 0;
+ fts->flags = flags;
+ fts->cd = (flags & FTS_NOCHDIR) ? 1 : -1;
+ fts->comparf = comparf;
+ fts->fs3d = fs3d(FS3D_TEST);
+
+ /*
+ * set up the path work buffer
+ */
+
+ fts->homesize = 2 * PATH_MAX;
+ for (;;)
+ {
+ if (!(fts->home = newof(fts->home, char, fts->homesize, 0)))
+ {
+ free(fts);
+ return 0;
+ }
+ if (fts->cd > 0 || getcwd(fts->home, fts->homesize))
+ break;
+ if (errno == ERANGE)
+ fts->homesize += PATH_MAX;
+ else
+ fts->cd = 1;
+ }
+ fts->endbuf = fts->home + fts->homesize - 4;
+
+ /*
+ * initialize the tippity-top
+ */
+
+ fts->parent = (FTSENT*)(fts + 1);
+ fts->parent->fts_info = FTS_D;
+ memcpy(fts->parent->fts_accpath = fts->parent->fts_path = fts->parent->fts_name = fts->parent->name, ".", 2);
+ fts->parent->fts_level = -1;
+#if __OBSOLETE__ < 20140101
+ fts->parent->_fts_level = (short)fts->parent->fts_level;
+#endif
+ fts->parent->fts_statp = &fts->parent->statb;
+ fts->parent->must = 2;
+ fts->parent->type = DT_UNKNOWN;
+ fts->path = fts->home + strlen(fts->home) + 1;
+
+ /*
+ * make the list of top elements
+ */
+
+ if (!pathnames || (flags & FTS_ONEPATH) || !*pathnames)
+ {
+ char* v[2];
+
+ v[0] = pathnames && (flags & FTS_ONEPATH) ? (char*)pathnames : ".";
+ v[1] = 0;
+ fts->todo = toplist(fts, v);
+ }
+ else
+ fts->todo = toplist(fts, pathnames);
+#if _HUH_1997_01_07
+ if (!fts->todo || fts->todo->fts_info == FTS_NS && !fts->todo->fts_link)
+#else
+ if (!fts->todo)
+#endif
+ {
+ fts_close(fts);
+ return 0;
+ }
+ return fts;
+}
+
+/*
+ * return the next FTS entry
+ */
+
+FTSENT*
+fts_read(register FTS* fts)
+{
+ register char* s;
+ register int n;
+ register FTSENT* f;
+ struct dirent* d;
+ size_t i;
+ FTSENT* t;
+ Notify_t* p;
+#ifdef verify
+ struct stat sb;
+#endif
+
+ for (;;)
+ switch (fts->state)
+ {
+
+ case FTS_top_return:
+
+ f = fts->todo;
+ t = 0;
+ while (f)
+ if (f->status == FTS_SKIP)
+ {
+ if (t)
+ {
+ t->fts_link = f->fts_link;
+ drop(fts, f);
+ f = t->fts_link;
+ }
+ else
+ {
+ fts->todo = f->fts_link;
+ drop(fts, f);
+ f = fts->todo;
+ }
+ }
+ else
+ {
+ t = f;
+ f = f->fts_link;
+ }
+ /*FALLTHROUGH*/
+
+ case 0:
+
+ if (!fts->state && fts->comparf)
+ order(fts);
+ if (!(f = fts->todo))
+ return 0;
+ /*FALLTHROUGH*/
+
+ case FTS_todo:
+
+ /*
+ * process the top object on the stack
+ */
+
+ fts->root = fts->top = fts->bot = 0;
+
+ /*
+ * initialize the top level
+ */
+
+ if (f->fts_level == 0)
+ {
+ fts->parent->fts_number = f->fts_number;
+ fts->parent->fts_pointer = f->fts_pointer;
+ fts->parent->fts_statp = f->fts_statp;
+ fts->parent->statb = *f->fts_statp;
+ f->fts_parent = fts->parent;
+ fts->diroot = 0;
+ if (fts->cd == 0)
+ pathcd(fts->home, NiL);
+ else if (fts->cd < 0)
+ fts->cd = 0;
+ fts->pwd = f->fts_parent;
+ fts->curdir = fts->cd ? 0 : f->fts_parent;
+ *(fts->base = fts->path) = 0;
+ }
+
+ /*
+ * chdir to parent if asked for
+ */
+
+ if (fts->cd < 0)
+ {
+ fts->cd = setdir(fts->home, fts->path);
+ fts->pwd = f->fts_parent;
+ fts->curdir = fts->cd ? 0 : f->fts_parent;
+ }
+
+ /*
+ * add object's name to the path
+ */
+
+ if ((fts->baselen = f->fts_namelen) >= (fts->endbuf - fts->base) && resize(fts, fts->baselen))
+ return 0;
+ memcpy(fts->base, f->name, fts->baselen + 1);
+ fts->name = fts->cd ? fts->path : fts->base;
+ /*FALLTHROUGH*/
+
+ case FTS_preorder:
+
+ /*
+ * check for cycle and open dir
+ */
+
+ if (f->fts_info == FTS_D)
+ {
+ if ((fts->diroot = search(f, fts->diroot, statcmp, 0)) != f || f->fts_level > 0 && (t = f) && statcmp(&t, &f->fts_parent) == 0)
+ {
+ f->fts_info = FTS_DC;
+ f->fts_cycle = fts->diroot;
+ }
+ else if (!(fts->flags & FTS_TOP) && (!(fts->flags & FTS_XDEV) || f->statb.st_dev == f->fts_parent->statb.st_dev))
+ {
+ /*
+ * buffer is known to be large enough here!
+ */
+
+ if (fts->base[fts->baselen - 1] != '/')
+ memcpy(fts->base + fts->baselen, "/.", 3);
+ if (!(fts->dir = opendir(fts->name)))
+ f->fts_info = FTS_DNX;
+ fts->base[fts->baselen] = 0;
+ if (!fts->dir && !(fts->dir = opendir(fts->name)))
+ f->fts_info = FTS_DNR;
+ }
+ }
+ f->nd = f->fts_info & ~FTS_DNX;
+ if (f->nd || !(fts->flags & FTS_NOPREORDER))
+ {
+ fts->current = f;
+ fts->link = f->fts_link;
+ f->fts_link = 0;
+ f->fts_path = PATH(fts, fts->path, f->fts_level);
+ f->fts_pathlen = (fts->base - f->fts_path) + fts->baselen;
+ f->fts_accpath = ACCESS(fts, f);
+ fts->state = FTS_preorder_return;
+ goto note;
+ }
+ /*FALLTHROUGH*/
+
+ case FTS_preorder_resume:
+
+ /*
+ * prune
+ */
+
+ if (!fts->dir || f->nd || f->status == FTS_SKIP)
+ {
+ if (fts->dir)
+ {
+ closedir(fts->dir);
+ fts->dir = 0;
+ }
+ fts->state = FTS_popstack;
+ continue;
+ }
+
+ /*
+ * FTS_D or FTS_DNX, about to read children
+ */
+
+ if (fts->cd == 0)
+ {
+ if ((fts->cd = chdir(fts->name)) < 0)
+ pathcd(fts->home, NiL);
+ else if (fts->pwd != f)
+ {
+ f->pwd = fts->pwd;
+ fts->pwd = f;
+ }
+ fts->curdir = fts->cd < 0 ? 0 : f;
+ }
+ fts->nostat = fts->children > 1 || f->fts_info == FTS_DNX;
+ fts->cpname = fts->cd && !fts->nostat || !fts->children && !fts->comparf;
+ fts->dotdot = 0;
+ fts->endbase = fts->base + fts->baselen;
+ if (fts->endbase[-1] != '/')
+ *fts->endbase++ = '/';
+ fts->current = f;
+ /*FALLTHROUGH*/
+
+ case FTS_readdir:
+
+ while (d = readdir(fts->dir))
+ {
+ s = d->d_name;
+ if (s[0] == '.')
+ {
+ if (s[1] == 0)
+ {
+ fts->current->nlink--;
+ if (!(fts->flags & FTS_SEEDOT))
+ continue;
+ n = 1;
+ }
+ else if (s[1] == '.' && s[2] == 0)
+ {
+ fts->current->nlink--;
+ if (fts->current->must == 1)
+ fts->current->must = 0;
+ if (!(fts->flags & FTS_SEEDOT))
+ continue;
+ n = 2;
+ }
+ else
+ n = 0;
+ }
+ else
+ n = 0;
+
+ /*
+ * make a new entry
+ */
+
+ i = D_NAMLEN(d);
+ if (!(f = node(fts, fts->current, s, i)))
+ return 0;
+ TYPE(f, D_TYPE(d));
+
+ /*
+ * check for space
+ */
+
+ if (i >= fts->endbuf - fts->endbase)
+ {
+ if (resize(fts, i))
+ return 0;
+ fts->endbase = fts->base + fts->baselen;
+ if (fts->endbase[-1] != '/')
+ fts->endbase++;
+ }
+ if (fts->cpname)
+ {
+ memcpy(fts->endbase, s, i + 1);
+ if (fts->cd)
+ s = fts->path;
+ }
+ if (n)
+ {
+ /*
+ * don't recurse on . and ..
+ */
+
+ if (n == 1)
+ f->fts_statp = fts->current->fts_statp;
+ else
+ {
+ if (f->fts_info != FTS_NS)
+ fts->dotdot = f;
+ if (fts->current->fts_parent->fts_level < 0)
+ {
+ f->fts_statp = &fts->current->fts_parent->statb;
+ info(fts, f, s, f->fts_statp, 0);
+ }
+ else
+ f->fts_statp = fts->current->fts_parent->fts_statp;
+ }
+ f->fts_info = FTS_DOT;
+ }
+ else if ((fts->nostat || SKIP(fts, f)) && (f->fts_info = FTS_NSOK) || info(fts, f, s, &f->statb, fts->flags))
+ f->statb.st_ino = D_FILENO(d);
+ if (fts->comparf)
+ fts->root = search(f, fts->root, fts->comparf, 1);
+ else if (fts->children || f->fts_info == FTS_D || f->fts_info == FTS_SL)
+ {
+ if (fts->top)
+ fts->bot = fts->bot->fts_link = f;
+ else
+ fts->top = fts->bot = f;
+ }
+ else
+ {
+ /*
+ * terminal node
+ */
+
+ f->fts_path = PATH(fts, fts->path, 1);
+ f->fts_pathlen = fts->endbase - f->fts_path + f->fts_namelen;
+ f->fts_accpath = ACCESS(fts, f);
+ fts->previous = fts->current;
+ fts->current = f;
+ fts->state = FTS_terminal;
+ goto note;
+ }
+ }
+
+ /*
+ * done with the directory
+ */
+
+ closedir(fts->dir);
+ fts->dir = 0;
+ if (fts->root)
+ getlist(&fts->top, &fts->bot, fts->root);
+ if (fts->children)
+ {
+ /*
+ * try moving back to parent dir
+ */
+
+ fts->base[fts->baselen] = 0;
+ if (fts->cd <= 0)
+ {
+ f = fts->current->fts_parent;
+ if (fts->cd < 0
+ || f != fts->curdir
+ || !fts->dotdot
+ || !SAME(f->fts_statp, fts->dotdot->fts_statp)
+ || fts->pwd && fts->pwd->symlink
+ || (fts->cd = chdir("..")) < 0
+#ifdef verify
+ || stat(".", &sb) < 0
+ || !SAME(&sb, fts->dotdot->fts_statp)
+#endif
+ )
+ fts->cd = setpdir(fts->home, fts->path, fts->base);
+ if (fts->pwd)
+ fts->pwd = fts->pwd->pwd;
+ fts->curdir = fts->cd ? 0 : f;
+ }
+ f = fts->current;
+ fts->link = f->fts_link;
+ f->fts_link = fts->top;
+ f->fts_path = PATH(fts, fts->path, f->fts_level);
+ f->fts_pathlen = (fts->base - f->fts_path) + f->fts_namelen;
+ f->fts_accpath = ACCESS(fts, f);
+ fts->state = FTS_children_return;
+ goto note;
+ }
+ /*FALLTHROUGH*/
+
+ case FTS_children_resume:
+
+ fts->base[fts->baselen] = 0;
+ if (fts->top)
+ {
+ fts->bot->fts_link = fts->todo;
+ fts->todo = fts->top;
+ fts->top = 0;
+ }
+ /*FALLTHROUGH*/
+
+ case FTS_popstack:
+
+ /*
+ * pop objects completely processed
+ */
+
+ fts->nd = 0;
+ f = fts->current;
+ /*FALLTHROUGH*/
+
+ case FTS_popstack_resume:
+
+ while (fts->todo && f == fts->todo)
+ {
+ t = f->fts_parent;
+ if ((f->fts_info & FTS_DP) == FTS_D)
+ {
+ /*
+ * delete from <dev,ino> tree
+ */
+
+ if (f != fts->diroot)
+ fts->diroot = search(f, fts->diroot, statcmp, 0);
+ fts->diroot = deleteroot(fts->diroot);
+ if (f == fts->curdir)
+ {
+ fts->nd++;
+ fts->curdir = t;
+ }
+
+ /*
+ * perform post-order processing
+ */
+
+ if (!(fts->flags & FTS_NOPOSTORDER) &&
+ f->status != FTS_SKIP &&
+ f->status != FTS_NOPOSTORDER)
+ {
+ /*
+ * move to parent dir
+ */
+
+ if (fts->nd > 0)
+ fts->cd = popdirs(fts);
+ if (fts->cd < 0)
+ fts->cd = setpdir(fts->home, fts->path, fts->base);
+ fts->curdir = fts->cd ? 0 : t;
+ f->fts_info = FTS_DP;
+ f->fts_path = PATH(fts, fts->path, f->fts_level);
+ f->fts_pathlen = (fts->base - f->fts_path) + f->fts_namelen;
+ f->fts_accpath = ACCESS(fts, f);
+
+ /*
+ * re-stat to update nlink/times
+ */
+
+ stat(f->fts_accpath, f->fts_statp);
+ fts->link = f->fts_link;
+ f->fts_link = 0;
+ fts->state = FTS_popstack_return;
+ goto note;
+ }
+ }
+
+ /*
+ * reset base
+ */
+
+ if (fts->base > fts->path + t->fts_namelen)
+ fts->base--;
+ *fts->base = 0;
+ fts->base -= t->fts_namelen;
+
+ /*
+ * try again or delete from top of stack
+ */
+
+ if (f->status == FTS_AGAIN)
+ {
+ f->fts_info = FTS_D;
+ f->status = 0;
+ }
+ else
+ {
+ fts->todo = fts->todo->fts_link;
+ drop(fts, f);
+ }
+ f = t;
+ }
+
+ /*
+ * reset current directory
+ */
+
+ if (fts->nd > 0 && popdirs(fts) < 0)
+ {
+ pathcd(fts->home, NiL);
+ fts->curdir = 0;
+ fts->cd = -1;
+ }
+ if (fts->todo)
+ {
+ if (*fts->base)
+ fts->base += f->fts_namelen;
+ if (*(fts->base - 1) != '/')
+ *fts->base++ = '/';
+ *fts->base = 0;
+ f = fts->todo;
+ fts->state = FTS_todo;
+ continue;
+ }
+ return 0;
+
+ case FTS_children_return:
+
+ f = fts->current;
+ f->fts_link = fts->link;
+
+ /*
+ * chdir down again
+ */
+
+ i = f->fts_info != FTS_DNX;
+ n = f->status == FTS_SKIP;
+ if (!n && fts->cd == 0)
+ {
+ if ((fts->cd = chdir(fts->base)) < 0)
+ pathcd(fts->home, NiL);
+ else if (fts->pwd != f)
+ {
+ f->pwd = fts->pwd;
+ fts->pwd = f;
+ }
+ fts->curdir = fts->cd ? 0 : f;
+ }
+
+ /*
+ * prune
+ */
+
+ if (fts->base[fts->baselen - 1] != '/')
+ fts->base[fts->baselen] = '/';
+ for (fts->bot = 0, f = fts->top; f; )
+ if (n || f->status == FTS_SKIP)
+ {
+ if (fts->bot)
+ fts->bot->fts_link = f->fts_link;
+ else
+ fts->top = f->fts_link;
+ drop(fts, f);
+ f = fts->bot ? fts->bot->fts_link : fts->top;
+ }
+ else
+ {
+ if (fts->children > 1 && i)
+ {
+ if (f->status == FTS_STAT)
+ info(fts, f, NiL, f->fts_statp, 0);
+ else if (f->fts_info == FTS_NSOK && !SKIP(fts, f))
+ {
+ s = f->fts_name;
+ if (fts->cd)
+ {
+ memcpy(fts->endbase, s, f->fts_namelen + 1);
+ s = fts->path;
+ }
+ info(fts, f, s, f->fts_statp, fts->flags);
+ }
+ }
+ fts->bot = f;
+ f = f->fts_link;
+ }
+ fts->children = 0;
+ fts->state = FTS_children_resume;
+ continue;
+
+ case FTS_popstack_return:
+
+ f = fts->todo;
+ f->fts_link = fts->link;
+ f->fts_info = f->status == FTS_AGAIN ? FTS_DP : 0;
+ fts->state = FTS_popstack_resume;
+ continue;
+
+ case FTS_preorder_return:
+
+ f = fts->current;
+ f->fts_link = fts->link;
+
+ /*
+ * follow symlink if asked to
+ */
+
+ if (f->status == FTS_FOLLOW)
+ {
+ f->status = 0;
+ if (f->fts_info == FTS_SL || ISTYPE(f, DT_LNK) || f->fts_info == FTS_NSOK)
+ {
+ info(fts, f, f->fts_accpath, f->fts_statp, 0);
+ if (f->fts_info != FTS_SL)
+ {
+ fts->state = FTS_preorder;
+ continue;
+ }
+ }
+ }
+
+ /*
+ * about to prune this f and already at home
+ */
+
+ if (fts->cd == 0 && f->fts_level == 0 && f->nd)
+ fts->cd = -1;
+ fts->state = FTS_preorder_resume;
+ continue;
+
+ case FTS_terminal:
+
+ f = fts->current;
+ if (f->status == FTS_FOLLOW)
+ {
+ f->status = 0;
+ if (f->fts_info == FTS_SL || ISTYPE(f, DT_LNK) || f->fts_info == FTS_NSOK)
+ {
+ info(fts, f, f->fts_accpath, f->fts_statp, 0);
+ if (f->symlink && f->fts_info != FTS_SL)
+ {
+ if (!(f->fts_link = fts->top))
+ fts->bot = f;
+ fts->top = f;
+ fts->current = fts->previous;
+ fts->state = FTS_readdir;
+ continue;
+ }
+ }
+ }
+ f = f->fts_parent;
+ drop(fts, fts->current);
+ fts->current = f;
+ fts->state = FTS_readdir;
+ continue;
+
+ case FTS_error:
+
+ return 0;
+
+ default:
+
+ fts->fts_errno = EINVAL;
+ fts->state = FTS_error;
+ return 0;
+
+ }
+ note:
+#if __OBSOLETE__ < 20140101
+ f->_fts_pathlen = (unsigned short)f->fts_pathlen;
+#endif
+ for (p = notify; p; p = p->next)
+ if ((n = (*p->notifyf)(fts, f, p->context)) > 0)
+ break;
+ else if (n < 0)
+ {
+ fts->fts_errno = EINVAL;
+ fts->state = FTS_error;
+ return 0;
+ }
+ return f;
+}
+
+/*
+ * set stream or entry flags
+ */
+
+int
+fts_set(register FTS* fts, register FTSENT* f, int status)
+{
+ if (fts || !f || f->fts->current != f)
+ return -1;
+ switch (status)
+ {
+ case FTS_AGAIN:
+ break;
+ case FTS_FOLLOW:
+ if (!(f->fts_info & FTS_SL))
+ return -1;
+ break;
+ case FTS_NOPOSTORDER:
+ break;
+ case FTS_SKIP:
+ if ((f->fts_info & (FTS_D|FTS_P)) != FTS_D)
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+ f->status = status;
+ return 0;
+}
+
+/*
+ * return the list of child entries
+ */
+
+FTSENT*
+fts_children(register FTS* fts, int flags)
+{
+ register FTSENT* f;
+
+ switch (fts->state)
+ {
+
+ case 0:
+
+ if (fts->comparf)
+ order(fts);
+ fts->state = FTS_top_return;
+ return fts->todo;
+
+ case FTS_preorder_return:
+
+ fts->children = ((flags | fts->flags) & FTS_NOSTAT) ? 2 : 1;
+ if (f = fts_read(fts))
+ f = f->fts_link;
+ return f;
+
+ }
+ return 0;
+}
+
+/*
+ * return default (FTS_LOGICAL|FTS_META|FTS_PHYSICAL|FTS_SEEDOTDIR) flags
+ * conditioned by astconf()
+ */
+
+int
+fts_flags(void)
+{
+ register char* s;
+
+ s = astconf("PATH_RESOLVE", NiL, NiL);
+ if (streq(s, "logical"))
+ return FTS_LOGICAL;
+ if (streq(s, "physical"))
+ return FTS_PHYSICAL|FTS_SEEDOTDIR;
+ return FTS_META|FTS_PHYSICAL|FTS_SEEDOTDIR;
+}
+
+/*
+ * return 1 if ent is mounted on a local filesystem
+ */
+
+int
+fts_local(FTSENT* ent)
+{
+#ifdef ST_LOCAL
+ struct statvfs fs;
+
+ return statvfs(ent->fts_path, &fs) || (fs.f_flag & ST_LOCAL);
+#else
+ return !strgrpmatch(fmtfs(ent->fts_statp), "([an]fs|samb)", NiL, 0, STR_LEFT|STR_ICASE);
+#endif
+}
+
+/*
+ * close an open fts stream
+ */
+
+int
+fts_close(register FTS* fts)
+{
+ register FTSENT* f;
+ register FTSENT* x;
+
+ if (fts->dir)
+ closedir(fts->dir);
+ if (fts->cd == 0)
+ pathcd(fts->home, NiL);
+ free(fts->home);
+ if (fts->state == FTS_children_return)
+ fts->current->fts_link = fts->link;
+ if (fts->top)
+ {
+ fts->bot->fts_link = fts->todo;
+ fts->todo = fts->top;
+ }
+ for (f = fts->todo; f; f = x)
+ {
+ x = f->fts_link;
+ free(f);
+ }
+ for (f = fts->free; f; f = x)
+ {
+ x = f->fts_link;
+ free(f);
+ }
+ free(fts);
+ return 0;
+}
+
+/*
+ * register function to be called for each fts_read() entry
+ * context==0 => unregister notifyf
+ */
+
+int
+fts_notify(Notify_f notifyf, void* context)
+{
+ register Notify_t* np;
+ register Notify_t* pp;
+
+ if (context)
+ {
+ if (!(np = newof(0, Notify_t, 1, 0)))
+ return -1;
+ np->notifyf = notifyf;
+ np->context = context;
+ np->next = notify;
+ notify = np;
+ }
+ else
+ {
+ for (np = notify, pp = 0; np; pp = np, np = np->next)
+ if (np->notifyf == notifyf)
+ {
+ if (pp)
+ pp->next = np->next;
+ else
+ notify = np->next;
+ free(np);
+ return 0;
+ }
+ return -1;
+ }
+ return 0;
+}
diff --git a/src/lib/libast/misc/ftwalk.c b/src/lib/libast/misc/ftwalk.c
new file mode 100644
index 0000000..30c293f
--- /dev/null
+++ b/src/lib/libast/misc/ftwalk.c
@@ -0,0 +1,156 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * ftwalk on top of fts
+ */
+
+#include <ast.h>
+#include <ftwalk.h>
+
+static struct
+{
+ int (*comparf)(Ftw_t*, Ftw_t*);
+} state;
+
+/*
+ * why does fts take FTSENT** instead of FTSENT*
+ */
+
+static int
+ftscompare(Ftw_t* const* pf1, Ftw_t* const* pf2)
+{
+ return (*state.comparf)(*pf1, *pf2);
+}
+
+/*
+ * the real thing -- well it used to be
+ */
+
+int
+ftwalk(const char* path, int (*userf)(Ftw_t*), int flags, int (*comparf)(Ftw_t*, Ftw_t*))
+{
+ register FTS* f;
+ register FTSENT* e;
+ register int children;
+ register int rv;
+ int oi;
+ int ns;
+ int os;
+ int nd;
+ FTSENT* x;
+ FTSENT* dd[2];
+
+ flags ^= FTS_ONEPATH;
+ if (flags & FTW_TWICE)
+ flags &= ~(FTS_NOPREORDER|FTS_NOPOSTORDER);
+ else if (flags & FTW_POST)
+ flags |= FTS_NOPREORDER;
+ else
+ flags |= FTS_NOPOSTORDER;
+ if (children = flags & FTW_CHILDREN)
+ flags |= FTS_SEEDOT;
+ state.comparf = comparf;
+ if (!(f = fts_open((char* const*)path, flags, comparf ? ftscompare : 0)))
+ {
+ if (!path || !(flags & FTS_ONEPATH) && !(path = (const char*)(*((char**)path))))
+ return -1;
+ ns = strlen(path) + 1;
+ if (!(e = newof(0, FTSENT, 1, ns)))
+ return -1;
+ e->fts_accpath = e->fts_name = e->fts_path = strcpy((char*)(e + 1), path);
+ e->fts_namelen = e->fts_pathlen = ns;
+ e->fts_info = FTS_NS;
+ e->parent = e;
+ e->parent->link = e;
+ rv = (*userf)((Ftw_t*)e);
+ free(e);
+ return rv;
+ }
+ rv = 0;
+ if (children && (e = fts_children(f, 0)))
+ {
+ nd = 0;
+ for (x = e; x; x = x->link)
+ if (x->info & FTS_DD)
+ {
+ x->statb = *x->fts_statp;
+ x->info &= ~FTS_DD;
+ dd[nd++] = x;
+ if (nd >= elementsof(dd))
+ break;
+ }
+ e->parent->link = e;
+ rv = (*userf)((Ftw_t*)e->parent);
+ e->parent->link = 0;
+ while (nd > 0)
+ dd[--nd]->info |= FTS_DD;
+ for (x = e; x; x = x->link)
+ if (!(x->info & FTS_D))
+ x->status = FTS_SKIP;
+ }
+ while (!rv && (e = fts_read(f)))
+ {
+ oi = e->info;
+ os = e->status;
+ ns = e->status = e->path == e->fts_accpath ? FTW_PATH : FTW_NAME;
+ nd = 0;
+ switch (e->info)
+ {
+ case FTS_D:
+ case FTS_DNX:
+ if (children)
+ for (x = fts_children(f, 0); x; x = x->link)
+ if (x->info & FTS_DD)
+ {
+ x->statb = *x->fts_statp;
+ x->info &= ~FTS_DD;
+ dd[nd++] = x;
+ if (nd >= elementsof(dd))
+ break;
+ }
+ break;
+ case FTS_DOT:
+ continue;
+ case FTS_ERR:
+ e->info = FTS_NS;
+ break;
+ case FTS_NSOK:
+ e->info = FTS_NSOK;
+ break;
+ case FTS_SLNONE:
+ e->info = FTS_SL;
+ break;
+ }
+ rv = (*userf)((Ftw_t*)e);
+ e->info = oi;
+ if (e->status == ns)
+ e->status = os;
+ while (nd > 0)
+ dd[--nd]->info |= FTS_DD;
+ }
+ fts_close(f);
+ return rv;
+}
diff --git a/src/lib/libast/misc/ftwflags.c b/src/lib/libast/misc/ftwflags.c
new file mode 100644
index 0000000..179a366
--- /dev/null
+++ b/src/lib/libast/misc/ftwflags.c
@@ -0,0 +1,35 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * return default FTW_* flags conditioned by astconf()
+ */
+
+#include <ast.h>
+#include <ftwalk.h>
+
+int
+ftwflags(void)
+{
+ return fts_flags();
+}
diff --git a/src/lib/libast/misc/getcwd.c b/src/lib/libast/misc/getcwd.c
new file mode 100644
index 0000000..c509648
--- /dev/null
+++ b/src/lib/libast/misc/getcwd.c
@@ -0,0 +1,334 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * pwd library support
+ */
+
+#include <ast.h>
+
+#if _WINIX
+
+NoN(getcwd)
+
+#else
+
+#include "FEATURE/syscall"
+
+#if defined(SYSGETCWD)
+
+#include <error.h>
+
+#define ERROR(e) { errno = e; return 0; }
+
+char*
+getcwd(char* buf, size_t len)
+{
+ size_t n;
+ size_t r;
+ int oerrno;
+
+ if (buf)
+ return SYSGETCWD(buf, len) < 0 ? 0 : buf;
+ oerrno = errno;
+ n = PATH_MAX;
+ for (;;)
+ {
+ if (!(buf = newof(buf, char, n, 0)))
+ ERROR(ENOMEM);
+ if (SYSGETCWD(buf, n) >= 0)
+ {
+ if ((r = strlen(buf) + len + 1) != n && !(buf = newof(buf, char, r, 0)))
+ ERROR(ENOMEM);
+ break;
+ }
+ if (errno != ERANGE)
+ {
+ free(buf);
+ return 0;
+ }
+ n += PATH_MAX / 4;
+ }
+ errno = oerrno;
+ return buf;
+}
+
+#else
+
+#include <ast_dir.h>
+#include <error.h>
+#include <fs3d.h>
+
+#ifndef ERANGE
+#define ERANGE E2BIG
+#endif
+
+#define ERROR(e) { errno = e; goto error; }
+
+struct dirlist /* long path chdir(2) component */
+{
+ struct dirlist* next; /* next component */
+ int index; /* index from end of buf */
+};
+
+/*
+ * pop long dir component chdir stack
+ */
+
+static int
+popdir(register struct dirlist* d, register char* end)
+{
+ register struct dirlist* dp;
+ int v;
+
+ v = 0;
+ while (dp = d)
+ {
+ d = d->next;
+ if (!v)
+ {
+ if (d) *(end - d->index - 1) = 0;
+ v = chdir(end - dp->index);
+ if (d) *(end - d->index - 1) = '/';
+ }
+ free(dp);
+ }
+ return v;
+}
+
+/*
+ * push long dir component onto stack
+ */
+
+static struct dirlist*
+pushdir(register struct dirlist* d, char* dots, char* path, char* end)
+{
+ register struct dirlist* p;
+
+ if (!(p = newof(0, struct dirlist, 1, 0)) || chdir(dots))
+ {
+ if (p) free(p);
+ if (d) popdir(d, end);
+ return 0;
+ }
+ p->index = end - path;
+ p->next = d;
+ return p;
+}
+
+/*
+ * return a pointer to the absolute path name of .
+ * this path name may be longer than PATH_MAX
+ *
+ * a few environment variables are checked before the search algorithm
+ * return value is placed in buf of len chars
+ * if buf is 0 then space is allocated via malloc() with
+ * len extra chars after the path name
+ * 0 is returned on error with errno set as appropriate
+ */
+
+char*
+getcwd(char* buf, size_t len)
+{
+ register char* d;
+ register char* p;
+ register char* s;
+ DIR* dirp = 0;
+ int n;
+ int x;
+ size_t namlen;
+ ssize_t extra = -1;
+ struct dirent* entry;
+ struct dirlist* dirstk = 0;
+ struct stat* cur;
+ struct stat* par;
+ struct stat* tmp;
+ struct stat curst;
+ struct stat parst;
+ struct stat tstst;
+ char dots[PATH_MAX];
+
+ static struct
+ {
+ char* name;
+ char* path;
+ dev_t dev;
+ ino_t ino;
+ } env[] =
+ {
+ { /*previous*/0 },
+ { "PWD" },
+ { "HOME" },
+ };
+
+ if (buf && !len) ERROR(EINVAL);
+ if (fs3d(FS3D_TEST) && (namlen = mount(".", dots, FS3D_GET|FS3D_VIEW|FS3D_SIZE(sizeof(dots)), NiL)) > 1 && namlen < sizeof(dots))
+ {
+ p = dots;
+ easy:
+ namlen++;
+ if (buf)
+ {
+ if (len < namlen) ERROR(ERANGE);
+ }
+ else if (!(buf = newof(0, char, namlen, len))) ERROR(ENOMEM);
+ return (char*)memcpy(buf, p, namlen);
+ }
+ cur = &curst;
+ par = &parst;
+ if (stat(".", par)) ERROR(errno);
+ for (n = 0; n < elementsof(env); n++)
+ {
+ if ((env[n].name && (p = getenv(env[n].name)) || (p = env[n].path)) && *p == '/' && !stat(p, cur))
+ {
+ env[n].path = p;
+ env[n].dev = cur->st_dev;
+ env[n].ino = cur->st_ino;
+ if (cur->st_ino == par->st_ino && cur->st_dev == par->st_dev)
+ {
+ namlen = strlen(p);
+ goto easy;
+ }
+ }
+ }
+ if (!buf)
+ {
+ extra = len;
+ len = PATH_MAX;
+ if (!(buf = newof(0, char, len, extra))) ERROR(ENOMEM);
+ }
+ d = dots;
+ p = buf + len - 1;
+ *p = 0;
+ n = elementsof(env);
+ for (;;)
+ {
+ tmp = cur;
+ cur = par;
+ par = tmp;
+ if ((d - dots) > (PATH_MAX - 4))
+ {
+ if (!(dirstk = pushdir(dirstk, dots, p, buf + len - 1))) ERROR(ERANGE);
+ d = dots;
+ }
+ *d++ = '.';
+ *d++ = '.';
+ *d = 0;
+ if (!(dirp = opendir(dots))) ERROR(errno);
+#if !_dir_ok || _mem_dd_fd_DIR
+ if (fstat(dirp->dd_fd, par)) ERROR(errno);
+#else
+ if (stat(dots, par)) ERROR(errno);
+#endif
+ *d++ = '/';
+ if (par->st_dev == cur->st_dev)
+ {
+ if (par->st_ino == cur->st_ino)
+ {
+ closedir(dirp);
+ *--p = '/';
+ pop:
+ if (p != buf)
+ {
+ d = buf;
+ while (*d++ = *p++);
+ len = d - buf;
+ if (extra >= 0 && !(buf = newof(buf, char, len, extra))) ERROR(ENOMEM);
+ }
+ if (dirstk && popdir(dirstk, buf + len - 1))
+ {
+ dirstk = 0;
+ ERROR(errno);
+ }
+ if (env[0].path)
+ free(env[0].path);
+ env[0].path = strdup(buf);
+ return buf;
+ }
+#ifdef D_FILENO
+ while (entry = readdir(dirp))
+ if (D_FILENO(entry) == cur->st_ino)
+ {
+ namlen = D_NAMLEN(entry);
+ goto found;
+ }
+#endif
+
+ /*
+ * this fallthrough handles logical naming
+ */
+
+ rewinddir(dirp);
+ }
+ do
+ {
+ if (!(entry = readdir(dirp))) ERROR(ENOENT);
+ namlen = D_NAMLEN(entry);
+ if ((d - dots) > (PATH_MAX - 1 - namlen))
+ {
+ *d = 0;
+ if (namlen >= PATH_MAX || !(dirstk = pushdir(dirstk, dots + 3, p, buf + len - 1))) ERROR(ERANGE);
+ d = dots + 3;
+ }
+ memcpy(d, entry->d_name, namlen + 1);
+ } while (stat(dots, &tstst) || tstst.st_ino != cur->st_ino || tstst.st_dev != cur->st_dev);
+ found:
+ if (*p) *--p = '/';
+ while ((p -= namlen) <= (buf + 1))
+ {
+ x = (buf + len - 1) - (p += namlen);
+ s = buf + len;
+ if (extra < 0 || !(buf = newof(buf, char, len += PATH_MAX, extra))) ERROR(ERANGE);
+ p = buf + len;
+ while (p > buf + len - 1 - x) *--p = *--s;
+ }
+ if (n < elementsof(env))
+ {
+ memcpy(p, env[n].path, namlen);
+ goto pop;
+ }
+ memcpy(p, entry->d_name, namlen);
+ closedir(dirp);
+ dirp = 0;
+ for (n = 0; n < elementsof(env); n++)
+ if (env[n].ino == par->st_ino && env[n].dev == par->st_dev)
+ {
+ namlen = strlen(env[n].path);
+ goto found;
+ }
+ }
+ error:
+ if (buf)
+ {
+ if (dirstk) popdir(dirstk, buf + len - 1);
+ if (extra >= 0) free(buf);
+ }
+ if (dirp) closedir(dirp);
+ return 0;
+}
+
+#endif
+
+#endif
diff --git a/src/lib/libast/misc/getenv.c b/src/lib/libast/misc/getenv.c
new file mode 100644
index 0000000..7e24817
--- /dev/null
+++ b/src/lib/libast/misc/getenv.c
@@ -0,0 +1,113 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#if _UWIN && __STDPP__
+__STDPP__directive pragma pp:hide getenv
+#endif
+
+#include "intercepts.h"
+
+#if _UWIN && __STDPP__
+__STDPP__directive pragma pp:nohide getenv
+#endif
+
+/*
+ * NOTE: the "intercepts" definition is here instead of astintercept.c because some
+ * static linkers miss lone references to "intercepts" without "astintercept()"
+ * ALSO: { 0 } definition required by some dynamic linkers averse to common symbols
+ * UWIN: no _ast_getenv macro map to maintain ast54 compatibility
+ */
+
+Intercepts_t intercepts
+#if _BLD_3d
+ ;
+#else
+ = { 0 };
+#endif
+
+#if _UWIN && !defined(getenv)
+
+#include <windows.h>
+
+extern char** environ;
+
+static char*
+default_getenv(const char* name)
+{
+ register char** av;
+ register const char* cp;
+ register const char* sp;
+ register char c0;
+ register char c1;
+
+ av = environ;
+ if (!av || !name || !(c0 = *name))
+ return 0;
+ if (!(c1 = *++name))
+ c1 = '=';
+ while (cp = *av++)
+ {
+ if (cp[0] != c0 || cp[1] != c1)
+ continue;
+ sp = name;
+ cp++;
+ while (*sp && *sp++ == *cp++);
+ if (*(sp-1) != *(cp-1))
+ continue;
+ if (*sp == 0 && *cp == '=')
+ return (char*)(cp+1);
+ }
+ return 0;
+}
+
+#endif
+
+/*
+ * get name from the environment
+ */
+
+#if defined(__EXPORT__) && defined(getenv)
+#define extern __EXPORT__
+#endif
+
+extern char*
+getenv(const char* name)
+{
+#if _UWIN && !defined(getenv) /* for ast54 compatibility */
+ HANDLE dll;
+
+ static char* (*posix_getenv)(const char*);
+
+ if (!posix_getenv)
+ {
+ if (dll = GetModuleHandle("posix.dll"))
+ posix_getenv = (char*(*)(const char*))GetProcAddress(dll, "getenv");
+ if (!posix_getenv)
+ posix_getenv = default_getenv;
+ }
+ return intercepts.intercept_getenv ? (*intercepts.intercept_getenv)(name) : (*posix_getenv)(name);
+#else
+#undef getenv
+ return intercepts.intercept_getenv ? (*intercepts.intercept_getenv)(name) : getenv(name);
+#endif
+}
diff --git a/src/lib/libast/misc/glob.c b/src/lib/libast/misc/glob.c
new file mode 100644
index 0000000..f05b40e
--- /dev/null
+++ b/src/lib/libast/misc/glob.c
@@ -0,0 +1,829 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * file name expansion - posix.2 glob with gnu and ast extensions
+ *
+ * David Korn
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+#include <ast.h>
+#include <ls.h>
+#include <stak.h>
+#include <ast_dir.h>
+#include <error.h>
+#include <ctype.h>
+#include <regex.h>
+
+#define GLOB_MAGIC 0xaaaa0000
+
+#define MATCH_RAW 1
+#define MATCH_MAKE 2
+#define MATCH_META 4
+
+#define MATCHPATH(g) (offsetof(globlist_t,gl_path)+(g)->gl_extra)
+
+typedef int (*GL_error_f)(const char*, int);
+typedef void* (*GL_opendir_f)(const char*);
+typedef struct dirent* (*GL_readdir_f)(void*);
+typedef void (*GL_closedir_f)(void*);
+typedef int (*GL_stat_f)(const char*, struct stat*);
+
+#define _GLOB_PRIVATE_ \
+ GL_error_f gl_errfn; \
+ int gl_error; \
+ char* gl_nextpath; \
+ globlist_t* gl_rescan; \
+ globlist_t* gl_match; \
+ Stak_t* gl_stak; \
+ int re_flags; \
+ int re_first; \
+ regex_t* gl_ignore; \
+ regex_t* gl_ignorei; \
+ regex_t re_ignore; \
+ regex_t re_ignorei; \
+ unsigned long gl_starstar; \
+ char* gl_opt; \
+ char* gl_pat; \
+ char* gl_pad[4];
+
+#include <glob.h>
+
+/*
+ * default gl_diropen
+ */
+
+static void*
+gl_diropen(glob_t* gp, const char* path)
+{
+ return (*gp->gl_opendir)(path);
+}
+
+/*
+ * default gl_dirnext
+ */
+
+static char*
+gl_dirnext(glob_t* gp, void* handle)
+{
+ struct dirent* dp;
+
+ while (dp = (struct dirent*)(*gp->gl_readdir)(handle))
+ {
+#ifdef D_TYPE
+ if (D_TYPE(dp) != DT_UNKNOWN && D_TYPE(dp) != DT_DIR && D_TYPE(dp) != DT_LNK)
+ gp->gl_status |= GLOB_NOTDIR;
+#endif
+ return dp->d_name;
+ }
+ return 0;
+}
+
+/*
+ * default gl_dirclose
+ */
+
+static void
+gl_dirclose(glob_t* gp, void* handle)
+{
+ (gp->gl_closedir)(handle);
+}
+
+/*
+ * default gl_type
+ */
+
+static int
+gl_type(glob_t* gp, const char* path, int flags)
+{
+ register int type;
+ struct stat st;
+
+ if ((flags & GLOB_STARSTAR) ? (*gp->gl_lstat)(path, &st) : (*gp->gl_stat)(path, &st))
+ type = 0;
+ else if (S_ISDIR(st.st_mode))
+ type = GLOB_DIR;
+ else if (!S_ISREG(st.st_mode))
+ type = GLOB_DEV;
+ else if (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))
+ type = GLOB_EXE;
+ else
+ type = GLOB_REG;
+ return type;
+}
+
+/*
+ * default gl_attr
+ */
+
+static int
+gl_attr(glob_t* gp, const char* path, int flags)
+{
+ return strchr(astconf("PATH_ATTRIBUTES", path, NiL), 'c') ? GLOB_ICASE : 0;
+}
+
+/*
+ * default gl_nextdir
+ */
+
+static char*
+gl_nextdir(glob_t* gp, char* dir)
+{
+ if (!(dir = gp->gl_nextpath))
+ dir = gp->gl_nextpath = stakcopy(pathbin());
+ switch (*gp->gl_nextpath)
+ {
+ case 0:
+ dir = 0;
+ break;
+ case ':':
+ while (*gp->gl_nextpath == ':')
+ gp->gl_nextpath++;
+ dir = ".";
+ break;
+ default:
+ while (*gp->gl_nextpath)
+ if (*gp->gl_nextpath++ == ':')
+ {
+ *(gp->gl_nextpath - 1) = 0;
+ break;
+ }
+ break;
+ }
+ return dir;
+}
+
+/*
+ * error intercept
+ */
+
+static int
+errorcheck(register glob_t* gp, const char* path)
+{
+ int r = 1;
+
+ if (gp->gl_errfn)
+ r = (*gp->gl_errfn)(path, errno);
+ if (gp->gl_flags & GLOB_ERR)
+ r = 0;
+ if (!r)
+ gp->gl_error = GLOB_ABORTED;
+ return r;
+}
+
+/*
+ * remove backslashes
+ */
+
+static void
+trim(register char* sp, register char* p1, int* n1, register char* p2, int* n2)
+{
+ register char* dp = sp;
+ register int c;
+
+ if (p1)
+ *n1 = 0;
+ if (p2)
+ *n2 = 0;
+ do
+ {
+ if ((c = *sp++) == '\\')
+ c = *sp++;
+ if (sp == p1)
+ {
+ p1 = 0;
+ *n1 = sp - dp - 1;
+ }
+ if (sp == p2)
+ {
+ p2 = 0;
+ *n2 = sp - dp - 1;
+ }
+ } while (*dp++ = c);
+}
+
+static void
+addmatch(register glob_t* gp, const char* dir, const char* pat, register const char* rescan, char* endslash, int meta)
+{
+ register globlist_t* ap;
+ int offset;
+ int type;
+
+ stakseek(MATCHPATH(gp));
+ if (dir)
+ {
+ stakputs(dir);
+ stakputc(gp->gl_delim);
+ }
+ if (endslash)
+ *endslash = 0;
+ stakputs(pat);
+ if (rescan)
+ {
+ if ((*gp->gl_type)(gp, stakptr(MATCHPATH(gp)), 0) != GLOB_DIR)
+ return;
+ stakputc(gp->gl_delim);
+ offset = staktell();
+ /* if null, reserve room for . */
+ if (*rescan)
+ stakputs(rescan);
+ else
+ stakputc(0);
+ stakputc(0);
+ rescan = stakptr(offset);
+ ap = (globlist_t*)stakfreeze(0);
+ ap->gl_begin = (char*)rescan;
+ ap->gl_next = gp->gl_rescan;
+ gp->gl_rescan = ap;
+ }
+ else
+ {
+ if (!endslash && (gp->gl_flags & GLOB_MARK) && (type = (*gp->gl_type)(gp, stakptr(MATCHPATH(gp)), 0)))
+ {
+ if ((gp->gl_flags & GLOB_COMPLETE) && type != GLOB_EXE)
+ {
+ stakseek(0);
+ return;
+ }
+ else if (type == GLOB_DIR && (gp->gl_flags & GLOB_MARK))
+ stakputc(gp->gl_delim);
+ }
+ ap = (globlist_t*)stakfreeze(1);
+ ap->gl_next = gp->gl_match;
+ gp->gl_match = ap;
+ gp->gl_pathc++;
+ }
+ ap->gl_flags = MATCH_RAW|meta;
+ if (gp->gl_flags & GLOB_COMPLETE)
+ ap->gl_flags |= MATCH_MAKE;
+}
+
+/*
+ * this routine builds a list of files that match a given pathname
+ * uses REG_SHELL of <regex> to match each component
+ * a leading . must match explicitly
+ */
+
+static void
+glob_dir(glob_t* gp, globlist_t* ap, int re_flags)
+{
+ register char* rescan;
+ register char* prefix;
+ register char* pat;
+ register char* name;
+ register int c;
+ char* dirname;
+ void* dirf;
+ char first;
+ regex_t* ire;
+ regex_t* pre;
+ regex_t rec;
+ regex_t rei;
+ int notdir;
+ int t1;
+ int t2;
+ int bracket;
+
+ int anymeta = ap->gl_flags & MATCH_META;
+ int complete = 0;
+ int err = 0;
+ int meta = ((gp->re_flags & REG_ICASE) && *ap->gl_begin != '/') ? MATCH_META : 0;
+ int quote = 0;
+ int savequote = 0;
+ char* restore1 = 0;
+ char* restore2 = 0;
+ regex_t* prec = 0;
+ regex_t* prei = 0;
+ char* matchdir = 0;
+ int starstar = 0;
+
+ if (*gp->gl_intr)
+ {
+ gp->gl_error = GLOB_INTR;
+ return;
+ }
+ pat = rescan = ap->gl_begin;
+ prefix = dirname = ap->gl_path + gp->gl_extra;
+ first = (rescan == prefix);
+again:
+ bracket = 0;
+ for (;;)
+ {
+ switch (c = *rescan++)
+ {
+ case 0:
+ if (meta)
+ {
+ rescan = 0;
+ break;
+ }
+ if (quote)
+ {
+ trim(ap->gl_begin, rescan, &t1, NiL, NiL);
+ rescan -= t1;
+ }
+ if (!first && !*rescan && *(rescan - 2) == gp->gl_delim)
+ {
+ *(rescan - 2) = 0;
+ c = (*gp->gl_type)(gp, prefix, 0);
+ *(rescan - 2) = gp->gl_delim;
+ if (c == GLOB_DIR)
+ addmatch(gp, NiL, prefix, NiL, rescan - 1, anymeta);
+ }
+ else if ((anymeta || !(gp->gl_flags & GLOB_NOCHECK)) && (*gp->gl_type)(gp, prefix, 0))
+ addmatch(gp, NiL, prefix, NiL, NiL, anymeta);
+ return;
+ case '[':
+ if (!bracket)
+ {
+ bracket = MATCH_META;
+ if (*rescan == '!' || *rescan == '^')
+ rescan++;
+ if (*rescan == ']')
+ rescan++;
+ }
+ continue;
+ case ']':
+ meta |= bracket;
+ continue;
+ case '(':
+ if (!(gp->gl_flags & GLOB_AUGMENTED))
+ continue;
+ case '*':
+ case '?':
+ meta = MATCH_META;
+ continue;
+ case '\\':
+ if (!(gp->gl_flags & GLOB_NOESCAPE))
+ {
+ quote = 1;
+ if (*rescan)
+ rescan++;
+ }
+ continue;
+ default:
+ if (c == gp->gl_delim)
+ {
+ if (meta)
+ break;
+ pat = rescan;
+ bracket = 0;
+ savequote = quote;
+ }
+ continue;
+ }
+ break;
+ }
+ anymeta |= meta;
+ if (matchdir)
+ goto skip;
+ if (pat == prefix)
+ {
+ prefix = 0;
+ if (!rescan && (gp->gl_flags & GLOB_COMPLETE))
+ {
+ complete = 1;
+ dirname = 0;
+ }
+ else
+ dirname = ".";
+ }
+ else
+ {
+ if (pat == prefix + 1)
+ dirname = "/";
+ if (savequote)
+ {
+ quote = 0;
+ trim(ap->gl_begin, pat, &t1, rescan, &t2);
+ pat -= t1;
+ if (rescan)
+ rescan -= t2;
+ }
+ *(restore1 = pat - 1) = 0;
+ }
+ if (!complete && (gp->gl_flags & GLOB_STARSTAR))
+ while (pat[0] == '*' && pat[1] == '*' && (pat[2] == '/' || pat[2]==0))
+ {
+ matchdir = pat;
+ if (pat[2])
+ {
+ pat += 3;
+ while (*pat=='/')
+ pat++;
+ if (*pat)
+ continue;
+ }
+ rescan = *pat?0:pat;
+ pat = "*";
+ goto skip;
+ }
+ if (matchdir)
+ {
+ rescan = pat;
+ goto again;
+ }
+skip:
+ if (rescan)
+ *(restore2 = rescan - 1) = 0;
+ if (rescan && !complete && (gp->gl_flags & GLOB_STARSTAR))
+ {
+ register char* p = rescan;
+
+ while (p[0] == '*' && p[1] == '*' && (p[2] == '/' || p[2]==0))
+ {
+ rescan = p;
+ if (starstar = (p[2]==0))
+ break;
+ p += 3;
+ while (*p=='/')
+ p++;
+ if (*p==0)
+ {
+ starstar = 2;
+ break;
+ }
+ }
+ }
+ if (matchdir)
+ gp->gl_starstar++;
+ if (gp->gl_opt)
+ pat = strcpy(gp->gl_opt, pat);
+ for (;;)
+ {
+ if (complete)
+ {
+ if (!(dirname = (*gp->gl_nextdir)(gp, dirname)))
+ break;
+ prefix = streq(dirname, ".") ? (char*)0 : dirname;
+ }
+ if ((!starstar && !gp->gl_starstar || (*gp->gl_type)(gp, dirname, GLOB_STARSTAR) == GLOB_DIR) && (dirf = (*gp->gl_diropen)(gp, dirname)))
+ {
+ if (!(gp->re_flags & REG_ICASE) && ((*gp->gl_attr)(gp, dirname, 0) & GLOB_ICASE))
+ {
+ if (!prei)
+ {
+ if (err = regcomp(&rei, pat, gp->re_flags|REG_ICASE))
+ break;
+ prei = &rei;
+ if (gp->re_first)
+ {
+ gp->re_first = 0;
+ gp->re_flags = regstat(prei)->re_flags & ~REG_ICASE;
+ }
+ }
+ pre = prei;
+ }
+ else
+ {
+ if (!prec)
+ {
+ if (err = regcomp(&rec, pat, gp->re_flags))
+ break;
+ prec = &rec;
+ if (gp->re_first)
+ {
+ gp->re_first = 0;
+ gp->re_flags = regstat(prec)->re_flags;
+ }
+ }
+ pre = prec;
+ }
+ if ((ire = gp->gl_ignore) && (gp->re_flags & REG_ICASE))
+ {
+ if (!gp->gl_ignorei)
+ {
+ if (regcomp(&gp->re_ignorei, gp->gl_fignore, re_flags|REG_ICASE))
+ {
+ gp->gl_error = GLOB_APPERR;
+ break;
+ }
+ gp->gl_ignorei = &gp->re_ignorei;
+ }
+ ire = gp->gl_ignorei;
+ }
+ if (restore2)
+ *restore2 = gp->gl_delim;
+ while ((name = (*gp->gl_dirnext)(gp, dirf)) && !*gp->gl_intr)
+ {
+ if (notdir = (gp->gl_status & GLOB_NOTDIR))
+ gp->gl_status &= ~GLOB_NOTDIR;
+ if (ire && !regexec(ire, name, 0, NiL, 0))
+ continue;
+ if (matchdir && (name[0] != '.' || name[1] && (name[1] != '.' || name[2])) && !notdir)
+ addmatch(gp, prefix, name, matchdir, NiL, anymeta);
+ if (!regexec(pre, name, 0, NiL, 0))
+ {
+ if (!rescan || !notdir)
+ addmatch(gp, prefix, name, rescan, NiL, anymeta);
+ if (starstar==1 || (starstar==2 && !notdir))
+ addmatch(gp, prefix, name, starstar==2?"":NiL, NiL, anymeta);
+ }
+ errno = 0;
+ }
+ (*gp->gl_dirclose)(gp, dirf);
+ if (err || errno && !errorcheck(gp, dirname))
+ break;
+ }
+ else if (!complete && !errorcheck(gp, dirname))
+ break;
+ if (!complete)
+ break;
+ if (*gp->gl_intr)
+ {
+ gp->gl_error = GLOB_INTR;
+ break;
+ }
+ }
+ if (restore1)
+ *restore1 = gp->gl_delim;
+ if (restore2)
+ *restore2 = gp->gl_delim;
+ if (prec)
+ regfree(prec);
+ if (prei)
+ regfree(prei);
+ if (err == REG_ESPACE)
+ gp->gl_error = GLOB_NOSPACE;
+}
+
+int
+glob(const char* pattern, int flags, int (*errfn)(const char*, int), register glob_t* gp)
+{
+ register globlist_t* ap;
+ register char* pat;
+ globlist_t* top;
+ Stak_t* oldstak;
+ char** argv;
+ char** av;
+ size_t skip;
+ unsigned long f;
+ int n;
+ int x;
+ int re_flags;
+
+ const char* nocheck = pattern;
+ int optlen = 0;
+ int suflen = 0;
+ int extra = 1;
+ unsigned char intr = 0;
+
+ gp->gl_rescan = 0;
+ gp->gl_error = 0;
+ gp->gl_errfn = errfn;
+ if (flags & GLOB_APPEND)
+ {
+ if ((gp->gl_flags |= GLOB_APPEND) ^ (flags|GLOB_MAGIC))
+ return GLOB_APPERR;
+ if (((gp->gl_flags & GLOB_STACK) == 0) == (gp->gl_stak == 0))
+ return GLOB_APPERR;
+ if (gp->gl_starstar > 1)
+ gp->gl_flags |= GLOB_STARSTAR;
+ else
+ gp->gl_starstar = 0;
+ }
+ else
+ {
+ gp->gl_flags = (flags&0xffff)|GLOB_MAGIC;
+ gp->re_flags = REG_SHELL|REG_NOSUB|REG_LEFT|REG_RIGHT|((flags&GLOB_AUGMENTED)?REG_AUGMENTED:0);
+ gp->gl_pathc = 0;
+ gp->gl_ignore = 0;
+ gp->gl_ignorei = 0;
+ gp->gl_starstar = 0;
+ if (!(flags & GLOB_DISC))
+ {
+ gp->gl_fignore = 0;
+ gp->gl_suffix = 0;
+ gp->gl_intr = 0;
+ gp->gl_delim = 0;
+ gp->gl_handle = 0;
+ gp->gl_diropen = 0;
+ gp->gl_dirnext = 0;
+ gp->gl_dirclose = 0;
+ gp->gl_type = 0;
+ gp->gl_attr = 0;
+ gp->gl_nextdir = 0;
+ gp->gl_stat = 0;
+ gp->gl_lstat = 0;
+ gp->gl_extra = 0;
+ }
+ if (!(flags & GLOB_ALTDIRFUNC))
+ {
+ gp->gl_opendir = (GL_opendir_f)opendir;
+ gp->gl_readdir = (GL_readdir_f)readdir;
+ gp->gl_closedir = (GL_closedir_f)closedir;
+ if (!gp->gl_stat)
+ gp->gl_stat = (GL_stat_f)pathstat;
+ }
+ if (!gp->gl_lstat)
+ gp->gl_lstat = (GL_stat_f)lstat;
+ if (!gp->gl_intr)
+ gp->gl_intr = &intr;
+ if (!gp->gl_delim)
+ gp->gl_delim = '/';
+ if (!gp->gl_diropen)
+ gp->gl_diropen = gl_diropen;
+ if (!gp->gl_dirnext)
+ gp->gl_dirnext = gl_dirnext;
+ if (!gp->gl_dirclose)
+ gp->gl_dirclose = gl_dirclose;
+ if (!gp->gl_type)
+ gp->gl_type = gl_type;
+ if (!gp->gl_attr)
+ gp->gl_attr = gl_attr;
+ if (flags & GLOB_GROUP)
+ gp->re_flags |= REG_SHELL_GROUP;
+ if (flags & GLOB_ICASE)
+ gp->re_flags |= REG_ICASE;
+ if (!gp->gl_fignore)
+ gp->re_flags |= REG_SHELL_DOT;
+ else if (*gp->gl_fignore)
+ {
+ if (regcomp(&gp->re_ignore, gp->gl_fignore, gp->re_flags))
+ return GLOB_APPERR;
+ gp->gl_ignore = &gp->re_ignore;
+ }
+ if (gp->gl_flags & GLOB_STACK)
+ gp->gl_stak = 0;
+ else if (!(gp->gl_stak = stakcreate(0)))
+ return GLOB_NOSPACE;
+ if ((gp->gl_flags & GLOB_COMPLETE) && !gp->gl_nextdir)
+ gp->gl_nextdir = gl_nextdir;
+ }
+ skip = gp->gl_pathc;
+ if (gp->gl_stak)
+ oldstak = stakinstall(gp->gl_stak, 0);
+ if (flags & GLOB_DOOFFS)
+ extra += gp->gl_offs;
+ if (gp->gl_suffix)
+ suflen = strlen(gp->gl_suffix);
+ if (*(pat = (char*)pattern) == '~' && *(pat + 1) == '(')
+ {
+ f = gp->gl_flags;
+ n = 1;
+ x = 1;
+ pat += 2;
+ for (;;)
+ {
+ switch (*pat++)
+ {
+ case 0:
+ case ':':
+ break;
+ case '-':
+ n = 0;
+ continue;
+ case '+':
+ n = 1;
+ continue;
+ case 'i':
+ if (n)
+ f |= GLOB_ICASE;
+ else
+ f &= ~GLOB_ICASE;
+ continue;
+ case 'M':
+ if (n)
+ f |= GLOB_BRACE;
+ else
+ f &= ~GLOB_BRACE;
+ continue;
+ case 'N':
+ if (n)
+ f &= ~GLOB_NOCHECK;
+ else
+ f |= GLOB_NOCHECK;
+ continue;
+ case 'O':
+ if (n)
+ f |= GLOB_STARSTAR;
+ else
+ f &= ~GLOB_STARSTAR;
+ continue;
+ case ')':
+ flags = (gp->gl_flags = f) & 0xffff;
+ if (f & GLOB_ICASE)
+ gp->re_flags |= REG_ICASE;
+ else
+ gp->re_flags &= ~REG_ICASE;
+ if (x)
+ optlen = pat - (char*)pattern;
+ break;
+ default:
+ x = 0;
+ continue;
+ }
+ break;
+ }
+ }
+ top = ap = (globlist_t*)stakalloc((optlen ? 2 : 1) * strlen(pattern) + sizeof(globlist_t) + suflen + gp->gl_extra);
+ ap->gl_next = 0;
+ ap->gl_flags = 0;
+ ap->gl_begin = ap->gl_path + gp->gl_extra;
+ pat = strcopy(ap->gl_begin, pattern + optlen);
+ if (suflen)
+ pat = strcopy(pat, gp->gl_suffix);
+ if (optlen)
+ strlcpy(gp->gl_pat = gp->gl_opt = pat + 1, pattern, optlen);
+ else
+ gp->gl_pat = 0;
+ suflen = 0;
+ if (!(flags & GLOB_LIST))
+ gp->gl_match = 0;
+ re_flags = gp->re_flags;
+ gp->re_first = 1;
+ do
+ {
+ gp->gl_rescan = ap->gl_next;
+ glob_dir(gp, ap, re_flags);
+ } while (!gp->gl_error && (ap = gp->gl_rescan));
+ gp->re_flags = re_flags;
+ if (gp->gl_pathc == skip)
+ {
+ if (flags & GLOB_NOCHECK)
+ {
+ gp->gl_pathc++;
+ top->gl_next = gp->gl_match;
+ gp->gl_match = top;
+ strcopy(top->gl_path + gp->gl_extra, nocheck);
+ }
+ else
+ gp->gl_error = GLOB_NOMATCH;
+ }
+ if (flags & GLOB_LIST)
+ gp->gl_list = gp->gl_match;
+ else
+ {
+ argv = (char**)stakalloc((gp->gl_pathc + extra) * sizeof(char*));
+ if (gp->gl_flags & GLOB_APPEND)
+ {
+ skip += --extra;
+ memcpy(argv, gp->gl_pathv, skip * sizeof(char*));
+ av = argv + skip;
+ }
+ else
+ {
+ av = argv;
+ while (--extra > 0)
+ *av++ = 0;
+ }
+ gp->gl_pathv = argv;
+ argv = av;
+ ap = gp->gl_match;
+ while (ap)
+ {
+ *argv++ = ap->gl_path + gp->gl_extra;
+ ap = ap->gl_next;
+ }
+ *argv = 0;
+ if (!(flags & GLOB_NOSORT) && (argv - av) > 1)
+ {
+ strsort(av, argv - av, strcoll);
+ if (gp->gl_starstar > 1)
+ av[gp->gl_pathc = struniq(av, argv - av)] = 0;
+ gp->gl_starstar = 0;
+ }
+ }
+ if (gp->gl_starstar > 1)
+ gp->gl_flags &= ~GLOB_STARSTAR;
+ if (gp->gl_stak)
+ stakinstall(oldstak, 0);
+ return gp->gl_error;
+}
+
+void
+globfree(glob_t* gp)
+{
+ if ((gp->gl_flags & GLOB_MAGIC) == GLOB_MAGIC)
+ {
+ gp->gl_flags &= ~GLOB_MAGIC;
+ if (gp->gl_stak)
+ stkclose(gp->gl_stak);
+ if (gp->gl_ignore)
+ regfree(gp->gl_ignore);
+ if (gp->gl_ignorei)
+ regfree(gp->gl_ignorei);
+ }
+}
diff --git a/src/lib/libast/misc/intercepts.h b/src/lib/libast/misc/intercepts.h
new file mode 100644
index 0000000..15959ea
--- /dev/null
+++ b/src/lib/libast/misc/intercepts.h
@@ -0,0 +1,40 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#ifndef _INTERCEPTS_H
+#define _INTERCEPTS_H 1
+
+#include <ast.h>
+#include <shcmd.h>
+
+typedef struct Intercepts_s
+{
+ char* (*intercept_getenv)(const char*);
+ char* (*intercept_setenviron)(const char*);
+} Intercepts_t;
+
+#define intercepts _ast_intercepts
+
+extern Intercepts_t intercepts;
+
+#endif
diff --git a/src/lib/libast/misc/magic.c b/src/lib/libast/misc/magic.c
new file mode 100644
index 0000000..aa2706e
--- /dev/null
+++ b/src/lib/libast/misc/magic.c
@@ -0,0 +1,2497 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * library interface to file
+ *
+ * the sum of the hacks {s5,v10,planix} is _____ than the parts
+ */
+
+static const char id[] = "\n@(#)$Id: magic library (AT&T Research) 2011-03-09 $\0\n";
+
+static const char lib[] = "libast:magic";
+
+#include <ast.h>
+#include <ctype.h>
+#include <ccode.h>
+#include <dt.h>
+#include <modex.h>
+#include <error.h>
+#include <regex.h>
+#include <swap.h>
+
+#define T(m) (*m?ERROR_translate(NiL,NiL,lib,m):m)
+
+#define match(s,p) strgrpmatch(s,p,NiL,0,STR_LEFT|STR_RIGHT|STR_ICASE)
+
+#define MAXNEST 10 /* { ... } nesting limit */
+#define MINITEM 4 /* magic buffer rounding */
+
+typedef struct /* identifier dictionary entry */
+{
+ const char name[16]; /* identifier name */
+ int value; /* identifier value */
+ Dtlink_t link; /* dictionary link */
+} Info_t;
+
+typedef struct Edit /* edit substitution */
+{
+ struct Edit* next; /* next in list */
+ regex_t* from; /* from pattern */
+} Edit_t;
+
+struct Entry;
+
+typedef struct /* loop info */
+{
+ struct Entry* lab; /* call this function */
+ int start; /* start here */
+ int size; /* increment by this amount */
+ int count; /* dynamic loop count */
+ int offset; /* dynamic offset */
+} Loop_t;
+
+typedef struct Entry /* magic file entry */
+{
+ struct Entry* next; /* next in list */
+ char* expr; /* offset expression */
+ union
+ {
+ unsigned long num;
+ char* str;
+ struct Entry* lab;
+ regex_t* sub;
+ Loop_t* loop;
+ } value; /* comparison value */
+ char* desc; /* file description */
+ char* mime; /* file mime type */
+ unsigned long offset; /* offset in bytes */
+ unsigned long mask; /* mask before compare */
+ char cont; /* continuation operation */
+ char type; /* datum type */
+ char op; /* comparison operation */
+ char nest; /* { or } nesting operation */
+ char swap; /* forced swap order */
+} Entry_t;
+
+#define CC_BIT 5
+
+#if (CC_MAPS*CC_BIT) <= (CHAR_BIT*2)
+typedef unsigned short Cctype_t;
+#else
+typedef unsigned long Cctype_t;
+#endif
+
+#define CC_text 0x01
+#define CC_control 0x02
+#define CC_latin 0x04
+#define CC_binary 0x08
+#define CC_utf_8 0x10
+
+#define CC_notext CC_text /* CC_text is flipped before checking */
+
+#define CC_MASK (CC_binary|CC_latin|CC_control|CC_text)
+
+#define CCTYPE(c) (((c)>0240)?CC_binary:((c)>=0200)?CC_latin:((c)<040&&(c)!=007&&(c)!=011&&(c)!=012&&(c)!=013&&(c)!=015)?CC_control:CC_text)
+
+#define ID_NONE 0
+#define ID_ASM 1
+#define ID_C 2
+#define ID_COBOL 3
+#define ID_COPYBOOK 4
+#define ID_CPLUSPLUS 5
+#define ID_FORTRAN 6
+#define ID_HTML 7
+#define ID_INCL1 8
+#define ID_INCL2 9
+#define ID_INCL3 10
+#define ID_MAM1 11
+#define ID_MAM2 12
+#define ID_MAM3 13
+#define ID_NOTEXT 14
+#define ID_PL1 15
+#define ID_YACC 16
+
+#define ID_MAX ID_YACC
+
+#define INFO_atime 1
+#define INFO_blocks 2
+#define INFO_ctime 3
+#define INFO_fstype 4
+#define INFO_gid 5
+#define INFO_mode 6
+#define INFO_mtime 7
+#define INFO_name 8
+#define INFO_nlink 9
+#define INFO_size 10
+#define INFO_uid 11
+
+#define _MAGIC_PRIVATE_ \
+ Magicdisc_t* disc; /* discipline */ \
+ Vmalloc_t* vm; /* vmalloc region */ \
+ Entry_t* magic; /* parsed magic table */ \
+ Entry_t* magiclast; /* last entry in magic */ \
+ char* mime; /* MIME type */ \
+ unsigned char* x2n; /* CC_ALIEN=>CC_NATIVE */ \
+ char fbuf[SF_BUFSIZE + 1]; /* file data */ \
+ char xbuf[SF_BUFSIZE + 1]; /* indirect file data */ \
+ char nbuf[256]; /* !CC_NATIVE data */ \
+ char mbuf[64]; /* mime string */ \
+ char sbuf[64]; /* type suffix string */ \
+ char tbuf[2 * PATH_MAX]; /* type string */ \
+ Cctype_t cctype[UCHAR_MAX + 1]; /* char code types */ \
+ unsigned int count[UCHAR_MAX + 1]; /* char frequency count */ \
+ unsigned int multi[UCHAR_MAX + 1]; /* muti char count */ \
+ int keep[MAXNEST]; /* ckmagic nest stack */ \
+ char* cap[MAXNEST]; /* ckmagic mime stack */ \
+ char* msg[MAXNEST]; /* ckmagic text stack */ \
+ Entry_t* ret[MAXNEST]; /* ckmagic return stack */ \
+ int fbsz; /* fbuf size */ \
+ int fbmx; /* fbuf max size */ \
+ int xbsz; /* xbuf size */ \
+ int swap; /* swap() operation */ \
+ unsigned long flags; /* disc+open flags */ \
+ long xoff; /* xbuf offset */ \
+ int identifier[ID_MAX + 1]; /* Info_t identifier */ \
+ Sfio_t* fp; /* fbuf fp */ \
+ Sfio_t* tmp; /* tmp string */ \
+ regdisc_t redisc; /* regex discipline */ \
+ Dtdisc_t dtdisc; /* dict discipline */ \
+ Dt_t* idtab; /* identifier dict */ \
+ Dt_t* infotab; /* info keyword dict */
+
+#include <magic.h>
+
+static Info_t dict[] = /* keyword dictionary */
+{
+ { "COMMON", ID_FORTRAN },
+ { "COMPUTE", ID_COBOL },
+ { "COMP", ID_COPYBOOK },
+ { "COMPUTATIONAL",ID_COPYBOOK },
+ { "DCL", ID_PL1 },
+ { "DEFINED", ID_PL1 },
+ { "DIMENSION", ID_FORTRAN },
+ { "DIVISION", ID_COBOL },
+ { "FILLER", ID_COPYBOOK },
+ { "FIXED", ID_PL1 },
+ { "FUNCTION", ID_FORTRAN },
+ { "HTML", ID_HTML },
+ { "INTEGER", ID_FORTRAN },
+ { "MAIN", ID_PL1 },
+ { "OPTIONS", ID_PL1 },
+ { "PERFORM", ID_COBOL },
+ { "PIC", ID_COPYBOOK },
+ { "REAL", ID_FORTRAN },
+ { "REDEFINES", ID_COPYBOOK },
+ { "S9", ID_COPYBOOK },
+ { "SECTION", ID_COBOL },
+ { "SELECT", ID_COBOL },
+ { "SUBROUTINE", ID_FORTRAN },
+ { "TEXT", ID_ASM },
+ { "VALUE", ID_COPYBOOK },
+ { "attr", ID_MAM3 },
+ { "binary", ID_YACC },
+ { "block", ID_FORTRAN },
+ { "bss", ID_ASM },
+ { "byte", ID_ASM },
+ { "char", ID_C },
+ { "class", ID_CPLUSPLUS },
+ { "clr", ID_NOTEXT },
+ { "comm", ID_ASM },
+ { "common", ID_FORTRAN },
+ { "data", ID_ASM },
+ { "dimension", ID_FORTRAN },
+ { "done", ID_MAM2 },
+ { "double", ID_C },
+ { "even", ID_ASM },
+ { "exec", ID_MAM3 },
+ { "extern", ID_C },
+ { "float", ID_C },
+ { "function", ID_FORTRAN },
+ { "globl", ID_ASM },
+ { "h", ID_INCL3 },
+ { "html", ID_HTML },
+ { "include", ID_INCL1 },
+ { "int", ID_C },
+ { "integer", ID_FORTRAN },
+ { "jmp", ID_NOTEXT },
+ { "left", ID_YACC },
+ { "libc", ID_INCL2 },
+ { "long", ID_C },
+ { "make", ID_MAM1 },
+ { "mov", ID_NOTEXT },
+ { "private", ID_CPLUSPLUS },
+ { "public", ID_CPLUSPLUS },
+ { "real", ID_FORTRAN },
+ { "register", ID_C },
+ { "right", ID_YACC },
+ { "sfio", ID_INCL2 },
+ { "static", ID_C },
+ { "stdio", ID_INCL2 },
+ { "struct", ID_C },
+ { "subroutine", ID_FORTRAN },
+ { "sys", ID_NOTEXT },
+ { "term", ID_YACC },
+ { "text", ID_ASM },
+ { "tst", ID_NOTEXT },
+ { "type", ID_YACC },
+ { "typedef", ID_C },
+ { "u", ID_INCL2 },
+ { "union", ID_YACC },
+ { "void", ID_C },
+};
+
+static Info_t info[] =
+{
+ { "atime", INFO_atime },
+ { "blocks", INFO_blocks },
+ { "ctime", INFO_ctime },
+ { "fstype", INFO_fstype },
+ { "gid", INFO_gid },
+ { "mode", INFO_mode },
+ { "mtime", INFO_mtime },
+ { "name", INFO_name },
+ { "nlink", INFO_nlink },
+ { "size", INFO_size },
+ { "uid", INFO_uid },
+};
+
+/*
+ * return pointer to data at offset off and size siz
+ */
+
+static char*
+getdata(register Magic_t* mp, register long off, register int siz)
+{
+ register long n;
+
+ if (off < 0)
+ return 0;
+ if (off + siz <= mp->fbsz)
+ return mp->fbuf + off;
+ if (off < mp->xoff || off + siz > mp->xoff + mp->xbsz)
+ {
+ if (off + siz > mp->fbmx)
+ return 0;
+ n = (off / (SF_BUFSIZE / 2)) * (SF_BUFSIZE / 2);
+ if (sfseek(mp->fp, n, SEEK_SET) != n)
+ return 0;
+ if ((mp->xbsz = sfread(mp->fp, mp->xbuf, sizeof(mp->xbuf) - 1)) < 0)
+ {
+ mp->xoff = 0;
+ mp->xbsz = 0;
+ return 0;
+ }
+ mp->xbuf[mp->xbsz] = 0;
+ mp->xoff = n;
+ if (off + siz > mp->xoff + mp->xbsz)
+ return 0;
+ }
+ return mp->xbuf + off - mp->xoff;
+}
+
+/*
+ * @... evaluator for strexpr()
+ */
+
+static long
+indirect(const char* cs, char** e, void* handle)
+{
+ register char* s = (char*)cs;
+ register Magic_t* mp = (Magic_t*)handle;
+ register long n = 0;
+ register char* p;
+
+ if (s)
+ {
+ if (*s == '@')
+ {
+ n = *++s == '(' ? strexpr(s, e, indirect, mp) : strtol(s, e, 0);
+ switch (*(s = *e))
+ {
+ case 'b':
+ case 'B':
+ s++;
+ if (p = getdata(mp, n, 1))
+ n = *(unsigned char*)p;
+ else
+ s = (char*)cs;
+ break;
+ case 'h':
+ case 'H':
+ s++;
+ if (p = getdata(mp, n, 2))
+ n = swapget(mp->swap, p, 2);
+ else
+ s = (char*)cs;
+ break;
+ case 'q':
+ case 'Q':
+ s++;
+ if (p = getdata(mp, n, 8))
+ n = swapget(mp->swap, p, 8);
+ else
+ s = (char*)cs;
+ break;
+ default:
+ if (isalnum(*s))
+ s++;
+ if (p = getdata(mp, n, 4))
+ n = swapget(mp->swap, p, 4);
+ else
+ s = (char*)cs;
+ break;
+ }
+ }
+ *e = s;
+ }
+ else if ((mp->flags & MAGIC_VERBOSE) && mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 2, "%s in indirect expression", *e);
+ return n;
+}
+
+/*
+ * emit regex error message
+ */
+
+static void
+regmessage(Magic_t* mp, regex_t* re, int code)
+{
+ char buf[128];
+
+ if ((mp->flags & MAGIC_VERBOSE) && mp->disc->errorf)
+ {
+ regerror(code, re, buf, sizeof(buf));
+ (*mp->disc->errorf)(mp, mp->disc, 3, "regex: %s", buf);
+ }
+}
+
+/*
+ * decompose vcodex(3) method composition
+ */
+
+static char*
+vcdecomp(char* b, char* e, unsigned char* m, unsigned char* x)
+{
+ unsigned char* map;
+ const char* o;
+ int c;
+ int n;
+ int i;
+ int a;
+
+ map = CCMAP(CC_ASCII, CC_NATIVE);
+ a = 0;
+ i = 1;
+ for (;;)
+ {
+ if (i)
+ i = 0;
+ else
+ *b++ = '^';
+ if (m < (x - 1) && !*(m + 1))
+ {
+ /*
+ * obsolete indices
+ */
+
+ if (!a)
+ {
+ a = 1;
+ o = "old, ";
+ while (b < e && (c = *o++))
+ *b++ = c;
+ }
+ switch (*m)
+ {
+ case 0: o = "delta"; break;
+ case 1: o = "huffman"; break;
+ case 2: o = "huffgroup"; break;
+ case 3: o = "arith"; break;
+ case 4: o = "bwt"; break;
+ case 5: o = "rle"; break;
+ case 6: o = "mtf"; break;
+ case 7: o = "transpose"; break;
+ case 8: o = "table"; break;
+ case 9: o = "huffpart"; break;
+ case 50: o = "map"; break;
+ case 100: o = "recfm"; break;
+ case 101: o = "ss7"; break;
+ default: o = "UNKNOWN"; break;
+ }
+ m += 2;
+ while (b < e && (c = *o++))
+ *b++ = c;
+ }
+ else
+ while (b < e && m < x && (c = *m++))
+ {
+ if (map)
+ c = map[c];
+ *b++ = c;
+ }
+ if (b >= e)
+ break;
+ n = 0;
+ while (m < x)
+ {
+ n = (n<<7) | (*m & 0x7f);
+ if (!(*m++ & 0x80))
+ break;
+ }
+ if (n >= (x - m))
+ break;
+ m += n;
+ }
+ return b;
+}
+
+/*
+ * check for magic table match in buf
+ */
+
+static char*
+ckmagic(register Magic_t* mp, const char* file, char* buf, char* end, struct stat* st, unsigned long off)
+{
+ register Entry_t* ep;
+ register char* p;
+ register char* b;
+ register int level = 0;
+ int call = -1;
+ int all = 0;
+ int c;
+ int str;
+ char* q;
+ char* t;
+ char* cur;
+ char* base = 0;
+ unsigned long num;
+ unsigned long mask;
+ regmatch_t matches[10];
+
+ mp->swap = 0;
+ b = mp->msg[0] = cur = buf;
+ mp->mime = mp->cap[0] = 0;
+ mp->keep[0] = 0;
+ for (ep = mp->magic; ep; ep = ep->next)
+ {
+ fun:
+ if (ep->nest == '{')
+ {
+ if (++level >= MAXNEST)
+ {
+ call = -1;
+ level = 0;
+ mp->keep[0] = 0;
+ b = mp->msg[0];
+ mp->mime = mp->cap[0];
+ continue;
+ }
+ mp->keep[level] = mp->keep[level - 1] != 0;
+ mp->msg[level] = b;
+ mp->cap[level] = mp->mime;
+ }
+ switch (ep->cont)
+ {
+ case '#':
+ if (mp->keep[level] && b > cur)
+ {
+ if ((mp->flags & MAGIC_ALL) && b < (end - 3))
+ {
+ all = 1;
+ *b++ = '\n';
+ cur = b;
+ continue;
+ }
+ *b = 0;
+ return buf;
+ }
+ mp->swap = 0;
+ b = mp->msg[0] = cur;
+ mp->mime = mp->cap[0] = 0;
+ if (ep->type == ' ')
+ continue;
+ break;
+ case '$':
+ if (mp->keep[level] && call < (MAXNEST - 1))
+ {
+ mp->ret[++call] = ep;
+ ep = ep->value.lab;
+ goto fun;
+ }
+ continue;
+ case ':':
+ ep = mp->ret[call--];
+ if (ep->op == 'l')
+ goto fun;
+ continue;
+ case '|':
+ if (mp->keep[level] > 1)
+ goto checknest;
+ /*FALLTHROUGH*/
+ default:
+ if (!mp->keep[level])
+ {
+ b = mp->msg[level];
+ mp->mime = mp->cap[level];
+ goto checknest;
+ }
+ break;
+ }
+ p = "";
+ num = 0;
+ if (!ep->expr)
+ num = ep->offset + off;
+ else
+ switch (ep->offset)
+ {
+ case 0:
+ num = strexpr(ep->expr, NiL, indirect, mp) + off;
+ break;
+ case INFO_atime:
+ num = st->st_atime;
+ ep->type = 'D';
+ break;
+ case INFO_blocks:
+ num = iblocks(st);
+ ep->type = 'N';
+ break;
+ case INFO_ctime:
+ num = st->st_ctime;
+ ep->type = 'D';
+ break;
+ case INFO_fstype:
+ p = fmtfs(st);
+ ep->type = toupper(ep->type);
+ break;
+ case INFO_gid:
+ if (ep->type == 'e' || ep->type == 'm' || ep->type == 's')
+ {
+ p = fmtgid(st->st_gid);
+ ep->type = toupper(ep->type);
+ }
+ else
+ {
+ num = st->st_gid;
+ ep->type = 'N';
+ }
+ break;
+ case INFO_mode:
+ if (ep->type == 'e' || ep->type == 'm' || ep->type == 's')
+ {
+ p = fmtmode(st->st_mode, 0);
+ ep->type = toupper(ep->type);
+ }
+ else
+ {
+ num = modex(st->st_mode);
+ ep->type = 'N';
+ }
+ break;
+ case INFO_mtime:
+ num = st->st_ctime;
+ ep->type = 'D';
+ break;
+ case INFO_name:
+ if (!base)
+ {
+ if (base = strrchr(file, '/'))
+ base++;
+ else
+ base = (char*)file;
+ }
+ p = base;
+ ep->type = toupper(ep->type);
+ break;
+ case INFO_nlink:
+ num = st->st_nlink;
+ ep->type = 'N';
+ break;
+ case INFO_size:
+ num = st->st_size;
+ ep->type = 'N';
+ break;
+ case INFO_uid:
+ if (ep->type == 'e' || ep->type == 'm' || ep->type == 's')
+ {
+ p = fmtuid(st->st_uid);
+ ep->type = toupper(ep->type);
+ }
+ else
+ {
+ num = st->st_uid;
+ ep->type = 'N';
+ }
+ break;
+ }
+ switch (ep->type)
+ {
+
+ case 'b':
+ if (!(p = getdata(mp, num, 1)))
+ goto next;
+ num = *(unsigned char*)p;
+ break;
+
+ case 'h':
+ if (!(p = getdata(mp, num, 2)))
+ goto next;
+ num = swapget(ep->swap ? (~ep->swap ^ mp->swap) : mp->swap, p, 2);
+ break;
+
+ case 'd':
+ case 'l':
+ case 'v':
+ if (!(p = getdata(mp, num, 4)))
+ goto next;
+ num = swapget(ep->swap ? (~ep->swap ^ mp->swap) : mp->swap, p, 4);
+ break;
+
+ case 'q':
+ if (!(p = getdata(mp, num, 8)))
+ goto next;
+ num = swapget(ep->swap ? (~ep->swap ^ mp->swap) : mp->swap, p, 8);
+ break;
+
+ case 'e':
+ if (!(p = getdata(mp, num, 0)))
+ goto next;
+ /*FALLTHROUGH*/
+ case 'E':
+ if (!ep->value.sub)
+ goto next;
+ if ((c = regexec(ep->value.sub, p, elementsof(matches), matches, 0)) || (c = regsubexec(ep->value.sub, p, elementsof(matches), matches)))
+ {
+ c = mp->fbsz;
+ if (c >= sizeof(mp->nbuf))
+ c = sizeof(mp->nbuf) - 1;
+ p = (char*)memcpy(mp->nbuf, p, c);
+ p[c] = 0;
+ ccmapstr(mp->x2n, p, c);
+ if ((c = regexec(ep->value.sub, p, elementsof(matches), matches, 0)) || (c = regsubexec(ep->value.sub, p, elementsof(matches), matches)))
+ {
+ if (c != REG_NOMATCH)
+ regmessage(mp, ep->value.sub, c);
+ goto next;
+ }
+ }
+ p = ep->value.sub->re_sub->re_buf;
+ q = T(ep->desc);
+ t = *q ? q : p;
+ if (mp->keep[level]++ && b > cur && b < end && *(b - 1) != ' ' && *t && *t != ',' && *t != '.' && *t != '\b')
+ *b++ = ' ';
+ b += sfsprintf(b, end - b, *q ? q : "%s", p + (*p == '\b'));
+ if (ep->mime)
+ mp->mime = ep->mime;
+ goto checknest;
+
+ case 's':
+ if (!(p = getdata(mp, num, ep->mask)))
+ goto next;
+ goto checkstr;
+ case 'm':
+ if (!(p = getdata(mp, num, 0)))
+ goto next;
+ /*FALLTHROUGH*/
+ case 'M':
+ case 'S':
+ checkstr:
+ for (;;)
+ {
+ if (*ep->value.str == '*' && !*(ep->value.str + 1) && isprint(*p))
+ break;
+ if ((ep->type == 'm' || ep->type == 'M') ? strmatch(p, ep->value.str) : !memcmp(p, ep->value.str, ep->mask))
+ break;
+ if (p == mp->nbuf || ep->mask >= sizeof(mp->nbuf))
+ goto next;
+ p = (char*)memcpy(mp->nbuf, p, ep->mask);
+ p[ep->mask] = 0;
+ ccmapstr(mp->x2n, p, ep->mask);
+ }
+ q = T(ep->desc);
+ if (mp->keep[level]++ && b > cur && b < end && *(b - 1) != ' ' && *q && *q != ',' && *q != '.' && *q != '\b')
+ *b++ = ' ';
+ for (t = p; (c = *t) >= 0 && c <= 0177 && isprint(c) && c != '\n'; t++);
+ *t = 0;
+ b += sfsprintf(b, end - b, q + (*q == '\b'), p);
+ *t = c;
+ if (ep->mime)
+ mp->mime = ep->mime;
+ goto checknest;
+
+ }
+ if (mask = ep->mask)
+ num &= mask;
+ switch (ep->op)
+ {
+
+ case '=':
+ case '@':
+ if (num == ep->value.num)
+ break;
+ if (ep->cont != '#')
+ goto next;
+ if (!mask)
+ mask = ~mask;
+ if (ep->type == 'h')
+ {
+ if ((num = swapget(mp->swap = 1, p, 2) & mask) == ep->value.num)
+ {
+ if (!(mp->swap & (mp->swap + 1)))
+ mp->swap = 7;
+ goto swapped;
+ }
+ }
+ else if (ep->type == 'l')
+ {
+ for (c = 1; c < 4; c++)
+ if ((num = swapget(mp->swap = c, p, 4) & mask) == ep->value.num)
+ {
+ if (!(mp->swap & (mp->swap + 1)))
+ mp->swap = 7;
+ goto swapped;
+ }
+ }
+ else if (ep->type == 'q')
+ {
+ for (c = 1; c < 8; c++)
+ if ((num = swapget(mp->swap = c, p, 8) & mask) == ep->value.num)
+ goto swapped;
+ }
+ goto next;
+
+ case '!':
+ if (num != ep->value.num)
+ break;
+ goto next;
+
+ case '^':
+ if (num ^ ep->value.num)
+ break;
+ goto next;
+
+ case '>':
+ if (num > ep->value.num)
+ break;
+ goto next;
+
+ case '<':
+ if (num < ep->value.num)
+ break;
+ goto next;
+
+ case 'l':
+ if (num > 0 && mp->keep[level] && call < (MAXNEST - 1))
+ {
+ if (!ep->value.loop->count)
+ {
+ ep->value.loop->count = num;
+ ep->value.loop->offset = off;
+ off = ep->value.loop->start;
+ }
+ else if (!--ep->value.loop->count)
+ {
+ off = ep->value.loop->offset;
+ goto next;
+ }
+ else
+ off += ep->value.loop->size;
+ mp->ret[++call] = ep;
+ ep = ep->value.loop->lab;
+ goto fun;
+ }
+ goto next;
+
+ case 'm':
+ c = mp->swap;
+ t = ckmagic(mp, file, b + (b > cur), end, st, num);
+ mp->swap = c;
+ if (t)
+ {
+ if (b > cur && b < end)
+ *b = ' ';
+ b += strlen(b);
+ }
+ else if (ep->cont == '&')
+ goto next;
+ break;
+
+ case 'r':
+#if _UWIN
+ {
+ char* e;
+ Sfio_t* rp;
+ Sfio_t* gp;
+
+ if (!(t = strrchr(file, '.')))
+ goto next;
+ sfprintf(mp->tmp, "/reg/classes_root/%s", t);
+ if (!(t = sfstruse(mp->tmp)) || !(rp = sfopen(NiL, t, "r")))
+ goto next;
+ *ep->desc = 0;
+ *ep->mime = 0;
+ gp = 0;
+ while (t = sfgetr(rp, '\n', 1))
+ {
+ if (strneq(t, "Content Type=", 13))
+ {
+ ep->mime = vmnewof(mp->vm, ep->mime, char, sfvalue(rp), 0);
+ strcpy(ep->mime, t + 13);
+ if (gp)
+ break;
+ }
+ else
+ {
+ sfprintf(mp->tmp, "/reg/classes_root/%s", t);
+ if ((e = sfstruse(mp->tmp)) && (gp = sfopen(NiL, e, "r")))
+ {
+ ep->desc = vmnewof(mp->vm, ep->desc, char, strlen(t), 1);
+ strcpy(ep->desc, t);
+ if (*ep->mime)
+ break;
+ }
+ }
+ }
+ sfclose(rp);
+ if (!gp)
+ goto next;
+ if (!*ep->mime)
+ {
+ t = T(ep->desc);
+ if (!strncasecmp(t, "microsoft", 9))
+ t += 9;
+ while (isspace(*t))
+ t++;
+ e = "application/x-ms-";
+ ep->mime = vmnewof(mp->vm, ep->mime, char, strlen(t), strlen(e));
+ e = strcopy(ep->mime, e);
+ while ((c = *t++) && c != '.' && c != ' ')
+ *e++ = isupper(c) ? tolower(c) : c;
+ *e = 0;
+ }
+ while (t = sfgetr(gp, '\n', 1))
+ if (*t && !streq(t, "\"\""))
+ {
+ ep->desc = vmnewof(mp->vm, ep->desc, char, sfvalue(gp), 0);
+ strcpy(ep->desc, t);
+ break;
+ }
+ sfclose(gp);
+ if (!*ep->desc)
+ goto next;
+ if (!t)
+ for (t = T(ep->desc); *t; t++)
+ if (*t == '.')
+ *t = ' ';
+ if (!mp->keep[level])
+ mp->keep[level] = 2;
+ mp->mime = ep->mime;
+ break;
+ }
+#else
+ if (ep->cont == '#' && !mp->keep[level])
+ mp->keep[level] = 1;
+ goto next;
+#endif
+
+ case 'v':
+ if (!(p = getdata(mp, num, 4)))
+ goto next;
+ c = 0;
+ do
+ {
+ num++;
+ c = (c<<7) | (*p & 0x7f);
+ } while (*p++ & 0x80);
+ if (!(p = getdata(mp, num, c)))
+ goto next;
+ if (mp->keep[level]++ && b > cur && b < (end - 1) && *(b - 1) != ' ')
+ {
+ *b++ = ',';
+ *b++ = ' ';
+ }
+ b = vcdecomp(b, cur + PATH_MAX, (unsigned char*)p, (unsigned char*)p + c);
+ goto checknest;
+
+ }
+ swapped:
+ q = T(ep->desc);
+ if (mp->keep[level]++ && b > cur && b < end && *(b - 1) != ' ' && *q && *q != ',' && *q != '.' && *q != '\b')
+ *b++ = ' ';
+ if (*q == '\b')
+ q++;
+ str = 0;
+ for (t = q; *t; t++)
+ if (*t == '%' && (c = *(t + 1)))
+ {
+ if (c == '%')
+ t++;
+ else
+ while (c && c != '%')
+ {
+ if (c == 's')
+ {
+ str = 1;
+ break;
+ }
+ else if (c == 'c' || c == 'd' || c == 'i' || c == 'u' || c == 'x' || c == 'X')
+ goto format;
+ t++;
+ c = *(t + 1);
+ }
+ }
+ format:
+ if (!str)
+ b += sfsprintf(b, end - b, q, num, num == 1 ? "" : "s", 0, 0, 0, 0, 0, 0);
+ else if (ep->type == 'd' || ep->type == 'D')
+ b += sfsprintf(b, end - b, q, fmttime("%?%QL", (time_t)num), 0, 0, 0, 0, 0, 0, 0);
+ else if (ep->type == 'v')
+ b += sfsprintf(b, end - b, q, fmtversion(num), 0, 0, 0, 0, 0, 0, 0);
+ else
+ b += sfsprintf(b, end - b, q, fmtnum(num, 0), num == 1 ? "" : "s", 0, 0, 0, 0, 0, 0);
+ if (ep->mime && *ep->mime)
+ mp->mime = ep->mime;
+ checknest:
+ if (ep->nest == '}')
+ {
+ if (!mp->keep[level])
+ {
+ b = mp->msg[level];
+ mp->mime = mp->cap[level];
+ }
+ else if (level > 0)
+ mp->keep[level - 1] = mp->keep[level];
+ if (--level < 0)
+ {
+ level = 0;
+ mp->keep[0] = 0;
+ }
+ }
+ continue;
+ next:
+ if (ep->cont == '&')
+ mp->keep[level] = 0;
+ goto checknest;
+ }
+ if (all && b-- || mp->keep[level] && b > cur)
+ {
+ *b = 0;
+ return buf;
+ }
+ return 0;
+}
+
+/*
+ * check english language stats
+ */
+
+static int
+ckenglish(register Magic_t* mp, int pun, int badpun)
+{
+ register char* s;
+ register int vowl = 0;
+ register int freq = 0;
+ register int rare = 0;
+
+ if (5 * badpun > pun)
+ return 0;
+ if (2 * mp->count[';'] > mp->count['E'] + mp->count['e'])
+ return 0;
+ if ((mp->count['>'] + mp->count['<'] + mp->count['/']) > mp->count['E'] + mp->count['e'])
+ return 0;
+ for (s = "aeiou"; *s; s++)
+ vowl += mp->count[toupper(*s)] + mp->count[*s];
+ for (s = "etaion"; *s; s++)
+ freq += mp->count[toupper(*s)] + mp->count[*s];
+ for (s = "vjkqxz"; *s; s++)
+ rare += mp->count[toupper(*s)] + mp->count[*s];
+ return 5 * vowl >= mp->fbsz - mp->count[' '] && freq >= 10 * rare;
+}
+
+/*
+ * check programming language stats
+ */
+
+static char*
+cklang(register Magic_t* mp, const char* file, char* buf, char* end, struct stat* st)
+{
+ register int c;
+ register unsigned char* b;
+ register unsigned char* e;
+ register int q;
+ register char* s;
+ char* t;
+ char* base;
+ char* suff;
+ char* t1;
+ char* t2;
+ char* t3;
+ int n;
+ int badpun;
+ int code;
+ int pun;
+ Cctype_t flags;
+ Info_t* ip;
+
+ b = (unsigned char*)mp->fbuf;
+ e = b + mp->fbsz;
+ memzero(mp->count, sizeof(mp->count));
+ memzero(mp->multi, sizeof(mp->multi));
+ memzero(mp->identifier, sizeof(mp->identifier));
+
+ /*
+ * check character coding
+ */
+
+ flags = 0;
+ while (b < e)
+ flags |= mp->cctype[*b++];
+ b = (unsigned char*)mp->fbuf;
+ code = 0;
+ q = CC_ASCII;
+ n = CC_MASK;
+ for (c = 0; c < CC_MAPS; c++)
+ {
+ flags ^= CC_text;
+ if ((flags & CC_MASK) < n)
+ {
+ n = flags & CC_MASK;
+ q = c;
+ }
+ flags >>= CC_BIT;
+ }
+ flags = n;
+ if (!(flags & (CC_binary|CC_notext)))
+ {
+ if (q != CC_NATIVE)
+ {
+ code = q;
+ ccmaps(mp->fbuf, mp->fbsz, q, CC_NATIVE);
+ }
+ if (b[0] == '#' && b[1] == '!')
+ {
+ for (b += 2; b < e && isspace(*b); b++);
+ for (s = (char*)b; b < e && isprint(*b); b++);
+ c = *b;
+ *b = 0;
+ if ((st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) || match(s, "/*bin*/*") || !access(s, F_OK))
+ {
+ if (t = strrchr(s, '/'))
+ s = t + 1;
+ for (t = s; *t; t++)
+ if (isspace(*t))
+ {
+ *t = 0;
+ break;
+ }
+ sfsprintf(mp->mbuf, sizeof(mp->mbuf), "application/x-%s", *s ? s : "sh");
+ mp->mime = mp->mbuf;
+ if (match(s, "*sh"))
+ {
+ t1 = T("command");
+ if (streq(s, "sh"))
+ *s = 0;
+ else
+ {
+ *b++ = ' ';
+ *b = 0;
+ }
+ }
+ else
+ {
+ t1 = T("interpreter");
+ *b++ = ' ';
+ *b = 0;
+ }
+ sfsprintf(mp->sbuf, sizeof(mp->sbuf), T("%s%s script"), s, t1);
+ s = mp->sbuf;
+ goto qualify;
+ }
+ *b = c;
+ b = (unsigned char*)mp->fbuf;
+ }
+ badpun = 0;
+ pun = 0;
+ q = 0;
+ s = 0;
+ t = 0;
+ while (b < e)
+ {
+ c = *b++;
+ mp->count[c]++;
+ if (c == q && (q != '*' || *b == '/' && b++))
+ {
+ mp->multi[q]++;
+ q = 0;
+ }
+ else if (c == '\\')
+ {
+ s = 0;
+ b++;
+ }
+ else if (!q)
+ {
+ if (isalpha(c) || c == '_')
+ {
+ if (!s)
+ s = (char*)b - 1;
+ }
+ else if (!isdigit(c))
+ {
+ if (s)
+ {
+ if (s > mp->fbuf)
+ switch (*(s - 1))
+ {
+ case ':':
+ if (*b == ':')
+ mp->multi[':']++;
+ break;
+ case '.':
+ if (((char*)b - s) == 3 && (s == (mp->fbuf + 1) || *(s - 2) == '\n'))
+ mp->multi['.']++;
+ break;
+ case '\n':
+ case '\\':
+ if (*b == '{')
+ t = (char*)b + 1;
+ break;
+ case '{':
+ if (s == t && *b == '}')
+ mp->multi['X']++;
+ break;
+ }
+ if (!mp->idtab)
+ {
+ if (mp->idtab = dtnew(mp->vm, &mp->dtdisc, Dtset))
+ for (q = 0; q < elementsof(dict); q++)
+ dtinsert(mp->idtab, &dict[q]);
+ else if (mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 3, "out of space");
+ q = 0;
+ }
+ if (mp->idtab)
+ {
+ *(b - 1) = 0;
+ if (ip = (Info_t*)dtmatch(mp->idtab, s))
+ mp->identifier[ip->value]++;
+ *(b - 1) = c;
+ }
+ s = 0;
+ }
+ switch (c)
+ {
+ case '\t':
+ if (b == (unsigned char*)(mp->fbuf + 1) || *(b - 2) == '\n')
+ mp->multi['\t']++;
+ break;
+ case '"':
+ case '\'':
+ q = c;
+ break;
+ case '/':
+ if (*b == '*')
+ q = *b++;
+ else if (*b == '/')
+ q = '\n';
+ break;
+ case '$':
+ if (*b == '(' && *(b + 1) != ' ')
+ mp->multi['$']++;
+ break;
+ case '{':
+ case '}':
+ case '[':
+ case ']':
+ case '(':
+ mp->multi[c]++;
+ break;
+ case ')':
+ mp->multi[c]++;
+ goto punctuation;
+ case ':':
+ if (*b == ':' && isspace(*(b + 1)) && b > (unsigned char*)(mp->fbuf + 1) && isspace(*(b - 2)))
+ mp->multi[':']++;
+ goto punctuation;
+ case '.':
+ case ',':
+ case '%':
+ case ';':
+ case '?':
+ punctuation:
+ pun++;
+ if (*b != ' ' && *b != '\n')
+ badpun++;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ while (b < e)
+ mp->count[*b++]++;
+ base = (t1 = strrchr(file, '/')) ? t1 + 1 : (char*)file;
+ suff = (t1 = strrchr(base, '.')) ? t1 + 1 : "";
+ if (!flags)
+ {
+ if (match(suff, "*sh|bat|cmd"))
+ goto id_sh;
+ if (match(base, "*@(mkfile)"))
+ goto id_mk;
+ if (match(base, "*@(makefile|.mk)"))
+ goto id_make;
+ if (match(base, "*@(mamfile|.mam)"))
+ goto id_mam;
+ if (match(suff, "[cly]?(pp|xx|++)|cc|ll|yy"))
+ goto id_c;
+ if (match(suff, "f"))
+ goto id_fortran;
+ if (match(suff, "htm+(l)"))
+ goto id_html;
+ if (match(suff, "cpy"))
+ goto id_copybook;
+ if (match(suff, "cob|cbl|cb2"))
+ goto id_cobol;
+ if (match(suff, "pl[1i]"))
+ goto id_pl1;
+ if (match(suff, "tex"))
+ goto id_tex;
+ if (match(suff, "asm|s"))
+ goto id_asm;
+ if ((st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) && (!suff || suff != strchr(suff, '.')))
+ {
+ id_sh:
+ s = T("command script");
+ mp->mime = "application/sh";
+ goto qualify;
+ }
+ if (strmatch(mp->fbuf, "From * [0-9][0-9]:[0-9][0-9]:[0-9][0-9] *"))
+ {
+ s = T("mail message");
+ mp->mime = "message/rfc822";
+ goto qualify;
+ }
+ if (match(base, "*@(mkfile)"))
+ {
+ id_mk:
+ s = "mkfile";
+ mp->mime = "application/mk";
+ goto qualify;
+ }
+ if (match(base, "*@(makefile|.mk)") || mp->multi['\t'] >= mp->count[':'] && (mp->multi['$'] > 0 || mp->multi[':'] > 0))
+ {
+ id_make:
+ s = "makefile";
+ mp->mime = "application/make";
+ goto qualify;
+ }
+ if (mp->multi['.'] >= 3)
+ {
+ s = T("nroff input");
+ mp->mime = "application/x-troff";
+ goto qualify;
+ }
+ if (mp->multi['X'] >= 3)
+ {
+ s = T("TeX input");
+ mp->mime = "application/x-tex";
+ goto qualify;
+ }
+ if (mp->fbsz < SF_BUFSIZE &&
+ (mp->multi['('] == mp->multi[')'] &&
+ mp->multi['{'] == mp->multi['}'] &&
+ mp->multi['['] == mp->multi[']']) ||
+ mp->fbsz >= SF_BUFSIZE &&
+ (mp->multi['('] >= mp->multi[')'] &&
+ mp->multi['{'] >= mp->multi['}'] &&
+ mp->multi['['] >= mp->multi[']']))
+ {
+ c = mp->identifier[ID_INCL1];
+ if (c >= 2 && mp->identifier[ID_INCL2] >= c && mp->identifier[ID_INCL3] >= c && mp->count['.'] >= c ||
+ mp->identifier[ID_C] >= 5 && mp->count[';'] >= 5 ||
+ mp->count['='] >= 20 && mp->count[';'] >= 20)
+ {
+ id_c:
+ t1 = "";
+ t2 = "c ";
+ t3 = T("program");
+ switch (*suff)
+ {
+ case 'c':
+ case 'C':
+ mp->mime = "application/x-cc";
+ break;
+ case 'l':
+ case 'L':
+ t1 = "lex ";
+ mp->mime = "application/x-lex";
+ break;
+ default:
+ t3 = T("header");
+ if (mp->identifier[ID_YACC] < 5 || mp->count['%'] < 5)
+ {
+ mp->mime = "application/x-cc";
+ break;
+ }
+ /*FALLTHROUGH*/
+ case 'y':
+ case 'Y':
+ t1 = "yacc ";
+ mp->mime = "application/x-yacc";
+ break;
+ }
+ if (mp->identifier[ID_CPLUSPLUS] >= 3)
+ {
+ t2 = "c++ ";
+ mp->mime = "application/x-c++";
+ }
+ sfsprintf(mp->sbuf, sizeof(mp->sbuf), "%s%s%s", t1, t2, t3);
+ s = mp->sbuf;
+ goto qualify;
+ }
+ }
+ if (mp->identifier[ID_MAM1] >= 2 && mp->identifier[ID_MAM3] >= 2 &&
+ (mp->fbsz < SF_BUFSIZE && mp->identifier[ID_MAM1] == mp->identifier[ID_MAM2] ||
+ mp->fbsz >= SF_BUFSIZE && mp->identifier[ID_MAM1] >= mp->identifier[ID_MAM2]))
+ {
+ id_mam:
+ s = T("mam program");
+ mp->mime = "application/x-mam";
+ goto qualify;
+ }
+ if (mp->identifier[ID_FORTRAN] >= 8)
+ {
+ id_fortran:
+ s = T("fortran program");
+ mp->mime = "application/x-fortran";
+ goto qualify;
+ }
+ if (mp->identifier[ID_HTML] > 0 && mp->count['<'] >= 8 && (c = mp->count['<'] - mp->count['>']) >= -2 && c <= 2)
+ {
+ id_html:
+ s = T("html input");
+ mp->mime = "text/html";
+ goto qualify;
+ }
+ if (mp->identifier[ID_COPYBOOK] > 0 && mp->identifier[ID_COBOL] == 0 && (c = mp->count['('] - mp->count[')']) >= -2 && c <= 2)
+ {
+ id_copybook:
+ s = T("cobol copybook");
+ mp->mime = "application/x-cobol";
+ goto qualify;
+ }
+ if (mp->identifier[ID_COBOL] > 0 && mp->identifier[ID_COPYBOOK] > 0 && (c = mp->count['('] - mp->count[')']) >= -2 && c <= 2)
+ {
+ id_cobol:
+ s = T("cobol program");
+ mp->mime = "application/x-cobol";
+ goto qualify;
+ }
+ if (mp->identifier[ID_PL1] > 0 && (c = mp->count['('] - mp->count[')']) >= -2 && c <= 2)
+ {
+ id_pl1:
+ s = T("pl1 program");
+ mp->mime = "application/x-pl1";
+ goto qualify;
+ }
+ if (mp->count['{'] >= 6 && (c = mp->count['{'] - mp->count['}']) >= -2 && c <= 2 && mp->count['\\'] >= mp->count['{'])
+ {
+ id_tex:
+ s = T("TeX input");
+ mp->mime = "text/tex";
+ goto qualify;
+ }
+ if (mp->identifier[ID_ASM] >= 4)
+ {
+ id_asm:
+ s = T("as program");
+ mp->mime = "application/x-as";
+ goto qualify;
+ }
+ if (ckenglish(mp, pun, badpun))
+ {
+ s = T("english text");
+ mp->mime = "text/plain";
+ goto qualify;
+ }
+ }
+ else if (streq(base, "core"))
+ {
+ mp->mime = "x-system/core";
+ return T("core dump");
+ }
+ if (flags & (CC_binary|CC_notext))
+ {
+ b = (unsigned char*)mp->fbuf;
+ e = b + mp->fbsz;
+ n = 0;
+ for (;;)
+ {
+ c = *b++;
+ q = 0;
+ while (c & 0x80)
+ {
+ c <<= 1;
+ q++;
+ }
+ switch (q)
+ {
+ case 4:
+ if (b < e && (*b++ & 0xc0) != 0x80)
+ break;
+ case 3:
+ if (b < e && (*b++ & 0xc0) != 0x80)
+ break;
+ case 2:
+ if (b < e && (*b++ & 0xc0) != 0x80)
+ break;
+ n = 1;
+ case 0:
+ if (b >= e)
+ {
+ if (n)
+ {
+ flags &= ~(CC_binary|CC_notext);
+ flags |= CC_utf_8;
+ }
+ break;
+ }
+ continue;
+ }
+ break;
+ }
+ }
+ if (flags & (CC_binary|CC_notext))
+ {
+ unsigned long d = 0;
+
+ if ((q = mp->fbsz / UCHAR_MAX) >= 2)
+ {
+ /*
+ * compression/encryption via standard deviation
+ */
+
+
+ for (c = 0; c < UCHAR_MAX; c++)
+ {
+ pun = mp->count[c] - q;
+ d += pun * pun;
+ }
+ d /= mp->fbsz;
+ }
+ if (d <= 0)
+ s = T("binary");
+ else if (d < 4)
+ s = T("encrypted");
+ else if (d < 16)
+ s = T("packed");
+ else if (d < 64)
+ s = T("compressed");
+ else if (d < 256)
+ s = T("delta");
+ else
+ s = T("data");
+ mp->mime = "application/octet-stream";
+ return s;
+ }
+ mp->mime = "text/plain";
+ if (flags & CC_utf_8)
+ s = (flags & CC_control) ? T("utf-8 text with control characters") : T("utf-8 text");
+ else if (flags & CC_latin)
+ s = (flags & CC_control) ? T("latin text with control characters") : T("latin text");
+ else
+ s = (flags & CC_control) ? T("text with control characters") : T("text");
+ qualify:
+ if (!flags && mp->count['\n'] >= mp->count['\r'] && mp->count['\n'] <= (mp->count['\r'] + 1) && mp->count['\r'])
+ {
+ t = "dos ";
+ mp->mime = "text/dos";
+ }
+ else
+ t = "";
+ if (code)
+ {
+ if (code == CC_ASCII)
+ sfsprintf(buf, end - buf, "ascii %s%s", t, s);
+ else
+ {
+ sfsprintf(buf, end - buf, "ebcdic%d %s%s", code - 1, t, s);
+ mp->mime = "text/ebcdic";
+ }
+ s = buf;
+ }
+ else if (*t)
+ {
+ sfsprintf(buf, end - buf, "%s%s", t, s);
+ s = buf;
+ }
+ return s;
+}
+
+/*
+ * return the basic magic string for file,st in buf,size
+ */
+
+static char*
+type(register Magic_t* mp, const char* file, struct stat* st, char* buf, char* end)
+{
+ register char* s;
+ register char* t;
+
+ mp->mime = 0;
+ if (!S_ISREG(st->st_mode))
+ {
+ if (S_ISDIR(st->st_mode))
+ {
+ mp->mime = "x-system/dir";
+ return T("directory");
+ }
+ if (S_ISLNK(st->st_mode))
+ {
+ mp->mime = "x-system/lnk";
+ s = buf;
+ s += sfsprintf(s, end - s, T("symbolic link to "));
+ if (pathgetlink(file, s, end - s) < 0)
+ return T("cannot read symbolic link text");
+ return buf;
+ }
+ if (S_ISBLK(st->st_mode))
+ {
+ mp->mime = "x-system/blk";
+ sfsprintf(buf, PATH_MAX, T("block special (%s)"), fmtdev(st));
+ return buf;
+ }
+ if (S_ISCHR(st->st_mode))
+ {
+ mp->mime = "x-system/chr";
+ sfsprintf(buf, end - buf, T("character special (%s)"), fmtdev(st));
+ return buf;
+ }
+ if (S_ISFIFO(st->st_mode))
+ {
+ mp->mime = "x-system/fifo";
+ return "fifo";
+ }
+#ifdef S_ISSOCK
+ if (S_ISSOCK(st->st_mode))
+ {
+ mp->mime = "x-system/sock";
+ return "socket";
+ }
+#endif
+ }
+ if (!(mp->fbmx = st->st_size))
+ s = T("empty");
+ else if (!mp->fp)
+ s = T("cannot read");
+ else
+ {
+ mp->fbsz = sfread(mp->fp, mp->fbuf, sizeof(mp->fbuf) - 1);
+ if (mp->fbsz < 0)
+ s = fmterror(errno);
+ else if (mp->fbsz == 0)
+ s = T("empty");
+ else
+ {
+ mp->fbuf[mp->fbsz] = 0;
+ mp->xoff = 0;
+ mp->xbsz = 0;
+ if (!(s = ckmagic(mp, file, buf, end, st, 0)))
+ s = cklang(mp, file, buf, end, st);
+ }
+ }
+ if (!mp->mime)
+ mp->mime = "application/unknown";
+ else if ((t = strchr(mp->mime, '%')) && *(t + 1) == 's' && !*(t + 2))
+ {
+ register char* b;
+ register char* be;
+ register char* m;
+ register char* me;
+
+ b = mp->mime;
+ me = (m = mp->mime = mp->fbuf) + sizeof(mp->fbuf) - 1;
+ while (m < me && b < t)
+ *m++ = *b++;
+ b = t = s;
+ for (;;)
+ {
+ if (!(be = strchr(t, ' ')))
+ {
+ be = b + strlen(b);
+ break;
+ }
+ if (*(be - 1) == ',' || strneq(be + 1, "data", 4) || strneq(be + 1, "file", 4))
+ break;
+ b = t;
+ t = be + 1;
+ }
+ while (m < me && b < be)
+ if ((*m++ = *b++) == ' ')
+ *(m - 1) = '-';
+ *m = 0;
+ }
+ return s;
+}
+
+/*
+ * low level for magicload()
+ */
+
+static int
+load(register Magic_t* mp, char* file, register Sfio_t* fp)
+{
+ register Entry_t* ep;
+ register char* p;
+ register char* p2;
+ char* p3;
+ char* next;
+ int n;
+ int lge;
+ int lev;
+ int ent;
+ int old;
+ int cont;
+ Info_t* ip;
+ Entry_t* ret;
+ Entry_t* first;
+ Entry_t* last = 0;
+ Entry_t* fun['z' - 'a' + 1];
+
+ memzero(fun, sizeof(fun));
+ cont = '$';
+ ent = 0;
+ lev = 0;
+ old = 0;
+ ret = 0;
+ error_info.file = file;
+ error_info.line = 0;
+ first = ep = vmnewof(mp->vm, 0, Entry_t, 1, 0);
+ while (p = sfgetr(fp, '\n', 1))
+ {
+ error_info.line++;
+ for (; isspace(*p); p++);
+
+ /*
+ * nesting
+ */
+
+ switch (*p)
+ {
+ case 0:
+ case '#':
+ cont = '#';
+ continue;
+ case '{':
+ if (++lev < MAXNEST)
+ ep->nest = *p;
+ else if ((mp->flags & MAGIC_VERBOSE) && mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 1, "{ ... } operator nesting too deep -- %d max", MAXNEST);
+ continue;
+ case '}':
+ if (!last || lev <= 0)
+ {
+ if (mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 2, "`%c': invalid nesting", *p);
+ }
+ else if (lev-- == ent)
+ {
+ ent = 0;
+ ep->cont = ':';
+ ep->offset = ret->offset;
+ ep->nest = ' ';
+ ep->type = ' ';
+ ep->op = ' ';
+ ep->desc = "[RETURN]";
+ last = ep;
+ ep = ret->next = vmnewof(mp->vm, 0, Entry_t, 1, 0);
+ ret = 0;
+ }
+ else
+ last->nest = *p;
+ continue;
+ default:
+ if (*(p + 1) == '{' || *(p + 1) == '(' && *p != '+' && *p != '>' && *p != '&' && *p != '|')
+ {
+ n = *p++;
+ if (n >= 'a' && n <= 'z')
+ n -= 'a';
+ else
+ {
+ if (mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 2, "%c: invalid function name", n);
+ n = 0;
+ }
+ if (ret && mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 2, "%c: function has no return", ret->offset + 'a');
+ if (*p == '{')
+ {
+ ent = ++lev;
+ ret = ep;
+ ep->desc = "[FUNCTION]";
+ }
+ else
+ {
+ if (*(p + 1) != ')' && mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 2, "%c: invalid function call argument list", n + 'a');
+ ep->desc = "[CALL]";
+ }
+ ep->cont = cont;
+ ep->offset = n;
+ ep->nest = ' ';
+ ep->type = ' ';
+ ep->op = ' ';
+ last = ep;
+ ep = ep->next = vmnewof(mp->vm, 0, Entry_t, 1, 0);
+ if (ret)
+ fun[n] = last->value.lab = ep;
+ else if (!(last->value.lab = fun[n]) && mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 2, "%c: function not defined", n + 'a');
+ continue;
+ }
+ if (!ep->nest)
+ ep->nest = (lev > 0 && lev != ent) ? ('0' + lev - !!ent) : ' ';
+ break;
+ }
+
+ /*
+ * continuation
+ */
+
+ cont = '$';
+ switch (*p)
+ {
+ case '>':
+ old = 1;
+ if (*(p + 1) == *p)
+ {
+ /*
+ * old style nesting push
+ */
+
+ p++;
+ old = 2;
+ if (!lev && last)
+ {
+ lev = 1;
+ last->nest = '{';
+ if (last->cont == '>')
+ last->cont = '&';
+ ep->nest = '1';
+ }
+ }
+ /*FALLTHROUGH*/
+ case '+':
+ case '&':
+ case '|':
+ ep->cont = *p++;
+ break;
+ default:
+ if ((mp->flags & MAGIC_VERBOSE) && !isalpha(*p) && mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 1, "`%c': invalid line continuation operator", *p);
+ /*FALLTHROUGH*/
+ case '*':
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ ep->cont = (lev > 0) ? '&' : '#';
+ break;
+ }
+ switch (old)
+ {
+ case 1:
+ old = 0;
+ if (lev)
+ {
+ /*
+ * old style nesting pop
+ */
+
+ lev = 0;
+ if (last)
+ last->nest = '}';
+ ep->nest = ' ';
+ if (ep->cont == '&')
+ ep->cont = '#';
+ }
+ break;
+ case 2:
+ old = 1;
+ break;
+ }
+ if (isdigit(*p))
+ {
+ /*
+ * absolute offset
+ */
+
+ ep->offset = strton(p, &next, NiL, 0);
+ p2 = next;
+ }
+ else
+ {
+ for (p2 = p; *p2 && !isspace(*p2); p2++);
+ if (!*p2)
+ {
+ if ((mp->flags & MAGIC_VERBOSE) && mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 1, "not enough fields: `%s'", p);
+ continue;
+ }
+
+ /*
+ * offset expression
+ */
+
+ *p2++ = 0;
+ ep->expr = vmstrdup(mp->vm, p);
+ if (isalpha(*p))
+ ep->offset = (ip = (Info_t*)dtmatch(mp->infotab, p)) ? ip->value : 0;
+ else if (*p == '(' && ep->cont == '>')
+ {
+ /*
+ * convert old style indirection to @
+ */
+
+ p = ep->expr + 1;
+ for (;;)
+ {
+ switch (*p++)
+ {
+ case 0:
+ case '@':
+ case '(':
+ break;
+ case ')':
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+ if (*--p == ')')
+ {
+ *p = 0;
+ *ep->expr = '@';
+ }
+ }
+ }
+ for (; isspace(*p2); p2++);
+ for (p = p2; *p2 && !isspace(*p2); p2++);
+ if (!*p2)
+ {
+ if ((mp->flags & MAGIC_VERBOSE) && mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 1, "not enough fields: `%s'", p);
+ continue;
+ }
+ *p2++ = 0;
+
+ /*
+ * type
+ */
+
+ if ((*p == 'b' || *p == 'l') && *(p + 1) == 'e')
+ {
+ ep->swap = ~(*p == 'l' ? 7 : 0);
+ p += 2;
+ }
+ if (*p == 's')
+ {
+ if (*(p + 1) == 'h')
+ ep->type = 'h';
+ else
+ ep->type = 's';
+ }
+ else if (*p == 'a')
+ ep->type = 's';
+ else
+ ep->type = *p;
+ if (p = strchr(p, '&'))
+ {
+ /*
+ * old style mask
+ */
+
+ ep->mask = strton(++p, NiL, NiL, 0);
+ }
+ for (; isspace(*p2); p2++);
+ if (ep->mask)
+ *--p2 = '=';
+
+ /*
+ * comparison operation
+ */
+
+ p = p2;
+ if (p2 = strchr(p, '\t'))
+ *p2++ = 0;
+ else
+ {
+ int qe = 0;
+ int qn = 0;
+
+ /*
+ * assume balanced {}[]()\\""'' field
+ */
+
+ for (p2 = p;;)
+ {
+ switch (n = *p2++)
+ {
+ case 0:
+ break;
+ case '{':
+ if (!qe)
+ qe = '}';
+ if (qe == '}')
+ qn++;
+ continue;
+ case '(':
+ if (!qe)
+ qe = ')';
+ if (qe == ')')
+ qn++;
+ continue;
+ case '[':
+ if (!qe)
+ qe = ']';
+ if (qe == ']')
+ qn++;
+ continue;
+ case '}':
+ case ')':
+ case ']':
+ if (qe == n && qn > 0)
+ qn--;
+ continue;
+ case '"':
+ case '\'':
+ if (!qe)
+ qe = n;
+ else if (qe == n)
+ qe = 0;
+ continue;
+ case '\\':
+ if (*p2)
+ p2++;
+ continue;
+ default:
+ if (!qe && isspace(n))
+ break;
+ continue;
+ }
+ if (n)
+ *(p2 - 1) = 0;
+ else
+ p2--;
+ break;
+ }
+ }
+ lge = 0;
+ if (ep->type == 'e' || ep->type == 'm' || ep->type == 's')
+ ep->op = '=';
+ else
+ {
+ if (*p == '&')
+ {
+ ep->mask = strton(++p, &next, NiL, 0);
+ p = next;
+ }
+ switch (*p)
+ {
+ case '=':
+ case '>':
+ case '<':
+ case '*':
+ ep->op = *p++;
+ if (*p == '=')
+ {
+ p++;
+ switch (ep->op)
+ {
+ case '>':
+ lge = -1;
+ break;
+ case '<':
+ lge = 1;
+ break;
+ }
+ }
+ break;
+ case '!':
+ case '@':
+ ep->op = *p++;
+ if (*p == '=')
+ p++;
+ break;
+ case 'x':
+ p++;
+ ep->op = '*';
+ break;
+ default:
+ ep->op = '=';
+ if (ep->mask)
+ ep->value.num = ep->mask;
+ break;
+ }
+ }
+ if (ep->op != '*' && !ep->value.num)
+ {
+ if (ep->type == 'e')
+ {
+ if (ep->value.sub = vmnewof(mp->vm, 0, regex_t, 1, 0))
+ {
+ ep->value.sub->re_disc = &mp->redisc;
+ if (!(n = regcomp(ep->value.sub, p, REG_DELIMITED|REG_LENIENT|REG_NULL|REG_DISCIPLINE)))
+ {
+ p += ep->value.sub->re_npat;
+ if (!(n = regsubcomp(ep->value.sub, p, NiL, 0, 0)))
+ p += ep->value.sub->re_npat;
+ }
+ if (n)
+ {
+ regmessage(mp, ep->value.sub, n);
+ ep->value.sub = 0;
+ }
+ else if (*p && mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 1, "invalid characters after substitution: %s", p);
+ }
+ }
+ else if (ep->type == 'm')
+ {
+ ep->mask = stresc(p) + 1;
+ ep->value.str = vmnewof(mp->vm, 0, char, ep->mask + 1, 0);
+ memcpy(ep->value.str, p, ep->mask);
+ if ((!ep->expr || !ep->offset) && !strmatch(ep->value.str, "\\!\\(*\\)"))
+ ep->value.str[ep->mask - 1] = '*';
+ }
+ else if (ep->type == 's')
+ {
+ ep->mask = stresc(p);
+ ep->value.str = vmnewof(mp->vm, 0, char, ep->mask, 0);
+ memcpy(ep->value.str, p, ep->mask);
+ }
+ else if (*p == '\'')
+ {
+ stresc(p);
+ ep->value.num = *(unsigned char*)(p + 1) + lge;
+ }
+ else if (strmatch(p, "+([a-z])\\(*\\)"))
+ {
+ char* t;
+
+ t = p;
+ ep->type = 'V';
+ ep->op = *p;
+ while (*p && *p++ != '(');
+ switch (ep->op)
+ {
+ case 'l':
+ n = *p++;
+ if (n < 'a' || n > 'z')
+ {
+ if (mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 2, "%c: invalid function name", n);
+ }
+ else if (!fun[n -= 'a'])
+ {
+ if (mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 2, "%c: function not defined", n + 'a');
+ }
+ else
+ {
+ ep->value.loop = vmnewof(mp->vm, 0, Loop_t, 1, 0);
+ ep->value.loop->lab = fun[n];
+ while (*p && *p++ != ',');
+ ep->value.loop->start = strton(p, &t, NiL, 0);
+ while (*t && *t++ != ',');
+ ep->value.loop->size = strton(t, &t, NiL, 0);
+ }
+ break;
+ case 'm':
+ case 'r':
+ ep->desc = vmnewof(mp->vm, 0, char, 32, 0);
+ ep->mime = vmnewof(mp->vm, 0, char, 32, 0);
+ break;
+ case 'v':
+ break;
+ default:
+ if ((mp->flags & MAGIC_VERBOSE) && mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 1, "%-.*s: unknown function", p - t, t);
+ break;
+ }
+ }
+ else
+ {
+ ep->value.num = strton(p, NiL, NiL, 0) + lge;
+ if (ep->op == '@')
+ ep->value.num = swapget(0, (char*)&ep->value.num, sizeof(ep->value.num));
+ }
+ }
+
+ /*
+ * file description
+ */
+
+ if (p2)
+ {
+ for (; isspace(*p2); p2++);
+ if (p = strchr(p2, '\t'))
+ {
+ /*
+ * check for message catalog index
+ */
+
+ *p++ = 0;
+ if (isalpha(*p2))
+ {
+ for (p3 = p2; isalnum(*p3); p3++);
+ if (*p3++ == ':')
+ {
+ for (; isdigit(*p3); p3++);
+ if (!*p3)
+ {
+ for (p2 = p; isspace(*p2); p2++);
+ if (p = strchr(p2, '\t'))
+ *p++ = 0;
+ }
+ }
+ }
+ }
+ stresc(p2);
+ ep->desc = vmstrdup(mp->vm, p2);
+ if (p)
+ {
+ for (; isspace(*p); p++);
+ if (*p)
+ ep->mime = vmstrdup(mp->vm, p);
+ }
+ }
+ else
+ ep->desc = "";
+
+ /*
+ * get next entry
+ */
+
+ last = ep;
+ ep = ep->next = vmnewof(mp->vm, 0, Entry_t, 1, 0);
+ }
+ if (last)
+ {
+ last->next = 0;
+ if (mp->magiclast)
+ mp->magiclast->next = first;
+ else
+ mp->magic = first;
+ mp->magiclast = last;
+ }
+ vmfree(mp->vm, ep);
+ if ((mp->flags & MAGIC_VERBOSE) && mp->disc->errorf)
+ {
+ if (lev < 0)
+ (*mp->disc->errorf)(mp, mp->disc, 1, "too many } operators");
+ else if (lev > 0)
+ (*mp->disc->errorf)(mp, mp->disc, 1, "not enough } operators");
+ if (ret)
+ (*mp->disc->errorf)(mp, mp->disc, 2, "%c: function has no return", ret->offset + 'a');
+ }
+ error_info.file = 0;
+ error_info.line = 0;
+ return 0;
+}
+
+/*
+ * load a magic file into mp
+ */
+
+int
+magicload(register Magic_t* mp, const char* file, unsigned long flags)
+{
+ register char* s;
+ register char* e;
+ register char* t;
+ int n;
+ int found;
+ int list;
+ Sfio_t* fp;
+
+ mp->flags = mp->disc->flags | flags;
+ found = 0;
+ if (list = !(s = (char*)file) || !*s || (*s == '-' || *s == '.') && !*(s + 1))
+ {
+ if (!(s = getenv(MAGIC_FILE_ENV)) || !*s)
+ s = MAGIC_FILE;
+ }
+ for (;;)
+ {
+ if (!list)
+ e = 0;
+ else if (e = strchr(s, ':'))
+ {
+ /*
+ * ok, so ~ won't work for the last list element
+ * we do it for MAGIC_FILES_ENV anyway
+ */
+
+ if ((strneq(s, "~/", n = 2) || strneq(s, "$HOME/", n = 6) || strneq(s, "${HOME}/", n = 8)) && (t = getenv("HOME")))
+ {
+ sfputr(mp->tmp, t, -1);
+ s += n - 1;
+ }
+ sfwrite(mp->tmp, s, e - s);
+ if (!(s = sfstruse(mp->tmp)))
+ goto nospace;
+ }
+ if (!*s || streq(s, "-"))
+ s = MAGIC_FILE;
+ if (!(fp = sfopen(NiL, s, "r")))
+ {
+ if (list)
+ {
+ if (!(t = pathpath(s, "", PATH_REGULAR|PATH_READ, mp->fbuf, sizeof(mp->fbuf))) && !strchr(s, '/'))
+ {
+ strcpy(mp->fbuf, s);
+ sfprintf(mp->tmp, "%s/%s", MAGIC_DIR, mp->fbuf);
+ if (!(s = sfstruse(mp->tmp)))
+ goto nospace;
+ if (!(t = pathpath(s, "", PATH_REGULAR|PATH_READ, mp->fbuf, sizeof(mp->fbuf))))
+ goto next;
+ }
+ if (!(fp = sfopen(NiL, t, "r")))
+ goto next;
+ }
+ else
+ {
+ if (mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 3, "%s: cannot open magic file", s);
+ return -1;
+ }
+ }
+ found = 1;
+ n = load(mp, s, fp);
+ sfclose(fp);
+ if (n && !list)
+ return -1;
+ next:
+ if (!e)
+ break;
+ s = e + 1;
+ }
+ if (!found)
+ {
+ if (mp->flags & MAGIC_VERBOSE)
+ {
+ if (mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 2, "cannot find magic file");
+ }
+ return -1;
+ }
+ return 0;
+ nospace:
+ if (mp->disc->errorf)
+ (*mp->disc->errorf)(mp, mp->disc, 3, "out of space");
+ return -1;
+}
+
+/*
+ * open a magic session
+ */
+
+Magic_t*
+magicopen(Magicdisc_t* disc)
+{
+ register Magic_t* mp;
+ register int i;
+ register int n;
+ register int f;
+ register int c;
+ register Vmalloc_t* vm;
+ unsigned char* map[CC_MAPS + 1];
+
+ if (!(vm = vmopen(Vmdcheap, Vmbest, 0)))
+ return 0;
+ if (!(mp = vmnewof(vm, 0, Magic_t, 1, 0)))
+ {
+ vmclose(vm);
+ return 0;
+ }
+ mp->id = lib;
+ mp->disc = disc;
+ mp->vm = vm;
+ mp->flags = disc->flags;
+ mp->redisc.re_version = REG_VERSION;
+ mp->redisc.re_flags = REG_NOFREE;
+ mp->redisc.re_errorf = (regerror_t)disc->errorf;
+ mp->redisc.re_resizef = (regresize_t)vmgetmem;
+ mp->redisc.re_resizehandle = (void*)mp->vm;
+ mp->dtdisc.key = offsetof(Info_t, name);
+ mp->dtdisc.link = offsetof(Info_t, link);
+ if (!(mp->tmp = sfstropen()) || !(mp->infotab = dtnew(mp->vm, &mp->dtdisc, Dtoset)))
+ goto bad;
+ for (n = 0; n < elementsof(info); n++)
+ dtinsert(mp->infotab, &info[n]);
+ for (i = 0; i < CC_MAPS; i++)
+ map[i] = ccmap(i, CC_ASCII);
+ mp->x2n = ccmap(CC_ALIEN, CC_NATIVE);
+ for (n = 0; n <= UCHAR_MAX; n++)
+ {
+ f = 0;
+ i = CC_MAPS;
+ while (--i >= 0)
+ {
+ c = ccmapchr(map[i], n);
+ f = (f << CC_BIT) | CCTYPE(c);
+ }
+ mp->cctype[n] = f;
+ }
+ return mp;
+ bad:
+ magicclose(mp);
+ return 0;
+}
+
+/*
+ * close a magicopen() session
+ */
+
+int
+magicclose(register Magic_t* mp)
+{
+ if (!mp)
+ return -1;
+ if (mp->tmp)
+ sfstrclose(mp->tmp);
+ if (mp->vm)
+ vmclose(mp->vm);
+ return 0;
+}
+
+/*
+ * return the magic string for file with optional stat info st
+ */
+
+char*
+magictype(register Magic_t* mp, Sfio_t* fp, const char* file, register struct stat* st)
+{
+ off_t off;
+ char* s;
+
+ mp->flags = mp->disc->flags;
+ mp->mime = 0;
+ if (!st)
+ s = T("cannot stat");
+ else
+ {
+ if (mp->fp = fp)
+ off = sfseek(mp->fp, (off_t)0, SEEK_CUR);
+ s = type(mp, file, st, mp->tbuf, &mp->tbuf[sizeof(mp->tbuf)-1]);
+ if (mp->fp)
+ sfseek(mp->fp, off, SEEK_SET);
+ if (!(mp->flags & (MAGIC_MIME|MAGIC_ALL)))
+ {
+ if (S_ISREG(st->st_mode) && (st->st_size > 0) && (st->st_size < 128))
+ sfprintf(mp->tmp, "%s ", T("short"));
+ sfprintf(mp->tmp, "%s", s);
+ if (!mp->fp && (st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)))
+ sfprintf(mp->tmp, ", %s", S_ISDIR(st->st_mode) ? T("searchable") : T("executable"));
+ if (st->st_mode & S_ISUID)
+ sfprintf(mp->tmp, ", setuid=%s", fmtuid(st->st_uid));
+ if (st->st_mode & S_ISGID)
+ sfprintf(mp->tmp, ", setgid=%s", fmtgid(st->st_gid));
+ if (st->st_mode & S_ISVTX)
+ sfprintf(mp->tmp, ", sticky");
+ if (!(s = sfstruse(mp->tmp)))
+ s = T("out of space");
+ }
+ }
+ if (mp->flags & MAGIC_MIME)
+ s = mp->mime;
+ if (!s)
+ s = T("error");
+ return s;
+}
+
+/*
+ * list the magic table in mp on sp
+ */
+
+int
+magiclist(register Magic_t* mp, register Sfio_t* sp)
+{
+ register Entry_t* ep = mp->magic;
+ register Entry_t* rp = 0;
+
+ mp->flags = mp->disc->flags;
+ sfprintf(sp, "cont\toffset\ttype\top\tmask\tvalue\tmime\tdesc\n");
+ while (ep)
+ {
+ sfprintf(sp, "%c %c\t", ep->cont, ep->nest);
+ if (ep->expr)
+ sfprintf(sp, "%s", ep->expr);
+ else
+ sfprintf(sp, "%ld", ep->offset);
+ sfprintf(sp, "\t%s%c\t%c\t%lo\t", ep->swap == (char)~3 ? "L" : ep->swap == (char)~0 ? "B" : "", ep->type, ep->op, ep->mask);
+ switch (ep->type)
+ {
+ case 'm':
+ case 's':
+ sfputr(sp, fmtesc(ep->value.str), -1);
+ break;
+ case 'V':
+ switch (ep->op)
+ {
+ case 'l':
+ sfprintf(sp, "loop(%d,%d,%d,%d)", ep->value.loop->start, ep->value.loop->size, ep->value.loop->count, ep->value.loop->offset);
+ break;
+ case 'v':
+ sfprintf(sp, "vcodex()");
+ break;
+ default:
+ sfprintf(sp, "%p", ep->value.str);
+ break;
+ }
+ break;
+ default:
+ sfprintf(sp, "%lo", ep->value.num);
+ break;
+ }
+ sfprintf(sp, "\t%s\t%s\n", ep->mime ? ep->mime : "", fmtesc(ep->desc));
+ if (ep->cont == '$' && !ep->value.lab->mask)
+ {
+ rp = ep;
+ ep = ep->value.lab;
+ }
+ else
+ {
+ if (ep->cont == ':')
+ {
+ ep = rp;
+ ep->value.lab->mask = 1;
+ }
+ ep = ep->next;
+ }
+ }
+ return 0;
+}
diff --git a/src/lib/libast/misc/magic.tab b/src/lib/libast/misc/magic.tab
new file mode 100644
index 0000000..00df074
--- /dev/null
+++ b/src/lib/libast/misc/magic.tab
@@ -0,0 +1,1721 @@
+#
+# @(#)magic (AT&T Research) 2011-11-02
+#
+# magic number database for file(1) and magic(3)
+#
+# the tab separated fields are:
+#
+# [op]offset type [mask]operator description mime
+#
+# + previous fields must match, current optional
+# & previous and current fields must match
+# { start nesting block
+# } end nesting block
+# s{ function declaration and call
+# } function return
+# s() function call
+#
+# offset byte offset for magic number test or (@offset) expr
+# or file meta-data from { atime blocks ctime fstype
+# gid mode mtime name nlink size uid }
+# type { byte short long quad date edit match }
+# mask optional &number before operator
+# operator comparison operator { < <= > >= != == (default) }
+# description file description for magic number match
+# mime optional mime type
+#
+# numeric values may be decimal, octal, or hex
+# the description string may have one printf format spec for the
+# matched magic number
+#
+
+0 short 070707 binary cpio archive application/pax
+0 string 070707 cpio archive application/pax
++76 edit %!PAX!C!\([^!]*\).*%\1% , compressed, version %s
++76 edit %!PAX!D!\([^!]*\).*%\1% , delta, version %s
++76 string DELTA!!! , delta, version 88
++76 match !(*!*) , [ %s ... ]
+0 string 070701 System V asc cpio archive application/pax
++110 string * , [ %s ... ]
+0 string 070702 System V aschk cpio archive application/pax
++110 string * , [ %s ... ]
+0 long 0177555 System III ar archive application/x-ar
+0 short 0177545 pdp11 ar archive application/x-ar
+0 long 0x04034b50 zip archive application/zip
++2 byte >0 , version %d
+&3 byte * .%d
+0 long 0x223e9f78 ms outlook tnef archive application/pax
+0 string MSCF ms cabinet archive application/pax
+&4 long 0
++25 byte * , version %d
++24 byte * .%d
+0 string \x52\x61\x72\x21\x1a\x07 rar archive application/pax
+0 long 0x0d010b05 make object application/x-nmake
+o{
++4 byte <037 (version %ld)
++4 edit %.*\(..\)/\(..\)/\(..\).*%19\3-\1-\2% , version %s
++4 edit %.*\(....-..-..\).*%\1% , version %s
+}
+0 long 0177535 make object, old magic application/x-nmake
+o()
+0 long 0x090f0301 jmake project db application/x-jmake
++4 string * , version %s
+0 long 0x0b130800 ksh binary script application/ksh
++4 byte * , version %ld
+0 string vkda delta application/x-vdelta
++4 byte >0 (version %ld)
+0 long 0x03040200 cql db application/x-cql
++4 byte * , version %d
++5 byte * .%d
++6 string * , %s
+0 string !<cdb-
++6 edit %\([^-]*\)-\([0-9.]*\)>.*%cql db, \1 format, version \2% %s application/x-cql
+0 long 0x08091800
++32 string * %s application/x-cql
++0 byte * hashed index
++4 long >0 , %d record%s
++8 long >0 , %d max
++12 date >0 , stamp %s
+0 string \1S\1B\1C\1S sbcs delta application/x-sbcs
+0 long 0100554 apl workspace application/x-apl
+0 short 017037 packed data application/zip
+0 string <ar> System V 1.0 ar archive application/x-ar
+0 string !<arch>\n/ ar library application/x-ar
++68 long 0x020b0619 , hp s800 relocatable
++68 long 0x02100619 , hp pa-risc 1.1 relocatable
++68 long 0x02110619 , hp pa-risc 1.2 relocatable
++68 long 0x02140619 , hp pa-risc 2.0 relocatable
+0 string !<arch>\n__.SYMDEF ar library, ranlib application/x-ar
+0 string !<arch>\n__________E ar library, hybrid application/x-ar
+0 string !<arch>\n_______[0-9_][0-9_][0-9_]E[BL]E[BL]_ ar library, hybrid application/x-ar
+o{
++22 byte 'X' , out of date
++20 byte 'U' , ucode members
++21 byte >='A' , %c-endian members
++19 byte >='A' , %c-endian hash
+}
+0 string !<arch>\n________64E ar library, 64 bit hybrid application/x-ar
+o()
+0 string !<arch> ar archive application/x-ar
+0 string <aiaff>\n aix ar library application/x-ar
+0 string <bigaf>\n aix ar library, big application/x-ar
+20 short 0xa7dc zoo archive application/x-zoo
+&22 short 0xfdc4
++32 byte * , version %ld
++33 byte * .%ld
+
+0 string \326\303\304\330 vcodex data application/x-vczip
++5 void vcodex()
+
+0 long 0x080456
+{
+85 byte <10 sun
++85 byte <3 m680%d0
++85 byte 3 sparc
++85 byte >3 *unknown*
+}
++85 byte * core dump x-system/core
++128 string * from `%s'
++132 string * from `%s'
+0 long 050632 core dump x-system/core
+0 long &0xfff00000==0xe8c00000 Alliant core dump
++160 string * from `%s'
+
+0 long 0x02100106 hp pa-risc 1.1 object x-system/obj
+0 long 0x02100107 hp pa-risc 1.1 executable x-system/exe
+o{
++(@144) long 0x054ef630 , dynamically linked
++96 long >0 , not stripped
+}
+0 long 0x02100108 hp pa-risc 1.1 executable, shared x-system/exe
+o()
+0 long 0x0210010b hp pa-risc 1.1 executable, demand-load x-system/exe
+o()
+0 long 0x0210010e hp pa-risc 1.1 shared library x-system/dll
+o()
+0 long 0x0210010d hp pa-risc 1.1 shared library x-system/dll
+s{
++96 long >0 , not stripped
+}
+
+0 long 0x02140106 hp pa-risc 2.0 object x-system/obj
+0 long 0x02140107 hp pa-risc 2.0 executable x-system/exe
+o()
+0 long 0x02140108 hp pa-risc 2.0 executable, shared x-system/exe
+o()
+0 long 0x0214010b hp pa-risc 2.0 executable, demand-load x-system/exe
+o()
+0 long 0x0214010e hp pa-risc 2.0 shared library x-system/dll
+o()
+0 long 0x0214010d hp pa-risc 2.0 shared library x-system/dll
+s()
+
+0 long 0x020b0106 hp s800 object x-system/obj
+0 long 0x020b0107 hp s800 executable x-system/exe
+o()
+0 long 0x020b0108 hp s800 executable, shared x-system/exe
+o()
+0 long 0x020b010b hp s800 executable, demand-load x-system/exe
+o()
+0 long 0x020b010d hp s800 shared library x-system/dll
+s()
+0 long 0x020b010e hp s800 shared library x-system/dll
+s()
+
+0 long 0x02080108 hp s500 executable, pure x-system/exe
+o{
++16 long >0 , version %ld
+}
+0 long 0x02080107 hp s500 executable x-system/exe
+o()
+0 long 0x02080106 hp s500 executable, relocatable x-system/obj
+o()
+0 long 0x020c0108 hp s200 executable, pure x-system/exe
+o{
++36 long >0 , not stripped
++4 short >0 , version %ld
+}
+0 long 0x020c0107 hp s200 executable x-system/exe
+o()
+0 long 0x020c010b hp s200 executable, demand-load x-system/exe
+o()
+0 long 0x020a0108 hp s200 2.x executable, pure x-system/exe
+o()
+0 long 0x020a0107 hp s200 2.x executable x-system/exe
+o()
+0 long 0x020c0106 hp s200 executable, relocatable x-system/exe
++4 short >0 , version %ld
+0 long 0x0208ff65 hp s500 old archive application/x-ar
+0 long 0x020cff65 hp s200 old archive application/x-ar
+0 long 0x020aff65 hp s200 old archive application/x-ar
+0 short 0x8000 hp lif file
+0 long 0x020c010c hp compiled Lisp
+0 long 0x4da7eee8 hp windows font
++8 byte >0 , version %ld
+
+0 string Joy!peffpwpc PowerPC executable
+0 short 0x01df PowerPC object x-system/obj
+&3 byte 3
+
+0 long 0x50900107 pyramid 90x executable x-system/exe
+o{
++0 long &0x7=0x3 , paged
++0 long &0x8 , pure
++16 long >0 , not stripped
+}
+0 long 0x50900108 pyramid 90x object x-system/obj
+0 long 0x5090010b pyramid 90x executable x-system/exe
+o()
+
+0 long 0x000001EB plan9 386 executable x-system/exe
+0 long 0x00000107 plan9 68020 executable x-system/exe
+&mode long &0111!=0
+0 long 0x00000197 plan9 hobbit executable x-system/exe
+0 long 0x00000407 plan9 mips executable x-system/exe
+0 long 0x000002AB plan9 sparc executable x-system/exe
+
+0 long 0x7E004501 plan9 386 object x-system/obj
+0 long 0x4D013201 plan9 68020 object x-system/obj
+0 long 0x430D013C plan9 hobbit object x-system/obj
+0 long 0x3A11013C plan9 mips object x-system/obj
+0 long 0x7410013C plan9 sparc object x-system/obj
+
+0 long &0x0030FFFF==0x00000064 linux 386
+&0 long &0x000F0000>0
++20 long &0xEFDFFFFF==0 executable x-system/exe
++20 long &0xEFDFFFFF!=0 shared library x-system/dll
++0 long 0x01080064 , pure
++0 long 0x010B0064 , paged
++0 long 0x00CC0064 , paged, no page 0
+{
+20 long &0xEFDFFFFF==0
+&16 long >0 , not stripped
+}
+216 long 0421 linux core dump x-system/core
+
+0 long 0x00cc0064 linux 386 kernel code x-system/exe
++size long <600000 , compressed
+510 short 0xaa55 linux 386 kernel image x-system/exe
++size long <600000 , compressed
+0 long 0x03010410 minix 386 executable x-system/exe
+0 long 0x000186a3 minix 386 object x-system/obj
+
+0 long 0314 bsd 386 executable, paged, no page 0 x-system/exe
++16 long >0 , not stripped
+0 long 0407 bsd 386 executable x-system/exe
+&mode long &0111!=0
++16 long >0 , not stripped
+0 long 0407 bsd-or-linux 386 object x-system/obj
+0 long 0410 bsd 386 executable, pure x-system/exe
++16 long >0 , not stripped
+0 long 0413 bsd 386 executable, paged x-system/exe
++16 long >0 , not stripped
+
+0 belong 0xcafebabe java object x-java/obj
+&4 belong >30
++6 beshort * version %d
++6 beshort * .%d
+
+a{
++4 long &0x00ffffff=1 vax
++4 long &0x00ffffff=2 romp
++4 long &0x00ffffff=3 architecture=%ld
++4 long &0x00ffffff=4 ns32032
++4 long &0x00ffffff=5 ns32332
++4 long &0x00ffffff=6 m68k
++4 long &0x00ffffff=7 i386
++4 long &0x00ffffff=8 mips
++4 long &0x00ffffff=9 ns32532
++4 long &0x00ffffff=10 architecture=%ld
++4 long &0x00ffffff=11 hp pa-risc
++4 long &0x00ffffff=12 acorn
++4 long &0x00ffffff=13 m88k
++4 long &0x00ffffff=14 sparc
++4 long &0x00ffffff=15 i860-big
++4 long &0x00ffffff=16 i860
++4 long &0x00ffffff=17 rs6000
++4 long &0x00ffffff=18 powerpc
++4 long &0x00ffffff>=19 architecture=%ld
++4 long &0x01000000!=0 \b-64
+}
+
+0 belong 0xcafebabe universal binary [
++4 belong loop(a,4,20)
++4 belong * ]
++010000 void magic()
++0 void * ...
+
+0 long &0xfffffffe=0xfeedface mach-o
++0 long &0x00000001!=0 64-bit
+a()
++12 long <=0 filetype=%ld
+{
+12 long 1 relocatable x-system/obj
+&mode long &0111!=0
+}
+{
+12 long 1 object x-system/obj
+&mode long &0111==0
+}
++12 long 2 executable x-system/exe
++12 long 3 fixed vm shared library x-system/dll
++12 long 4 core x-system/core
++12 long 5 preload executable x-system/exe
++12 long 6 shared library x-system/dll
++12 long 7 dynamic link editor x-system/exe
++12 long 8 bundle x-system/dll
++12 long >=9 filetype=%ld
+
+2 short 0407
+m{
+1 byte <10 sun
++1 byte <3 m680%d0
++1 byte 3 sparc
++1 byte >3 *unknown*
+}
++0 byte !=0xffffffff object x-system/obj
+2 short 0410
+m()
++0 byte !=0xffffffff executable, pure x-system/exe
+o{
+{
+0 byte &0200
+&20 long >=0x2000 , dynamically linked
+}
++16 long >0 , not stripped
+}
+2 short 0413
+m()
+{
+0 byte &0200
+&20 long <0x2000 shared library x-system/dll
+}
++0 byte !=0xffffffff executable, paged x-system/exe
+o()
+
+0 short 0420 Alliant virtual executable x-system/exe
++16 long >0 , not stripped
+o{
++2 short &0x0001 , 68020 only
++2 short &0x0002 , vector instructions
++2 short &0x0008 , IP only
++2 short &0x0010 , CE only
++2 short &0x0020 , common library
++2 short &0x0200 , no complex
+}
+0 short 0421 Alliant object x-system/obj
++16 long 0 , no symbols
+o()
+
+0 short 0x01df aix RISC
+{
+18 short &0x2002==0x0002 executable x-system/exe
++18 short &0x1000 , dynamically linked
++12 long >0 , not stripped
+}
++18 short &0x2002==0 object x-system/obj
++18 short &0x2000 shared library x-system/dll
+0 short 0x0103 aix RT executable x-system/exe
++2 byte 0x50 , pure
++28 long >0 , not stripped
++6 short >0 , version %ld
+0 short 0x0104 aix shared library x-system/dll
+0 short 0x0105 aix ctab data
+0 short 0xfe04 aix structured file
+
+0 short 0401 unix-rt ldp
+0 short 0405 old overlay
+0 short 0437 pdp11 kernel overlay
+
+0 short 0407 System III executable x-system/exe
+o{
++16 long >0 , not stripped
++2 short >0 , version %ld
+}
+0 short 0410 System III executable, pure x-system/exe
+o()
+0 short 0411 System III executable, separate I&D x-system/exe
+o()
+
+0 long 0407 vax object x-system/obj
+0 long 0410 vax executable, pure x-system/exe
+o{
++16 long >0 , not stripped
+}
+0 long 0413 vax executable, paged x-system/exe
+o()
+
+0 short 0413 vax executable, pure x-system/exe
++8 short >0 , not stripped
++15 byte >0 , version %ld
+
+0 short 0570 vax
+o{
+{
+16 short >0 executable x-system/exe
++12 long >0 , not stripped
++22 short >0 , version %ld
+}
++16 short 0 object x-system/obj
+}
+0 short 0575 vax
+o()
+0 short 0502 basic-16
+o()
+0 short 0503 basic-16 (TV)
+o()
+0 short 0510 x86
+o()
+0 short 0511 x86 (TV)
+o()
+0 short 0550 3b20
+o()
+0 short 0551 3b20d (TV)
+o()
+
+0 long 0x464c457f elf
+&4 byte <2
+&5 byte 1
+o{
+{
++18 short 0 machine=UNKNOWN
++18 short 1 3b
++18 short 2 sparc
++18 short 3 i386
++18 short 4 m68k
++18 short 5 m88k
++18 short 6 i486
++18 short 7 i860
+{
+18 short 8
+{
+36 long &0xf00000f0==0x00000000
++4 byte 1 mips2
++4 byte 2 mips4
+}
++36 long &0xf0000000==0x10000000 mips2
++36 long &0xf0000000==0x20000000 mips3
++36 long &0xf0000000==0x30000000 mips4
++36 long &0xf00000f0==0x00000040 mips4
++36 long &0xf0000000==0x40000000 mips5
++36 long &0xf0000000==0x50000000 mips6
++36 long &0xf0000000==0x60000000 mips7
++36 long &0xf0000000==0x70000000 mips8
++36 long &0xf0000000==0x80000000 mips9
+}
++18 short 9 amdahl
++18 short 10 mips_le
++18 short 11 rs6000
++18 short 15 pa
++18 short 16 n-cube
++18 short 17 fujitsu500
++18 short 18 sparc32+
++18 short 20 powerpc
++18 short 21 powerpc-64
++18 short 22 s390
++18 short 23 cell-BE
++18 short 36 nec-v800
++18 short 37 fujitsu-fr20
++18 short 38 trw-rh32
++18 short 39 fujitsu-mma
++18 short 40 arm
++18 short 41 alpha
++18 short 42 hitachi-sh
++18 short 43 sparc64-v9
++18 short 44 siemens-tricore
++18 short 45 argonaut
++18 short 46 hitachi-h8/300
++18 short 47 hitachi-h8/300h
++18 short 48 hitachi-h8s
++18 short 49 hitachi-h8/500
++18 short 50 itanium
++18 short 51 mips-x
++18 short 52 motorola-coldfire
++18 short 53 motorola-m68hc12
++18 short 54 fujutsu-mma
++18 short 55 siemens-pcp
++18 short 56 sony-ncpu
++18 short 57 denso-ndr1
++18 short 58 motorola-startcore
++18 short 59 toyota-me16
++18 short 60 stm-st100
++18 short 61 alc-tinyj
++18 short 62 x86-64
++18 short 63 sony-dsp
++18 short 66 siemens-fx66
++18 short 67 stm-st9-16
++18 short 68 stm-st7-8
++18 short 69 motorola-mc68hc16
++18 short 70 motorola-mc68hc11
++18 short 71 motorola-mc68hc08
++18 short 72 motorola-mc68hc05
++18 short 73 sgi-svx
++18 short 74 stm-st19-8
++18 short 75 vax
++18 short 76 axis, 32-bit
++18 short 77 infineon-javelin-32
++18 short 78 element-14-firepath-64
++18 short 79 lsi-zsp-16
++18 short 80 knuth-mmix-64
++18 short 81 harvard-huany
++18 short 82 sitera-prism
++18 short 83 amtel-avr-8
++18 short 84 fujitsu-fr30
++18 short 85 mitsubishi-d10v
++18 short 86 mitsubishi-d30v
++18 short 87 nec-v850
++18 short 88 matsushita-m32r
++18 short 89 matsushita-mn10300
++18 short 90 matsushita-mn10200
++18 short 91 picojava
++18 short 92 openrisc-32
++18 short 93 arc-tangent-a5
++18 short 94 tensilica-xtensa
++18 short 0x9026 alpha
++18 short 0xa390 s390
+|18 short * machine=0x%04lX
+}
++16 short 0 type=UNKNOWN
++16 short 1 object x-system/obj
++16 short 2 executable x-system/exe
++16 short 3 shared library x-system/dll
+{
+16 short 4 core dump x-system/core
++(@28+@42H*@44H+104) string * from `%s'
+}
++16 short >4 type=%d
++4 byte 0 , 16-bit
++4 byte 1 , 32-bit
++5 byte 1 , little-endian
+{
+18 short ==8
+&36 long &0x000000f0==0x00000000
+&4 byte 1 , old
+}
+{
+18 short 1
++36 long 1 , mau
+}
++20 long >1 , version %ld
+{
+16 short 2
+&(@28+4*32) long 2 , dynamically linked
+}
+}
+
+0 long 0x7f454c46 elf
+&4 byte 1
+&5 byte 2
+o()
+
+0 long 0x464c457f elf
+&4 byte 2
+&5 byte 1
+o{
+{
++18 short 0 machine=UNKNOWN
++18 short 1 3b
++18 short 2 sparc
++18 short 3 i386
++18 short 4 m68k
++18 short 5 m88k
++18 short 6 i486
++18 short 7 i860
+{
+18 short 8
+{
+48 long &0xf00000f0==0x00000000
++4 byte 1 mips2
++4 byte 2 mips4
+}
++48 long &0xf0000000==0x10000000 mips2
++48 long &0xf0000000==0x20000000 mips3
++48 long &0xf0000000==0x30000000 mips4
++48 long &0xf00000f0==0x00000040 mips4
++48 long &0xf0000000==0x40000000 mips5
++48 long &0xf0000000==0x50000000 mips6
++48 long &0xf0000000==0x60000000 mips7
++48 long &0xf0000000==0x70000000 mips8
++48 long &0xf0000000==0x80000000 mips9
+}
++18 short 9 amdahl
++18 short 10 mips_le
++18 short 11 rs6000
++18 short 15 pa
++18 short 16 n-cube
++18 short 17 fujitsu500
++18 short 18 sparc32+
++18 short 20 powerpc
++18 short 21 powerpc-64
++18 short 22 s390
++18 short 23 cell-BE
++18 short 36 nec-v800
++18 short 37 fujitsu-fr20
++18 short 38 trw-rh32
++18 short 39 fujitsu-mma
++18 short 40 arm
++18 short 41 alpha
++18 short 42 hitachi-sh
++18 short 43 sparc64-v9
++18 short 44 siemens-tricore
++18 short 45 argonaut
++18 short 46 hitachi-h8/300
++18 short 47 hitachi-h8/300h
++18 short 48 hitachi-h8s
++18 short 49 hitachi-h8/500
++18 short 50 itanium
++18 short 51 mips-x
++18 short 52 motorola-coldfire
++18 short 53 motorola-m68hc12
++18 short 54 fujutsu-mma
++18 short 55 siemens-pcp
++18 short 56 sony-ncpu
++18 short 57 denso-ndr1
++18 short 58 motorola-startcore
++18 short 59 toyota-me16
++18 short 60 stm-st100
++18 short 61 alc-tinyj
++18 short 62 x86-64
++18 short 63 sony-dsp
++18 short 66 siemens-fx66
++18 short 67 stm-st9-16
++18 short 68 stm-st7-8
++18 short 69 motorola-mc68hc16
++18 short 70 motorola-mc68hc11
++18 short 71 motorola-mc68hc08
++18 short 72 motorola-mc68hc05
++18 short 73 sgi-svx
++18 short 74 stm-st19-8
++18 short 75 vax
++18 short 76 axis-32
++18 short 77 infineon-javelin-32
++18 short 78 element-14-firepath-64
++18 short 79 lsi-zsp-16
++18 short 80 knuth-mmix-64
++18 short 81 harvard-huany
++18 short 82 sitera-prism
++18 short 83 amtel-avr-8
++18 short 84 fujitsu-fr30
++18 short 85 mitsubishi-d10v
++18 short 86 mitsubishi-d30v
++18 short 87 nec-v850
++18 short 88 matsushita-m32r
++18 short 89 matsushita-mn10300
++18 short 90 matsushita-mn10200
++18 short 91 picojava
++18 short 92 openrisc-32
++18 short 93 arc-tangent-a5
++18 short 94 tensilica-xtensa
++18 short 0x9026 alpha
++18 short 0xa390 s390
+|18 short * machine=0x%04lX
+}
++16 short 0 type=UNKNOWN
++16 short 1 object x-system/obj
++16 short 2 executable x-system/exe
++16 short 3 shared library x-system/dll
+{
+16 short 4 core dump x-system/core
++(@28+@42H*@44H+104) string * from `%s'
+}
++16 short >4 type=%ld
++4 byte 2 , 64-bit
++5 byte 1 , little-endian
++20 long >1 , version %ld
+{
+16 short 2
++(@32Q+3*56) long 2 , dynamically linked
++(@32Q+4*56) long 2 , dynamically linked
+}
+}
+
+0 long 0x7f454c46 elf
+&4 byte 2
+&5 byte 2
+o()
+
+0 lelong 000000407 netbsd little-endian object x-system/obj
++16 lelong 0 , stripped
+0 belong 000000407 netbsd big-endian object x-system/obj
++16 belong 0 , stripped
+
+0 belong&0377777777 041400413 netbsd i386
+d{
+0 byte &0x80
++20 lelong <4096 shared library x-system/dll
++20 lelong >=4096 executable, dynamically linked x-system/exe
+}
++0 byte ^0x80 executable x-system/exe
++16 lelong 0 , stripped
+0 belong&0377777777 041400410 netbsd i386 pure
+p{
++0 byte &0x80 executable, dynamically linked x-system/exe
++0 byte ^0x80 executable x-system/exe
++16 lelong 0 , stripped
+}
+0 belong&0377777777 041400407 netbsd i386
+n{
++0 byte &0x80 executable, dynamically linked, impure x-system/exe
+{
+0 byte ^0x80
++0 byte &0x40 position independent
++20 lelong !0 executable x-system/exe
++20 lelong =0 object x-system/obj
+}
++16 lelong 0 , stripped
+}
+0 belong&0377777777 041400507 netbsd i386 core
+c{
++12 string * from '%s' x-system/core
+}
+
+0 belong&0377777777 042000413 netbsd m68k4k
+d()
+0 belong&0377777777 042000410 netbsd m68k4k pure
+p()
+0 belong&0377777777 042000407 netbsd m68k4k
+n()
+0 belong&0377777777 042000507 netbsd m68k4k core
+c()
+
+0 belong&0377777777 042200413 netbsd ns32532
+d()
+0 belong&0377777777 042200410 netbsd ns32532 pure
+p()
+0 belong&0377777777 042200407 netbsd ns32532
+n()
+0 belong&0377777777 042200507 netbsd ns32532 core
+c()
+
+0 belong&0377777777 042600413 netbsd pmax
+d()
+0 belong&0377777777 042600410 netbsd pmax pure
+p()
+0 belong&0377777777 042600407 netbsd pmax
+n()
+0 belong&0377777777 042600507 netbsd pmax core
+c()
+
+0 belong&0377777777 043000413 netbsd vax 1k
+d()
+0 belong&0377777777 043000410 netbsd vax 1k pure
+p()
+0 belong&0377777777 043000407 netbsd vax 1k
+n()
+0 belong&0377777777 043000507 netbsd vax 1k core
+c()
+
+0 belong&0377777777 045400413 netbsd vax 4k
+d()
+0 belong&0377777777 045400410 netbsd vax 4k pure
+p()
+0 belong&0377777777 045400407 netbsd vax 4k
+n()
+0 belong&0377777777 045400507 netbsd vax 4k core
+c()
+
+0 belong&0377777777 041600413 netbsd m68k
+d{
+0 byte &0x80
++20 belong <8192 shared library x-system/dll
++20 belong >=8192 executable, dynamically linked x-system/exe
+}
++0 byte ^0x80 executable x-system/exe
++16 belong 0 , stripped
+0 belong&0377777777 041600410 netbsd m68k pure
+p()
+0 belong&0377777777 041600407 netbsd m68k
+n()
+0 belong&0377777777 041600507 netbsd m68k core
+c()
+0 belong&0377777777 042400413 netbsd sparc
+d()
+
+0 belong&0377777777 042400410 netbsd sparc pure
+p()
+0 belong&0377777777 042400407 netbsd sparc
+n()
+0 belong&0377777777 042400507 netbsd sparc core
+c()
+
+0 belong&0377777777 043400413 netbsd mips
+d()
+0 belong&0377777777 043400410 netbsd mips pure
+p()
+0 belong&0377777777 043400407 netbsd mips
+n()
+0 belong&0377777777 043400507 netbsd mips core
+c()
+
+0 belong&0377777777 043600413 netbsd arm32
+d()
+0 belong&0377777777 043600410 netbsd arm32 pure
+p()
+0 belong&0377777777 043600407 netbsd arm32
+n()
+0 belong&0377777777 043600507 netbsd arm32 core
+c()
+
+0 lelong 0x00070185 ECOFF netbsd alpha binary
++10 leshort 0x0000 , stripped x-system/obj
+0 belong&0377777777 043200507 netbsd alpha core
+c()
+
+0 short 0560 3b
+{
+16 short >0 executable x-system/exe
++12 long >0 , not stripped
+}
++16 short 0 object x-system/obj
++18 short &010000 , paging 3b2/300
++18 short &020000 , 32100
++18 short &040000 , mau
+{
+16 short >0
++20 short 0443 , shared library x-system/dll
++20 short 0410 , swapped
++20 short 0413 , paged
++22 short >0 , version %ld
+}
+0 short 0561 3b (TV)
+{
+16 short >0 executable x-system/exe
++12 long >0 , not stripped
+}
++16 short 0 object x-system/obj
++18 short &020000 , 32100 required
++18 short &040000 , mau hardware required
+
+0 short 0512 pc 286 small model (COFF)
+o{
+{
+16 short >0 executable x-system/exe
++12 long >0 , not stripped
+}
++16 short 0 object x-system/obj
+{
+16 short >0
+&22 short >0 , version %ld
+}
+}
+0 short 0522 pc 286 large model (COFF)
+o()
+
+0 short 0514 pc 386
+o{
+{
+16 short >0 executable x-system/exe
++12 long >0 , not stripped
+}
++16 short 0 object x-system/obj
+{
+16 short >0
+&22 short >0 , version %ld
+}
++0 short !=0x8664 , 32 bit
++0 short 0x8664 , 64 bit
+}
+0 short 0x8664 pc 386
+o()
+0 short 0524 pc 386
+o()
+0 short 0604 pc alpha
+o()
+
+0 short 0520 m68k
+{
+16 short >0 executable x-system/exe
++12 long >0 , not stripped
+}
++16 short 0 object x-system/obj
+{
+16 short >0
++20 short 0410 , pure
++20 short 0413 , paged
++22 short >0 , version %ld
+}
+
+0 short 0521 m68k executable, shared x-system/exe
+o{
++12 long >0 , not stripped
+}
+0 short 0522 m68k executable, shared, paged x-system/exe
+o()
+
+0 long 0x02c5e2c4 mvs OpenEdition object x-system/obj
+&4 long 0x40404040
+0 long 0xc9c5e6d7 mvs OpenEdition executable x-system/exe
+&4 long 0xd3d4c840
+
+0 short 0530 u370 5.2/5.0
+o{
+{
+20 long !=0440
+&18 short &01 executable x-system/exe
++0 short &01==0 , pure
++12 long >0 , not stripped
+}
++20 long 0440 shared library x-system/dll
++18 short &01==0 object x-system/obj
++18 byte &0x40 , BIG
++49 byte &0xf!=0 , pre-XA
+{
+18 short &01
++24 long >0 , version %ld
+}
+}
+0 short 0531 amdahl 5.2
+o()
+0 short 0534 amdahl 5.2
+o()
+0 short 0535 u370 5.2
+o()
+
+0 short 0700 ncr tower32
+o{
++18 short &0040000 68000
++18 short &0040000==0 68020
++18 short &0020000 \b+68881
+{
+18 short &0000001==0 object x-system/obj
++22 short >0 , version %ld
+}
+{
+18 short &0001 executable x-system/exe
++20 short 0413 , paged
++20 short 0443 shared library x-system/dll
++20 short 0410 , pure, swapped
++20 short 0407 , swapped
++12 long >0 , not stripped
+}
+}
+0 short 0720 ncr towe32r/600
+o()
+0 short 0740 ncr tower32/800
+o()
+0 short 0610 ncr tower/XP rel 2
+o()
+0 short 0615 ncr tower/XP rel 2
+o()
+0 short 0620 ncr tower/XP rel 3
+o()
+0 short 0625 ncr tower/XP rel 3
+o()
+0 short 0630 ncr tower32/600/400
+o()
+0 short 0640 ncr tower32/800
++18 short &00040000 compatible
+o()
+0 short 0645 ncr tower32/800 68010
+o()
+
+0 short 0457 DG MV pure executable x-system/exe
++40 long >0 , not stripped
++2 short >0 , version %ld
+0 short 0460 DG MV object x-system/obj
++2 short >0 , version %ld
+0 short 0541 m88k pure executable x-system/exe
++12 long >0 , not stripped
++22 short >0 , version %ld
+0 short 0555 m88k object x-system/obj
++22 short >0 , version %ld
+
+0 short &0xfffd==0x0160 mips
+{
+18 short &02 executable x-system/exe
++20 short 0410 , pure
++20 short 0413 , paged
++20 short 0443 , shared library x-system/dll
++8 long !=0 , not stripped
+}
++18 short &02==0 object x-system/obj
+o{
++0 short &0x2 , little-endian
++22 byte * , version %ld
++23 byte * .%ld
+}
+0 short &0xfffd==0x180 mips ucode x-system/obj
+o()
+0 long 0xdeadadb0 mips core dump x-system/core
+f{
++4 long 1
+&16 string * from `%s'
++0 long &0xff==0xb0 , 32-bit, old
++0 long &0xff==0xbb , 32-bit
++0 long &0xff==0x40 , 64-bit
+}
+0 long 0xbabec0bb mips core dump x-system/core
+f()
+0 long 0xdeadad40 mips core dump x-system/core
+f()
+
+0 short 0603 alpha
+{
+22 short &02
+&22 short &030000!=020000 executable x-system/exe
++24 short 0410 , pure
++24 short 0413 , paged
++22 short &020000 , dynamically linked
++16 long !=0 , not stripped
+}
++22 short &030000==020000 shared library x-system/dll
+{
+22 short &030002==0
++24 short 0407 object x-system/obj
+}
++27 byte * , version %ld
++26 byte * .%ld
+
+0 short 0432 compiled terminfo entry
+0 short 0433 curses screen image
+0 short 0434 curses screen image
+
+0 long 0x14031008 tcpdump cons headers application/x-tcpdump
+v{
++4 long >0 , version %d
+&8 long * .%d
+}
+0 long 0x14031004 tcpdump cons data application/x-tcpdump
+v()
+
+257 string ustar pax archive application/pax
+&156 match [gx]
+o{
+&99 byte 0
+&100 match +([ 0-7])?
+}
+
+257 string ustar\ \ gnu tar archive application/pax
+o{
+&99 byte 0
+&100 match +([ 0-7])?
++0 match ???* , [ %s ... ]
+}
+
+257 string ustar tar archive application/pax
+o()
+
+99 byte 0 old tar archive application/pax
+o()
+
+0 string \301\304\331\100\323\311\302\331\306 ca librarian archive application/pax
+
+0 match <[hH][tT][mM][lL]> html input text/html
+0 match <!?(--)[Dd][Oo][Cc][Tt][Yy][Pp][Ee] [Hh][Tt][Mm][Ll] html input text/html
+
+0 long 0x02f78301
++16 string TeX TeX dvi output application/x-dvi
+
+0 byte 0201 shell history application/sh
+&1 byte <07 version %d
+
+0 byte 1
+&1 byte 0150
+&2 match [0-9][0-9][0-9][0-9][0-9] sccs application/x-sccs
+
+0 short 0x5a4d
+o{
+&24 short 0x0040
+{
++(@60H) short 0x454c os/2 linear
++(@60H) short 0x454e os/2
++(@60H) short 0x4550 win32
++(@60H+4) short 0x014c 386
++(@60H+4) short 0x0150 powerpc
++(@60H+4) short 0x0162 mips
++(@60H+4) short 0x0166 mips, big endian?
++(@60H+4) short 0x0184 alpha
++(@60H+4) short 0x8664 386
+|(@60H+4) short * machine=0x%04lX
+}
++(@60H+22) short &0x2002==0x0002 executable x-system/exe
++(@60H+22) short &0x2000 shared library x-system/dll
++(@60H+22) short &0x0120==0 , 16 bit
++(@60H+22) short &0x0120==0x0100 , 32 bit
++(@60H+22) short &0x0120==0x0020 , 64 bit
++(@60H+92) short 0 , unknown subsystem
++(@60H+92) short 1 , native
++(@60H+92) short 2 , windows gui
++(@60H+92) short 5 , os2
++(@60H+92) short 7 , posix
++(@60H+92) short >7 , subsystem %d
++50 string PKWARE , self extracting zip
++36 string LHA's , self extracting lha
++233 string PKSFX2 , self extracting zip
+}
+
+0 short 0x5a4c
+o()
+
+0 long 0x4c000000
+&4 long 0x01140200 windows shortcut application/x-windows-lnk
+
+0 string PMCC windows GRP application/dos-grp
+369 string MICROSOFT windows PIF application/dos-pif
+0 long 0xffffffff dos device driver application/dos-drv
+&name match *.(SYS|sys)
+0 string LZ dos builtin
+0 byte 0xe9 dos executable, COM application/x-dos
+0 byte 0xeb dos executable, COM application/x-dos
+0 byte 0xf0 dos library application/x-ar
+0 byte 0x80 dos object, OMF application/dos-omf
+
+0 match x[ ]T[ ] ditroff application/x-ditroff
+&4 string * for %s
+0 string %! postscript input application/postscript
+{
+2 string PS-Adobe- , conforming
++11 match +([0-9]).+([0-9]) , version %s
+}
+0 string %PDF adobe acrobat file application/x-pdf
++5 match +([0-9]).+([0-9]) , version %s
+0 string @document( imagen input
+
+0 long 0x2e736e64 audio data audio/basic
+o{
++12 long 1 , 8-bit u-law
++12 long 2 , 8-bit linear pcm
++12 long 3 , 16-bit linear pcm
++12 long 4 , 24-bit linear pcm
++12 long 5 , 32-bit linear pcm
++12 long 6 , 32-bit floating point
++12 long 7 , 64-bit floating point
++12 long 23 , compressed (G.721 ADPCM)
++20 long =1 , mono
++20 long =2 , stereo
++20 short =3 , 3 channels
++20 short =4 , quad
++20 short >4 , %d channel%s
++16 long * , %d hz
+}
+0 long 0x0064732E dec audio data audio/x-dec
+o()
+
+0 string Creative\ Voice\ File soundblaster audio data audio/x-soundblaster
+0 long 0x4e54524b multitrack audio data file audio/x-multitrack
++4 long * , version %ld
+
+0 string MThd standard midi data audio/midi
++9 byte >0 , format %d
++11 byte >1 , %d channel%s
+0 string CTMF creative music data
+0 string SBI soundblaster instrument data
+0 string Creative\ Voice\ File creative labs voice data
+&19 byte 0x1A
++23 byte >0 , version %d
++22 byte >0 \b.%d
+
+0 string RIFF riff audio data audio/riff
++8 string AIFF aiff format
++8 string AIFC aiff-c format
++8 string WAVE , wave format
++8 string 8SVX 8svx format
++34 leshort >0 , %d bit
++22 leshort =1 , mono
++22 leshort =2 , stereo
++22 leshort =3 , 3 channels
++22 leshort =4 , quad
++22 leshort >4 , %d channel%s
++24 lelong >0 , %d hz
+
+8 long 0x41494646 aiff audio data audio/aiff
+8 long 0x41494643 aiff-C audio data audio/aiff
+0 long 0x4e54524b multitrack audio data audio/multitrack
+
+0 string ;vdb;ciao ciao virtual database application/x-ciao
+0 string ;vdb; vdb archive application/pax
++5 string * , %s
+
+0 string #pragma pp:checkpoint preprocessor checkpoint application/x-libpp
++22 edit %"\([^"]*\)".*%\1% , version %s
+
+#
+# pc application files
+#
+
+0 string HDR*PowerBuilder power builder library application/x-powerbuilder
++18 edit %\([0-9][0-9]\)\([0-9][0-9]\).*%\1.\2% , version %s
+
+#
+# database files
+#
+
+0 long 0x13579ace dbm 1.x database application/x-dbm
+0 string GDBM gnu dbm 2.x database application/x-gdbm
+
+12 long 0x00042253 bsd db queue
++16 long >0 version %d
++12 belong 0x00042253 , big-endian
++12 lelong 0x00042253 , little-endian
+
+0 long 0x00053162 bsd db btree application/x-bsd-db
++4 long >2 1.86
++4 long <3 1.85
++4 long >0 , version %d
++0 belong 0x00053162 , big-endian
++0 lelong 0x00053162 , little-endian
++16 long * , %d record%s
++20 long * , flags 0x%x
+
+12 long 0x00053162 bsd db btree
++16 long >0 version %d
++12 belong 0x00053162 , big-endian
++12 lelong 0x00053162 , little-endian
+
+0 long 0x00061561 bsd db hash application/x-bsd-db
++4 long >2 1.86
++4 long <3 1.85
++4 long >0 version %d
++8 long 4321 , big-endian
++8 long 1234 , little-endian
++56 long * , %d key%s
+
+12 long 0x00061561 bsd db hash
++16 long >0 version %d
++12 belong 0x00061561 , big-endian
++12 lelong 0x00061561 , little-endian
+
+0 long 0x950412de gnu message catalog application/x-locale
++4 long * , revision %d
++8 long * , %d message%s
+
+#
+# from the net
+#
+
+1 string # This is a shell archive. shar archive application/x-shar
+81 string # This is a shell archive. shar archive application/x-shar
+
+0 short 0x1f9d compressed data application/zip
+{
+2 byte &0200
+&2 byte &037>0 , %d bit%s
+}
+0 short 017436 packed data application/zip
+0 short 0x9d1f compressed data application/zip
++2 byte &0200 , blocked
++2 byte &037>0 , with %d bit%s
+
+0 short 0x1f10 pzip compressed data application/pzip
+&2 byte >0 , version %d
+&3 byte <10 .%d
+
+0 short 0x1f8b pzip compressed data application/pzip
+&10 short 0x9217
+
+0 short 0x1f8b gzip compressed data application/gzip
++9 byte 0 , dos
++9 byte 1 , amiga
++9 byte 2 , vms
++9 byte 3 , unix
++9 byte 5 , atari
++9 byte 6 , os/2
++9 byte 7 , mac
++9 byte 10 , tops/20
++9 byte 11 , win/32
++2 byte <8 , reserved
++2 byte 8 , deflate
++3 byte &0x1 , ascii
++3 byte &0x2 , continuation
++3 byte &0x4 , extra field
++3 byte &0x8 , original name
++3 byte &0x10 , comment
++3 byte &0x20 , encrypted
++8 byte 2 , max compression
++8 byte 4 , max speed
++4 ledate >0 , %s
+
+0 string BZh bzip compressed data application/zip
++3 byte >='0'&<='9' , %c00k blocks
+0 long 0x0000abcd NOC newbridge raw stats
+v{
++4 short * , version %d
++6 short * .%d
+}
+0 long 0x0e130414 NOC switch stats
+v()
+0 long 0x0e13130d NOC switch summary stats
+v()
+
+0 leshort 0 windows icon resource application/x-ms-icon
+&2 leshort 1
++4 leshort x , %d icon%s
+
+0 string begin 0 uuencoded data application/x-uuencode
+0 string \x89PNG PNG image data image/png
+&4 belong 0x0d0a1a0a
++16 belong x , %ld x
++20 belong x %ld
++24 byte x , %d-bit
++25 byte 0 , grayscale
++25 byte 2 , color RGB
++25 byte 3 , colormap
++25 byte 4 , gray+alpha
++25 byte 6 , color RGBA
+#+26 byte 0 , deflate/32K
++28 byte 0 , non-interlaced
++28 byte 1 , interlaced
+0 string \377\330\377 JPEG image image/jpeg
+0 string GIF GIF image image/gif
++3 string * , version %-.3s
+{
+6 leshort >0 , %d
+&8 leshort >0 x %d
+}
++10 byte &0x40 , interlaced
++10 byte &0x03==0x00 , 2 colors
++10 byte &0x03==0x01 , 4 colors
++10 byte &0x03==0x02 , 8 colors
++10 byte &0x03==0x03 , 16 colors
++10 byte &0x03==0x04 , 32 colors
++10 byte &0x03==0x05 , 64 colors
++10 byte &0x03==0x06 , 128 colors
++10 byte &0x03==0x07 , 256 colors
+0 short 0x4d4d TIFF image, big-endian image/tiff
++2 short >0 , version %d
+0 short 0x4949 TIFF image, little-endian image/tiff
++2 short >0 , version %d
+0 short 000732 sgi imagelib image image/x-imagelib
++6 short * , %d
++8 short * x %d
+
+0 string gimp xcf gimp XCF image image/x-gimp
++9 string file , version 0
+{
+9 string v , version
+&10 string * %s
+}
++14 belong x , %lu x
++18 belong x %lu
++22 belong 0 , rgb color
++22 belong 1 , greyscale
++22 belong 2 , indexed color
+
+0 string MOVI sgi movie video/x-sgi
+
+0 byte 0
+&4 string moov quicktime movie video/quicktime
+0 byte 0
+&4 string mdat quicktime movie video/quicktime
+8 string AVI avi movie video/avi
+0 long 0x000001BA mpeg movie video/mpeg
+0 long 0x000001B3 mpeg movie video/mpeg
+
+0 string <MakerFile frame maker file application/framemaker
+0 string {\\rtf rich text application/rtf
+
+0 long 0xd0cf11e0 ms powerpoint document application/x-powerpoint
+
+0 string ms C/C++ program database ms program database application/x-dbx
++33 string * , version %s
+
+0 string \377WPC corel wordperfect document application/x-wordperfect
+
+0 beshort 0xedab
+&2 beshort 0xeedb red hat package manager
++4 byte * v%d
++8 beshort 1 i386
++8 beshort 2 alpha
++8 beshort 3 sparc
++8 beshort 4 mips
++8 beshort 5 powerpc
++8 beshort 6 68k
++8 beshort 7 sgi
++8 beshort >7 unknown
++6 beshort 0 binary
++6 beshort 1 source
++10 string * , %s
+
+0 short 0x9900 pgp key public ring application/pgp
+0 short 0x9501 pgp key security ring application/pgp
+0 short 0x9500 pgp key security ring application/pgp
+0 string -----BEGIN\040PGP pgp armored data application/pgp
++15 string PUBLIC\040KEY\040BLOCK- , public key block
++15 string MESSAGE- , message
++15 string SIGNED\040MESSAGE- , signed message
++15 string PGP\040SIGNATURE- , signature
+
+0 string Core osf unknown core dump x-system/core
+&name match core*
++24 string * from `%s'
+
+0 match From[ ] mail message message/rfc822
+0 match (BABYL|From|Received|Return-Path|To)?(:)[ ] mail message message/partial
+
+0 string \001fcp X11 portable compiled font x-X11/font
+
+0 string \357\273\277 utf-8 encoded text application/x-iconv
+0 string \376\377 utf-16 encoded text application/x-iconv
+0 string \377\376 utf-16 encoded text, little-endian application/x-iconv
+
+32769 string CD001 ISO 9660 CD-ROM filesystem image data/x-filesystem
++32808 string * , '%s'
++34816 string \000CD001\001EL\ TORITO\ SPECIFICATION , bootable
+37633 string CD001 ISO 9660 CD-ROM filesystem image, raw 2352 byte sectors data/x-filesystem
+32776 string CDROM High Sierra CD-ROM filesystem image data/x-filesystem
+
+#
+# front compression data
+#
+
+0 byte 0
+&1 edit %^\([A-Z_][A-Z_]*\)-\([^0-9]*\)-\([0-9][0-9]\)%\1 data, with \2, version \3%l %s application/x-%s
+0 byte 0
+&1 edit %^\([A-Z_][A-Z_]*\)\([0-9][0-9]\)%\1 data, version \2%l %s application/x-%s
+
+#
+# generic binary magic
+#
+
+0 long 0x00010203
+&4 string * %s application/x-%s
+&12 string * %s data
+&24 version * , version %s
++28 long >0 , size %u
+{
+&28 long >=4
+&32 long >0 , %u
+}
+{
+&28 long >=8
+&36 long >0 , %u
+}
+
+#
+# local additions
+#
+
+0 match info mam mam program application/x-mam
+0 edit %^!<\([^>]*\)>.*%\1%l %s data application/x-%s
+0 string \015\023\007\000 ast message catalog application/x-locale
++4 string * , %s
+
+#
+# last chance
+#
+
+name match *.(o|obj) unknown object x-system/obj
+name match core unknown core dump x-system/core
+name match core.* unknown core dump x-system/core
+
+#
+# we resisted til now
+#
+
+0 void registry()
+|name match *.acp Office.ActorPreview application/x-ms-office
+|name match *.act Office.Actor application/x-ms-office
+|name match *.ade Microsoft Access project extension application/x-ms
+|name match *.adp Microsoft Access project application/x-ms
+|name match *.aif AIFF Audio audio/x-aiff
+|name match *.aifc AIFF Audio audio/aiff
+|name match *.aiff AIFF Audio audio/aiff
+|name match *.aim AOL Instant Messenger Launch application/x-aim
+|name match *.ani Animated Cursor application/x-ms-anifile
+|name match *.app Application file application/x-ms
+|name match *.arc WinZip File application/x-ms-winzip
+|name match *.arj WinZip File application/x-ms-winzip
+|name match *.art ART Image image/x-jg
+|name match *.asp Active Server Page application/x-ms
+|name match *.asx Windows Media Audio / Video application/x-ms
+|name match *.au Sound Clip audio/basic
+|name match *.avi Video Clip video/avi
+|name match *.awx Custom AppWizard application/x-ms-awxfile
+|name match *.b64 WinZip File application/x-ms-winzip
+|name match *.bas Microsoft Visual Basic class module application/x-ms
+|name match *.bat MS-DOS Batch File application/x-ms-batfile
+|name match *.bfc Briefcase application/x-ms-briefcase
+|name match *.bhx WinZip File application/x-ms-winzip
+|name match *.bmp Bitmap Image image/bmp
+|name match *.bpg Borland Project Group application/x-ms-borlandprojectgroup
+|name match *.bpk C++Builder Package application/x-ms-bcbpackage
+|name match *.bpr C++Builder Project application/x-ms-bcbproject
+|name match *.bsc Browser Information application/x-ms-bscfile
+|name match *.cda CD Audio Track application/x-ms-cdafile
+|name match *.cdf Channel File application/x-netcdf
+|name match *.cer Internet Security Certificate application/x-x509-ca-cert
+|name match *.cfg CFG File application/x-ms-cfg_auto_file
+|name match *.chm Compiled HTML Help file application/x-ms-help
+|name match *.cil Clip Gallery Download Package application/x-ms-clipgallerydownloadpackage
+|name match *.class Java class file application/x-java
+|name match *.clp Clipboard Clip application/x-ms-clpfile
+|name match *.cmd Windows Command Script application/x-ms-cmdfile
+|name match *.com MS-DOS Application application/x-ms-comfile
+|name match *.cpl Control Panel extension application/x-ms-cplfile
+|name match *.cpp C++ Source File application/x-c++
+|name match *.crt Internet Security Certificate application/x-x509-ca-cert
+|name match *.css HyperText Style Sheet text/css
+|name match *.csv Microsoft Excel Comma Separated Values File application/x-ms-excel
+|name match *.cur Cursor application/x-ms-curfile
+|name match *.cxx C++ Source File application/x-c++
+|name match *.dcx DCX Image Document application/x-ms-dcximage
+|name match *.der Internet Security Certificate application/x-x509-ca-cert
+|name match *.dfm C++Builder Form application/x-ms-bcbform
+|name match *.dic Text Document application/x-ms-txtfile
+|name match *.dif DV video/x-dv
+|name match *.dll Windows dynamic link library application/x-ms-dll
+|name match *.doc Microsoft Word Document application/x-ms-word
+|name match *.dot Microsoft Word Template application/x-ms-word
+|name match *.drv Device driver application/x-ms-drvfile
+|name match *.dsm Developer Studio Macro File application/x-ms-dsmfile
+|name match *.dsn Microsoft OLE DB Provider for ODBC Drivers application/x-ms-msdasql
+|name match *.dsp Project File application/x-ms-dspfile
+|name match *.dsw Project Workspace application/x-ms-dswfile
+|name match *.dv DV video/x-dv
+|name match *.ebh Ebasic Files application/x-ms-hclebasich
+|name match *.ebx Ebrun Files application/x-ms-hclebrun
+|name match *.exc Text Document application/x-ms-txtfile
+|name match *.exe Application application/x-msdownload
+|name match *.fav Outlook Bar Shortcuts application/x-ms-outlook
+|name match *.fdf Adobe Acrobat Forms Document application/x-ms-acroexch
+|name match *.fnd Saved Search application/x-ms-fndfile
+|name match *.fon Font file application/x-ms-fonfile
+|name match *.fs Ftp Files application/x-ms-hclftp
+|name match *.fxp Microsoft Visual FoxPro compiled program application/x-ms-foxpro
+|name match *.gfi Genigraphics GraphicsLink application/x-ms-graphicslink
+|name match *.gfx Genigraphics GraphicsLink application/x-ms-graphicslink
+|name match *.gif GIF Image image/gif
+|name match *.gim Genigraphics GraphicsLink application/x-ms-graphicslink
+|name match *.gix Genigraphics GraphicsLink application/x-ms-graphicslink
+|name match *.gna Genigraphics GraphicsLink application/x-ms-graphicslink
+|name match *.gnx Genigraphics GraphicsLink application/x-ms-graphicslink
+|name match *.gra Microsoft Graph 97 Chart application/x-ms-msgraph
+|name match *.grp Microsoft Program Group application/x-ms-msprogramgroup
+|name match *.gst MSMap.Datainst.8 application/x-ms-msmap
+|name match *.gwx Genigraphics GraphicsLink application/x-ms-graphicslink
+|name match *.gwz Genigraphics GraphicsLink application/x-ms-graphicslink
+|name match *.gz WinZip File application/gzip
+|name match *.hep HostExplorer Session Profile application/x-ms-hostexplorer
+|name match *.hlp Help File application/x-ms-help
+|name match *.hpp C++ Header File application/x-c++
+|name match *.hqx WinZip File application/mac-binhex40
+|name match *.hs3 HostExplorer Hotspot Definition application/x-ms-hostexplorer
+|name match *.hs5 HostExplorer Hotspot Definition application/x-ms-hostexplorer
+|name match *.hsv HostExplorer Hotspot Definition application/x-ms-hostexplorer
+|name match *.ht HyperTerminal File application/x-ms-htfile
+|name match *.hta HTML program application/x-ms
+|name match *.htm html source text/html
+|name match *.hts Hummingbird Telnet Program v6.0.0.0 application/x-ms-hummingbird
+|name match *.htt HyperText Template text/webviewhtml
+|name match *.htw HTML Document application/x-ms-htmlfile
+|name match *.htx HTML Document text/html
+|name match *.hxx C++ Header File application/x-c++
+|name match *.ico Icon application/x-ms-icon
+|name match *.idb Intermediate File application/x-ms-mdpxfile
+|name match *.ilk Intermediate File application/x-ms-mdpxfile
+|name match *.inf Setup Information application/x-ms-setup
+|name match *.ini Configuration Settings application/x-ms-config
+|name match *.ins Internet Communication Settings application/x-internet-signup
+|name match *.iqy Microsoft Excel Web Query File application/x-ms-iqyfile
+|name match *.isp Internet Communication Settings application/x-internet-signup
+|name match *.its Internet Document Set application/x-ms-its
+|name match *.ivt InfoViewer Title application/x-ms-ivt
+|name match *.jfif JPEG Image image/jpeg
+|name match *.job Scheduler Job Object application/x-ms-jobobject
+|name match *.jod Microsoft.Jet.OLEDB.3.51 application/x-ms-microsoft
+|name match *.jpe JPEG Image image/jpeg
+|name match *.jpeg JPEG Image image/jpeg
+|name match *.jpg JPEG Image image/jpeg
+|name match *.js JavaScript file application/x-java
+|name match *.jse JavaScript Encoded Script file application/x-ms
+|name match *.jsp JavaScript Page application/x-ms
+|name match *.km3 HostExplorer KeyMap Definition application/x-ms-hostexplorer
+|name match *.km5 HostExplorer KeyMap Definition application/x-ms-hostexplorer
+|name match *.kmv HostExplorer KeyMap Definition application/x-ms-hostexplorer
+|name match *.lam LAMDocument application/x-ms-lamdocument
+|name match *.ldb Microsoft Access Record-Locking Information application/x-ms-access
+|name match *.lnk Shortcut application/x-ms
+|name match *.log Text Document application/x-text
+|name match *.lzh WinZip File application/x-ms-winzip
+|name match *.m1v Movie Clip video/mpeg
+|name match *.mac MacPaint Image image/x-macpaint
+|name match *.mad Microsoft Access Module Shortcut application/x-ms-access
+|name match *.maf Microsoft Access Form Shortcut application/x-ms-access
+|name match *.mam Microsoft Access Macro Shortcut application/x-ms-access
+|name match *.maq Microsoft Access Query Shortcut application/x-ms-access
+|name match *.mar Microsoft Access Report Shortcut application/x-ms-access
+|name match *.mat Microsoft Access Table Shortcut application/x-ms-access
+|name match *.mda Microsoft Access Add-in application/x-ms-access
+|name match *.mdb Microsoft Access Database application/x-ms-access
+|name match *.mdb Microsoft Access program application/x-ms
+|name match *.mde Microsoft Access MDE Database application/x-ms-access
+|name match *.mdn Microsoft Access Blank Database Template application/x-ms-access
+|name match *.mdp Project Workspace application/x-ms-mdpfile
+|name match *.mdt Microsoft Access Add-in Data application/x-ms-access
+|name match *.mdw Microsoft Access Workgroup Information application/x-ms-access
+|name match *.mdz Microsoft Access Database Wizard Template application/x-ms-access
+|name match *.mht Microsoft MHTML Document 4.0 message/rfc822
+|name match *.mhtml Microsoft MHTML Document 4.0 message/rfc822
+|name match *.mid MIDI Sequence audio/mid
+|name match *.mmm Media Clip application/x-ms-mplayer
+|name match *.mov QuickTime Movie video/quicktime
+|name match *.mp2 Movie Clip video/mpeg
+|name match *.mpa Movie Clip video/mpeg
+|name match *.mpe Movie Clip video/mpeg
+|name match *.mpeg Movie Clip video/mpeg
+|name match *.mpg Movie Clip video/mpeg
+|name match *.msc Microsoft Common Console Document application/x-ms-mmc
+|name match *.msg Outlook Item application/x-ms-msgfile
+|name match *.msi Microsoft Windows Installer package application/x-ms
+|name match *.msp Windows Installer patch application/x-ms
+|name match *.mst Visual Test source files application/x-ms
+|name match *.nsc Netscape Conference Call File application/x-conference
+|name match *.obd Microsoft Office Binder application/x-ms-office
+|name match *.obt Microsoft Office Binder Template application/x-ms-office
+|name match *.obz Microsoft Office Binder Wizard application/x-ms-office
+|name match *.odl Object Definition Language File application/x-ms-odlfile
+|name match *.ofn Other Office Documents... application/x-ms-office
+|name match *.oft Outlook Item Template application/x-ms-outlook
+|name match *.ops Microsoft Office profile settings file application/x-ms
+|name match *.opx MS Organization Chart 2.0 application/x-ms-orgpluswopx
+|name match *.oss Office Search application/x-ms-ossfile
+|name match *.pcd Photo CD Image application/x-ms-pcdfile
+|name match *.pch Intermediate File application/x-ms-mdpxfile
+|name match *.pct PICT Image image/pict
+|name match *.pcx PCX Image application/x-ms-pcxfile
+|name match *.pdb Intermediate File application/x-ms-mdpxfile
+|name match *.pdf Adobe Acrobat Document application/pdf
+|name match *.pfm Type 1 Font file application/x-ms-pfmfile
+|name match *.php Perl CGI Script File application/x-perl
+|name match *.pic PICT Image image/pict
+|name match *.pict PICT Image image/pict
+|name match *.pif Shortcut to MS-DOS Program application/x-ms-piffile
+|name match *.pif Shortcut to MS-DOS program application/x-ms
+|name match *.pkg Microsoft Developer Extension application/x-ms-pkgfile
+|name match *.pma Performance Monitor File application/x-ms-perffile
+|name match *.pmc Performance Monitor File application/x-ms-perffile
+|name match *.pml Performance Monitor File application/x-ms-perffile
+|name match *.pmr Performance Monitor File application/x-ms-perffile
+|name match *.pmw Performance Monitor File application/x-ms-perffile
+|name match *.pnf Precompiled Setup Information application/x-ms-pnffile
+|name match *.png PNG Image application/x-ms-pngfile
+|name match *.pntg MacPaint Image image/x-macpaint
+|name match *.pop HostExplorer Poppad Definition application/x-ms-hostexplorer
+|name match *.pot Microsoft PowerPoint Template application/vnd.ms-powerpoint
+|name match *.ppa Microsoft PowerPoint Addin application/vnd.ms-powerpoint
+|name match *.pps Microsoft PowerPoint SlideShow application/vnd.ms-powerpoint
+|name match *.ppt Microsoft PowerPoint Presentation application/vnd.ms-powerpoint
+|name match *.prf System file application/x-ms
+|name match *.prg Program source file application/x-ms
+|name match *.psd Photoshop Image image/x-photoshop
+|name match *.pwz Microsoft PowerPoint Wizard application/vnd.ms-powerpoint
+|name match *.qif QuickTime Image image/x-quicktime
+|name match *.qk3 HostExplorer QuickKeys application/x-ms-hostexplorer
+|name match *.qk5 HostExplorer QuickKeys application/x-ms-hostexplorer
+|name match *.qkv HostExplorer QuickKeys application/x-ms-hostexplorer
+|name match *.qt QuickTime Movie video/quicktime
+|name match *.qti QuickTime Image image/x-quicktime
+|name match *.qtif QuickTime Image image/x-quicktime
+|name match *.qtp QuickTime Preferences application/x-ms-quicktimepreferences
+|name match *.qts QuickTime application/x-ms-quicktimesystem
+|name match *.qtx QuickTime Extension application/x-ms-quicktimeextension
+|name match *.que Scheduler Queue Object application/x-ms-queueobject
+|name match *.rc Resource Template application/x-ms-rcfile
+|name match *.rct Resource Template application/x-ms-rcfile
+|name match *.reg Registration Entries application/x-ms-regfile
+|name match *.res Intermediate File application/x-ms-mdpxfile
+|name match *.rmi MIDI Sequence audio/mid
+|name match *.rnk Dial-Up Shortcut application/x-ms-rnkfile
+|name match *.rtf Rich Text Format application/x-ms-word
+|name match *.rx XRX Files application/x-ms-hclbroadway
+|name match *.sbr Intermediate File application/x-ms-mdpxfile
+|name match *.sc2 Microsoft Schedule+ 7.0 Application application/x-ms-scheduleplus
+|name match *.scd Microsoft Schedule+ 7.0 Application application/x-ms-scheduleplus
+|name match *.scf Windows Explorer Command application/x-ms-explorer
+|name match *.sch Microsoft Schedule+ 7.0 Application application/x-ms-scheduleplus
+|name match *.scp Text Document application/x-ms-txtfile
+|name match *.scr Screen Saver application/x-ms-scrfile
+|name match *.sct Windows Script Component application/x-ms
+|name match *.sd2 Sound Designer 2 audio/x-sd2
+|name match *.ses Xsession Files application/x-ms-hclxsession
+|name match *.shb Shortcut into a document application/x-ms-docshortcut
+|name match *.shs Scrap object application/x-ms-shellscrap
+|name match *.shtml Netscape Hypertext Document application/x-ms-netscapemarkup
+|name match *.slk Microsoft Excel SLK Data Import Format application/x-ms-excel
+|name match *.snd Sound Clip audio/basic
+|name match *.stm HTML Document text/html
+|name match *.sys System file application/x-ms-sysfile
+|name match *.taz WinZip File application/x-ms-winzip
+|name match *.tga TGA Image application/x-ms-tgafile
+|name match *.tif TIF Image Document image/tiff
+|name match *.tlb Type Library application/x-ms-tlbfile
+|name match *.ttf TrueType Font file application/x-ms-ttffile
+|name match *.txt Text Document text/plain
+|name match *.tz WinZip File application/x-ms-winzip
+|name match *.udl Microsoft Data Link application/x-ms-msdasc
+|name match *.url Internet Shortcut application/x-ms-internetshortcut
+|name match *.uue WinZip File application/x-ms-winzip
+|name match *.vb Microsoft Visual Basic Scripting Edition (VBScript) file application/x-ms
+|name match *.vbe VBScript Encoded Script file application/x-ms
+|name match *.vbs VBScript file application/x-ms
+|name match *.vir Virus Infected File application/x-ms-virus
+|name match *.wav Wave Sound audio/x-wav
+|name match *.wbk Microsoft Word Backup Document application/x-ms-word
+|name match *.wiz Microsoft Word Wizard application/x-ms-word
+|name match *.wll Microsoft Word Addin application/x-ms-word
+|name match *.wpd corel wordperfect document application/x-wordperfect
+|name match *.wri Write Document application/x-ms-wrifile
+|name match *.wrl SGI.CosmoPlayer.1 application/x-ms-sgi
+|name match *.wrz SGI.CosmoPlayer.1 application/x-ms-sgi
+|name match *.ws Wstart Files application/x-ms-hclwstart
+|name match *.wsc Windows Script Component application/x-ms
+|name match *.wsf Windows Script file application/x-ms
+|name match *.wsh Windows Script Host Settings file application/x-ms
+|name match *.wtx Text Document application/x-ms-txtfile
+|name match *.xbm Netscape Hypertext Document image/x-xbitmap
+|name match *.xif XIF Image Document application/x-ms-xifimage
+|name match *.xla Microsoft Excel Add-In application/x-ms-excel
+|name match *.xlb Microsoft Excel Worksheet application/x-ms-excel
+|name match *.xlc Microsoft Excel Chart application/x-ms-excel
+|name match *.xld Microsoft Excel 5.0 DialogSheet application/x-ms-excel
+|name match *.xlk Microsoft Excel Backup File application/x-ms-excel
+|name match *.xll Microsoft Excel XLL Add-In application/x-ms-excel
+|name match *.xlm Microsoft Excel 4.0 Macro application/x-ms-excel
+|name match *.xls Microsoft Excel Worksheet application/vnd.ms-excel
+|name match *.xlt Microsoft Excel Template application/x-ms-excel
+|name match *.xlv Microsoft Excel VBA Module application/x-ms-excel
+|name match *.xlw Microsoft Excel Workspace application/x-ms-excel
+|name match *.xnk Microsoft Exchange Shortcut application/x-ms-exchange
+|name match *.xs Microsoft Exchange start Files application/x-ms-exchange
+|name match *.xxe WinZip File application/x-ms-winzip
+|name match *.zip WinZip File application/x-zip-compressed
diff --git a/src/lib/libast/misc/mime.c b/src/lib/libast/misc/mime.c
new file mode 100644
index 0000000..49cfaa1
--- /dev/null
+++ b/src/lib/libast/misc/mime.c
@@ -0,0 +1,839 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * mime/mailcap support library
+ */
+
+static const char id[] = "\n@(#)$Id: mime library (AT&T Research) 2002-10-29 $\0\n";
+
+static const char lib[] = "libast:mime";
+
+#include "mimelib.h"
+
+typedef struct Att_s
+{
+ struct Att_s* next;
+ char* name;
+ char* value;
+} Att_t;
+
+typedef struct Cap_s
+{
+ struct Cap_s* next;
+ unsigned long flags;
+ Att_t att;
+ char* test;
+ char data[1];
+} Cap_t;
+
+typedef struct
+{
+ Dtlink_t link;
+ Cap_t* cap;
+ Cap_t* pac;
+ char name[1];
+} Ent_t;
+
+typedef struct
+{
+ char* data;
+ int size;
+} String_t;
+
+typedef struct
+{
+ char* next;
+ String_t name;
+ String_t value;
+} Parse_t;
+
+typedef struct
+{
+ const char* pattern;
+ int prefix;
+ Sfio_t* fp;
+ int hit;
+} Walk_t;
+
+/*
+ * convert c to lower case
+ */
+
+static int
+lower(register int c)
+{
+ return isupper(c) ? tolower(c) : c;
+}
+
+/*
+ * Ent_t case insensitive comparf
+ */
+
+static int
+order(Dt_t* dt, void* a, void* b, Dtdisc_t* disc)
+{
+ return strcasecmp(a, b);
+}
+
+/*
+ * Cap_t free
+ */
+
+static void
+dropcap(register Cap_t* cap)
+{
+ register Att_t* att;
+
+ while (att = cap->att.next)
+ {
+ cap->att.next = att->next;
+ free(att);
+ }
+ free(cap);
+}
+
+/*
+ * Ent_t freef
+ */
+
+static void
+drop(Dt_t* dt, void* object, Dtdisc_t* disc)
+{
+ register Ent_t* ent = (Ent_t*)object;
+ register Cap_t* cap;
+
+ while (cap = ent->cap)
+ {
+ ent->cap = cap->next;
+ dropcap(cap);
+ }
+ free(ent);
+}
+
+/*
+ * add mime type entry in s to mp
+ */
+
+int
+mimeset(Mime_t* mp, register char* s, unsigned long flags)
+{
+ register Ent_t* ent;
+ register Cap_t* cap;
+ register Att_t* att;
+ register char* t;
+ register char* v;
+ register char* k;
+ char* x;
+ Att_t* tta;
+ int q;
+
+ for (; isspace(*s); s++);
+ if (*s && *s != '#')
+ {
+ cap = 0;
+ for (v = s; *v && *v != ';'; v++)
+ if (isspace(*v) || *v == '/' && *(v + 1) == '*')
+ *v = 0;
+ if (*v)
+ {
+ *v++ = 0;
+ do
+ {
+ for (; isspace(*v); v++);
+ if (cap)
+ {
+ for (t = v; *t && !isspace(*t) && *t != '='; t++);
+ for (k = t; isspace(*t); t++);
+ if (!*t || *t == '=' || *t == ';')
+ {
+ if (*t)
+ while (isspace(*++t));
+ *k = 0;
+ k = v;
+ v = t;
+ }
+ else
+ k = 0;
+ }
+ if (*v == '"')
+ q = *v++;
+ else
+ q = 0;
+ for (t = v; *t; t++)
+ if (*t == '\\')
+ {
+ switch (*(t + 1))
+ {
+ case 0:
+ case '\\':
+ case '%':
+ *t = *(t + 1);
+ break;
+ default:
+ *t = ' ';
+ break;
+ }
+ if (!*++t)
+ break;
+ }
+ else if (*t == q)
+ {
+ *t = ' ';
+ q = 0;
+ }
+ else if (*t == ';' && !q)
+ {
+ *t = ' ';
+ break;
+ }
+ for (; t > v && isspace(*(t - 1)); t--);
+ if (t <= v && (!cap || !k))
+ break;
+ if (!cap)
+ {
+ if (!(cap = newof(0, Cap_t, 1, strlen(v) + 1)))
+ return -1;
+ if (*t)
+ *t++ = 0;
+ tta = &cap->att;
+ tta->name = "default";
+ x = strcopy(tta->value = cap->data, v) + 1;
+ }
+ else if (k)
+ {
+ if (*t)
+ *t++ = 0;
+ if (!(att = newof(0, Att_t, 1, 0)))
+ return -1;
+ x = strcopy(att->name = x, k) + 1;
+ x = strcopy(att->value = x, v) + 1;
+ tta = tta->next = att;
+ if (!strcasecmp(k, "test"))
+ cap->test = att->value;
+ }
+ } while (*(v = t));
+ }
+ ent = (Ent_t*)dtmatch(mp->cap, s);
+ if (cap)
+ {
+ if (ent)
+ {
+ register Cap_t* dup;
+ register Cap_t* pud;
+
+ for (pud = 0, dup = ent->cap; dup; pud = dup, dup = dup->next)
+ if (!cap->test && !dup->test || cap->test && dup->test && streq(cap->test, dup->test))
+ {
+ if (flags & MIME_REPLACE)
+ {
+ if (pud)
+ pud->next = cap;
+ else
+ ent->cap = cap;
+ if (!(cap->next = dup->next))
+ ent->pac = cap;
+ cap = dup;
+ }
+ dropcap(cap);
+ return 0;
+ }
+ ent->pac = ent->pac->next = cap;
+ }
+ else if (!(ent = newof(0, Ent_t, 1, strlen(s) + 1)))
+ return -1;
+ else
+ {
+ strcpy(ent->name, s);
+ ent->cap = ent->pac = cap;
+ dtinsert(mp->cap, ent);
+ }
+ }
+ else if (ent && (flags & MIME_REPLACE))
+ dtdelete(mp->cap, ent);
+ }
+ return 0;
+}
+
+/*
+ * load mime type files into mp
+ */
+
+int
+mimeload(Mime_t* mp, const char* file, unsigned long flags)
+{
+ register char* s;
+ register char* t;
+ register char* e;
+ register int n;
+ Sfio_t* fp;
+
+ if (!(s = (char*)file))
+ {
+ flags |= MIME_LIST;
+ if (!(s = getenv(MIME_FILES_ENV)))
+ s = MIME_FILES;
+ }
+ for (;;)
+ {
+ if (!(flags & MIME_LIST))
+ e = 0;
+ else if (e = strchr(s, ':'))
+ {
+ /*
+ * ok, so ~ won't work for the last list element
+ * we do it for MIME_FILES_ENV anyway
+ */
+
+ if ((strneq(s, "~/", n = 2) || strneq(s, "$HOME/", n = 6) || strneq(s, "${HOME}/", n = 8)) && (t = getenv("HOME")))
+ {
+ sfputr(mp->buf, t, -1);
+ s += n - 1;
+ }
+ sfwrite(mp->buf, s, e - s);
+ if (!(s = sfstruse(mp->buf)))
+ return -1;
+ }
+ if (fp = tokline(s, SF_READ, NiL))
+ {
+ while (t = sfgetr(fp, '\n', 1))
+ if (mimeset(mp, t, flags))
+ break;
+ sfclose(fp);
+ }
+ else if (!(flags & MIME_LIST))
+ return -1;
+ if (!e)
+ break;
+ s = e + 1;
+ }
+ return 0;
+}
+
+/*
+ * mimelist walker
+ */
+
+static int
+list(Dt_t* dt, void* object, void* context)
+{
+ register Walk_t* wp = (Walk_t*)context;
+ register Ent_t* ent = (Ent_t*)object;
+ register Cap_t* cap;
+ register Att_t* att;
+
+ if (!wp->pattern || !strncasecmp(ent->name, wp->pattern, wp->prefix) && (!ent->name[wp->prefix] || ent->name[wp->prefix] == '/'))
+ {
+ wp->hit++;
+ for (cap = ent->cap; cap; cap = cap->next)
+ {
+ sfprintf(wp->fp, "%s", ent->name);
+ for (att = &cap->att; att; att = att->next)
+ {
+ sfprintf(wp->fp, "\n\t");
+ if (att != &cap->att)
+ {
+ sfprintf(wp->fp, "%s", att->name);
+ if (*att->value)
+ sfprintf(wp->fp, " = ");
+ }
+ sfputr(wp->fp, att->value, -1);
+ }
+ sfprintf(wp->fp, "\n");
+ }
+ }
+ return 0;
+}
+
+/*
+ * find entry matching type
+ * if exact match fails then left and right x- and right version number
+ * permutations are attempted
+ */
+
+static Ent_t*
+find(Mime_t* mp, const char* type)
+{
+ register char* lp;
+ register char* rp;
+ register char* rb;
+ register char* rv;
+ register int rc;
+ register int i;
+ char* s;
+ Ent_t* ent;
+ char buf[256];
+
+ static const char* prefix[] = { "", "", "x-", "x-", "" };
+
+ if ((ent = (Ent_t*)dtmatch(mp->cap, type)) ||
+ !(rp = strchr(lp = (char*)type, '/')) ||
+ strlen(lp) >= sizeof(buf))
+ return ent;
+ strcpy(buf, type);
+ rp = buf + (rp - lp);
+ *rp++ = 0;
+ if (*rp == 'x' && *(rp + 1) == '-')
+ rp += 2;
+ lp = buf;
+ if (*lp == 'x' && *(lp + 1) == '-')
+ lp += 2;
+ rb = rp;
+ for (rv = rp + strlen(rp); rv > rp && (isdigit(*(rv - 1)) || *(rv - 1) == '.'); rv--);
+ rc = *rv;
+ do
+ {
+ rp = rb;
+ do
+ {
+ for (i = 0; i < elementsof(prefix) - 1; i++)
+ {
+ sfprintf(mp->buf, "%s%s/%s%s", prefix[i], lp, prefix[i + 1], rp);
+ if (!(s = sfstruse(mp->buf)))
+ return 0;
+ if (ent = (Ent_t*)dtmatch(mp->cap, s))
+ return ent;
+ if (rc)
+ {
+ *rv = 0;
+ sfprintf(mp->buf, "%s%s/%s%s", prefix[i], lp, prefix[i + 1], rp);
+ if (!(s = sfstruse(mp->buf)))
+ return 0;
+ if (ent = (Ent_t*)dtmatch(mp->cap, s))
+ return ent;
+ *rv = rc;
+ }
+ }
+ while (*rp && *rp++ != '-');
+ } while (*rp);
+ while (*lp && *lp++ != '-');
+ } while (*lp);
+ return (Ent_t*)dtmatch(mp->cap, buf);
+}
+
+/*
+ * list mime <type,data> for pat on fp
+ */
+
+int
+mimelist(Mime_t* mp, Sfio_t* fp, register const char* pattern)
+{
+ Ent_t* ent;
+ Walk_t ws;
+
+ ws.fp = fp;
+ ws.hit = 0;
+ ws.prefix = 0;
+ if (ws.pattern = pattern)
+ {
+ while (*pattern && *pattern++ != '/');
+ if (!*pattern || *pattern == '*' && !*(pattern + 1))
+ ws.prefix = pattern - ws.pattern;
+ else if (ent = find(mp, ws.pattern))
+ {
+ ws.pattern = 0;
+ list(mp->cap, ent, &ws);
+ return ws.hit;
+ }
+ }
+ dtwalk(mp->cap, list, &ws);
+ return ws.hit;
+}
+
+/*
+ * get next arg in pp
+ * 0 returned if no more args
+ */
+
+static int
+arg(register Parse_t* pp, int first)
+{
+ register char* s;
+ register int c;
+ register int q;
+ int x;
+
+ for (s = pp->next; isspace(*s) && *s != '\n'; s++);
+ if (!*s || *s == '\n')
+ {
+ pp->next = s;
+ return 0;
+ }
+ pp->name.data = s;
+ pp->value.data = 0;
+ q = 0;
+ x = 0;
+ while ((c = *s++) && c != ';' && c != '\n')
+ {
+ if (c == '"')
+ {
+ q = 1;
+ if (pp->value.data)
+ {
+ pp->value.data = s;
+ if (x)
+ x = -1;
+ else
+ x = 1;
+ }
+ else if (!x && pp->name.data == (s - 1))
+ {
+ x = 1;
+ pp->name.data = s;
+ }
+ do
+ {
+ if (!(c = *s++) || c == '\n')
+ {
+ s--;
+ break;
+ }
+ } while (c != '"');
+ if (first < 0 || x > 0)
+ {
+ c = ';';
+ break;
+ }
+ }
+ else if (c == '=' && !first)
+ {
+ first = 1;
+ pp->name.size = s - pp->name.data - 1;
+ pp->value.data = s;
+ }
+ else if (first >= 0 && isspace(c))
+ break;
+ }
+ pp->next = s - (c != ';');
+ if (first >= 0 || !q)
+ for (s--; s > pp->name.data && isspace(*(s - 1)); s--);
+ if (pp->value.data)
+ pp->value.size = s - pp->value.data - (q && first < 0);
+ else
+ {
+ pp->value.size = 0;
+ pp->name.size = s - pp->name.data - (q && first < 0);
+ }
+ if (first >= 0 && pp->name.size > 0 && pp->name.data[pp->name.size - 1] == ':')
+ return 0;
+ return pp->name.size > 0;
+}
+
+/*
+ * low level for mimeview()
+ */
+
+static char*
+expand(Mime_t* mp, register char* s, const char* name, const char* type, const char* opts)
+{
+ register char* t;
+ register char* v;
+ register int c;
+ register int e;
+ register int n;
+ Parse_t pp;
+
+ mp->disc->flags |= MIME_PIPE;
+ for (;;)
+ {
+ switch (c = *s++)
+ {
+ case 0:
+ case '\n':
+ break;
+ case '%':
+ if ((c = *s++) == '{' && (e = '}') || c == '(' && (e = ')'))
+ {
+ for (t = s; *s && *s != e; s++);
+ n = s - t;
+ switch (*s)
+ {
+ case '}':
+ s++;
+ c = '{';
+ break;
+ case ')':
+ s++;
+ if (c = *s)
+ s++;
+ break;
+ }
+ }
+ else
+ t = 0;
+ switch (c)
+ {
+ case 's':
+ v = (char*)name;
+ mp->disc->flags &= ~MIME_PIPE;
+ break;
+ case 't':
+ v = (char*)type;
+ break;
+ case '{':
+ for (t = s; *s && *s != '}'; s++);
+ if (*s && (c = s++ - t) && (pp.next = (char*)opts))
+ while (arg(&pp, 0))
+ if (pp.name.size == c && !strncasecmp(pp.name.data, t, c))
+ {
+ if (pp.value.size)
+ sfwrite(mp->buf, pp.value.data, pp.value.size);
+ break;
+ }
+ continue;
+ default:
+ sfputc(mp->buf, c);
+ continue;
+ }
+ if (v && *v)
+ n = strlen(v);
+ else if (t)
+ v = t;
+ else
+ continue;
+ sfputr(mp->buf, fmtquote(v, 0, 0, n, FMT_SHELL), -1);
+ continue;
+ default:
+ sfputc(mp->buf, c);
+ continue;
+ }
+ break;
+ }
+ return sfstruse(mp->buf);
+}
+
+/*
+ * return expanded command/path/value for <view,name,type,opts>
+ * return value valid until next mime*() call
+ */
+
+char*
+mimeview(Mime_t* mp, const char* view, const char* name, const char* type, const char* opts)
+{
+ register Ent_t* ent;
+ register Cap_t* cap;
+ register Att_t* att;
+ register char* s;
+ int c;
+
+ if (ent = find(mp, type))
+ {
+ cap = ent->cap;
+ if (!view || strcasecmp(view, "test"))
+ while (s = cap->test)
+ {
+ if (s = expand(mp, s, name, type, opts))
+ {
+ Parse_t a1;
+ Parse_t a2;
+ Parse_t a3;
+ Parse_t a4;
+
+ /*
+ * try to do a few common cases here
+ * mailcap consistency is a winning
+ * strategy
+ */
+
+ a1.next = s;
+ if (arg(&a1, -1))
+ {
+ if ((c = *a1.name.data == '!') && --a1.name.size <= 0 && !arg(&a1, -1))
+ goto lose;
+ if (a1.name.size == 6 && strneq(a1.name.data, "strcmp", 6) || a1.name.size == 10 && strneq(a1.name.data, "strcasecmp", 10))
+ {
+ a2.next = a1.next;
+ if (!arg(&a2, -1))
+ goto lose;
+ a3.next = a2.next;
+ if (!arg(&a3, -1))
+ goto lose;
+ if (a2.name.size != a3.name.size)
+ c ^= 0;
+ else c ^= (a1.name.size == 6 ? strncmp : strncasecmp)(a2.name.data, a3.name.data, a2.name.size) == 0;
+ if (c)
+ break;
+ goto skip;
+ }
+ else if (a1.name.size == 4 && strneq(a1.name.data, "test", 4))
+ {
+ if (!arg(&a1, -1))
+ goto lose;
+ a2.next = a1.next;
+ if (!arg(&a2, -1) || a2.name.size > 2 || a2.name.size == 1 && *a2.name.data != '=' || a2.name.size == 2 && (!strneq(a1.name.data, "!=", 2) || !strneq(a2.name.data, "==", 2)))
+ goto lose;
+ a3.next = a2.next;
+ if (!arg(&a3, -1))
+ goto lose;
+ if (*a3.name.data == '`' && *(a3.name.data + a3.name.size - 1) == '`')
+ {
+ a4 = a3;
+ a3 = a1;
+ a1 = a4;
+ }
+ if (*a1.name.data == '`' && *(a1.name.data + a1.name.size - 1) == '`')
+ {
+ a1.next = a1.name.data + 1;
+ if (!arg(&a1, -1) || a1.name.size != 4 || !strneq(a1.name.data, "echo", 4) || !arg(&a1, -1))
+ goto lose;
+ a4.next = a1.next;
+ if (!arg(&a4, 1) || a4.name.size < 21 || !strneq(a4.name.data, "| tr '[A-Z]' '[a-z]'`", 21))
+ goto lose;
+ }
+ else
+ a4.name.size = 0;
+ c = *a2.name.data == '!';
+ if (a1.name.size != a3.name.size)
+ c ^= 0;
+ else c ^= (a4.name.size ? strncasecmp : strncmp)(a1.name.data, a3.name.data, a1.name.size) == 0;
+ if (c)
+ break;
+ goto skip;
+ }
+ }
+ lose:
+ if (!system(s))
+ break;
+ }
+ skip:
+ if (!(cap = cap->next))
+ return 0;
+ }
+ att = &cap->att;
+ if (view && *view && !streq(view, "-"))
+ while (strcasecmp(view, att->name))
+ if (!(att = att->next))
+ return 0;
+ return expand(mp, att->value, name, type, opts);
+ }
+ return 0;
+}
+
+/*
+ * lower case identifier prefix strcmp
+ * if e!=0 then it will point to the next char after the match
+ */
+
+int
+mimecmp(register const char* s, register const char* v, char** e)
+{
+ register int n;
+
+ while (isalnum(*v) || *v == *s && (*v == '_' || *v == '-' || *v == '/'))
+ if (n = lower(*s++) - lower(*v++))
+ return n;
+ if (!isalnum(*s) && *s != '_' && *s != '-')
+ {
+ if (e)
+ *e = (char*)s;
+ return 0;
+ }
+ return lower(*s) - lower(*v);
+}
+
+/*
+ * parse mime headers in strsearch(tab,num,siz) from s
+ * return >0 if mime header consumed
+ */
+
+int
+mimehead(Mime_t* mp, void* tab, size_t num, size_t siz, register char* s)
+{
+ register void* p;
+ char* e;
+ Parse_t pp;
+ Mimevalue_f set;
+
+ set = mp->disc->valuef;
+ if (!strncasecmp(s, "original-", 9))
+ s += 9;
+ if (!strncasecmp(s, "content-", 8))
+ {
+ s += 8;
+ if ((p = strsearch(tab, num, siz, (Strcmp_f)mimecmp, s, &e)) && *e == ':')
+ {
+ pp.next = e + 1;
+ if (arg(&pp, 1))
+ {
+ if ((*set)(mp, p, pp.name.data, pp.name.size, mp->disc))
+ return 0;
+ while (arg(&pp, 0))
+ if (pp.value.size &&
+ (p = strsearch(tab, num, siz, (Strcmp_f)mimecmp, pp.name.data, &e)) &&
+ (*set)(mp, p, pp.value.data, pp.value.size, mp->disc))
+ return 0;
+ return 1;
+ }
+ }
+ else if (strchr(s, ':'))
+ return 1;
+ }
+ return !strncasecmp(s, "x-", 2);
+}
+
+/*
+ * open a mime library handle
+ */
+
+Mime_t*
+mimeopen(Mimedisc_t* disc)
+{
+ register Mime_t* mp;
+
+ if (!(mp = newof(0, Mime_t, 1, 0)))
+ return 0;
+ mp->id = lib;
+ mp->disc = disc;
+ mp->dict.key = offsetof(Ent_t, name);
+ mp->dict.comparf = order;
+ mp->dict.freef = drop;
+ if (!(mp->buf = sfstropen()) || !(mp->cap = dtopen(&mp->dict, Dtoset)))
+ {
+ mimeclose(mp);
+ return 0;
+ }
+ return mp;
+}
+
+/*
+ * close a mimeopen() handle
+ */
+
+int
+mimeclose(Mime_t* mp)
+{
+ if (mp)
+ {
+ if (mp->buf)
+ sfclose(mp->buf);
+ if (mp->cap)
+ dtclose(mp->cap);
+ if (mp->freef)
+ (*mp->freef)(mp);
+ free(mp);
+ }
+ return 0;
+}
diff --git a/src/lib/libast/misc/mimelib.h b/src/lib/libast/misc/mimelib.h
new file mode 100644
index 0000000..ebfa343
--- /dev/null
+++ b/src/lib/libast/misc/mimelib.h
@@ -0,0 +1,52 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * mime/mailcap internal interface
+ */
+
+#ifndef _MIMELIB_H
+#define _MIMELIB_H 1
+
+#include <ast.h>
+#include <cdt.h>
+#include <magic.h>
+#include <tok.h>
+
+struct Mime_s;
+
+typedef void (*Free_f)(struct Mime_s*);
+
+#define _MIME_PRIVATE_ \
+ Mimedisc_t* disc; /* mime discipline */ \
+ Dtdisc_t dict; /* cdt discipline */ \
+ Magicdisc_t magicd; /* magic discipline */ \
+ Dt_t* cap; /* capability tree */ \
+ Sfio_t* buf; /* string buffer */ \
+ Magic_t* magic; /* mimetype() magic handle */ \
+ Free_f freef; /* avoid magic lib if possible */ \
+
+#include <mime.h>
+#include <ctype.h>
+
+#endif
diff --git a/src/lib/libast/misc/mimetype.c b/src/lib/libast/misc/mimetype.c
new file mode 100644
index 0000000..63fdd0b
--- /dev/null
+++ b/src/lib/libast/misc/mimetype.c
@@ -0,0 +1,69 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * mime/mailcap to magic support
+ */
+
+#include "mimelib.h"
+
+/*
+ * close magic handle
+ * done this way so that magic is only pulled in
+ * if mimetype() is used
+ */
+
+static void
+drop(Mime_t* mp)
+{
+ if (mp->magic)
+ {
+ magicclose(mp->magic);
+ mp->magic = 0;
+ }
+}
+
+/*
+ * return mime type for file
+ */
+
+char*
+mimetype(Mime_t* mp, Sfio_t* fp, const char* file, struct stat* st)
+{
+ if (mp->disc->flags & MIME_NOMAGIC)
+ return 0;
+ if (!mp->magic)
+ {
+ mp->magicd.version = MAGIC_VERSION;
+ mp->magicd.flags = MAGIC_MIME;
+ mp->magicd.errorf = mp->disc->errorf;
+ if (!(mp->magic = magicopen(&mp->magicd)))
+ {
+ mp->disc->flags |= MIME_NOMAGIC;
+ return 0;
+ }
+ mp->freef = drop;
+ magicload(mp->magic, NiL, 0);
+ }
+ return magictype(mp->magic, fp, file, st);
+}
diff --git a/src/lib/libast/misc/optctx.c b/src/lib/libast/misc/optctx.c
new file mode 100644
index 0000000..1dbdf71
--- /dev/null
+++ b/src/lib/libast/misc/optctx.c
@@ -0,0 +1,70 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * _opt_infop_ context control
+ *
+ * allocate new context:
+ * new_context = optctx(0, 0);
+ * free new context:
+ * optctx(0, new_context);
+ * switch to new_context:
+ * old_context = optctx(new_context, 0);
+ * switch to old_context and free new_context:
+ * optctx(old_context, new_context);
+ */
+
+#include <optlib.h>
+
+static Opt_t* freecontext;
+
+Opt_t*
+optctx(Opt_t* p, Opt_t* o)
+{
+ if (o)
+ {
+ if (freecontext)
+ free(o);
+ else
+ freecontext = o;
+ if (!p)
+ return 0;
+ }
+ if (p)
+ {
+ o = _opt_infop_;
+ _opt_infop_ = p;
+ }
+ else
+ {
+ if (o = freecontext)
+ freecontext = 0;
+ else if (!(o = newof(0, Opt_t, 1, 0)))
+ return 0;
+ memset(o, 0, sizeof(Opt_t));
+ o->state = _opt_infop_->state;
+ }
+ return o;
+}
diff --git a/src/lib/libast/misc/optesc.c b/src/lib/libast/misc/optesc.c
new file mode 100644
index 0000000..8b023c5
--- /dev/null
+++ b/src/lib/libast/misc/optesc.c
@@ -0,0 +1,93 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * escape optget() special chars in s and write to sp
+ * esc == '?' or ':' also escaped
+ */
+
+#include <optlib.h>
+#include <ctype.h>
+
+int
+optesc(Sfio_t* sp, register const char* s, int esc)
+{
+ register const char* m;
+ register int c;
+
+ if (*s == '[' && *(s + 1) == '+' && *(s + 2) == '?')
+ {
+ c = strlen(s);
+ if (s[c - 1] == ']')
+ {
+ sfprintf(sp, "%-.*s", c - 4, s + 3);
+ return 0;
+ }
+ }
+ if (esc != '?' && esc != ':')
+ esc = 0;
+ while (c = *s++)
+ {
+ if (isalnum(c))
+ {
+ for (m = s - 1; isalnum(*s); s++);
+ if (isalpha(c) && *s == '(' && isdigit(*(s + 1)) && *(s + 2) == ')')
+ {
+ sfputc(sp, '\b');
+ sfwrite(sp, m, s - m);
+ sfputc(sp, '\b');
+ sfwrite(sp, s, 3);
+ s += 3;
+ }
+ else
+ sfwrite(sp, m, s - m);
+ }
+ else if (c == '-' && *s == '-' || c == '<')
+ {
+ m = s - 1;
+ if (c == '-')
+ s++;
+ else if (*s == '/')
+ s++;
+ while (isalnum(*s))
+ s++;
+ if (c == '<' && *s == '>' || isspace(*s) || *s == 0 || *s == '=' || *s == ':' || *s == ';' || *s == '.' || *s == ',')
+ {
+ sfputc(sp, '\b');
+ sfwrite(sp, m, s - m);
+ sfputc(sp, '\b');
+ }
+ else
+ sfwrite(sp, m, s - m);
+ }
+ else
+ {
+ if (c == ']' || c == esc)
+ sfputc(sp, c);
+ sfputc(sp, c);
+ }
+ }
+ return 0;
+}
diff --git a/src/lib/libast/misc/optget.c b/src/lib/libast/misc/optget.c
new file mode 100644
index 0000000..bd4df04
--- /dev/null
+++ b/src/lib/libast/misc/optget.c
@@ -0,0 +1,5751 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * command line option parser and usage formatter
+ * its a monster but its all in one place
+ * widen your window while you're at it
+ */
+
+#include <optlib.h>
+#include <debug.h>
+#include <ccode.h>
+#include <ctype.h>
+#include <errno.h>
+
+#define KEEP "*[A-Za-z][A-Za-z]*"
+#define OMIT "*@(\\[[-+]*\\?*\\]|\\@\\(#\\)|Copyright \\(c\\)|\\$\\I\\d\\: )*"
+
+#define GO '{' /* group nest open */
+#define OG '}' /* group nest close */
+
+#define OPT_WIDTH 80 /* default help text width */
+#define OPT_MARGIN 10 /* default help text margin */
+#define OPT_USAGE 7 /* usage continuation indent */
+
+#define OPT_flag 0x001 /* flag ( 0 or 1 ) */
+#define OPT_hidden 0x002 /* remaining are hidden */
+#define OPT_ignorecase 0x004 /* arg match ignores case */
+#define OPT_invert 0x008 /* flag inverts long sense */
+#define OPT_listof 0x010 /* arg is ' ' or ',' list */
+#define OPT_number 0x020 /* arg is strtonll() number */
+#define OPT_oneof 0x040 /* arg may be set once */
+#define OPT_optional 0x080 /* arg is optional */
+#define OPT_string 0x100 /* arg is string */
+
+#define OPT_preformat 0001 /* output preformat string */
+#define OPT_proprietary 0002 /* proprietary docs */
+
+#define OPT_TYPE (OPT_flag|OPT_number|OPT_string)
+
+#define STYLE_posix 0 /* posix getopt usage */
+#define STYLE_short 1 /* [default] short usage */
+#define STYLE_long 2 /* long usage */
+#define STYLE_match 3 /* long description of matches */
+#define STYLE_options 4 /* short and long descriptions */
+#define STYLE_man 5 /* pretty details */
+#define STYLE_html 6 /* html details */
+#define STYLE_nroff 7 /* nroff details */
+#define STYLE_api 8 /* program details */
+#define STYLE_keys 9 /* translation key strings */
+#define STYLE_usage 10 /* escaped usage string */
+
+#define FONT_BOLD 1
+#define FONT_ITALIC 2
+#define FONT_LITERAL 4
+
+#define HELP_head 0x01
+#define HELP_index 0x02
+
+#define TAG_NONE 0
+#define TAG_DIV 1
+#define TAG_DL 2
+
+#define SEP(c) ((c)=='-'||(c)=='_')
+
+typedef struct Attr_s
+{
+ const char* name;
+ int flag;
+} Attr_t;
+
+typedef struct Help_s
+{
+ const char* match; /* builtin help match name */
+ const char* name; /* builtin help name */
+ int style; /* STYLE_* */
+ const char* text; /* --? text */
+ unsigned int size; /* strlen text */
+} Help_t;
+
+typedef struct Font_s
+{
+ const char* html[2];
+ const char* nroff[2];
+ const char* term[2];
+} Font_t;
+
+typedef struct List_s
+{
+ int type; /* { - + : } */
+ const char* name; /* list name */
+ const char* text; /* help text */
+} List_t;
+
+typedef struct Msg_s
+{
+ const char* text; /* default message text */
+ Dtlink_t link; /* cdt link */
+} Msg_t;
+
+typedef struct Save_s
+{
+ Dtlink_t link; /* cdt link */
+ char text[1]; /* saved text text */
+} Save_t;
+
+typedef struct Push_s
+{
+ struct Push_s* next; /* next string */
+ char* ob; /* next char in old string */
+ char* oe; /* end of old string */
+ char* nb; /* next char in new string */
+ char* ne; /* end of new string */
+ int ch; /* localize() translation */
+} Push_t;
+
+typedef struct Tag_s
+{
+ unsigned char level; /* indent level */
+ unsigned char id; /* TAG_* id */
+} Tag_t;
+
+typedef struct Indent_s
+{
+ int stop; /* tab column position */
+} Indent_t;
+
+static Indent_t indent[] =
+{
+ 0,2, 4,10, 12,18, 20,26, 28,34, 36,42, 44,50, 0,0
+};
+
+static const char* end[] =
+{
+ "", "</DIV>\n", "</DL>\n"
+};
+
+static const char term_off[] = {CC_esc,'[','0','m',0};
+static const char term_B_on[] = {CC_esc,'[','1','m',0};
+static const char term_I_on[] = {CC_esc,'[','1',';','4','m',0};
+
+static const Font_t fonts[] =
+{
+ "", "", "", "", "", "",
+ "</B>", "<B>", "\\fP", "\\fB", &term_off[0], &term_B_on[0],
+ "</I>", "<I>", "\\fP", "\\fI", &term_off[0], &term_I_on[0],
+ "", "", "", "", "", "",
+ "</TT>","<TT>","\\fP", "\\f5", "", "",
+};
+
+static char native[] = "";
+
+static unsigned char map[UCHAR_MAX];
+
+static Optstate_t state;
+
+#if !_PACKAGE_astsa
+
+#define ID ast.id
+
+#define C(s) ERROR_catalog(s)
+#define D(s) (state.msgdict && dtmatch(state.msgdict, (s)))
+#define T(i,c,m) (X(c)?translate(i,c,C(m)):(m))
+#define X(c) (ERROR_translating()&&(c)!=native)
+#define Z(x) C(x),sizeof(x)-1
+
+/*
+ * translate with C_LC_MESSAGES_libast[] check
+ */
+
+static char*
+translate(const char* cmd, const char* cat, const char* msg)
+{
+ if (!X(cat))
+ return (char*)msg;
+ if (cat != (const char*)ID && D(msg))
+ cat = (const char*)ID;
+ return errorx(NiL, cmd, cat, msg);
+}
+
+#else
+
+static char ID[] = "ast";
+
+#define C(s) s
+#define D(s) (state.msgdict && dtmatch(state.msgdict, (s)))
+#define T(i,c,m) m
+#define X(c) 0
+#define Z(x) C(x),sizeof(x)-1
+
+#endif
+
+static const List_t help_head[] =
+{
+ '-', 0,
+ 0,
+ '+', C("NAME"),
+ C("options available to all \bast\b commands"),
+ '+', C("DESCRIPTION"),
+ C("\b-?\b and \b--?\b* options are the same \
+for all \bast\b commands. For any \aitem\a below, if \b--\b\aitem\a is not \
+supported by a given command then it is equivalent to \b--\?\?\b\aitem\a. The \
+\b--\?\?\b form should be used for portability. All output is written to the \
+standard error."),
+};
+
+static const Help_t styles[] =
+{
+ C("about"), "-", STYLE_match,
+ Z("List all implementation info."),
+ C("api"), "?api", STYLE_api,
+ Z("List detailed info in program readable form."),
+ C("help"), "", -1,
+ Z("List detailed help option info."),
+ C("html"), "?html", STYLE_html,
+ Z("List detailed info in html."),
+ C("keys"), "?keys", STYLE_keys,
+ Z("List the usage translation key strings with C style escapes."),
+ C("long"), "?long", STYLE_long,
+ Z("List long option usage."),
+ C("man"), "?man", STYLE_man,
+ Z("List detailed info in displayed man page form."),
+ C("nroff"), "?nroff", STYLE_nroff,
+ Z("List detailed info in nroff."),
+ C("options"), "?options", STYLE_options,
+ Z("List short and long option details."),
+ C("posix"), "?posix", STYLE_posix,
+ Z("List posix getopt usage."),
+ C("short"), "?short", STYLE_short,
+ Z("List short option usage."),
+ C("usage"), "?usage", STYLE_usage,
+ Z("List the usage string with C style escapes."),
+};
+
+static const List_t help_tail[] =
+{
+ ':', C("\?\?-\alabel\a"),
+ C("List implementation info matching \alabel\a*."),
+ ':', C("\?\?\aname\a"),
+ C("Equivalent to \b--help=\b\aname\a."),
+ ':', C("\?\?"),
+ C("Equivalent to \b--\?\?options\b."),
+ ':', C("\?\?\?\?"),
+ C("Equivalent to \b--\?\?man\b."),
+ ':', C("\?\?\?\?\?\?"),
+ C("Equivalent to \b--\?\?help\b."),
+ ':', C("\?\?\?\?\?\?\aitem\a"),
+ C("If the next argument is \b--\b\aoption\a then list \
+the \aoption\a output in the \aitem\a style. Otherwise print \
+\bversion=\b\an\a where \an\a>0 if \b--\?\?\b\aitem\a is supported, \b0\b \
+if not."),
+ ':', C("\?\?\?\?\?\?ESC"),
+ C("Emit escape codes even if output is not a terminal."),
+ ':', C("\?\?\?\?\?\?MAN[=\asection\a]]"),
+ C("List the \bman\b(1) section title for \asection\a [the \
+current command]]."),
+ ':', C("\?\?\?\?\?\?SECTION"),
+ C("List the \bman\b(1) section number for the current command."),
+ ':', C("\?\?\?\?\?\?TEST"),
+ C("Massage the output for regression testing."),
+};
+
+static const Attr_t attrs[] =
+{
+ "flag", OPT_flag,
+ "hidden", OPT_hidden,
+ "ignorecase", OPT_ignorecase,
+ "invert", OPT_invert,
+ "listof", OPT_listof,
+ "number", OPT_number,
+ "oneof", OPT_oneof,
+ "optional", OPT_optional,
+ "string", OPT_string,
+};
+
+static const char unknown[] = C("unknown option or attribute");
+
+static const char* heading[] =
+{
+ C("INDEX"),
+ C("USER COMMANDS"),
+ C("SYSTEM LIBRARY"),
+ C("USER LIBRARY"),
+ C("FILE FORMATS"),
+ C("MISCELLANEOUS"),
+ C("GAMES and DEMOS"),
+ C("SPECIAL FILES"),
+ C("ADMINISTRATIVE COMMANDS"),
+ C("GUIs"),
+};
+
+/*
+ * list of common man page strings
+ * NOTE: add but do not delete from this table
+ */
+
+static Msg_t C_LC_MESSAGES_libast[] =
+{
+ { C("APPLICATION USAGE") },
+ { C("ASYNCHRONOUS EVENTS") },
+ { C("BUGS") },
+ { C("CAVEATS") },
+ { C("CONSEQUENCES OF ERRORS") },
+ { C("DESCRIPTION") },
+ { C("ENVIRONMENT VARIABLES") },
+ { C("EXAMPLES") },
+ { C("EXIT STATUS") },
+ { C("EXTENDED DESCRIPTION") },
+ { C("INPUT FILES") },
+ { C("LIBRARY") },
+ { C("NAME") },
+ { C("OPERANDS") },
+ { C("OPTIONS") },
+ { C("OUTPUT FILES") },
+ { C("PLUGIN") },
+ { C("SEE ALSO") },
+ { C("STDERR") },
+ { C("STDIN") },
+ { C("STDOUT") },
+ { C("SYNOPSIS") },
+ { C("author") },
+ { C("copyright") },
+ { C("license") },
+ { C("name") },
+ { C("path") },
+ { C("version") },
+};
+
+/*
+ * 2007-03-19 move opt_info from _opt_info_ to (*_opt_data_)
+ * to allow future Opt_t growth
+ * by 2009 _opt_info_ can be static
+ */
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+
+extern Opt_t _opt_info_;
+
+Opt_t _opt_info_ = { 0,0,0,0,0,0,0,{0},{0},0,0,0,{0},{0},&state };
+
+#undef extern
+
+__EXTERN__(Opt_t, _opt_info_);
+
+__EXTERN__(Opt_t*, _opt_infop_);
+
+Opt_t* _opt_infop_ = &_opt_info_;
+
+Optstate_t*
+optstate(Opt_t* p)
+{
+ return &state;
+}
+
+#if DEBUG || _BLD_DEBUG
+
+/*
+ * debug usage string segment format
+ */
+
+static char*
+show(register char* s)
+{
+ register int c;
+ register char* t;
+ register char* e;
+
+ static char buf[32];
+
+ if (!s)
+ return "(null)";
+ t = buf;
+ e = buf + sizeof(buf) - 2;
+ while (t < e)
+ {
+ switch (c = *s++)
+ {
+ case 0:
+ goto done;
+ case '\a':
+ *t++ = '\\';
+ c = 'a';
+ break;
+ case '\b':
+ *t++ = '\\';
+ c = 'b';
+ break;
+ case '\f':
+ *t++ = '\\';
+ c = 'f';
+ break;
+ case '\n':
+ *t++ = '\\';
+ c = 'n';
+ break;
+ case '\t':
+ *t++ = '\\';
+ c = 't';
+ break;
+ case '\v':
+ *t++ = '\\';
+ c = 'v';
+ break;
+ }
+ *t++ = c;
+ }
+ done:
+ *t = 0;
+ return buf;
+}
+
+#endif
+
+typedef struct Section_s
+{
+ const char section[4];
+ const char* name;
+} Section_t;
+
+static const Section_t sections[] =
+{
+ "1M", "MAKE ASSERTION OPERATORS AND RULES",
+ "1", "USER COMMANDS",
+ "2", "SYSTEM CALLS",
+ "3F", "FORTRAN LIBRARY ROUTINES",
+ "3K", "KERNEL VM LIBRARY FUNCTIONS",
+ "3L", "LIGHTWEIGHT PROCESSES LIBRARY",
+ "3M", "MATHEMATICAL LIBRARY",
+ "3N", "NETWORK FUNCTIONS",
+ "3R", "RPC SERVICES LIBRARY",
+ "3S", "STANDARD I/O FUNCTIONS",
+ "3V", "SYSTEM V LIBRARY",
+ "3", "C LIBRARY FUNCTIONS",
+ "4F", "PROTOCOL FAMILIES",
+ "4P", "PROTOCOLS",
+ "4", "DEVICES AND NETWORK INTERFACES",
+ "5P", "PLUGINS",
+ "5", "FILE FORMATS",
+ "6", "GAMES AND DEMOS",
+ "7", "PUBLIC FILES AND TABLES",
+ "8", "ADMINISTRATIVE COMMANDS",
+ "L", "LOCAL COMMANDS",
+};
+
+/*
+ * return section name given abbreviation
+ */
+
+static char*
+secname(char* section)
+{
+ int i;
+ char* b;
+ char* t;
+ const char* s;
+
+ b = t = fmtbuf(64);
+ if (section[1])
+ {
+ switch (section[2] ? section[2] : section[1])
+ {
+ case 'C':
+ s = "COMPATIBILITY ";
+ break;
+ case 'U':
+ s = "UWIN ";
+ break;
+ case 'X':
+ s = "MISCELLANEOUS ";
+ break;
+ default:
+ s = 0;
+ break;
+ }
+ if (s)
+ t = strcopy(t, s);
+ }
+ s = 0;
+ for (i = 0; i < elementsof(sections); i++)
+ if (section[0] == sections[i].section[0] && (section[1] == sections[i].section[1] || !sections[i].section[1]))
+ {
+ s = sections[i].name;
+ break;
+ }
+ if (!s)
+ {
+ t = strcopy(t, "SECTION ");
+ s = section;
+ }
+ strcopy(t, s);
+ return b;
+}
+
+/*
+ * pop the push stack
+ */
+
+static Push_t*
+pop(register Push_t* psp)
+{
+ register Push_t* tsp;
+
+ while (tsp = psp)
+ {
+ psp = psp->next;
+ free(tsp);
+ }
+ return 0;
+}
+
+/*
+ * skip over line space to the next token
+ */
+
+static char*
+next(register char* s, int version)
+{
+ register char* b;
+
+ while (*s == '\t' || *s == '\r' || version >= 1 && *s == ' ')
+ s++;
+ if (*s == '\n')
+ {
+ b = s;
+ while (*++s == ' ' || *s == '\t' || *s == '\r');
+ if (*s == '\n')
+ return b;
+ }
+ return s;
+}
+
+/*
+ * skip to t1 or t2 or t3, whichever first, in s
+ * n==0 outside [...]
+ * n==1 inside [...] before ?
+ * n==2 inside [...] after ?
+ * b==0 outside {...}
+ * b==1 inside {...}
+ * past skips past the terminator to the next token
+ * otherwise a pointer to the terminator is returned
+ *
+ * ]] for ] inside [...]
+ * ?? for ? inside [...] before ?
+ * :: for : inside [...] before ?
+ */
+
+static char*
+skip(register char* s, register int t1, register int t2, register int t3, register int n, register int b, int past, int version)
+{
+ register int c;
+ register int on = n;
+ register int ob = b;
+
+ if (version < 1)
+ {
+ n = n >= 1;
+ for (;;)
+ {
+ switch (*s++)
+ {
+ case 0:
+ break;
+ case '[':
+ n++;
+ continue;
+ case ']':
+ if (--n <= 0)
+ break;
+ continue;
+ default:
+ continue;
+ }
+ break;
+ }
+ }
+ else while (c = *s++)
+ {
+ message((-22, "optget: skip t1=%c t2=%c t3=%c n=%d b=%d `%s'", t1 ? t1 : '@', t2 ? t2 : '@', t3 ? t3 : '@', n, b, show(s - 1)));
+ if (c == '[')
+ {
+ if (!n)
+ n = 1;
+ }
+ else if (c == ']')
+ {
+ if (n)
+ {
+ if (*s == ']')
+ s++;
+ else if (on == 1)
+ break;
+ else
+ n = 0;
+ }
+ }
+ else if (c == GO)
+ {
+ if (n == 0)
+ b++;
+ }
+ else if (c == OG)
+ {
+ if (n == 0 && b-- == ob)
+ break;
+ }
+ else if (c == '?')
+ {
+ if (n == 1)
+ {
+ if (*s == '?')
+ s++;
+ else
+ {
+ if (n == on && (c == t1 || c == t2 || c == t3))
+ break;
+ n = 2;
+ }
+ }
+ }
+ else if (n == on && (c == t1 || c == t2 || c == t3))
+ {
+ if (n == 1 && c == ':' && *s == c)
+ s++;
+ else
+ break;
+ }
+ }
+ return past && *(s - 1) ? next(s, version) : s - 1;
+}
+
+/*
+ * *s points to '(' on input
+ * return is one past matching ')'
+ */
+
+static char*
+nest(register char* s)
+{
+ int n;
+
+ n = 0;
+ for (;;)
+ {
+ switch (*s++)
+ {
+ case '(':
+ n++;
+ continue;
+ case ')':
+ if (!--n)
+ break;
+ continue;
+ default:
+ continue;
+ }
+ break;
+ }
+ return s;
+}
+
+/*
+ * match s with t
+ * t translated if possible
+ * embedded { - _ ' } ignored
+ * * separates required prefix from optional suffix
+ * otherwise prefix match
+ */
+
+static int
+match(char* s, char* t, int version, const char* id, const char* catalog)
+{
+ register char* w;
+ register char* x;
+ char* xw;
+ char* ww;
+ int n;
+ int v;
+ int j;
+
+ for (n = 0; n < 2; n++)
+ {
+ if (n)
+ x = t;
+ else
+ {
+ if (catalog)
+ {
+ w = skip(t, ':', '?', 0, 1, 0, 0, version);
+ w = sfprints("%-.*s", w - t, t);
+ x = T(id, catalog, w);
+ if (x == w)
+ continue;
+ }
+ x = T(NiL, ID, t);
+ if (x == t)
+ continue;
+ }
+ do
+ {
+ v = 0;
+ xw = x;
+ w = ww = s;
+ while (*x && *w)
+ {
+ if (isupper(*x))
+ xw = x;
+ if (isupper(*w))
+ ww = w;
+ if (*x == '*' && !v++ || *x == '\a')
+ {
+ if (*x == '\a')
+ do
+ {
+ if (!*++x)
+ {
+ x--;
+ break;
+ }
+ } while (*x != '\a');
+ j = *(x + 1);
+ if (j == ':' || j == '|' || j == '?' || j == ']' || j == 0)
+ while (*w)
+ w++;
+ }
+ else if (SEP(*x))
+ xw = ++x;
+ else if (SEP(*w) && w != s)
+ ww = ++w;
+ else if (*x == *w)
+ {
+ x++;
+ w++;
+ }
+ else if (w == ww && x == xw)
+ break;
+ else
+ {
+ if (x != xw)
+ {
+ while (*x && !SEP(*x) && !isupper(*x))
+ x++;
+ if (!*x)
+ break;
+ if (SEP(*x))
+ x++;
+ xw = x;
+ }
+ while (w > ww && *w != *x)
+ w--;
+ }
+ }
+ if (!*w)
+ {
+ if (!v)
+ {
+ for (;;)
+ {
+ switch (*x++)
+ {
+ case 0:
+ case ':':
+ case '|':
+ case '?':
+ case ']':
+ return 1;
+ case '*':
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+ break;
+ }
+ return 1;
+ }
+ } while (*(x = skip(x, '|', 0, 0, 1, 0, 0, version)) == '|' && x++);
+ }
+ return 0;
+}
+
+/*
+ * prefix search for s in tab with num elements of size
+ * with optional translation
+ */
+
+static void*
+search(const void* tab, size_t num, size_t siz, char* s)
+{
+ register char* p;
+ register char* e;
+
+ for (e = (p = (char*)tab) + num * siz; p < e; p += siz)
+ if (match(s, *((char**)p), -1, NiL, NiL))
+ return (void*)p;
+ return 0;
+}
+
+/*
+ * save ap+bp+cp and return the saved pointer
+ */
+
+static char*
+save(const char* ap, size_t az, const char* bp, size_t bz, const char* cp, size_t cz)
+{
+ char* b;
+ char* e;
+ const char* ep;
+ Save_t* p;
+ Dtdisc_t* d;
+ char buf[1024];
+
+ static Dt_t* dict;
+
+ if (!dict)
+ {
+ if (!(d = newof(0, Dtdisc_t, 1, 0)))
+ return (char*)ap;
+ d->key = offsetof(Save_t, text);
+ if (!(dict = dtopen(d, Dtset)))
+ return (char*)ap;
+ }
+ b = buf;
+ e = b + sizeof(buf) - 1;
+ for (ep = ap + az; b < e && ap < ep; *b++ = *ap++);
+ if (bp)
+ {
+ for (ep = bp + bz; b < e && bp < ep; *b++ = *bp++);
+ if (cp)
+ for (ep = cp + cz; b < e && cp < ep; *b++ = *cp++);
+ }
+ *b = 0;
+ if (!(p = (Save_t*)dtmatch(dict, buf)))
+ {
+ if (!(p = newof(0, Save_t, 1, b - buf)))
+ return (char*)ap;
+ strcpy(p->text, buf);
+ dtinsert(dict, p);
+ }
+ return p->text;
+}
+
+/*
+ * expand \f...\f info
+ * *p set to next char after second \f
+ * expanded value returned
+ */
+
+static char*
+expand(register char* s, register char* e, char** p, Sfio_t* ip, char* id)
+{
+ register int c;
+ register char* b = s;
+ int n;
+
+ n = sfstrtell(ip);
+ c = 1;
+ while ((!e || s < e) && (c = *s++) && c != '\f');
+ sfwrite(ip, b, s - b - 1);
+ sfputc(ip, 0);
+ b = sfstrbase(ip) + n;
+ n = sfstrtell(ip);
+ if (!c)
+ s--;
+ if (*b == '?')
+ {
+ if (!*++b || streq(b, "NAME"))
+ {
+ if (!(b = id))
+ b = "command";
+ sfstrseek(ip, 0, SEEK_SET);
+ sfputr(ip, b, -1);
+ n = 0;
+ }
+ else
+ n = 1;
+ }
+ else if (!opt_info.disc || !opt_info.disc->infof || (*opt_info.disc->infof)(&opt_info, ip, b, opt_info.disc) < 0)
+ n = 0;
+ *p = s;
+ if (s = sfstruse(ip))
+ s += n;
+ else
+ s = "error";
+ return s;
+}
+
+/*
+ * initialize the translation dictionary and flag maps
+ */
+
+static void
+initdict(void)
+{
+ register int n;
+
+ state.vp = sfstropen();
+ state.msgdisc.key = offsetof(Msg_t, text);
+ state.msgdisc.size = -1;
+ state.msgdisc.link = offsetof(Msg_t, link);
+ if (state.msgdict = dtopen(&state.msgdisc, Dtset))
+ for (n = 0; n < elementsof(C_LC_MESSAGES_libast); n++)
+ dtinsert(state.msgdict, C_LC_MESSAGES_libast + n);
+}
+
+/*
+ * initialize the attributes for pass p from opt string s
+ */
+
+static int
+init(register char* s, Optpass_t* p)
+{
+ register char* t;
+ register char* u;
+ register int c;
+ register int a;
+ register int n;
+ char* e;
+ int l;
+
+ if (!state.localized)
+ {
+ state.localized = 1;
+#if !_PACKAGE_astsa
+ if (!ast.locale.serial)
+ setlocale(LC_ALL, "");
+#endif
+ state.xp = sfstropen();
+ if (!map[OPT_FLAGS[0]])
+ for (n = 0, t = OPT_FLAGS; *t; t++)
+ map[*t] = ++n;
+ }
+#if _BLD_DEBUG
+ error(-1, "optget debug");
+#endif
+ p->oopts = s;
+ p->version = 0;
+ p->prefix = 2;
+ p->section[0] = '1';
+ p->section[1] = 0;
+ p->flags = 0;
+ p->id = error_info.id;
+ p->catalog = 0;
+ s = next(s, 0);
+ if (*s == ':')
+ s++;
+ if (*s == '+')
+ s++;
+ s = next(s, 0);
+ if (*s++ == '[')
+ {
+ if (*s == '+')
+ p->version = 1;
+ else if (*s++ == '-')
+ {
+ if (*s == '?' || *s == ']')
+ p->version = 1;
+ else
+ {
+ if (!isdigit(*s))
+ p->version = 1;
+ else
+ while (isdigit(*s))
+ p->version = p->version * 10 + (*s++ - '0');
+ while (*s && *s != ']')
+ {
+ if ((c = *s++) == '?')
+ {
+ p->release = s;
+ while (*s && *s != ']')
+ if (isspace(*s++))
+ p->release = s;
+ break;
+ }
+ else if (!isdigit(*s))
+ n = 1;
+ else
+ {
+ n = 0;
+ while (isdigit(*s))
+ n = n * 10 + (*s++ - '0');
+ }
+ switch (c)
+ {
+ case '+':
+ p->flags |= OPT_plus;
+ break;
+ case 'a':
+ p->flags |= OPT_append;
+ break;
+ case 'c':
+ p->flags |= OPT_cache;
+ break;
+ case 'i':
+ p->flags |= OPT_ignore;
+ break;
+ case 'l':
+ p->flags |= OPT_long;
+ break;
+ case 'm':
+ p->flags |= OPT_module;
+ break;
+ case 'n':
+ p->flags |= OPT_numeric;
+ break;
+ case 'o':
+ p->flags |= OPT_old;
+ break;
+ case 'p':
+ p->prefix = n;
+ break;
+ case 's':
+ if (n > 1 && n < 5)
+ {
+ p->flags |= OPT_functions;
+ p->prefix = 0;
+ }
+ p->section[0] = '0' + (n % 10);
+ n = 1;
+ if (isupper(*s))
+ p->section[n++] = *s++;
+ if (isupper(*s))
+ p->section[n++] = *s++;
+ p->section[n] = 0;
+ break;
+ }
+ }
+ }
+ }
+ while (*s)
+ if (*s++ == ']')
+ {
+ while (isspace(*s))
+ s++;
+ if (*s++ == '[')
+ {
+ if (*s++ != '-')
+ {
+ l = 0;
+ if (strneq(s - 1, "+NAME?", 6) && (s += 5) || strneq(s - 1, "+LIBRARY?", 9) && (s += 8) && (l = 1) || strneq(s - 1, "+PLUGIN?", 8) && (s += 7) && (l = 1))
+ {
+ for (; *s == '\a' || *s == '\b' || *s == '\v' || *s == ' '; s++);
+ if (*s == '\f')
+ {
+ if (*(s + 1) == '?' && *(s + 2) == '\f')
+ break;
+ s = expand(s + 1, NiL, &e, state.xp, p->id);
+ }
+ for (t = s; *t && *t != ' ' && *t != ']'; t++);
+ if (t > s)
+ {
+ u = t;
+ if (*(t - 1) == '\a' || *(t - 1) == '\b' || *(t - 1) == '\v')
+ t--;
+ if (t > s)
+ {
+ while (*u == ' ' || *u == '\\')
+ u++;
+ if (*u == '-' || *u == ']')
+ {
+ if (!l)
+ p->id = save(s, t - s, 0, 0, 0, 0);
+ else if ((a = strlen(p->id)) <= (n = t - s) || strncmp(p->id + a - n, s, n) || *(p->id + a - n - 1) != ':')
+ p->id = save(p->id, strlen(p->id), "::", 2, s, t - s);
+ }
+ }
+ }
+ }
+ break;
+ }
+ if (*s == '-')
+ s++;
+ if (strneq(s, "catalog?", 8))
+ p->catalog = s += 8;
+ }
+ }
+ }
+ if (!error_info.id)
+ {
+ if (!(error_info.id = p->id))
+ p->id = "command";
+ }
+ else if (p->id == error_info.id)
+ p->id = save(p->id, strlen(p->id), 0, 0, 0, 0);
+ if (s = p->catalog)
+ p->catalog = ((t = strchr(s, ']')) && (!p->id || (t - s) != strlen(p->id) || !strneq(s, p->id, t - s))) ? save(s, t - s, 0, 0, 0, 0) : (char*)0;
+ if (!p->catalog)
+ {
+ if (opt_info.disc && opt_info.disc->catalog && (!p->id || !streq(opt_info.disc->catalog, p->id)))
+ p->catalog = opt_info.disc->catalog;
+ else
+ p->catalog = ID;
+ }
+ s = p->oopts;
+ if (*s == ':')
+ s++;
+ if (*s == '+')
+ {
+ s++;
+ p->flags |= OPT_plus;
+ }
+ s = next(s, 0);
+ if (*s != '[')
+ for (t = s, a = 0; *t; t++)
+ if (!a && *t == '-')
+ {
+ p->flags |= OPT_minus;
+ break;
+ }
+ else if (*t == '[')
+ a++;
+ else if (*t == ']')
+ a--;
+ if (!p->version && (t = strchr(s, '(')) && strchr(t, ')') && (state.cp || (state.cp = sfstropen())))
+ {
+ /*
+ * solaris long option compatibility
+ */
+
+ p->version = 1;
+ for (t = p->oopts; t < s; t++)
+ sfputc(state.cp, *t);
+ n = t - p->oopts;
+ sfputc(state.cp, '[');
+ sfputc(state.cp, '-');
+ sfputc(state.cp, ']');
+ c = *s++;
+ while (c)
+ {
+ sfputc(state.cp, '[');
+ sfputc(state.cp, c);
+ if (a = (c = *s++) == ':')
+ c = *s++;
+ if (c == '(')
+ {
+ sfputc(state.cp, ':');
+ for (;;)
+ {
+ while ((c = *s++) && c != ')')
+ sfputc(state.cp, c);
+ if (!c || (c = *s++) != '(')
+ break;
+ sfputc(state.cp, '|');
+ }
+ }
+ sfputc(state.cp, ']');
+ if (a)
+ sfputr(state.cp, ":[string]", -1);
+ }
+ if (!(p->oopts = s = sfstruse(state.cp)))
+ return -1;
+ s += n;
+ }
+ p->opts = s;
+ message((-1, "version=%d prefix=%d section=%s flags=%04x id=%s catalog=%s oopts=%p", p->version, p->prefix, p->section, p->flags, p->id, p->catalog, p->oopts));
+ return 0;
+}
+
+/*
+ * return the bold set/unset sequence for style
+ */
+
+static const char*
+font(int f, int style, int set)
+{
+ switch (style)
+ {
+ case STYLE_html:
+ return fonts[f].html[set];
+ case STYLE_nroff:
+ return fonts[f].nroff[set];
+ case STYLE_short:
+ case STYLE_long:
+ case STYLE_posix:
+ case STYLE_api:
+ break;
+ default:
+ if (state.emphasis > 0)
+ return fonts[f].term[set];
+ break;
+ }
+ return "";
+}
+
+/*
+ * push \f...\f info
+ */
+
+static Push_t*
+info(Push_t* psp, char* s, char* e, Sfio_t* ip, char* id)
+{
+ register char* b;
+ int n;
+ Push_t* tsp;
+
+ static Push_t push;
+
+ b = expand(s, e, &s, ip, id);
+ n = strlen(b);
+ if (tsp = newof(0, Push_t, 1, n + 1))
+ {
+ tsp->nb = (char*)(tsp + 1);
+ tsp->ne = tsp->nb + n;
+ strcpy(tsp->nb, b);
+ }
+ else
+ tsp = &push;
+ tsp->next = psp;
+ tsp->ob = s;
+ tsp->oe = e;
+ return tsp;
+}
+
+/*
+ * push translation
+ */
+
+static Push_t*
+localize(Push_t* psp, char* s, char* e, int term, int n, Sfio_t* ip, int version, char* id, char* catalog)
+{
+ char* t;
+ char* u;
+ Push_t* tsp;
+ int c;
+
+ t = skip(s, term, 0, 0, n, 0, 0, version);
+ if (e && t > e)
+ t = e;
+ while (s < t)
+ {
+ switch (c = *s++)
+ {
+ case ':':
+ case '?':
+ if (term && *s == c)
+ s++;
+ break;
+ case ']':
+ if (*s == c)
+ s++;
+ break;
+ }
+ sfputc(ip, c);
+ }
+ if (!(s = sfstruse(ip)) || (u = T(id, catalog, s)) == s)
+ return 0;
+ n = strlen(u);
+ if (tsp = newof(0, Push_t, 1, n + 1))
+ {
+ tsp->nb = (char*)(tsp + 1);
+ tsp->ne = tsp->nb + n;
+ strcpy(tsp->nb, u);
+ tsp->ob = t;
+ tsp->oe = e;
+ tsp->ch = 1;
+ }
+ tsp->next = psp;
+ return tsp;
+}
+
+/*
+ * output label s from [ ...label...[?...] ] to sp
+ * 1 returned if the label was translated
+ */
+
+static int
+label(register Sfio_t* sp, int sep, register char* s, int about, int z, int level, int style, int f, Sfio_t* ip, int version, char* id, char* catalog)
+{
+ register int c;
+ register char* t;
+ register char* e;
+ int ostyle;
+ int a;
+ int i;
+ char* p;
+ char* q;
+ char* w;
+ char* y;
+ int va;
+ Push_t* tsp;
+
+ int r = 0;
+ int n = 1;
+ Push_t* psp = 0;
+
+ if ((ostyle = style) > (STYLE_nroff - (sep <= 0)) && f != FONT_LITERAL && f >= 0)
+ style = 0;
+ if (z < 0)
+ e = s + strlen(s);
+ else
+ e = s + z;
+ if (sep > 0)
+ {
+ if (sep == ' ' && style == STYLE_nroff)
+ sfputc(sp, '\\');
+ sfputc(sp, sep);
+ }
+ sep = !sep || z < 0;
+ va = 0;
+ y = 0;
+ if (about)
+ sfputc(sp, '(');
+ if (version < 1)
+ {
+ a = 0;
+ for (;;)
+ {
+ if (s >= e)
+ return r;
+ switch (c = *s++)
+ {
+ case '[':
+ a++;
+ break;
+ case ']':
+ if (--a < 0)
+ return r;
+ break;
+ }
+ sfputc(sp, c);
+ }
+ }
+ else if (level && (*(p = skip(s, 0, 0, 0, 1, level, 1, version)) == ':' || *p == '#'))
+ {
+ va = 0;
+ if (*++p == '?' || *p == *(p - 1))
+ {
+ p++;
+ va |= OPT_optional;
+ }
+ if (*(p = next(p, version)) == '[')
+ y = p + 1;
+ }
+ if (X(catalog) && (!level || *s == '\a' || *(s - 1) != '+') &&
+ (tsp = localize(psp, s, e, (sep || level) ? '?' : 0, sep || level, ip, version, id, catalog)))
+ {
+ psp = tsp;
+ s = psp->nb;
+ e = psp->ne;
+ r = psp->ch > 0;
+ }
+ switch (*s)
+ {
+ case '\a':
+ if (f == FONT_ITALIC || f < 0)
+ s++;
+ if (f > 0)
+ f = 0;
+ break;
+ case '\b':
+ if (f == FONT_BOLD || f < 0)
+ s++;
+ if (f > 0)
+ f = 0;
+ break;
+ case '\v':
+ if (f == FONT_LITERAL || f < 0)
+ s++;
+ if (f > 0)
+ f = 0;
+ break;
+ default:
+ if (f > 0)
+ sfputr(sp, font(f, style, 1), -1);
+ break;
+ }
+ for (;;)
+ {
+ if (s >= e)
+ {
+ if (!(tsp = psp))
+ goto restore;
+ s = psp->ob;
+ e = psp->oe;
+ psp = psp->next;
+ free(tsp);
+ continue;
+ }
+ switch (c = *s++)
+ {
+ case '(':
+ if (n)
+ {
+ n = 0;
+ if (f > 0)
+ {
+ sfputr(sp, font(f, style, 0), -1);
+ f = 0;
+ }
+ }
+ break;
+ case '?':
+ case ':':
+ case ']':
+ if (psp && psp->ch)
+ break;
+ if (y)
+ {
+ if (va & OPT_optional)
+ sfputc(sp, '[');
+ sfputc(sp, '=');
+ label(sp, 0, y, 0, -1, 0, style, f >= 0 ? FONT_ITALIC : f, ip, version, id, catalog);
+ if (va & OPT_optional)
+ sfputc(sp, ']');
+ y = 0;
+ }
+ switch (c)
+ {
+ case '?':
+ if (*s == '?')
+ s++;
+ else if (*s == ']' && *(s + 1) != ']')
+ continue;
+ else if (sep)
+ goto restore;
+ else if (X(catalog) && (tsp = localize(psp, s, e, 0, 1, ip, version, id, catalog)))
+ {
+ psp = tsp;
+ s = psp->nb;
+ e = psp->ne;
+ }
+ break;
+ case ']':
+ if (sep && *s++ != ']')
+ goto restore;
+ break;
+ case ':':
+ if (sep && *s++ != ':')
+ goto restore;
+ break;
+ }
+ break;
+ case '\a':
+ a = FONT_ITALIC;
+ setfont:
+ if (f >= 0)
+ {
+ if (f & ~a)
+ {
+ sfputr(sp, font(f, style, 0), -1);
+ f = 0;
+ }
+ if (!f && style == STYLE_html)
+ {
+ for (t = s; t < e && !isspace(*t) && !iscntrl(*t); t++);
+ if (*t == c && *++t == '(')
+ {
+ w = t;
+ if (++t < e && isdigit(*t))
+ while (++t < e && isupper(*t));
+ if (t < e && *t == ')' && t > w + 1)
+ {
+ sfprintf(sp, "<NOBR><A href=\"../man%-.*s/"
+ , t - w - 1, w + 1
+ );
+ for (q = s; q < w - 1; q++)
+ if (*q == ':' && q < w - 2 && *(q + 1) == ':')
+ {
+ sfputc(sp, '-');
+ q++;
+ }
+ else
+ sfputc(sp, *q);
+ sfprintf(sp, ".html\">%s%-.*s%s</A>%-.*s</NOBR>"
+ , font(a, style, 1)
+ , w - s - 1, s
+ , font(a, style, 0)
+ , t - w + 1, w
+ );
+ s = t + 1;
+ continue;
+ }
+ }
+ }
+ sfputr(sp, font(a, style, !!(f ^= a)), -1);
+ }
+ continue;
+ case '\b':
+ a = FONT_BOLD;
+ goto setfont;
+ case '\f':
+ psp = info(psp, s, e, ip, id);
+ if (psp->nb)
+ {
+ s = psp->nb;
+ e = psp->ne;
+ }
+ else
+ {
+ s = psp->ob;
+ psp = psp->next;
+ }
+ continue;
+ case '\n':
+ sfputc(sp, c);
+ for (i = 0; i < level; i++)
+ sfputc(sp, '\t');
+ continue;
+ case '\v':
+ a = FONT_LITERAL;
+ goto setfont;
+ case '<':
+ if (style == STYLE_html)
+ {
+ sfputr(sp, "&lt;", -1);
+ c = 0;
+ for (t = s; t < e; t++)
+ if (!isalnum(*t) && *t != '_' && *t != '.' && *t != '-')
+ {
+ if (*t == '@')
+ {
+ if (c)
+ break;
+ c = 1;
+ }
+ else if (*t == '>')
+ {
+ if (c)
+ {
+ sfprintf(sp, "<A href=\"mailto:%-.*s>%-.*s</A>&gt;", t - s, s, t - s, s);
+ s = t + 1;
+ }
+ break;
+ }
+ else
+ break;
+ }
+ continue;
+ }
+ break;
+ case '>':
+ if (style == STYLE_html)
+ {
+ sfputr(sp, "&gt;", -1);
+ continue;
+ }
+ break;
+ case '&':
+ if (style == STYLE_html)
+ {
+ sfputr(sp, "&amp;", -1);
+ continue;
+ }
+ break;
+ case '"':
+ if (style == STYLE_html)
+ {
+ sfputr(sp, "&quot;", -1);
+ continue;
+ }
+ break;
+ case '-':
+ if (ostyle == STYLE_nroff)
+ sfputc(sp, '\\');
+ break;
+ case '.':
+ if (ostyle == STYLE_nroff)
+ {
+ sfputc(sp, '\\');
+ sfputc(sp, '&');
+ }
+ break;
+ case '\\':
+ if (ostyle == STYLE_nroff)
+ {
+ c = 'e';
+ sfputc(sp, '\\');
+ }
+ break;
+ case ' ':
+ if (ostyle == STYLE_nroff)
+ sfputc(sp, '\\');
+ break;
+ }
+ sfputc(sp, c);
+ }
+ restore:
+ if (f > 0)
+ sfputr(sp, font(f, style, 0), -1);
+ if (about)
+ sfputc(sp, ')');
+ if (psp)
+ pop(psp);
+ return r;
+}
+
+/*
+ * output args description to sp from p of length n
+ */
+
+static void
+args(register Sfio_t* sp, register char* p, register int n, int flags, int style, Sfio_t* ip, int version, char* id, char* catalog)
+{
+ register int i;
+ register char* t;
+ register char* o;
+ register char* a = 0;
+ char* b;
+ int sep;
+
+ if (flags & OPT_functions)
+ sep = '\t';
+ else
+ {
+ sep = ' ';
+ o = T(NiL, ID, "options");
+ b = style == STYLE_nroff ? "\\ " : " ";
+ for (;;)
+ {
+ t = (char*)memchr(p, '\n', n);
+ if (style >= STYLE_man)
+ {
+ if (!(a = id))
+ a = "...";
+ sfprintf(sp, "\t%s%s%s%s[%s%s%s%s%s]", font(FONT_BOLD, style, 1), a, font(FONT_BOLD, style, 0), b, b, font(FONT_ITALIC, style, 1), o, font(FONT_ITALIC, style, 0), b);
+ }
+ else if (a)
+ sfprintf(sp, "%*.*s%s%s%s[%s%s%s]", OPT_USAGE - 1, OPT_USAGE - 1, T(NiL, ID, "Or:"), b, a, b, b, o, b);
+ else
+ {
+ if (!(a = error_info.id) && !(a = id))
+ a = "...";
+ if (!sfstrtell(sp))
+ sfprintf(sp, "[%s%s%s]", b, o, b);
+ }
+ if (!t)
+ break;
+ i = ++t - p;
+ if (i)
+ {
+ sfputr(sp, b, -1);
+ if (X(catalog))
+ {
+ sfwrite(ip, p, i);
+ if (b = sfstruse(ip))
+ sfputr(sp, T(id, catalog, b), -1);
+ else
+ sfwrite(sp, p, i);
+ }
+ else
+ sfwrite(sp, p, i);
+ }
+ if (style == STYLE_html)
+ sfputr(sp, "<BR>", '\n');
+ else if (style == STYLE_nroff)
+ sfputr(sp, ".br", '\n');
+ else if (style == STYLE_api)
+ sfputr(sp, ".BR", '\n');
+ p = t;
+ n -= i;
+ while (n > 0 && (*p == ' ' || *p == '\t'))
+ {
+ p++;
+ n--;
+ }
+ }
+ }
+ if (n)
+ label(sp, sep, p, 0, n, 0, style, 0, ip, version, id, catalog);
+}
+
+/*
+ * output [+-...label...?...] label s to sp
+ * according to {...} level and style
+ * return 0:header 1:paragraph
+ */
+
+static int
+item(Sfio_t* sp, char* s, int about, int level, int style, Sfio_t* ip, int version, char* id, char* catalog, int* hflags)
+{
+ register char* t;
+ int n;
+ int par;
+
+ sfputc(sp, '\n');
+ if (*s == '\n')
+ {
+ par = 0;
+ if (style >= STYLE_nroff)
+ sfprintf(sp, ".DS\n");
+ else
+ {
+ if (style == STYLE_html)
+ sfprintf(sp, "<PRE>\n");
+ else
+ sfputc(sp, '\n');
+ for (n = 0; n < level; n++)
+ sfputc(sp, '\t');
+ }
+ label(sp, 0, s + 1, about, -1, level, style, FONT_LITERAL, ip, version, id, catalog);
+ sfputc(sp, '\n');
+ if (style >= STYLE_nroff)
+ sfprintf(sp, ".DE");
+ else if (style == STYLE_html)
+ sfprintf(sp, "</PRE>");
+ }
+ else if (*s != ']' && (*s != '?' || *(s + 1) == '?'))
+ {
+ par = 0;
+ if (level)
+ {
+ if (style >= STYLE_nroff)
+ sfprintf(sp, ".H%d ", (level - (level > 2)) / 2);
+ else
+ for (n = 0; n < level; n++)
+ sfputc(sp, '\t');
+ }
+ if (style == STYLE_html)
+ {
+ if (!level)
+ {
+ if (*hflags & HELP_head)
+ sfputr(sp, "</DIV>", '\n');
+ else
+ *hflags |= HELP_head;
+ sfputr(sp, "<H4>", -1);
+ }
+ sfputr(sp, "<A name=\"", -1);
+ if (s[-1] == '-' && s[0] == 'l' && s[1] == 'i' && s[2] == 'c' && s[3] == 'e' && s[4] == 'n' && s[5] == 's' && s[6] == 'e' && s[7] == '?')
+ for (t = s + 8; *t && *t != ']'; t++)
+ if (t[0] == 'p' && (!strncmp(t, "proprietary", 11) || !strncmp(t, "private", 7)) || t[0] == 'n' && !strncmp(t, "noncommercial", 13))
+ {
+ state.flags |= OPT_proprietary;
+ break;
+ }
+ label(sp, 0, s, about, -1, level, style, -1, ip, version, id, catalog);
+ sfputr(sp, "\">", -1);
+ label(sp, 0, s, about, -1, level, style, level ? FONT_BOLD : 0, ip, version, id, catalog);
+ sfputr(sp, "</A>", -1);
+ if (!level)
+ {
+ if (!strncmp(s, C("SYNOPSIS"), strlen(C("SYNOPSIS"))))
+ sfputr(sp, "</H4>\n<DIV class=SY>", -1);
+ else
+ {
+ sfputr(sp, "</H4>\n<DIV class=SH>", -1);
+ if (!strncmp(s, C("NAME"), strlen(C("NAME"))) || !strncmp(s, C("PLUGIN"), strlen(C("PLUGIN"))))
+ *hflags |= HELP_index;
+ }
+ }
+ }
+ else
+ {
+ if (!level)
+ {
+ if (style >= STYLE_nroff)
+ sfprintf(sp, ".SH ");
+ else if (style == STYLE_man)
+ sfputc(sp, '\n');
+ else if (style != STYLE_options && style != STYLE_match || *s == '-' || *s == '+')
+ sfputc(sp, '\t');
+ }
+ label(sp, 0, s, about, -1, level, style, FONT_BOLD, ip, version, id, catalog);
+ }
+ }
+ else
+ {
+ par = 1;
+ if (style >= STYLE_nroff)
+ sfputr(sp, level ? ".SP" : ".PP", -1);
+ }
+ if (style >= STYLE_nroff || !level)
+ sfputc(sp, '\n');
+ if (par && style < STYLE_nroff)
+ for (n = 0; n < level; n++)
+ sfputc(sp, '\t');
+ return par;
+}
+
+/*
+ * output text to sp from p according to style
+ */
+
+#if _BLD_DEBUG
+
+static char* textout(Sfio_t*, char*, char*, int, int, int, int, Sfio_t*, int, char*, char*, int*);
+
+static char*
+trace_textout(Sfio_t* sp, register char* p, char* conform, int conformlen, int style, int level, int bump, Sfio_t* ip, int version, char* id, char* catalog, int* hflags, int line)
+{
+ static int depth = 0;
+
+ message((-21, "opthelp: txt#%d +++ %2d \"%s\" style=%d level=%d bump=%d", line, ++depth, show(p), style, level, bump));
+ p = textout(sp, p, conform, conformlen, style, level, bump, ip, version, id, catalog, hflags);
+ message((-21, "opthelp: txt#%d --- %2d \"%s\"", line, depth--, show(p)));
+ return p;
+}
+
+#endif
+
+static char*
+textout(Sfio_t* sp, register char* s, char* conform, int conformlen, int style, int level, int bump, Sfio_t* ip, int version, char* id, char* catalog, int* hflags)
+{
+#if _BLD_DEBUG
+#define textout(sp,s,conform,conformlen,style,level,bump,ip,version,id,catalog,hflags) trace_textout(sp,s,conform,conformlen,style,level,bump,ip,version,id,catalog,hflags,__LINE__)
+#endif
+ register char* t;
+ register int c;
+ register int n;
+ char* w;
+ char* q;
+ int a;
+ int f;
+ int par;
+ int about;
+ Push_t* tsp;
+
+ int ident = 0;
+ int lev = level;
+ Push_t* psp = 0;
+
+ again:
+ about = 0;
+ if ((c = *s) == GO)
+ {
+ for (;;)
+ {
+ while (*(s = next(s + 1, version)) == '\n');
+ if (*s == GO)
+ {
+ if (level > 1)
+ level++;
+ level++;
+ }
+ else if (*s != OG)
+ {
+ if (level <= 1 || *s != '[' || *(s + 1) != '-' || style == STYLE_man && *(s + 2) == '?' || isalpha(*(s + 2)))
+ break;
+ s = skip(s, 0, 0, 0, 1, level, 0, version);
+ }
+ else if ((level -= 2) <= lev)
+ return s + 1;
+ }
+ if (*s == '\f')
+ {
+ psp = info(psp, s + 1, NiL, ip, id);
+ if (psp->nb)
+ s = psp->nb;
+ else
+ {
+ s = psp->ob;
+ psp = psp->next;
+ }
+ }
+ if (*s != '[')
+ return s;
+ c = *++s;
+ if (level > 1)
+ level++;
+ level++;
+ }
+ if (c == '-' && level > 1)
+ {
+ if (style == STYLE_man)
+ {
+ about = 1;
+ if (*(s + 1) == '-')
+ s++;
+ }
+ else
+ for (;;)
+ {
+ s = skip(s, 0, 0, 0, 1, level, 0, version);
+ while (*(s = next(s + 1, version)) == '\n');
+ if (*s == '[')
+ {
+ if ((c = *++s) != '-')
+ break;
+ }
+ else if (*s == GO)
+ goto again;
+ else if (*s == OG)
+ return s + 1;
+ }
+ }
+ if (c == '+' || c == '-' && (bump = 3) || c != ' ' && level > 1)
+ {
+ s = skip(t = s + 1, '?', 0, 0, 1, level, 0, version);
+ if (c == '-' && (*t == '?' || isdigit(*t) || *s == '?' && *(s + 1) == '\n'))
+ {
+ if ((c = *s) != '?')
+ return skip(s, 0, 0, 0, 1, level, 1, version);
+ w = C("version");
+ par = item(sp, w, about, level, style, ip, version, id, ID, hflags);
+ for (;;)
+ {
+ while (isspace(*(s + 1)))
+ s++;
+ w = s;
+ if (w[1] == '@' && w[2] == '(' && w[3] == '#' && w[4] == ')')
+ s = w + 4;
+ else if (w[1] == '$' && w[2] == 'I' && w[3] == 'd' && w[4] == ':' && w[5] == ' ')
+ {
+ s = w + 5;
+ ident = 1;
+ }
+ else
+ break;
+ }
+ }
+ else
+ {
+ if (isdigit(c) && isdigit(*t))
+ {
+ while (isdigit(*t))
+ t++;
+ if (*t == ':')
+ t++;
+ }
+ else if (isalnum(c) && *t-- == ':')
+ {
+ if (X(catalog) || *t == *(t + 2))
+ t += 2;
+ else
+ {
+ sfprintf(ip, "%s", t);
+ if (w = sfstruse(ip))
+ *((t = w) + 1) = '|';
+ }
+ }
+ par = item(sp, t, about, level, style, ip, version, id, catalog, hflags);
+ c = *s;
+ }
+ if (!about && level)
+ par = 0;
+ }
+ else
+ {
+ if (style >= STYLE_nroff)
+ sfputc(sp, '\n');
+ else if (c == '?')
+ for (n = 0; n < level; n++)
+ sfputc(sp, '\t');
+ par = 0;
+ }
+ if (c == ':')
+ c = *(s = skip(s, '?', 0, 0, 1, 0, 0, version));
+ if ((c == ']' || c == '?' && *(s + 1) == ']' && *(s + 2) != ']' && s++) && (c = *(s = next(s + 1, version))) == GO)
+ {
+ s = textout(sp, s, conform, conformlen, style, level + bump + par + 1, 0, ip, version, id, catalog, hflags);
+ if (level > lev && *s && *(s = next(s, version)) == '[')
+ {
+ s++;
+ message((-21, "textout#%d s=%s", __LINE__, show(s)));
+ goto again;
+ }
+ }
+ else if (c == '?' || c == ' ')
+ {
+ s++;
+ if (c == ' ')
+ sfputc(sp, c);
+ else
+ {
+ if (X(catalog) && (tsp = localize(psp, s, NiL, 0, 1, ip, version, id, catalog)))
+ {
+ psp = tsp;
+ s = psp->nb;
+ }
+ if (style < STYLE_nroff)
+ for (n = 0; n < bump + 1; n++)
+ sfputc(sp, '\t');
+ }
+ if (conform)
+ {
+ sfprintf(sp, "[%-.*s %s] ", conformlen, conform, T(NiL, ID, "conformance"));
+ conform = 0;
+ }
+ if (*hflags & HELP_index)
+ {
+ *hflags &= ~HELP_index;
+ sfputr(sp, "<!--MAN-INDEX-->", -1);
+ }
+ f = 0;
+ for (;;)
+ {
+ switch (c = *s++)
+ {
+ case 0:
+ if (!(tsp = psp))
+ {
+ if (f)
+ sfputr(sp, font(f, style, 0), -1);
+ return s - 1;
+ }
+ s = psp->ob;
+ psp = psp->next;
+ free(tsp);
+ continue;
+ case ']':
+ if (psp && psp->ch)
+ break;
+ if (*s != ']')
+ {
+ if (f)
+ {
+ sfputr(sp, font(f, style, 0), -1);
+ f = 0;
+ }
+ for (;;)
+ {
+ if ((*s == '#' || *s == ':') && level > lev)
+ {
+ char* o;
+ char* v;
+ int j;
+ int m;
+ int ol;
+ int vl;
+
+ a = 0;
+ o = 0;
+ v = 0;
+ if (*++s == '?' || *s == *(s - 1))
+ {
+ s++;
+ a |= OPT_optional;
+ }
+ if (*(s = next(s, version)) == '[')
+ {
+ s = skip(s + 1, ':', '?', 0, 1, 0, 0, version);
+ while (*s == ':')
+ {
+ s = skip(t = s + 1, ':', '?', 0, 1, 0, 0, version);
+ m = s - t;
+ if (*t == '!')
+ {
+ o = t + 1;
+ ol = m - 1;
+ }
+ else if (*t == '=')
+ {
+ v = t + 1;
+ vl = m - 1;
+ }
+ else
+ for (j = 0; j < elementsof(attrs); j++)
+ if (strneq(t, attrs[j].name, m))
+ {
+ a |= attrs[j].flag;
+ break;
+ }
+ }
+ }
+ if (a & OPT_optional)
+ {
+ if (o)
+ {
+ sfprintf(sp, " %s ", T(NiL, ID, "If the option value is omitted then"));
+ sfputr(sp, font(FONT_BOLD, style, 1), -1);
+ t = o + ol;
+ while (o < t)
+ {
+ if (((c = *o++) == ':' || c == '?') && *o == c)
+ o++;
+ sfputc(sp, c);
+ }
+ sfputr(sp, font(FONT_BOLD, style, 0), -1);
+ sfprintf(sp, " %s.", T(NiL, ID, "is assumed"));
+ }
+ else
+ sfprintf(sp, " %s", T(NiL, ID, "The option value may be omitted."));
+ }
+ if (v)
+ {
+ sfprintf(sp, " %s ", T(NiL, ID, "The default value is"));
+ sfputr(sp, font(FONT_BOLD, style, 1), -1);
+ t = v + vl;
+ while (v < t)
+ {
+ if (((c = *v++) == ':' || c == '?') && *v == c)
+ v++;
+ sfputc(sp, c);
+ }
+ sfputr(sp, font(FONT_BOLD, style, 0), -1);
+ sfputc(sp, '.');
+ }
+ s = skip(s, 0, 0, 0, 1, 0, 1, version);
+ }
+ if (*(s = next(s, version)) == GO)
+ {
+ s = textout(sp, s, 0, 0, style, level + bump + !level, 0, ip, version, id, catalog, hflags);
+ if (*s && *(s = next(s, version)) == '[' && !isalnum(*(s + 1)))
+ {
+ s++;
+ message((-21, "textout#%d s=%s", __LINE__, show(s)));
+ goto again;
+ }
+ }
+ else if (*s == '[' && level > lev)
+ {
+ s++;
+ goto again;
+ }
+ else if (*s == '\f')
+ {
+ s++;
+ if (style != STYLE_keys)
+ {
+ psp = info(psp, s, NiL, ip, id);
+ if (psp->nb)
+ s = psp->nb;
+ else
+ {
+ s = psp->ob;
+ psp = psp->next;
+ }
+ }
+ }
+ else if (!*s)
+ {
+ if (!(tsp = psp))
+ break;
+ s = psp->ob;
+ psp = psp->next;
+ free(tsp);
+ }
+ else if (*s != OG)
+ break;
+ else
+ {
+ s++;
+ if ((level -= 2) <= lev)
+ break;
+ }
+ }
+ return s;
+ }
+ s++;
+ break;
+ case '\a':
+ a = FONT_ITALIC;
+ setfont:
+ if (f & ~a)
+ {
+ sfputr(sp, font(f, style, 0), -1);
+ f = 0;
+ }
+ if (!f && style == STYLE_html)
+ {
+ for (t = s; *t && !isspace(*t) && !iscntrl(*t); t++);
+ if (*t == c && *++t == '(')
+ {
+ w = t;
+ if (isdigit(*++t))
+ while (isupper(*++t));
+ if (*t == ')' && t > w + 1)
+ {
+ sfprintf(sp, "<NOBR><A href=\"../man%-.*s/"
+ , t - w - 1, w + 1
+ );
+ for (q = s; q < w - 1; q++)
+ if (*q == ':' && q < w - 2 && *(q + 1) == ':')
+ {
+ sfputc(sp, '-');
+ q++;
+ }
+ else
+ sfputc(sp, *q);
+ sfprintf(sp, ".html\">%s%-.*s%s</A>%-.*s</NOBR>"
+ , font(a, style, 1)
+ , w - s - 1, s
+ , font(a, style, 0)
+ , t - w + 1, w
+ );
+ s = t + 1;
+ continue;
+ }
+ }
+ }
+ sfputr(sp, font(a, style, !!(f ^= a)), -1);
+ continue;
+ case '\b':
+ a = FONT_BOLD;
+ goto setfont;
+ case '\f':
+ if (style != STYLE_keys)
+ {
+ psp = info(psp, s, NiL, ip, id);
+ if (psp->nb)
+ s = psp->nb;
+ else
+ {
+ s = psp->ob;
+ psp = psp->next;
+ }
+ }
+ continue;
+ case '\v':
+ a = FONT_LITERAL;
+ goto setfont;
+ case ' ':
+ if (ident && *s == '$')
+ {
+ while (*++s)
+ if (*s == ']')
+ {
+ if (*(s + 1) != ']')
+ break;
+ s++;
+ }
+ continue;
+ }
+ case '\n':
+ case '\r':
+ case '\t':
+ while (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n')
+ s++;
+ if (*s == ']' && *(s + 1) != ']' && (!psp || !psp->ch))
+ continue;
+ c = ' ';
+ break;
+ case '<':
+ if (style == STYLE_html)
+ {
+ sfputr(sp, "&lt;", -1);
+ c = 0;
+ for (t = s; *t; t++)
+ if (!isalnum(*t) && *t != '_' && *t != '.' && *t != '-')
+ {
+ if (*t == '@')
+ {
+ if (c)
+ break;
+ c = 1;
+ }
+ else if (*t == '>')
+ {
+ if (c)
+ {
+ sfprintf(sp, "<A href=\"mailto:%-.*s\">%-.*s</A>&gt;", t - s, s, t - s, s);
+ s = t + 1;
+ }
+ break;
+ }
+ else
+ break;
+ }
+ continue;
+ }
+ break;
+ case '>':
+ if (style == STYLE_html)
+ {
+ sfputr(sp, "&gt;", -1);
+ continue;
+ }
+ break;
+ case '&':
+ if (style == STYLE_html)
+ {
+ sfputr(sp, "&amp;", -1);
+ continue;
+ }
+ break;
+ case '-':
+ if (style == STYLE_nroff)
+ sfputc(sp, '\\');
+ break;
+ case '.':
+ if (style == STYLE_nroff)
+ {
+ sfputc(sp, '\\');
+ sfputc(sp, '&');
+ }
+ break;
+ case '\\':
+ if (style == STYLE_nroff)
+ {
+ sfputc(sp, c);
+ c = 'e';
+ }
+ break;
+ }
+ sfputc(sp, c);
+ }
+ }
+ else if (c == '[' && level > lev)
+ {
+ s++;
+ goto again;
+ }
+ return s;
+}
+
+/*
+ * generate optget() help [...] list from lp
+ */
+
+static void
+list(Sfio_t* sp, register const List_t* lp)
+{
+ sfprintf(sp, "[%c", lp->type);
+ if (lp->name)
+ {
+ sfprintf(sp, "%s", lp->name);
+ if (lp->text)
+ sfprintf(sp, "?%s", lp->text);
+ }
+ sfputc(sp, ']');
+}
+
+/*
+ * return pointer to help message sans `Usage: command'
+ * if oopts is 0 then state.pass is used
+ * what:
+ * 0 ?short by default, ?long if any long options used
+ * * otherwise see help_text[] (--???)
+ * external formatter:
+ * \a...\a italic
+ * \b...\b bold
+ * \f...\f discipline infof callback on ...
+ * \v...\v literal
+ * internal formatter:
+ * \t indent
+ * \n newline
+ * margin flush pops to previous indent
+ */
+
+char*
+opthelp(const char* oopts, const char* what)
+{
+ register Sfio_t* sp;
+ register Sfio_t* mp;
+ register int c;
+ register char* p;
+ register Indent_t* ip;
+ char* t;
+ char* x;
+ char* w;
+ char* u;
+ char* y;
+ char* s;
+ char* d;
+ char* v;
+ char* cb;
+ char* dt;
+ char* ov;
+ char* pp;
+ char* rb;
+ char* re;
+ int f;
+ int i;
+ int j;
+ int m;
+ int n;
+ int a;
+ int cl;
+ int sl;
+ int vl;
+ int ol;
+ int wl;
+ int xl;
+ int rm;
+ int ts;
+ int co;
+ int z;
+ int style;
+ int head;
+ int margin;
+ int mode;
+ int mutex;
+ int prefix;
+ int version;
+ long tp;
+ char* id;
+ char* catalog;
+ Optpass_t* o;
+ Optpass_t* q;
+ Optpass_t* e;
+ Optpass_t one;
+ Optpass_t top;
+ Help_t* hp;
+ Tag_t ptstk[elementsof(indent) + 2];
+ Tag_t* pt;
+ Sfio_t* vp;
+ Push_t* tsp;
+
+ char* opts = (char*)oopts;
+ char* section = "1";
+ int flags = 0;
+ int bflags = 0;
+ int dflags = 0;
+ int hflags = 0;
+ int sflags = 0;
+ int matched = 0;
+ int paragraph = 0;
+ Push_t* psp = 0;
+ Sfio_t* sp_help = 0;
+ Sfio_t* sp_text = 0;
+ Sfio_t* sp_plus = 0;
+ Sfio_t* sp_head = 0;
+ Sfio_t* sp_body = 0;
+ Sfio_t* sp_info = 0;
+ Sfio_t* sp_misc = 0;
+
+ if (!(mp = state.mp) && !(mp = state.mp = sfstropen()))
+ goto nospace;
+ if (!what)
+ style = state.style;
+ else if (!*what)
+ style = STYLE_options;
+ else if (*what != '?')
+ style = STYLE_match;
+ else if (!*(what + 1))
+ style = STYLE_man;
+ else if ((hp = (Help_t*)search(styles, elementsof(styles), sizeof(styles[0]), (char*)what + 1)) && hp->style >= 0)
+ {
+ style = hp->style;
+ if (*hp->name != '?')
+ what = hp->name;
+ }
+ else
+ {
+ if ((style = state.force) < STYLE_man)
+ style = STYLE_man;
+ if (!(sp_help = sfstropen()))
+ goto nospace;
+ for (i = 0; i < elementsof(help_head); i++)
+ list(sp_help, &help_head[i]);
+ for (i = 0; i < elementsof(styles); i++)
+ sfprintf(sp_help, "[:%s?%s]", styles[i].match, styles[i].text);
+ for (i = 0; i < elementsof(help_tail); i++)
+ list(sp_help, &help_tail[i]);
+ if (!(opts = sfstruse(sp_help)))
+ goto nospace;
+ }
+
+ /*
+ * this is a workaround for static optjoin() data
+ * clobbered by plugins/builtins that may be called
+ * evaluating \f...\f -- it would be good to hide
+ * optjoin() interactions a bit more ...
+ */
+
+ top = state.pass[0];
+ again:
+ if (opts)
+ {
+ for (i = 0; i < state.npass; i++)
+ if (state.pass[i].oopts == opts)
+ {
+ o = &state.pass[i];
+ break;
+ }
+ if (i >= state.npass)
+ {
+ o = &one;
+ if (init((char*)opts, o))
+ goto nospace;
+ }
+ e = o + 1;
+ }
+ else
+ {
+ if (state.npass > 0)
+ {
+ o = state.pass;
+ e = o + state.npass;
+ }
+ else if (state.npass < 0)
+ {
+ o = &state.cache->pass;
+ e = o + 1;
+ }
+ else
+ return T(NiL, ID, "[* call optget() before opthelp() *]");
+ oopts = (const char*)state.pass[0].oopts;
+ }
+ if (style <= STYLE_usage)
+ {
+ if (!(sp_text = sfstropen()) || !(sp_info = sfstropen()))
+ goto nospace;
+ if (style >= STYLE_match && style < STYLE_keys && !(sp_body = sfstropen()))
+ goto nospace;
+ }
+ switch (style)
+ {
+ case STYLE_api:
+ case STYLE_html:
+ case STYLE_nroff:
+ state.emphasis = 0;
+ break;
+ case STYLE_usage:
+ case STYLE_keys:
+ for (q = o; q < e; q++)
+ if (!(q->flags & OPT_ignore) && !streq(q->catalog, o->catalog))
+ o = q;
+ /*FALLTHROUGH*/
+ case STYLE_posix:
+ sfputc(mp, '\f');
+ break;
+ default:
+ if (!state.emphasis)
+ {
+ if (x = getenv("ERROR_OPTIONS"))
+ {
+ if (strmatch(x, "*noemphasi*"))
+ break;
+ if (strmatch(x, "*emphasi*"))
+ {
+ state.emphasis = 1;
+ break;
+ }
+ }
+ if ((x = getenv("TERM")) && strmatch(x, "(ansi|vt100|xterm)*") && isatty(sffileno(sfstderr)))
+ state.emphasis = 1;
+ }
+ break;
+ }
+ x = "";
+ xl = 0;
+ for (q = o; q < e; q++)
+ {
+ if (q->flags & OPT_ignore)
+ continue;
+ section = q->section;
+ flags |= q->flags;
+ p = q->opts;
+ prefix = q->prefix;
+ version = q->version;
+ id = q->id;
+ catalog = q->catalog;
+ switch (style)
+ {
+ case STYLE_usage:
+ if (xl)
+ sfputc(mp, '\n');
+ else
+ xl = 1;
+ psp = 0;
+ for (;;)
+ {
+ switch (c = *p++)
+ {
+ case 0:
+ if (!(tsp = psp))
+ goto style_usage;
+ p = psp->ob;
+ psp = psp->next;
+ free(tsp);
+ continue;
+ case '\a':
+ c = 'a';
+ break;
+ case '\b':
+ c = 'b';
+ break;
+ case '\f':
+ psp = info(psp, p, NiL, sp_info, id);
+ if (psp->nb)
+ p = psp->nb;
+ else
+ {
+ p = psp->ob;
+ psp = psp->next;
+ }
+ continue;
+ case '\n':
+ c = 'n';
+ break;
+ case '\r':
+ c = 'r';
+ break;
+ case '\t':
+ c = 't';
+ break;
+ case '\v':
+ c = 'v';
+ break;
+ case '"':
+ c = '"';
+ break;
+ case '\'':
+ c = '\'';
+ break;
+ case '\\':
+ c = '\\';
+ break;
+ default:
+ sfputc(mp, c);
+ continue;
+ }
+ sfputc(mp, '\\');
+ sfputc(mp, c);
+ }
+ style_usage:
+ continue;
+ case STYLE_keys:
+ a = 0;
+ psp = 0;
+ vl = 0;
+ for (;;)
+ {
+ if (!(c = *p++))
+ {
+ if (!(tsp = psp))
+ break;
+ p = psp->ob;
+ psp = psp->next;
+ free(tsp);
+ continue;
+ }
+ if (c == '\f')
+ {
+ psp = info(psp, p, NiL, sp_info, id);
+ if (psp->nb)
+ p = psp->nb;
+ else
+ {
+ p = psp->ob;
+ psp = psp->next;
+ }
+ continue;
+ }
+ f = z = 1;
+ t = 0;
+ if (a == 0 && (c == ' ' || c == '\n' && *p == '\n'))
+ {
+ if (c == ' ' && *p == ']')
+ {
+ p++;
+ continue;
+ }
+ if (*p == '\n')
+ p++;
+ a = c;
+ }
+ else if (c == '\n')
+ {
+ if (a == ' ')
+ a = -1;
+ else if (a == '\n' || *p == '\n')
+ {
+ a = -1;
+ p++;
+ }
+ continue;
+ }
+ else if ((c == ':' || c == '#') && (*p == '[' || *p == '?' && *(p + 1) == '[' && p++))
+ p++;
+ else if (c != '[')
+ {
+ if (c == GO)
+ vl++;
+ else if (c == OG)
+ vl--;
+ continue;
+ }
+ else if (*p == ' ')
+ {
+ p++;
+ continue;
+ }
+ else if (*p == '-')
+ {
+ z = 0;
+ if (*++p == '-')
+ {
+ p = skip(p, 0, 0, 0, 1, 0, 1, version);
+ continue;
+ }
+ }
+ else if (*p == '+')
+ {
+ p++;
+ if (vl > 0 && *p != '\a')
+ {
+ f = 0;
+ p = skip(p, '?', 0, 0, 1, 0, 0, version);
+ if (*p == '?')
+ p++;
+ }
+ }
+ else
+ {
+ if (*(p + 1) == '\f' && (vp = state.vp))
+ p = expand(p + 2, NiL, &t, vp, id);
+ p = skip(p, ':', '?', 0, 1, 0, 0, version);
+ if (*p == ':')
+ p++;
+ }
+ if (f && *p == '?' && *(p + 1) != '?')
+ {
+ f = 0;
+ if (z)
+ p++;
+ else
+ p = skip(p, 0, 0, 0, 1, 0, 0, version);
+ }
+ if (*p == ']' && *(p + 1) != ']')
+ {
+ p++;
+ continue;
+ }
+ if (!*p)
+ {
+ if (!t)
+ break;
+ p = t;
+ t = 0;
+ }
+ m = sfstrtell(mp);
+ sfputc(mp, '"');
+ xl = 1;
+ /*UNDENT...*/
+
+ for (;;)
+ {
+ if (!(c = *p++))
+ {
+ if (t)
+ {
+ p = t;
+ t = 0;
+ }
+ if (!(tsp = psp))
+ {
+ p--;
+ break;
+ }
+ p = psp->ob;
+ psp = psp->next;
+ free(tsp);
+ continue;
+ }
+ if (a > 0)
+ {
+ if (c == '\n')
+ {
+ if (a == ' ')
+ {
+ a = -1;
+ break;
+ }
+ if (a == '\n' || *p == '\n')
+ {
+ a = -1;
+ p++;
+ break;
+ }
+ }
+ }
+ else if (c == ']')
+ {
+ if (*p != ']')
+ {
+ sfputc(mp, 0);
+ y = sfstrbase(mp) + m + 1;
+ if (D(y) || !strmatch(y, KEEP) || strmatch(y, OMIT))
+ {
+ sfstrseek(mp, m, SEEK_SET);
+ xl = 0;
+ }
+ else
+ sfstrseek(mp, -1, SEEK_CUR);
+ break;
+ }
+ sfputc(mp, *p++);
+ continue;
+ }
+ switch (c)
+ {
+ case '?':
+ if (f)
+ {
+ if (*p == '?')
+ {
+ p++;
+ sfputc(mp, c);
+ }
+ else
+ {
+ f = 0;
+ sfputc(mp, 0);
+ y = sfstrbase(mp) + m + 1;
+ if (D(y) || !strmatch(y, KEEP) || strmatch(y, OMIT))
+ {
+ sfstrseek(mp, m, SEEK_SET);
+ xl = 0;
+ }
+ else
+ sfstrseek(mp, -1, SEEK_CUR);
+ if (z && (*p != ']' || *(p + 1) == ']'))
+ {
+ if (xl)
+ {
+ sfputc(mp, '"');
+ sfputc(mp, '\n');
+ }
+ m = sfstrtell(mp);
+ sfputc(mp, '"');
+ xl = 1;
+ }
+ else
+ {
+ p = skip(p, 0, 0, 0, 1, 0, 0, version);
+ if (*p == '?')
+ p++;
+ }
+ }
+ }
+ else
+ sfputc(mp, c);
+ continue;
+ case ':':
+ if (f && *p == ':')
+ p++;
+ sfputc(mp, c);
+ continue;
+ case '\a':
+ c = 'a';
+ break;
+ case '\b':
+ c = 'b';
+ break;
+ case '\f':
+ c = 'f';
+ break;
+ case '\n':
+ c = 'n';
+ break;
+ case '\r':
+ c = 'r';
+ break;
+ case '\t':
+ c = 't';
+ break;
+ case '\v':
+ c = 'v';
+ break;
+ case '"':
+ c = '"';
+ break;
+ case '\\':
+ c = '\\';
+ break;
+ case CC_esc:
+ c = 'E';
+ break;
+ default:
+ sfputc(mp, c);
+ continue;
+ }
+ sfputc(mp, '\\');
+ sfputc(mp, c);
+ }
+
+ /*...INDENT*/
+ if (xl)
+ {
+ sfputc(mp, '"');
+ sfputc(mp, '\n');
+ }
+ }
+ continue;
+ }
+ z = 0;
+ head = 0;
+ mode = 0;
+ mutex = 0;
+ if (style > STYLE_short && style < STYLE_nroff && version < 1)
+ {
+ style = STYLE_short;
+ if (sp_body)
+ {
+ sfclose(sp_body);
+ sp_body = 0;
+ }
+ }
+ else if (style == STYLE_short && prefix < 2)
+ style = STYLE_long;
+ if (*p == ':')
+ p++;
+ if (*p == '+')
+ {
+ p++;
+ if (!(sp = sp_plus) && !(sp = sp_plus = sfstropen()))
+ goto nospace;
+ }
+ else if (style >= STYLE_match)
+ sp = sp_body;
+ else
+ sp = sp_text;
+ psp = 0;
+ for (;;)
+ {
+ if (!(*(p = next(p, version))))
+ {
+ if (!(tsp = psp))
+ break;
+ p = psp->ob;
+ psp = psp->next;
+ free(tsp);
+ continue;
+ }
+ if (*p == '\f')
+ {
+ psp = info(psp, p + 1, NiL, sp_info, id);
+ if (psp->nb)
+ p = psp->nb;
+ else
+ {
+ p = psp->ob;
+ psp = psp->next;
+ }
+ continue;
+ }
+ if (*p == '\n' || *p == ' ')
+ {
+ if (*(x = p = next(p + 1, version)))
+ while (*++p)
+ if (*p == '\n')
+ {
+ while (*++p == ' ' || *p == '\t' || *p == '\r');
+ if (*p == '\n')
+ break;
+ }
+ xl = p - x;
+ if (!*p)
+ break;
+ continue;
+ }
+ if (*p == OG)
+ {
+ p++;
+ continue;
+ }
+ message((-20, "opthelp: opt %s", show(p)));
+ if (z < 0)
+ z = 0;
+ a = 0;
+ f = 0;
+ w = 0;
+ d = 0;
+ s = 0;
+ rb = re = 0;
+ sl = 0;
+ vl = 0;
+ if (*p == '[')
+ {
+ if ((c = *(p = next(p + 1, version))) == '(')
+ {
+ p = nest(cb = p);
+ cl = p - cb;
+ c = *p;
+ }
+ else
+ cb = 0;
+ if (c == '-')
+ {
+ if (style >= STYLE_man)
+ {
+ if (*(p + 1) != '-')
+ {
+ if (!sp_misc && !(sp_misc = sfstropen()))
+ goto nospace;
+ else
+ p = textout(sp_misc, p, cb, cl, style, 1, 3, sp_info, version, id, catalog, &hflags);
+ continue;
+ }
+ }
+ else if (style == STYLE_match && *what == '-')
+ {
+ if (*(p + 1) == '?' || *(s = skip(p + 1, ':', '?', 0, 1, 0, 0, version)) == '?' && isspace(*(s + 1)))
+ s = C("version");
+ else
+ s = p + 1;
+ w = (char*)what;
+ if (*s != '-' || *(w + 1) == '-')
+ {
+ if (*s == '-')
+ s++;
+ if (*(w + 1) == '-')
+ w++;
+ if (match(w + 1, s, version, id, catalog))
+ {
+ if (*(p + 1) == '-')
+ p++;
+ p = textout(sp, p, cb, cl, style, 1, 3, sp_info, version, id, catalog, &hflags);
+ matched = -1;
+ continue;
+ }
+ }
+ }
+ if (!z)
+ z = -1;
+ }
+ else if (c == '+')
+ {
+ if (style >= STYLE_man)
+ {
+ p = textout(sp_body, p, cb, cl, style, 0, 0, sp_info, version, id, catalog, &bflags);
+ if (!sp_head)
+ {
+ sp_head = sp_body;
+ hflags = dflags = bflags;
+ if (!(sp_body = sfstropen()))
+ goto nospace;
+ }
+ continue;
+ }
+ else if (style == STYLE_match && *what == '+')
+ {
+ if (paragraph)
+ {
+ if (p[1] == '?')
+ {
+ p = textout(sp, p, cb, cl, style, 1, 3, sp_info, version, id, catalog, &hflags);
+ continue;
+ }
+ paragraph = 0;
+ }
+ if (match((char*)what + 1, p + 1, version, id, catalog))
+ {
+ p = textout(sp, p, cb, cl, style, 1, 3, sp_info, version, id, catalog, &hflags);
+ matched = -1;
+ paragraph = 1;
+ continue;
+ }
+ }
+ if (!z)
+ z = -1;
+ }
+ else if (c == '[' || version < 1)
+ {
+ mutex++;
+ continue;
+ }
+ else
+ {
+ if (c == '!')
+ {
+ a |= OPT_invert;
+ p++;
+ }
+ rb = p;
+ if (*p != ':')
+ {
+ s = p;
+ if (*(p + 1) == '|')
+ {
+ while (*++p && *p != '=' && *p != '!' && *p != ':' && *p != '?');
+ if ((p - s) > 1)
+ sl = p - s;
+ if (*p == '!')
+ a |= OPT_invert;
+ }
+ if (*(p + 1) == '\f')
+ p++;
+ else
+ p = skip(p, ':', '?', 0, 1, 0, 0, version);
+ if (sl || (p - s) == 1 || *(s + 1) == '=' || *(s + 1) == '!' && (a |= OPT_invert) || *(s + 1) == '|')
+ f = *s;
+ }
+ re = p;
+ if (style <= STYLE_short)
+ {
+ if (!z && !f)
+ z = -1;
+ }
+ else
+ {
+ if (*p == '\f' && (vp = state.vp))
+ p = expand(p + 1, NiL, &t, vp, id);
+ else
+ t = 0;
+ if (*p == ':')
+ {
+ p = skip(w = p + 1, ':', '?', 0, 1, 0, 0, version);
+ if (!(wl = p - w))
+ w = 0;
+ }
+ else
+ wl = 0;
+ if (*p == ':' || *p == '?')
+ {
+ d = p;
+ p = skip(p, 0, 0, 0, 1, 0, 0, version);
+ }
+ else
+ d = 0;
+ if (style == STYLE_match)
+ {
+ if (wl && !match((char*)what, w, version, id, catalog))
+ wl = 0;
+ if ((!wl || *w == ':' || *w == '?') && (what[1] || sl && !memchr(s, what[0], sl) || !sl && what[0] != f))
+ {
+ w = 0;
+ if (!z)
+ z = -1;
+ }
+ else
+ matched = 1;
+ }
+ if (t)
+ {
+ p = t;
+ if (*p == ':' || *p == '?')
+ {
+ d = p;
+ p = skip(p, 0, 0, 0, 1, 0, 0, version);
+ }
+ }
+ }
+ }
+ p = skip(p, 0, 0, 0, 1, 0, 1, version);
+ if (*p == GO)
+ p = skip(p + 1, 0, 0, 0, 0, 1, 1, version);
+ }
+ else if (*p == ']')
+ {
+ if (mutex)
+ {
+ if (style >= STYLE_nroff)
+ sfputr(sp_body, "\n.OP - - anyof", '\n');
+ if (!(mutex & 1))
+ {
+ mutex--;
+ if (style <= STYLE_long)
+ {
+ sfputc(sp_body, ' ');
+ sfputc(sp_body, ']');
+ }
+ }
+ mutex--;
+ }
+ p++;
+ continue;
+ }
+ else if (*p == '?')
+ {
+ if (style < STYLE_match)
+ z = 1;
+ mode |= OPT_hidden;
+ p++;
+ continue;
+ }
+ else if (*p == '\\' && style==STYLE_posix)
+ {
+ if (*++p)
+ p++;
+ continue;
+ }
+ else
+ {
+ f = *p++;
+ s = 0;
+ if (style == STYLE_match && !z)
+ z = -1;
+ }
+ if (!z)
+ {
+ if (style == STYLE_long || prefix < 2 || (q->flags & OPT_long))
+ f = 0;
+ else if (style <= STYLE_short)
+ w = 0;
+ if (!f && !w)
+ z = -1;
+ }
+ ov = 0;
+ u = v = y = 0;
+ if (*p == ':' && (a |= OPT_string) || *p == '#' && (a |= OPT_number))
+ {
+ message((-21, "opthelp: arg %s", show(p)));
+ if (*++p == '?' || *p == *(p - 1))
+ {
+ p++;
+ a |= OPT_optional;
+ }
+ if (*(p = next(p, version)) == '[')
+ {
+ if (!z)
+ {
+ p = skip(y = p + 1, ':', '?', 0, 1, 0, 0, version);
+ while (*p == ':')
+ {
+ p = skip(t = p + 1, ':', '?', 0, 1, 0, 0, version);
+ m = p - t;
+ if (*t == '!')
+ {
+ ov = t + 1;
+ ol = m - 1;
+ }
+ else if (*t == '=')
+ {
+ v = t + 1;
+ vl = m - 1;
+ }
+ else
+ for (j = 0; j < elementsof(attrs); j++)
+ if (strneq(t, attrs[j].name, m))
+ {
+ a |= attrs[j].flag;
+ break;
+ }
+ }
+ if (*p == '?')
+ u = p;
+ p = skip(p, 0, 0, 0, 1, 0, 1, version);
+ }
+ else
+ p = skip(p + 1, 0, 0, 0, 1, 0, 1, version);
+ }
+ else
+ y = (a & OPT_number) ? T(NiL, ID, "#") : T(NiL, ID, "arg");
+ }
+ else
+ a |= OPT_flag;
+ if (!z)
+ {
+ if (style <= STYLE_short && !y && !mutex || style == STYLE_posix)
+ {
+ if (style != STYLE_posix && !sfstrtell(sp))
+ {
+ sfputc(sp, '[');
+ if (sp == sp_plus)
+ sfputc(sp, '+');
+ sfputc(sp, '-');
+ }
+ if (!sl)
+ sfputc(sp, f);
+ else
+ for (c = 0; c < sl; c++)
+ if (s[c] != '|')
+ sfputc(sp, s[c]);
+ if (style == STYLE_posix && y)
+ sfputc(sp, ':');
+ }
+ else
+ {
+ if (style >= STYLE_match)
+ {
+ sfputc(sp_body, '\n');
+ if (!head)
+ {
+ head = 1;
+ item(sp_body, (flags & OPT_functions) ? C("FUNCTIONS") : C("OPTIONS"), 0, 0, style, sp_info, version, id, ID, &bflags);
+ }
+ if (style >= STYLE_nroff)
+ {
+ if (mutex & 1)
+ {
+ mutex++;
+ sfputr(sp_body, "\n.OP - - oneof", '\n');
+ }
+ }
+ else
+ sfputc(sp_body, '\t');
+ }
+ else
+ {
+ if (sp_body)
+ sfputc(sp_body, ' ');
+ else if (!(sp_body = sfstropen()))
+ goto nospace;
+ if (mutex)
+ {
+ if (mutex & 1)
+ {
+ mutex++;
+ sfputc(sp_body, '[');
+ }
+ else
+ sfputc(sp_body, '|');
+ sfputc(sp_body, ' ');
+ }
+ else
+ sfputc(sp_body, '[');
+ }
+ if (style >= STYLE_nroff)
+ {
+ if (flags & OPT_functions)
+ {
+ sfputr(sp_body, ".FN", ' ');
+ if (re > rb)
+ sfwrite(sp_body, rb, re - rb);
+ else
+ sfputr(sp, "void", -1);
+ if (w)
+ label(sp_body, ' ', w, 0, -1, 0, style, FONT_BOLD, sp_info, version, id, catalog);
+ }
+ else
+ {
+ sfputr(sp_body, ".OP", ' ');
+ if (sl)
+ sfwrite(sp_body, s, sl);
+ else
+ sfputc(sp_body, f ? f : '-');
+ sfputc(sp_body, ' ');
+ if (w)
+ {
+ if (label(sp_body, 0, w, 0, -1, 0, style, 0, sp_info, version, id, catalog))
+ {
+ sfputc(sp_body, '|');
+ label(sp_body, 0, w, 0, -1, 0, style, 0, sp_info, version, id, native);
+ }
+ }
+ else
+ sfputc(sp_body, '-');
+ sfputc(sp_body, ' ');
+ m = a & OPT_TYPE;
+ for (j = 0; j < elementsof(attrs); j++)
+ if (m & attrs[j].flag)
+ {
+ sfputr(sp_body, attrs[j].name, -1);
+ break;
+ }
+ if (m = (a & ~m) | mode)
+ for (j = 0; j < elementsof(attrs); j++)
+ if (m & attrs[j].flag)
+ {
+ sfputc(sp_body, ':');
+ sfputr(sp_body, attrs[j].name, -1);
+ }
+ sfputc(sp_body, ' ');
+ if (y)
+ label(sp_body, 0, y, 0, -1, 0, style, 0, sp_info, version, id, catalog);
+ else
+ sfputc(sp_body, '-');
+ if (v)
+ sfprintf(sp_body, " %-.*s", vl, v);
+ }
+ }
+ else
+ {
+ if (f)
+ {
+ if (sp_body == sp_plus)
+ sfputc(sp_body, '+');
+ sfputc(sp_body, '-');
+ sfputr(sp_body, font(FONT_BOLD, style, 1), -1);
+ if (!sl)
+ {
+ sfputc(sp_body, f);
+ if (f == '-' && y)
+ {
+ y = 0;
+ sfputr(sp_body, C("long-option[=value]"), -1);
+ }
+ }
+ else
+ sfwrite(sp_body, s, sl);
+ sfputr(sp_body, font(FONT_BOLD, style, 0), -1);
+ if (w)
+ {
+ sfputc(sp_body, ',');
+ sfputc(sp_body, ' ');
+ }
+ }
+ else if ((flags & OPT_functions) && re > rb)
+ {
+ sfwrite(sp_body, rb, re - rb);
+ sfputc(sp_body, ' ');
+ }
+ if (w)
+ {
+ if (prefix > 0)
+ {
+ sfputc(sp_body, '-');
+ if (prefix > 1)
+ sfputc(sp_body, '-');
+ }
+ if (label(sp_body, 0, w, 0, -1, 0, style, FONT_BOLD, sp_info, version, id, catalog))
+ {
+ sfputc(sp_body, '|');
+ label(sp_body, 0, w, 0, -1, 0, style, FONT_BOLD, sp_info, version, id, native);
+ }
+ }
+ if (y)
+ {
+ if (a & OPT_optional)
+ sfputc(sp_body, '[');
+ else if (!w)
+ sfputc(sp_body, ' ');
+ if (w)
+ sfputc(sp_body, prefix == 1 ? ' ' : '=');
+ label(sp_body, 0, y, 0, -1, 0, style, FONT_ITALIC, sp_info, version, id, catalog);
+ if (a & OPT_optional)
+ sfputc(sp_body, ']');
+ }
+ }
+ if (style >= STYLE_match)
+ {
+ if (d)
+ {
+ textout(sp_body, d, cb, cl, style, 0, 3, sp_info, version, id, catalog, &bflags);
+ cb = 0;
+ }
+ if (u)
+ textout(sp_body, u, cb, cl, style, 0, 3, sp_info, version, id, catalog, &bflags);
+ if ((a & OPT_invert) && w && (d || u))
+ {
+ u = skip(w, ':', '?', 0, 1, 0, 0, version);
+ if (f)
+ sfprintf(sp_info, " %s; -\b%c\b %s --\bno%-.*s\b.", T(NiL, ID, "On by default"), f, T(NiL, ID, "means"), u - w, w);
+ else
+ sfprintf(sp_info, " %s %s\bno%-.*s\b %s.", T(NiL, ID, "On by default; use"), "--"+2-prefix, u - w, w, T(NiL, ID, "to turn off"));
+ if (!(t = sfstruse(sp_info)))
+ goto nospace;
+ textout(sp_body, t, 0, 0, style, 0, 0, sp_info, version, NiL, NiL, &bflags);
+ }
+ if (*p == GO)
+ {
+ p = u ? skip(p + 1, 0, 0, 0, 0, 1, 1, version) : textout(sp_body, p, 0, 0, style, 4, 0, sp_info, version, id, catalog, &bflags);
+ y = "+?";
+ }
+ else
+ y = " ";
+ if (a & OPT_optional)
+ {
+ if (ov)
+ {
+ sfprintf(sp_info, "%s%s \b", y, T(NiL, ID, "If the option value is omitted then"));
+ t = ov + ol;
+ while (ov < t)
+ {
+ if (((c = *ov++) == ':' || c == '?') && *ov == c)
+ ov++;
+ sfputc(sp_info, c);
+ }
+ sfprintf(sp_info, "\b %s.", T(NiL, ID, "is assumed"));
+ }
+ else
+ sfprintf(sp_info, "%s%s", y, T(NiL, ID, "The option value may be omitted."));
+ if (!(t = sfstruse(sp_info)))
+ goto nospace;
+ textout(sp_body, t, 0, 0, style, 4, 0, sp_info, version, NiL, NiL, &bflags);
+ y = " ";
+ }
+ if (v)
+ {
+ sfprintf(sp_info, "%s%s \b", y, T(NiL, ID, "The default value is"));
+ t = v + vl;
+ while (v < t)
+ {
+ if (((c = *v++) == ':' || c == '?') && *v == c)
+ v++;
+ sfputc(sp_info, c);
+ }
+ sfputc(sp_info, '\b');
+ sfputc(sp_info, '.');
+ if (!(t = sfstruse(sp_info)))
+ goto nospace;
+ textout(sp_body, t, 0, 0, style, 4, 0, sp_info, version, NiL, NiL, &bflags);
+ }
+ }
+ else if (!mutex)
+ sfputc(sp_body, ']');
+ }
+ if (*p == GO)
+ {
+ if (style >= STYLE_match)
+ p = textout(sp_body, p, 0, 0, style, 4, 0, sp_info, version, id, catalog, &bflags);
+ else
+ p = skip(p + 1, 0, 0, 0, 0, 1, 1, version);
+ }
+ }
+ else if (*p == GO)
+ p = skip(p + 1, 0, 0, 0, 0, 1, 1, version);
+ }
+ psp = pop(psp);
+ if (sp_misc)
+ {
+ if (!(p = sfstruse(sp_misc)))
+ goto nospace;
+ for (t = p; *t == '\t' || *t == '\n'; t++);
+ if (*t)
+ {
+ item(sp_body, C("IMPLEMENTATION"), 0, 0, style, sp_info, version, id, ID, &bflags);
+ sfputr(sp_body, p, -1);
+ }
+ }
+ }
+ if (oopts != o->oopts && oopts == top.oopts)
+ state.pass[0] = top;
+ version = o->version;
+ id = o->id;
+ catalog = o->catalog;
+ if (style >= STYLE_keys)
+ {
+ if (sp_info)
+ sfclose(sp_info);
+ if (style == STYLE_keys && sfstrtell(mp) > 1)
+ sfstrseek(mp, -1, SEEK_CUR);
+ if (!(p = sfstruse(mp)))
+ goto nospace;
+ return opt_info.msg = p;
+ }
+ sp = sp_text;
+ if (sfstrtell(sp) && style != STYLE_posix)
+ sfputc(sp, ']');
+ if (style == STYLE_nroff)
+ {
+ char rd[64];
+ char ud[64];
+
+ s = o->id;
+ t = ud;
+ while (t < &ud[sizeof(ud)-2] && (c = *s++))
+ {
+ if (islower(c))
+ c = toupper(c);
+ *t++ = c;
+ }
+ *t = 0;
+ t = rd;
+ if (s = o->release)
+ {
+ *t++ = ' ';
+ while (t < &rd[sizeof(rd)-2] && (c = *s++) && c != ']')
+ *t++ = c;
+ }
+ *t = 0;
+ sfprintf(sp, "\
+.\\\" format with nroff|troff|groff -man\n\
+.TH %s %s%s\n\
+.fp 5 CW\n\
+.nr mH 5\n\
+.de H0\n\
+.nr mH 0\n\
+.in 5n\n\
+\\fB\\\\$1\\fP\n\
+.in 7n\n\
+..\n\
+.de H1\n\
+.nr mH 1\n\
+.in 7n\n\
+\\fB\\\\$1\\fP\n\
+.in 9n\n\
+..\n\
+.de H2\n\
+.nr mH 2\n\
+.in 11n\n\
+\\fB\\\\$1\\fP\n\
+.in 13n\n\
+..\n\
+.de H3\n\
+.nr mH 3\n\
+.in 15n\n\
+\\fB\\\\$1\\fP\n\
+.in 17n\n\
+..\n\
+.de H4\n\
+.nr mH 4\n\
+.in 19n\n\
+\\fB\\\\$1\\fP\n\
+.in 21n\n\
+..\n\
+.de OP\n\
+.nr mH 0\n\
+.ie !'\\\\$1'-' \\{\n\
+.ds mO \\\\fB\\\\-\\\\$1\\\\fP\n\
+.ds mS ,\\\\0\n\
+.\\}\n\
+.el \\{\n\
+.ds mO \\\\&\n\
+.ds mS \\\\&\n\
+.\\}\n\
+.ie '\\\\$2'-' \\{\n\
+.if !'\\\\$4'-' .as mO \\\\0\\\\fI\\\\$4\\\\fP\n\
+.\\}\n\
+.el \\{\n\
+.as mO \\\\*(mS\\\\fB%s\\\\$2\\\\fP\n\
+.if !'\\\\$4'-' .as mO =\\\\fI\\\\$4\\\\fP\n\
+.\\}\n\
+.in 5n\n\
+\\\\*(mO\n\
+.in 9n\n\
+..\n\
+.de SP\n\
+.if \\\\n(mH==2 .in 9n\n\
+.if \\\\n(mH==3 .in 13n\n\
+.if \\\\n(mH==4 .in 17n\n\
+..\n\
+.de FN\n\
+.nr mH 0\n\
+.in 5n\n\
+\\\\$1 \\\\$2\n\
+.in 9n\n\
+..\n\
+.de DS\n\
+.in +3n\n\
+.ft 5\n\
+.nf\n\
+..\n\
+.de DE\n\
+.fi\n\
+.ft R\n\
+.in -3n\n\
+..\n\
+"
+, ud
+, section
+, rd
+, o->prefix == 2 ? "\\\\-\\\\-" : o->prefix == 1 ? "\\\\-" : ""
+);
+ }
+ if (style == STYLE_match)
+ {
+ if (!matched)
+ {
+ if (hp = (Help_t*)search(styles, elementsof(styles), sizeof(styles[0]), (char*)what))
+ {
+ if (!sp_help && !(sp_help = sfstropen()))
+ goto nospace;
+ sfprintf(sp_help, "[-][:%s?%s]", hp->match, hp->text);
+ if (!(opts = sfstruse(sp_help)))
+ goto nospace;
+ goto again;
+ }
+ s = (char*)unknown;
+ goto nope;
+ }
+ else if (matched < 0)
+ x = 0;
+ }
+ if (sp_plus)
+ {
+ if (sfstrtell(sp_plus))
+ {
+ if (sfstrtell(sp))
+ sfputc(sp, ' ');
+ if (!(t = sfstruse(sp_plus)))
+ goto nospace;
+ sfputr(sp, t, ']');
+ }
+ sfclose(sp_plus);
+ }
+ if (style >= STYLE_man)
+ {
+ if (sp_head)
+ {
+ if (!(t = sfstruse(sp_head)))
+ goto nospace;
+ for (; *t == '\n'; t++);
+ sfputr(sp, t, '\n');
+ sfclose(sp_head);
+ sp_head = 0;
+ }
+ if (x)
+ item(sp, C("SYNOPSIS"), 0, 0, style, sp_info, version, id, ID, &hflags);
+ }
+ if (x)
+ {
+ for (t = x + xl; t > x && (*(t - 1) == '\n' || *(t - 1) == '\r'); t--);
+ xl = t - x;
+ if (style >= STYLE_match)
+ {
+ u = id;
+ if (o->flags & OPT_functions)
+ t = 0;
+ else if (t = strchr(u, ':'))
+ {
+ if ((o->flags & OPT_module) && *(t + 1) == ':' && *(t + 2))
+ {
+ u = t + 2;
+ t = 0;
+ }
+ else
+ *t = 0;
+ }
+ args(sp, x, xl, o->flags, style, sp_info, version, u, catalog);
+ if (t)
+ *t = ':';
+ x = 0;
+ }
+ }
+ if (sp_body)
+ {
+ if (sfstrtell(sp_body))
+ {
+ if (style < STYLE_match && sfstrtell(sp))
+ sfputc(sp, ' ');
+ if (!(t = sfstruse(sp_body)))
+ goto nospace;
+ if (style == STYLE_html && !(dflags & HELP_head) && (bflags & HELP_head))
+ sfputr(sp, "\n</DIV>", '\n');
+ sfputr(sp, t, -1);
+ }
+ sfclose(sp_body);
+ sp_body = 0;
+ }
+ if (x && style != STYLE_posix)
+ args(sp, x, xl, flags, style, sp_info, version, id, catalog);
+ if (sp_info)
+ {
+ sfclose(sp_info);
+ sp_info = 0;
+ }
+ if (sp_misc)
+ {
+ sfclose(sp_misc);
+ sp_misc = 0;
+ }
+ if (!(p = sfstruse(sp)))
+ goto nospace;
+ astwinsize(1, NiL, &state.width);
+ if (state.width < 20)
+ state.width = OPT_WIDTH;
+ m = strlen((style <= STYLE_long && error_info.id && !strchr(error_info.id, '/')) ? error_info.id : id) + 1;
+ margin = style == STYLE_api ? (8 * 1024) : (state.width - 1);
+ if (!(state.flags & OPT_preformat))
+ {
+ if (style >= STYLE_man || matched < 0)
+ {
+ sfputc(mp, '\f');
+ ts = 0;
+ }
+ else
+ ts = OPT_USAGE + m;
+ if (style == STYLE_html)
+ {
+ char ud[64];
+
+ s = id;
+ t = ud;
+ while (t < &ud[sizeof(ud)-2] && (c = *s++))
+ {
+ if (islower(c))
+ c = toupper(c);
+ *t++ = c;
+ }
+ *t = 0;
+ sfprintf(mp, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n<HTML>\n<HEAD>\n<META name=\"generator\" content=\"optget (AT&T Research) 2011-11-11\">\n%s<TITLE>%s man document</TITLE>\n<STYLE type=\"text/css\">\ndiv.SH { padding-left:2em; text-indent:0em; }\ndiv.SY { padding-left:4em; text-indent:-2em; }\ndt { float:left; clear:both; }\ndd { margin-left:3em; }\n</STYLE>\n</HEAD>\n<BODY bgcolor=white>\n", (state.flags & OPT_proprietary) ? "<!--INTERNAL-->\n" : "", id);
+ sfprintf(mp, "<H4><TABLE width=100%%><TR><TH align=left>%s&nbsp;(&nbsp;%s&nbsp;)&nbsp;<TH align=center><A href=\".\" title=\"Index\">%s</A><TH align=right>%s&nbsp;(&nbsp;%s&nbsp;)</TR></TABLE></H4>\n<HR>\n", ud, section, T(NiL, ID, secname(section)), ud, section);
+ co = 2;
+ pt = ptstk;
+ pt->level = 0;
+ pt->id = TAG_DIV;
+ }
+ else
+ co = 0;
+ if ((rm = margin - ts) < OPT_MARGIN)
+ rm = OPT_MARGIN;
+ ip = indent;
+ ip->stop = (ip+1)->stop = style >= STYLE_html ? 0 : 2;
+ tp = 0;
+ n = 0;
+ head = 1;
+ while (*p == '\n')
+ p++;
+ while (c = *p++)
+ {
+ if (c == '\n')
+ {
+ ip = indent;
+ n = 0;
+ tp = 0;
+ sfputc(mp, '\n');
+ co = 0;
+ rm = margin;
+ ts = ip->stop;
+ if (*p == '\n')
+ {
+ while (*++p == '\n');
+ if ((style == STYLE_man || style == STYLE_html) && (!head || *p != ' ' && *p != '\t'))
+ {
+ if (style == STYLE_man)
+ p--;
+ else
+ sfprintf(mp, "<P>\n");
+ }
+ }
+ head = *p != ' ' && *p != '\t';
+ if (style == STYLE_html && (*p != '<' || !strneq(p, "<BR>", 4) && !strneq(p, "<P>", 3)))
+ {
+ y = p;
+ while (*p == '\t')
+ p++;
+ if (*p == '\n')
+ continue;
+ j = p - y;
+ if (j > pt->level)
+ {
+ pt++;
+ pt->level = j;
+ pt->id = TAG_NONE;
+ for (y = p; *y && *y != '\n'; y++)
+ if (*y == '\t')
+ {
+ pt->id = TAG_DL;
+ sfprintf(mp, "<DL>\n");
+ break;
+ }
+ }
+ else
+ while (j < pt->level && pt > ptstk)
+ {
+ sfprintf(mp, "%s", end[pt->id]);
+ pt--;
+ }
+ if (pt->id == TAG_DL)
+ {
+ dt = p;
+ sfprintf(mp, "<DT>");
+ }
+ else
+ dt = 0;
+ }
+ }
+ else if (c == '\t')
+ {
+ if (style == STYLE_html)
+ {
+ while (*p == '\t')
+ p++;
+ if (*p != '\n')
+ {
+ co += sfprintf(mp, "<DD>");
+ if (dt)
+ {
+ c = 0;
+ m = 0;
+ for (;;)
+ {
+ switch (*dt++)
+ {
+ case '\t':
+ break;
+ case '<':
+ c = '>';
+ continue;
+ case '>':
+ if (c == '>')
+ c = 0;
+ else
+ m++;
+ continue;
+ case '&':
+ c = ';';
+ continue;
+ case ';':
+ if (c == ';')
+ c = 0;
+ m++;
+ continue;
+ default:
+ if (!c)
+ m++;
+ continue;
+ }
+ break;
+ }
+ if (m >= 5)
+ co += sfprintf(mp, "<BR>");
+ }
+ }
+ }
+ else
+ {
+ if ((ip+1)->stop)
+ {
+ do
+ {
+ ip++;
+ if (*p != '\t')
+ break;
+ p++;
+ } while ((ip+1)->stop);
+ if (*p == '\n')
+ continue;
+ ts = ip->stop;
+ if (co >= ts)
+ {
+ sfputc(mp, '\n');
+ co = 0;
+ rm = margin;
+ ts = ip->stop;
+ }
+ }
+ while (co < ts)
+ {
+ sfputc(mp, ' ');
+ co++;
+ }
+ }
+ }
+ else
+ {
+ if (c == ' ' && !n)
+ {
+ if (co >= rm)
+ tp = 0;
+ else
+ {
+ tp = sfstrtell(mp);
+ pp = p;
+ }
+ if (style == STYLE_nroff && !co)
+ continue;
+ }
+ else if (style == STYLE_html)
+ {
+ if (c == '<')
+ {
+ if (strneq(p, "NOBR>", 5))
+ n++;
+ else if (n && strneq(p, "/NOBR>", 6) && !--n)
+ {
+ for (y = p += 6; (c = *p) && c != ' ' && c != '\t' && c != '\n' && c != '<'; p++)
+ if (c == '[')
+ sfputr(mp, "&#0091;", -1);
+ else if (c == ']')
+ sfputr(mp, "&#0093;", -1);
+ else
+ sfputc(mp, c);
+ sfwrite(mp, "</NOBR", 6);
+ c = '>';
+ co += p - y + 6;
+ }
+ }
+ else if (c == '>' && !n)
+ {
+ for (y = --p; (c = *p) && c != ' ' && c != '\t' && c != '\n' && c != '<'; p++)
+ if (c == '[')
+ sfputr(mp, "&#0091;", -1);
+ else if (c == ']')
+ sfputr(mp, "&#0093;", -1);
+ else
+ sfputc(mp, c);
+ c = *sfstrseek(mp, -1, SEEK_CUR);
+ if (p > y + 1)
+ {
+ tp = 0;
+ co += p - y - 1;
+ }
+ if (co >= rm)
+ tp = 0;
+ else
+ {
+ tp = sfstrtell(mp);
+ pp = p;
+ }
+ }
+ else if (c == '[')
+ {
+ sfputr(mp, "&#0091", -1);
+ c = ';';
+ }
+ else if (c == ']')
+ {
+ sfputr(mp, "&#0093", -1);
+ c = ';';
+ }
+ else if (c == 'h')
+ {
+ y = p;
+ if (*y++ == 't' && *y++ == 't' && *y++ == 'p' && (*y == ':' || *y++ == 's' && *y == ':') && *y++ == ':' && *y++ == '/' && *y++ == '/')
+ {
+ while (isalnum(*y) || *y == '_' || *y == '/' || *y == '-' || *y == '.')
+ y++;
+ if (*y == '?')
+ while (isalnum(*y) || *y == '_' || *y == '/' || *y == '-' || *y == '.' || *y == '?' || *y == '=' || *y == '%' || *y == '&' || *y == ';' || *y == '#')
+ y++;
+ if (*(y - 1) == '.')
+ y--;
+ p--;
+ sfprintf(mp, "<A href=\"%-.*s\">%-.*s</A", y - p, p, y - p, p);
+ p = y;
+ c = '>';
+ }
+ }
+ else if (c == 'C')
+ {
+ y = p;
+ if (*y++ == 'o' && *y++ == 'p' && *y++ == 'y' && *y++ == 'r' && *y++ == 'i' && *y++ == 'g' && *y++ == 'h' && *y++ == 't' && *y++ == ' ' && *y++ == '(' && (*y++ == 'c' || *(y - 1) == 'C') && *y++ == ')')
+ {
+ sfputr(mp, "Copyright &copy", -1);
+ p = y;
+ c = ';';
+ }
+ }
+ }
+ else if (c == ']')
+ {
+ if (n)
+ n--;
+ }
+ else if (c == '[')
+ n++;
+ if (c == CC_esc)
+ {
+ sfputc(mp, c);
+ do
+ {
+ if (!(c = *p++))
+ {
+ p--;
+ break;
+ }
+ sfputc(mp, c);
+ } while (c < 'a' || c > 'z');
+ }
+ else if (co++ >= rm && !n)
+ {
+ if (tp)
+ {
+ if (*sfstrseek(mp, tp, SEEK_SET) != ' ')
+ sfstrseek(mp, 1, SEEK_CUR);
+ tp = 0;
+ p = pp;
+ n = 0;
+ }
+ else if (c != ' ' && c != '\n')
+ sfputc(mp, c);
+ if (*p == ' ')
+ p++;
+ if (*p != '\n')
+ {
+ sfputc(mp, '\n');
+ for (co = 0; co < ts; co++)
+ sfputc(mp, ' ');
+ rm = margin;
+ }
+ }
+ else
+ sfputc(mp, c);
+ }
+ }
+ for (d = sfstrbase(mp), t = sfstrseek(mp, 0, SEEK_CUR); t > d && ((c = *(t - 1)) == '\n' || c == '\r' || c == ' ' || c == '\t'); t--);
+ sfstrseek(mp, t - d, SEEK_SET);
+ if (style == STYLE_html)
+ {
+ sfprintf(mp, "\n");
+ while (pt > ptstk)
+ {
+ sfprintf(mp, "%s", end[pt->id]);
+ pt--;
+ }
+ sfprintf(mp, "</DIV>\n</BODY>\n</HTML>");
+ }
+ }
+ else
+ sfputr(mp, p, 0);
+ if (!(p = sfstruse(mp)))
+ goto nospace;
+ if (sp)
+ sfclose(sp);
+ return opt_info.msg = p;
+ nospace:
+ s = T(NiL, ID, "[* out of space *]");
+ nope:
+ if (psp)
+ pop(psp);
+ if (sp_help)
+ sfclose(sp_help);
+ if (sp_text)
+ sfclose(sp_text);
+ if (sp_plus)
+ sfclose(sp_plus);
+ if (sp_info)
+ sfclose(sp_info);
+ if (sp_head)
+ sfclose(sp_head);
+ if (sp_body)
+ sfclose(sp_body);
+ if (sp_misc)
+ sfclose(sp_misc);
+ return s;
+}
+
+/*
+ * compatibility wrapper to opthelp()
+ */
+
+char*
+optusage(const char* opts)
+{
+ return opthelp(opts, NiL);
+}
+
+/*
+ * convert number using strtonll() *except* that
+ * 0*[[:digit:]].* is treated as [[:digit:]].*
+ * i.e., it looks octal but isn't, to meet
+ * posix Utility Argument Syntax -- use
+ * 0x.* or <base>#* for alternate bases
+ */
+
+static intmax_t
+optnumber(const char* s, char** t, int* e)
+{
+ intmax_t n;
+ int oerrno;
+
+ while (*s == '0' && isdigit(*(s + 1)))
+ s++;
+ oerrno = errno;
+ errno = 0;
+ n = strtonll(s, t, NiL, 0);
+ if (e)
+ *e = errno;
+ errno = oerrno;
+ return n;
+}
+
+/*
+ * point opt_info.arg to an error/info message for opt_info.name
+ * p points to opts location for opt_info.name
+ * optget() return value is returned
+ */
+
+static int
+opterror(register char* p, int err, int version, char* id, char* catalog)
+{
+ register Sfio_t* mp;
+ register Sfio_t* tp;
+ register char* s;
+ register int c;
+
+ if (opt_info.num != LONG_MIN)
+ opt_info.num = (long)(opt_info.number = 0);
+ if (!p || !(mp = state.mp) && !(mp = state.mp = sfstropen()))
+ goto nospace;
+ s = *p == '-' ? p : opt_info.name;
+ if (*p == '!')
+ {
+ while (*s == '-')
+ sfputc(mp, *s++);
+ sfputc(mp, 'n');
+ sfputc(mp, 'o');
+ }
+ sfputr(mp, s, ':');
+ sfputc(mp, ' ');
+ if (*p == '#' || *p == ':')
+ {
+ if (*p == '#')
+ {
+ s = T(NiL, ID, "numeric");
+ sfputr(mp, s, ' ');
+ }
+ if (*(p = next(p + 1, version)) == '[')
+ {
+ p = skip(s = p + 1, ':', '?', 0, 1, 0, 0, version);
+ tp = X(catalog) ? state.xp : mp;
+ while (s < p)
+ {
+ if ((c = *s++) == '?' || c == ']')
+ s++;
+ sfputc(tp, c);
+ }
+ if (!X(catalog))
+ sfputc(mp, ' ');
+ else if (p = sfstruse(tp))
+ sfputr(mp, T(id, catalog, p), ' ');
+ else
+ goto nospace;
+ }
+ p = opt_info.name[2] ? C("value expected") : C("argument expected");
+ }
+ else if (*p == '*' || *p == '&')
+ {
+ sfputr(mp, opt_info.arg, ':');
+ sfputc(mp, ' ');
+ p = *p == '&' ? C("ambiguous option argument value") : C("unknown option argument value");
+ }
+ else if (*p == '=' || *p == '!')
+ p = C("value not expected");
+ else if (*p == '?')
+ p = *(p + 1) == '?' ? C("optget: option not supported") : C("ambiguous option");
+ else if (*p == '+')
+ p = C("section not found");
+ else
+ {
+ if (opt_info.option[0] != '?' && opt_info.option[0] != '-' || opt_info.option[1] != '?' && opt_info.option[1] != '-')
+ opt_info.option[0] = 0;
+ p = C("unknown option");
+ }
+ p = T(NiL, ID, p);
+ sfputr(mp, p, -1);
+ if (err)
+ sfputr(mp, " -- out of range", -1);
+ if (opt_info.arg = sfstruse(mp))
+ return ':';
+ nospace:
+ opt_info.arg = T(NiL, ID, "[* out of space *]");
+ return ':';
+}
+
+/*
+ * argv: command line argv where argv[0] is command name
+ *
+ * opts: option control string
+ *
+ * '[' [flag][=][index][:<long-name>[|<alias-name>...]['?'description]] ']'
+ * long option name, index, description; -index returned
+ * ':' option takes string arg
+ * '#' option takes numeric arg (concat option may follow)
+ * '?' (option) following options not in usage
+ * (following # or :) optional arg
+ * '[' '[' ... ] ... '[' ... ']' ']'
+ * mutually exclusive option grouping
+ * '[' name [:attr]* [?description] ']'
+ * (following # or :) optional option arg description
+ * '\n'[' '|'\t']* ignored for legibility
+ * ' ' ... optional argument(s) description (to end of string)
+ * or after blank line
+ * ']]' literal ']' within '[' ... ']'
+ *
+ * return:
+ * 0 no more options
+ * '?' usage: opt_info.arg points to message sans
+ * `Usage: command '
+ * ':' error: opt_info.arg points to message sans `command: '
+ *
+ * ':' '#' ' ' '[' ']'
+ * invalid option chars
+ *
+ * -- terminates option list and returns 0
+ *
+ * + as first opts char makes + equivalent to -
+ *
+ * if any # option is specified then numeric options (e.g., -123)
+ * are associated with the leftmost # option in opts
+ *
+ * usage info in placed opt_info.arg when '?' returned
+ * see help_text[] (--???) for more info
+ */
+
+int
+optget(register char** argv, const char* oopts)
+{
+ register int c;
+ register char* s;
+ char* a;
+ char* b;
+ char* e;
+ char* f;
+ char* g;
+ char* v;
+ char* w;
+ char* p;
+ char* q;
+ char* t;
+ char* y;
+ char* numopt;
+ char* opts;
+ char* id;
+ char* catalog;
+ int n;
+ int m;
+ int k;
+ int j;
+ int x;
+ int err;
+ int no;
+ int nov;
+ int num;
+ int numchr;
+ int prefix;
+ int version;
+ Help_t* hp;
+ Push_t* psp;
+ Push_t* tsp;
+ Sfio_t* vp;
+ Sfio_t* xp;
+ Optcache_t* cache;
+ Optcache_t* pcache;
+ Optpass_t* pass;
+
+#if !_PACKAGE_astsa && !_YOU_FIGURED_OUT_HOW_TO_GET_ALL_DLLS_TO_DO_THIS_
+ /*
+ * these are not initialized by all dlls!
+ */
+
+ extern Error_info_t _error_info_;
+ extern Opt_t _opt_info_;
+
+ if (!_error_infop_)
+ _error_infop_ = &_error_info_;
+ if (!_opt_infop_)
+ _opt_infop_ = &_opt_info_;
+#endif
+ if (!oopts)
+ return 0;
+ state.pindex = opt_info.index;
+ state.poffset = opt_info.offset;
+ if (!opt_info.index)
+ {
+ opt_info.index = 1;
+ opt_info.offset = 0;
+ if (state.npass)
+ {
+ state.npass = 0;
+ state.join = 0;
+ }
+ }
+ if (!argv)
+ cache = 0;
+ else
+ for (pcache = 0, cache = state.cache; cache; pcache = cache, cache = cache->next)
+ if (cache->pass.oopts == (char*)oopts)
+ break;
+ if (cache)
+ {
+ if (pcache)
+ {
+ pcache->next = cache->next;
+ cache->next = state.cache;
+ state.cache = cache;
+ }
+ pass = &cache->pass;
+ state.npass = -1;
+ }
+ else
+ {
+ if (!argv)
+ n = state.npass ? state.npass : 1;
+ else if ((n = state.join - 1) < 0)
+ n = 0;
+ if (n >= state.npass || state.pass[n].oopts != (char*)oopts)
+ {
+ for (m = 0; m < state.npass && state.pass[m].oopts != (char*)oopts; m++);
+ if (m < state.npass)
+ n = m;
+ else
+ {
+ if (n >= elementsof(state.pass))
+ n = elementsof(state.pass) - 1;
+ init((char*)oopts, &state.pass[n]);
+ if (state.npass <= n)
+ state.npass = n + 1;
+ }
+ }
+ if (!argv)
+ return 0;
+ pass = &state.pass[n];
+ }
+ opts = pass->opts;
+ prefix = pass->prefix;
+ version = pass->version;
+ id = pass->id;
+ if (!(xp = state.xp) || (catalog = pass->catalog) && !X(catalog))
+ catalog = 0;
+ else /* if (!error_info.catalog) */
+ error_info.catalog = catalog;
+ again:
+ psp = 0;
+
+ /*
+ * check if any options remain and determine if the
+ * next option is short or long
+ */
+
+ opt_info.assignment = 0;
+ num = 1;
+ w = v = 0;
+ x = 0;
+ for (;;)
+ {
+ if (!opt_info.offset)
+ {
+ /*
+ * finished with the previous arg
+ */
+
+ if (opt_info.index == 1 && opt_info.argv != state.strv)
+ {
+ opt_info.argv = 0;
+ state.argv[0] = 0;
+ if (argv[0] && (state.argv[0] = save(argv[0], strlen(argv[0]), 0, 0, 0, 0)))
+ opt_info.argv = state.argv;
+ state.style = STYLE_short;
+ }
+ if (!(s = argv[opt_info.index]))
+ return 0;
+ if (!prefix)
+ {
+ /*
+ * long with no prefix (dd style)
+ */
+
+ n = 2;
+ if ((c = *s) != '-' && c != '+')
+ c = '-';
+ else if (*++s == c)
+ {
+ if (!*++s)
+ {
+ opt_info.index++;
+ return 0;
+ }
+ else if (*s == c)
+ return 0;
+ }
+ else if (*s == '?')
+ n = 1;
+ }
+ else if ((c = *s++) != '-' && (c != '+' || !(pass->flags & OPT_plus) && (!(pass->flags & OPT_numeric) || !isdigit(*s))))
+ {
+ if (!(pass->flags & OPT_old) || !isalpha(c))
+ return 0;
+ s--;
+ n = 1;
+ opt_info.offset--;
+ }
+ else if (*s == c)
+ {
+ if (!*++s)
+ {
+ /*
+ * -- or ++ end of options
+ */
+
+ opt_info.index++;
+ return 0;
+ }
+ else if (*s == c)
+ {
+ /*
+ * ---* or +++* are operands
+ */
+
+ return 0;
+ }
+ if (version || *s == '?' || !(pass->flags & OPT_minus))
+ {
+ /*
+ * long with double prefix
+ */
+
+ n = 2;
+ }
+ else
+ {
+ /*
+ * short option char '-'
+ */
+
+ s--;
+ n = 1;
+ }
+ }
+ else if (prefix == 1 && *s != '?')
+ {
+ /*
+ * long with single prefix (find style)
+ */
+
+ n = 2;
+ }
+ else
+ {
+ /*
+ * short (always with single prefix)
+ */
+
+ n = 1;
+ }
+
+ /*
+ * just a prefix is an option (e.g., `-' == stdin)
+ */
+
+ if (!*s)
+ return 0;
+ if (c == '+')
+ opt_info.arg = 0;
+ if (n == 2)
+ {
+ x = 0;
+ state.style = STYLE_long;
+ opt_info.option[0] = opt_info.name[0] = opt_info.name[1] = c;
+ w = &opt_info.name[prefix];
+ if ((*s == 'n' || *s == 'N') && (*(s + 1) == 'o' || *(s + 1) == 'O') && *(s + 2) && *(s + 2) != '=')
+ no = *(s + 2) == '-' ? 3 : 2;
+ else
+ no = 0;
+ for (c = *s; *s; s++)
+ {
+ if (*s == '=')
+ {
+ if (*(s + 1) == '=')
+ s++;
+ if (!isalnum(*(s - 1)) && *(w - 1) == (opt_info.assignment = *(s - 1)))
+ w--;
+ v = ++s;
+ break;
+ }
+ if (w < &opt_info.name[elementsof(opt_info.name) - 1] && *s != ':' && *s != '|' && *s != '[' && *s != ']')
+ *w++ = *s;
+ }
+ *w = 0;
+ w = &opt_info.name[prefix];
+ c = *w;
+ opt_info.offset = 0;
+ opt_info.index++;
+ break;
+ }
+ opt_info.offset++;
+ }
+ if (!argv[opt_info.index])
+ return 0;
+ if (c = argv[opt_info.index][opt_info.offset++])
+ {
+ if ((k = argv[opt_info.index][0]) != '-' && k != '+')
+ k = '-';
+ opt_info.option[0] = opt_info.name[0] = k;
+ opt_info.option[1] = opt_info.name[1] = c;
+ opt_info.option[2] = opt_info.name[2] = 0;
+ break;
+ }
+ opt_info.offset = 0;
+ opt_info.index++;
+ }
+
+ /*
+ * at this point:
+ *
+ * c the first character of the option
+ * w long option name if != 0, otherwise short
+ * v long option value (via =) if w != 0
+ */
+
+ if (c == '?')
+ {
+ /*
+ * ? always triggers internal help
+ */
+
+ if (!state.msgdict)
+ initdict();
+ if (w)
+ {
+ if (!v && (*(w + 1) || !(v = argv[opt_info.index]) || !++opt_info.index))
+ v = w + 1;
+ else if (w[0] != '?' || w[1])
+ {
+ s = w;
+ w = v;
+ v = s + 1;
+ }
+ }
+ opt_info.option[1] = c;
+ opt_info.option[2] = 0;
+ if (!w)
+ {
+ opt_info.name[1] = c;
+ opt_info.name[2] = 0;
+ }
+ goto help;
+ }
+ else if (w && !state.msgdict)
+ initdict();
+ numopt = 0;
+ f = 0;
+ s = opts;
+
+ /*
+ * no option can start with these characters
+ */
+
+ if (c == ':' || c == '#' || c == ' ' || c == '[' || c == ']')
+ {
+ if (c != *s)
+ s = "";
+ }
+ else
+ {
+ a = 0;
+ if (!w && (pass->flags & OPT_cache))
+ {
+ if (cache)
+ {
+ if (k = cache->flags[map[c]])
+ {
+ opt_info.arg = 0;
+
+ /*
+ * this is a ksh getopts workaround
+ */
+
+ if (opt_info.num != LONG_MIN)
+ opt_info.num = (long)(opt_info.number = !(k & OPT_cache_invert));
+ if (!(k & (OPT_cache_string|OPT_cache_numeric)))
+ return c;
+ if (*(opt_info.arg = &argv[opt_info.index++][opt_info.offset]))
+ {
+ if (!(k & OPT_cache_numeric))
+ {
+ opt_info.offset = 0;
+ return c;
+ }
+ opt_info.num = (long)(opt_info.number = optnumber(opt_info.arg, &e, &err));
+ if (err || e == opt_info.arg)
+ {
+ if (!err && (k & OPT_cache_optional))
+ {
+ opt_info.arg = 0;
+ opt_info.index--;
+ return c;
+ }
+ }
+ else if (*e)
+ {
+ opt_info.offset += e - opt_info.arg;
+ opt_info.index--;
+ return c;
+ }
+ else
+ {
+ opt_info.offset = 0;
+ return c;
+ }
+ }
+ else if (opt_info.arg = argv[opt_info.index])
+ {
+ opt_info.index++;
+ if ((k & OPT_cache_optional) && (*opt_info.arg == '-' || (pass->flags & OPT_plus) && *opt_info.arg == '+') && *(opt_info.arg + 1))
+ {
+ opt_info.arg = 0;
+ opt_info.index--;
+ opt_info.offset = 0;
+ return c;
+ }
+ if (k & OPT_cache_string)
+ {
+ opt_info.offset = 0;
+ return c;
+ }
+ opt_info.num = (long)(opt_info.number = optnumber(opt_info.arg, &e, &err));
+ if (!err)
+ {
+ if (!*e)
+ {
+ opt_info.offset = 0;
+ return c;
+ }
+ if (k & OPT_cache_optional)
+ {
+ opt_info.arg = 0;
+ opt_info.index--;
+ opt_info.offset = 0;
+ return c;
+ }
+ }
+ }
+ else if (k & OPT_cache_optional)
+ {
+ opt_info.offset = 0;
+ return c;
+ }
+ opt_info.index--;
+ }
+ cache = 0;
+ }
+ else if (cache = newof(0, Optcache_t, 1, 0))
+ {
+ cache->caching = c;
+ c = 0;
+ cache->pass = *pass;
+ cache->next = state.cache;
+ state.cache = cache;
+ }
+ }
+ else
+ cache = 0;
+ for (;;)
+ {
+ if (!(*(s = next(s, version))) || *s == '\n' || *s == ' ')
+ {
+ if (!(tsp = psp))
+ {
+ if (cache)
+ {
+ /*
+ * the first loop pass
+ * initialized the cache
+ * so one more pass to
+ * check the cache or
+ * bail for a full scan
+ */
+
+ cache->flags[0] = 0;
+ c = cache->caching;
+ cache->caching = 0;
+ cache = 0;
+ s = opts;
+ continue;
+ }
+ if (!x && catalog)
+ {
+ /*
+ * the first loop pass
+ * translated long
+ * options and there
+ * were no matches so
+ * one more pass for C
+ * locale
+ */
+
+ catalog = 0;
+ s = opts;
+ continue;
+ }
+ s = "";
+ break;
+ }
+ s = psp->ob;
+ psp = psp->next;
+ free(tsp);
+ continue;
+ }
+ if (*s == '\f')
+ {
+ psp = info(psp, s + 1, NiL, xp, id);
+ if (psp->nb)
+ s = psp->nb;
+ else
+ {
+ s = psp->ob;
+ psp = psp->next;
+ }
+ continue;
+ }
+ message((-20, "optget: opt %s c %c w %s num %ld", show(s), c, w, num));
+ if (*s == c && !w)
+ break;
+ else if (*s == '[')
+ {
+ s = next(s + 1, version);
+ if (*s == '(')
+ {
+ s = nest(f = s);
+ if (!conformance(f, s - f))
+ goto disable;
+ }
+ k = *(f = s);
+ if (k == '+' || k == '-')
+ /* ignore */;
+ else if (k == '[' || version < 1)
+ continue;
+ else if (w && !cache)
+ {
+ nov = no;
+ if (*(s + 1) == '\f' && (vp = state.vp))
+ {
+ sfputc(vp, k);
+ s = expand(s + 2, NiL, &t, vp, id);
+ if (*s)
+ *(f = s - 1) = k;
+ else
+ {
+ f = sfstrbase(vp);
+ if (s = strrchr(f, ':'))
+ f = s - 1;
+ else
+ s = f + 1;
+ }
+ }
+ else
+ t = 0;
+ if (*s != ':')
+ s = skip(s, ':', '?', 0, 1, 0, 0, version);
+ if (*s == ':')
+ {
+ if (catalog)
+ {
+ p = skip(s + 1, '?', 0, 0, 1, 0, 0, version);
+ e = sfprints("%-.*s", p - (s + 1), s + 1);
+ g = T(id, catalog, e);
+ if (g == e)
+ p = 0;
+ else
+ {
+ sfprintf(xp, ":%s|%s?", g, e);
+ if (!(s = sfstruse(xp)))
+ goto nospace;
+ }
+ }
+ else
+ p = 0;
+ y = w;
+ for (;;)
+ {
+ n = m = 0;
+ e = s + 1;
+ while (*++s)
+ {
+ if (*s == '*' || *s == '\a')
+ {
+ if (*s == '\a')
+ do
+ {
+ if (!*++s)
+ {
+ s--;
+ break;
+ }
+ } while (*s != '\a');
+ j = *(s + 1);
+ if (j == ':' || j == '|' || j == '?' || j == ']' || j == 0)
+ {
+ while (*w)
+ w++;
+ m = 0;
+ break;
+ }
+ m = 1;
+ }
+ else if (*s == *w || SEP(*s) && SEP(*w))
+ w++;
+ else if (*w == 0)
+ break;
+ else if (!SEP(*s))
+ {
+ if (SEP(*w))
+ {
+ if (*++w == *s)
+ {
+ w++;
+ continue;
+ }
+ }
+ else if (w == y || SEP(*(w - 1)) || isupper(*(w - 1)) && islower(*w))
+ break;
+ for (q = s; *q && !SEP(*q) && *q != '|' && *q != '?' && *q != ']'; q++);
+ if (!SEP(*q))
+ break;
+ for (s = q; w > y && *w != *(s + 1); w--);
+ }
+ else if (*w != *(s + 1))
+ break;
+ }
+ if (!*w)
+ {
+ nov = 0;
+ break;
+ }
+ if (n = no)
+ {
+ m = 0;
+ s = e - 1;
+ w = y + n;
+ while (*++s)
+ {
+ if (*s == '*' || *s == '\a')
+ {
+ if (*s == '\a')
+ do
+ {
+ if (!*++s)
+ {
+ s--;
+ break;
+ }
+ } while (*s != '\a');
+ j = *(s + 1);
+ if (j == ':' || j == '|' || j == '?' || j == ']' || j == 0)
+ {
+ while (*w)
+ w++;
+ m = 0;
+ break;
+ }
+ m = 1;
+ }
+ else if (*s == *w || SEP(*s) && SEP(*w))
+ w++;
+ else if (*w == 0)
+ break;
+ else if (!SEP(*s))
+ {
+ if (SEP(*w))
+ {
+ if (*++w == *s)
+ {
+ w++;
+ continue;
+ }
+ }
+ else if (w == y || SEP(*(w - 1)) || isupper(*(w - 1)) && islower(*w))
+ break;
+ for (q = s; *q && !SEP(*q) && *q != '|' && *q != '?' && *q != ']'; q++);
+ if (!SEP(*q))
+ break;
+ for (s = q; w > y && *w != *(s + 1); w--);
+ }
+ else if (*w != *(s + 1))
+ break;
+ }
+ if (!*w)
+ break;
+ }
+ if (*(s = skip(s, ':', '|', '?', 1, 0, 0, version)) != '|')
+ break;
+ w = y;
+ }
+ if (p)
+ s = p;
+ if (!*w)
+ {
+ if (n)
+ num = 0;
+ if (!(n = (m || *s == ':' || *s == '|' || *s == '?' || *s == ']' || *s == 0)) && x)
+ {
+ psp = pop(psp);
+ return opterror("?", 0, version, id, catalog);
+ }
+ for (x = k; *(f + 1) == '|' && (j = *(f + 2)) && j != '!' && j != '=' && j != ':' && j != '?' && j != ']'; f += 2);
+ if (*f == ':')
+ {
+ x = -1;
+ opt_info.option[1] = '-';
+ opt_info.option[2] = 0;
+ }
+ else if (*(f + 1) == ':' || *(f + 1) == '!' && *(f + 2) == ':')
+ {
+ opt_info.option[1] = x;
+ opt_info.option[2] = 0;
+ }
+ else
+ {
+ a = f;
+ if (*a == '=')
+ a++;
+ else
+ {
+ if (*(a + 1) == '!')
+ a++;
+ if (*(a + 1) == '=')
+ a += 2;
+ }
+ x = -strtol(a, &b, 0);
+ if ((b - a) > sizeof(opt_info.option) - 2)
+ b = a + sizeof(opt_info.option) - 2;
+ memcpy(&opt_info.option[1], a, b - a);
+ opt_info.option[b - a + 1] = 0;
+ }
+ b = e;
+ if (t)
+ {
+ s = t;
+ t = 0;
+ }
+ a = s = skip(s, 0, 0, 0, 1, 0, 0, version);
+ if (n)
+ {
+ w = y;
+ break;
+ }
+ }
+ w = y;
+ }
+ else if (k == c && prefix == 1)
+ {
+ w = 0;
+ opt_info.name[1] = c;
+ opt_info.name[2] = 0;
+ opt_info.offset = 2;
+ opt_info.index--;
+ break;
+ }
+ if (t)
+ {
+ s = t;
+ if (a)
+ a = t;
+ }
+ }
+ disable:
+ s = skip(s, 0, 0, 0, 1, 0, 1, version);
+ if (*s == GO)
+ s = skip(s + 1, 0, 0, 0, 0, 1, 1, version);
+ if (cache)
+ {
+ m = OPT_cache_flag;
+ v = s;
+ if (*v == '#')
+ {
+ v++;
+ m |= OPT_cache_numeric;
+ }
+ else if (*v == ':')
+ {
+ v++;
+ m |= OPT_cache_string;
+ }
+ if (*v == '?')
+ {
+ v++;
+ m |= OPT_cache_optional;
+ }
+ else if (*v == *(v - 1))
+ v++;
+ if (*(v = next(v, version)) == '[')
+ v = skip(v + 1, 0, 0, 0, 1, 0, 1, version);
+ if (*v != GO)
+ {
+ v = f;
+ for (;;)
+ {
+ if (isdigit(*f) && isdigit(*(f + 1)))
+ while (isdigit(*(f + 1)))
+ f++;
+ else if (*(f + 1) == '=')
+ break;
+ else
+ cache->flags[map[*f]] = m;
+ j = 0;
+ while (*(f + 1) == '|')
+ {
+ f += 2;
+ if (!(j = *f) || j == '!' || j == '=' || j == ':' || j == '?' || j == ']')
+ break;
+ cache->flags[map[j]] = m;
+ }
+ if (j != '!' || (m & OPT_cache_invert))
+ break;
+ f = v;
+ m |= OPT_cache_invert;
+ }
+ }
+ }
+ else
+ {
+ m = 0;
+ if (!w)
+ {
+ if (isdigit(*f) && isdigit(*(f + 1)))
+ k = -1;
+ if (c == k)
+ m = 1;
+ while (*(f + 1) == '|')
+ {
+ f += 2;
+ if (!(j = *f))
+ {
+ m = 0;
+ break;
+ }
+ else if (j == c)
+ m = 1;
+ else if (j == '!' || j == '=' || j == ':' || j == '?' || j == ']')
+ break;
+ }
+ }
+ if (m)
+ {
+ s--;
+ if (*++f == '!')
+ {
+ f++;
+ num = 0;
+ }
+ if (*f == '=')
+ {
+ c = -strtol(++f, &b, 0);
+ if ((b - f) > sizeof(opt_info.option) - 2)
+ b = f + sizeof(opt_info.option) - 2;
+ memcpy(&opt_info.option[1], f, b - f);
+ opt_info.option[b - f + 1] = 0;
+ }
+ else
+ c = k;
+ break;
+ }
+ }
+ if (*s == '#')
+ {
+ if (!numopt && s > opts)
+ {
+ numopt = s - 1;
+ numchr = k;
+ if (*f == ':')
+ numchr = -1;
+ else if (*(f + 1) != ':' && *(f + 1) != '!' && *(f + 1) != ']')
+ {
+ a = f;
+ if (*a == '=')
+ a++;
+ else
+ {
+ if (*(a + 1) == '!')
+ a++;
+ if (*(a + 1) == '=')
+ a += 2;
+ }
+ numchr = -strtol(a, NiL, 0);
+ }
+ }
+ }
+ else if (*s != ':')
+ continue;
+ }
+ else if (*s == ']')
+ {
+ s++;
+ continue;
+ }
+ else if (*s == '#')
+ {
+ if (!numopt && s > opts)
+ numchr = *(numopt = s - 1);
+ }
+ else if (*s != ':')
+ {
+ if (cache)
+ {
+ m = OPT_cache_flag;
+ if (*(s + 1) == '#')
+ {
+ m |= OPT_cache_numeric;
+ if (*(s + 2) == '?')
+ m |= OPT_cache_optional;
+ }
+ else if (*(s + 1) == ':')
+ {
+ m |= OPT_cache_string;
+ if (*(s + 2) == '?')
+ m |= OPT_cache_optional;
+ }
+ cache->flags[map[*s]] = m;
+ }
+ s++;
+ continue;
+ }
+ message((-21, "optget: opt %s", show(s)));
+ if (*++s == '?' || *s == *(s - 1))
+ s++;
+ if (*(s = next(s, version)) == '[')
+ {
+ s = skip(s + 1, 0, 0, 0, 1, 0, 1, version);
+ if (*s == GO)
+ s = skip(s + 1, 0, 0, 0, 0, 1, 1, version);
+ }
+ message((-21, "optget: opt %s", show(s)));
+ }
+ if (w && x)
+ {
+ s = skip(b, '|', '?', 0, 1, 0, 0, version);
+ if (v && (a == 0 || *a == 0 || *(a + 1) != ':' && *(a + 1) != '#') && (*v == '0' || *v == '1') && !*(v + 1))
+ {
+ if (*v == '0')
+ num = !num;
+ v = 0;
+ }
+ if ((s - b) >= elementsof(opt_info.name))
+ s = b + elementsof(opt_info.name) - 1;
+ for (;;)
+ {
+ if (b >= s)
+ {
+ *w = 0;
+ break;
+ }
+ if (*b == '*')
+ break;
+ *w++ = *b++;
+ }
+ if (!num && v)
+ return opterror(no ? "!" : "=", 0, version, id, catalog);
+ w = &opt_info.name[prefix];
+ c = x;
+ s = a;
+ }
+ }
+ if (!*s)
+ {
+ if (w)
+ {
+ if (hp = (Help_t*)search(styles, elementsof(styles), sizeof(styles[0]), w))
+ {
+ if (!v)
+ v = (char*)hp->name;
+ goto help;
+ }
+ if (!v)
+ {
+ v = opt_info.name;
+ goto help;
+ }
+ }
+ if (w || !isdigit(c) || !numopt || !(pass->flags & OPT_numeric))
+ {
+ pop(psp);
+ return opterror("", 0, version, id, catalog);
+ }
+ s = numopt;
+ c = opt_info.option[1] = numchr;
+ opt_info.offset--;
+ }
+ opt_info.arg = 0;
+
+ /*
+ * this is a ksh getopts workaround
+ */
+
+ if (opt_info.num != LONG_MIN)
+ opt_info.num = (long)(opt_info.number = num);
+ if ((n = *++s == '#') || *s == ':' || w && !nov && v && (optnumber(v, &e, NiL), n = !*e))
+ {
+ if (w)
+ {
+ if (nov)
+ {
+ if (v)
+ {
+ pop(psp);
+ return opterror("!", 0, version, id, catalog);
+ }
+ opt_info.num = (long)(opt_info.number = 0);
+ }
+ else
+ {
+ if (!v && *(s + 1) != '?' && (v = argv[opt_info.index]))
+ {
+ opt_info.index++;
+ opt_info.offset = 0;
+ }
+ if (!(opt_info.arg = v) || (*v == '0' || *v == '1') && !*(v + 1))
+ {
+ if (*(s + 1) != '?')
+ {
+ if (!opt_info.arg)
+ {
+ pop(psp);
+ return opterror(s, 0, version, id, catalog);
+ }
+ }
+ else if (*(t = next(s + 2, version)) == '[')
+ while (*(t = skip(t, ':', 0, 0, 1, 0, 0, version)) == ':')
+ if (*++t == '!')
+ {
+ if (!v || *v == '1')
+ {
+ e = skip(t, ':', '?', ']', 1, 0, 0, version);
+ opt_info.arg = sfprints("%-.*s", e - t - 1, t + 1);
+ }
+ else
+ {
+ opt_info.arg = 0;
+ opt_info.num = (long)(opt_info.number = 0);
+ }
+ break;
+ }
+ }
+ if (opt_info.arg && n)
+ {
+ opt_info.num = (long)(opt_info.number = optnumber(opt_info.arg, &e, &err));
+ if (err || e == opt_info.arg)
+ {
+ pop(psp);
+ return opterror(s, err, version, id, catalog);
+ }
+ }
+ }
+ goto optarg;
+ }
+ else if (*(opt_info.arg = &argv[opt_info.index++][opt_info.offset]))
+ {
+ if (*s == '#')
+ {
+ opt_info.num = (long)(opt_info.number = optnumber(opt_info.arg, &e, &err));
+ if (err || e == opt_info.arg)
+ {
+ if (!err && *(s + 1) == '?')
+ {
+ opt_info.arg = 0;
+ opt_info.index--;
+ }
+ else
+ {
+ opt_info.offset = 0;
+ c = opterror(s, err, version, id, catalog);
+ }
+ pop(psp);
+ return c;
+ }
+ else if (*e)
+ {
+ opt_info.offset += e - opt_info.arg;
+ opt_info.index--;
+ pop(psp);
+ return c;
+ }
+ }
+ }
+ else if (opt_info.arg = argv[opt_info.index])
+ {
+ opt_info.index++;
+ if (*(s + 1) == '?' && (*opt_info.arg == '-' || (pass->flags & OPT_plus) && *opt_info.arg == '+') && *(opt_info.arg + 1))
+ {
+ opt_info.index--;
+ opt_info.arg = 0;
+ }
+ else if (*s == '#')
+ {
+ opt_info.num = (long)(opt_info.number = optnumber(opt_info.arg, &e, &err));
+ if (err || *e)
+ {
+ if (!err && *(s + 1) == '?')
+ {
+ opt_info.arg = 0;
+ opt_info.index--;
+ }
+ else
+ {
+ pop(psp);
+ opt_info.offset = 0;
+ return opterror(s, err, version, id, catalog);
+ }
+ }
+ }
+ }
+ else if (*(s + 1) != '?')
+ {
+ opt_info.index--;
+ pop(psp);
+ return opterror(s, 0, version, id, catalog);
+ }
+ opt_info.offset = 0;
+ optarg:
+ if (*s == ':' && *(s = skip(s, 0, 0, 0, 1, 0, 1, version)) == GO && *(s = next(s + 1, version)) == '[' && isalnum(*(s + 1)))
+ {
+ x = 0;
+ if (opt_info.arg)
+ {
+ do
+ {
+ w = y = opt_info.arg;
+ f = s = next(s + 1, version);
+ k = *f;
+ if (k == *w && isalpha(k) && !*(w + 1))
+ {
+ x = k;
+ break;
+ }
+ if (*s == '+' || *s == '-')
+ continue;
+ else if (*s == '[' || version < 1)
+ continue;
+ else
+ {
+ if (*s != ':')
+ s = skip(s, ':', '?', 0, 1, 0, 0, version);
+ if (*s == ':')
+ {
+ if (catalog)
+ {
+ p = skip(s + 1, '?', 0, 0, 1, 0, 0, version);
+ e = sfprints("%-.*s", p - (s + 1), s + 1);
+ b = T(id, catalog, e);
+ if (b == e)
+ p = 0;
+ else
+ {
+ sfprintf(xp, ":%s|%s?", b, e);
+ if (!(s = sfstruse(xp)))
+ goto nospace;
+ }
+ }
+ else
+ p = 0;
+ for (;;)
+ {
+ n = m = 0;
+ e = s + 1;
+ while (*++s)
+ {
+ if (*s == '*' || *s == '\a')
+ {
+ if (*s == '\a')
+ do
+ {
+ if (!*++s)
+ {
+ s--;
+ break;
+ }
+ } while (*s != '\a');
+ j = *(s + 1);
+ if (j == ':' || j == '|' || j == '?' || j == ']' || j == 0)
+ {
+ while (*w)
+ w++;
+ m = 0;
+ break;
+ }
+ m = 1;
+ }
+ else if (*s == *w || SEP(*s) && SEP(*w))
+ w++;
+ else if (*w == 0)
+ break;
+ else if (!SEP(*s))
+ {
+ if (SEP(*w))
+ {
+ if (*++w == *s)
+ {
+ w++;
+ continue;
+ }
+ }
+ else if (w == y || SEP(*(w - 1)) || isupper(*(w - 1)) && islower(*w))
+ break;
+ for (q = s; *q && !SEP(*q) && *q != '|' && *q != '?' && *q != ']'; q++);
+ if (!SEP(*q))
+ break;
+ for (s = q; w > y && *w != *(s + 1); w--);
+ }
+ else if (*w != *(s + 1))
+ break;
+ }
+ if (!*w)
+ {
+ nov = 0;
+ break;
+ }
+ if (*(s = skip(s, ':', '|', '?', 1, 0, 0, version)) != '|')
+ break;
+ w = y;
+ }
+ if (p)
+ s = p;
+ if (!*w)
+ {
+ if (n)
+ num = 0;
+ if (!(n = (m || *s == ':' || *s == '|' || *s == '?' || *s == ']')) && x)
+ {
+ pop(psp);
+ return opterror("&", 0, version, id, catalog);
+ }
+ for (x = k; *(f + 1) == '|' && (j = *(f + 2)) && j != '!' && j != '=' && j != ':' && j != '?' && j != ']'; f += 2);
+ if (*f == ':')
+ x = -1;
+ else if (*(f + 1) == ':' || *(f + 1) == '!' && *(f + 2) == ':')
+ /* ok */;
+ else
+ {
+ a = f;
+ if (*a == '=')
+ a++;
+ else
+ {
+ if (*(a + 1) == '!')
+ a++;
+ if (*(a + 1) == '=')
+ a += 2;
+ }
+ x = -strtol(a, &b, 0);
+ }
+ b = e;
+ a = s = skip(s, 0, 0, 0, 1, 0, 0, version);
+ if (n)
+ break;
+ }
+ }
+ }
+ } while (*(s = skip(s, 0, 0, 0, 1, 0, 1, version)) == '[');
+ if (!(opt_info.num = (long)(opt_info.number = x)))
+ {
+ pop(psp);
+ return opterror("*", 0, version, id, catalog);
+ }
+ }
+ }
+ }
+ else if (w && v)
+ {
+ pop(psp);
+ return opterror("=", 0, version, id, catalog);
+ }
+ else
+ {
+ opt_info.num = (long)(opt_info.number = num);
+ if (!w && !argv[opt_info.index][opt_info.offset])
+ {
+ opt_info.offset = 0;
+ opt_info.index++;
+ }
+ }
+ pop(psp);
+ return c;
+ help:
+ if (v && *v == '?' && *(v + 1) == '?' && *(v + 2))
+ {
+ s = v + 2;
+ if ((s[0] == 'n' || s[0] == 'N') && (s[1] == 'o' || s[1] == 'O'))
+ {
+ s += 2;
+ n = -1;
+ }
+ else
+ n = 1;
+ if (hp = (Help_t*)search(styles, elementsof(styles), sizeof(styles[0]), s))
+ {
+ if (hp->style < STYLE_man || !(s = argv[opt_info.index]) || s[0] != '-' || s[1] != '-' || !s[2])
+ {
+ opt_info.arg = sfprints("\fversion=%d", version);
+ pop(psp);
+ return '?';
+ }
+ state.force = hp->style;
+ }
+ else if (match(s, "CONFORMANCE", -1, ID, NiL))
+ {
+ opt_info.arg = sfprints("\f%s", conformance(w, 0));
+ pop(psp);
+ return '?';
+ }
+ else if (match(s, "ESC", -1, ID, NiL) || match(s, "EMPHASIS", -1, ID, NiL))
+ state.emphasis = n;
+ else if (match(s, "MAN", -1, ID, NiL))
+ {
+ opt_info.arg = sfprints("\f%s", secname(*w != '?' ? w : pass->section));
+ pop(psp);
+ return '?';
+ }
+ else if (match(s, "PREFORMAT", -1, ID, NiL))
+ state.flags |= OPT_preformat;
+ else if (match(s, "SECTION", -1, ID, NiL))
+ {
+ opt_info.arg = sfprints("\f%s", pass->section);
+ pop(psp);
+ return '?';
+ }
+ else if (match(s, "TEST", -1, ID, NiL))
+ {
+ state.width = OPT_WIDTH;
+ state.emphasis = 1;
+ }
+ else
+ {
+ pop(psp);
+ return opterror(v, 0, version, id, catalog);
+ }
+ psp = pop(psp);
+ if (argv == state.strv)
+ return '#';
+ goto again;
+ }
+ if ((opt_info.arg = opthelp(NiL, v)) == (char*)unknown)
+ {
+ pop(psp);
+ return opterror(v, 0, version, id, catalog);
+ }
+ pop(psp);
+ return '?';
+ nospace:
+ pop(psp);
+ return opterror(NiL, 0, 0, NiL, NiL);
+}
+
+/*
+ * parse long options with 0,1,2 leading '-' or '+' from string and pass to optget()
+ * syntax is the unquoted
+ *
+ * <length> [-|+|--|++]<name>[[-+:|&=]=<value>\n (or \0 for the last)
+ *
+ * or the quoted
+ *
+ * [-|+|--|++][no]name[[-+:|&=]=['"{(]value[)}"']][, ]...
+ *
+ * with \x escapes passed to chresc()
+ *
+ * return '#' for `label:', with opt_info.name==label
+ * str[opt_info.offset] next arg
+ *
+ * optstr(s, 0)
+ * return '-' if arg, 0 otherwise
+ * optstr(0, opts)
+ * use previous parsed str
+ */
+
+int
+optstr(const char* str, const char* opts)
+{
+ register char* s = (char*)str;
+ register Sfio_t* mp;
+ register int c;
+ register int ql;
+ register int qr;
+ register int qc;
+ int v;
+ char* e;
+
+ again:
+ if (s)
+ {
+ if (!(mp = state.strp) && !(mp = state.strp = sfstropen()))
+ return 0;
+ if (state.str != s)
+ state.str = s;
+ else if (opt_info.index == 1)
+ s += opt_info.offset;
+ while (*s == ',' || *s == ' ' || *s == '\t' || *s == '\n' || *s == '\r')
+ s++;
+ if (!*s)
+ {
+ state.str = 0;
+ return 0;
+ }
+ if (*s == '-' || *s == '+')
+ {
+ c = *s++;
+ sfputc(mp, c);
+ if (*s == c)
+ {
+ sfputc(mp, c);
+ s++;
+ }
+ }
+ else
+ {
+ sfputc(mp, '-');
+ sfputc(mp, '-');
+ }
+ if (isdigit(*s) && (v = (int)strtol(s, &e, 10)) > 1 && isspace(*e) && --v <= strlen(s) && (s[v] == 0 || s[v] == '\n'))
+ {
+ s += v;
+ while (isspace(*++e));
+ sfwrite(mp, e, s - e);
+ }
+ else
+ {
+ while (*s && *s != ',' && *s != ' ' && *s != '\t' && *s != '\n' && *s != '\r' && *s != '=' && *s != ':')
+ sfputc(mp, *s++);
+ if ((c = *s) == ':' && *(s + 1) != '=')
+ {
+ opt_info.index = 1;
+ opt_info.offset = ++s - (char*)str;
+ if (!(s = sfstruse(mp)))
+ goto nospace;
+ s += 2;
+ e = opt_info.name;
+ while (e < &opt_info.name[sizeof(opt_info.name)-1] && (*e++ = *s++));
+ opt_info.arg = 0;
+ opt_info.num = (long)(opt_info.number = 0);
+ opt_info.option[0] = ':';
+ opt_info.option[1] = 0;
+ return '#';
+ }
+ if (c == ':' || c == '=')
+ {
+ sfputc(mp, c);
+ ql = qr = 0;
+ while (c = *++s)
+ {
+ if (c == '\\')
+ {
+ sfputc(mp, chresc(s, &e));
+ s = e - 1;
+ }
+ else if (c == qr)
+ {
+ if (qr != ql)
+ sfputc(mp, c);
+ if (--qc <= 0)
+ qr = ql = 0;
+ }
+ else if (c == ql)
+ {
+ sfputc(mp, c);
+ qc++;
+ }
+ else if (qr)
+ sfputc(mp, c);
+ else if (c == ',' || c == ' ' || c == '\t' || c == '\n' || c == '\r')
+ break;
+ else if (c == '"' || c == '\'')
+ {
+ ql = qr = c;
+ qc = 1;
+ }
+ else
+ {
+ sfputc(mp, c);
+ if (c == GO)
+ {
+ ql = c;
+ qr = OG;
+ qc = 1;
+ }
+ else if (c == '(')
+ {
+ ql = c;
+ qr = ')';
+ qc = 1;
+ }
+ }
+ }
+ }
+ }
+ opt_info.argv = state.strv;
+ state.strv[0] = T(NiL, ID, "option");
+ if (!(state.strv[1] = sfstruse(mp)))
+ goto nospace;
+ state.strv[2] = 0;
+ opt_info.offset = s - (char*)str;
+ }
+ if (opts)
+ {
+ if (!state.strv[1])
+ {
+ state.str = 0;
+ return 0;
+ }
+ opt_info.index = 1;
+ v = opt_info.offset;
+ opt_info.offset = 0;
+ c = optget(state.strv, opts);
+ opt_info.index = 1;
+ opt_info.offset = v;
+ if (c == '#')
+ {
+ s = state.str;
+ goto again;
+ }
+ if ((c == '?' || c == ':') && (opt_info.arg[0] == '-' && opt_info.arg[1] == '-'))
+ opt_info.arg += 2;
+ s = opt_info.name;
+ if (*s++ == '-' && *s++ == '-' && *s)
+ {
+ e = opt_info.name;
+ while (*e++ = *s++);
+ }
+ }
+ else
+ c = '-';
+ return c;
+ nospace:
+ return opterror(NiL, 0, 0, NiL, NiL);
+}
diff --git a/src/lib/libast/misc/optjoin.c b/src/lib/libast/misc/optjoin.c
new file mode 100644
index 0000000..1648dec
--- /dev/null
+++ b/src/lib/libast/misc/optjoin.c
@@ -0,0 +1,129 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * multi-pass commmand line option parse assist
+ *
+ * int fun(char** argv, int last)
+ *
+ * each fun() argument parses as much of argv as
+ * possible starting at (opt_info.index,opt_info.offset) using
+ * optget()
+ *
+ * if last!=0 then fun is the last pass to view
+ * the current arg, otherwise fun sets opt_info.again=1
+ * and another pass will get a crack at it
+ *
+ * 0 fun() return causes immediate optjoin() 0 return
+ *
+ * optjoin() returns non-zero if more args remain
+ * to be parsed at opt_info.index
+ */
+
+#include <optlib.h>
+
+typedef int (*Optpass_f)(char**, int);
+
+int
+optjoin(char** argv, ...)
+{
+ va_list ap;
+ register Optpass_f fun;
+ register Optpass_f rep;
+ Optpass_f err;
+ Optstate_t* state;
+ int r;
+ int more;
+ int user;
+ int last_index;
+ int last_offset;
+ int err_index;
+ int err_offset;
+
+ state = optstate(&opt_info);
+ err = rep = 0;
+ r = -1;
+ while (r < 0)
+ {
+ va_start(ap, argv);
+ state->join = 0;
+ while (fun = va_arg(ap, Optpass_f))
+ {
+ last_index = opt_info.index;
+ last_offset = opt_info.offset;
+ state->join++;
+ user = (*fun)(argv, 0);
+ more = argv[opt_info.index] != 0;
+ if (!opt_info.again)
+ {
+ if (!more)
+ {
+ state->join = 0;
+ r = 0;
+ break;
+ }
+ if (!user)
+ {
+ if (*argv[opt_info.index] != '+')
+ {
+ state->join = 0;
+ r = 1;
+ break;
+ }
+ opt_info.again = -1;
+ }
+ else
+ err = 0;
+ }
+ if (opt_info.again)
+ {
+ if (opt_info.again > 0 && (!err || err_index < opt_info.index || err_index == opt_info.index && err_offset < opt_info.offset))
+ {
+ err = fun;
+ err_index = opt_info.index;
+ err_offset = opt_info.offset;
+ }
+ opt_info.again = 0;
+ opt_info.index = state->pindex ? state->pindex : 1;
+ opt_info.offset = state->poffset;
+ }
+ if (!rep || opt_info.index != last_index || opt_info.offset != last_offset)
+ rep = fun;
+ else if (fun == rep)
+ {
+ if (!err)
+ {
+ state->join = 0;
+ r = 1;
+ break;
+ }
+ (*err)(argv, 1);
+ opt_info.offset = 0;
+ }
+ }
+ va_end(ap);
+ }
+ return r;
+}
diff --git a/src/lib/libast/misc/optlib.h b/src/lib/libast/misc/optlib.h
new file mode 100644
index 0000000..5cafed9
--- /dev/null
+++ b/src/lib/libast/misc/optlib.h
@@ -0,0 +1,115 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * command line option parser and usage formatter private definitions
+ */
+
+#ifndef _OPTLIB_H
+#define _OPTLIB_H
+
+#include <ast.h>
+#include <cdt.h>
+
+#define OPT_append 0x001
+#define OPT_cache 0x002
+#define OPT_functions 0x004
+#define OPT_ignore 0x008
+#define OPT_long 0x010
+#define OPT_minus 0x020
+#define OPT_module 0x040
+#define OPT_numeric 0x080
+#define OPT_old 0x100
+#define OPT_plus 0x200
+
+#define OPT_cache_flag 0x001
+#define OPT_cache_invert 0x002
+#define OPT_cache_numeric 0x004
+#define OPT_cache_optional 0x008
+#define OPT_cache_string 0x010
+
+#define OPT_CACHE 128
+#define OPT_FLAGS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+
+struct Optdisc_s;
+
+typedef struct Optpass_s
+{
+ char* opts;
+ char* oopts;
+ char* id;
+ char* catalog;
+ char* release;
+ char section[4];
+ unsigned char version;
+ unsigned char prefix;
+ unsigned short flags;
+} Optpass_t;
+
+typedef struct Optcache_s
+{
+ struct Optcache_s* next;
+ Optpass_t pass;
+ int caching;
+ unsigned char flags[sizeof(OPT_FLAGS)];
+} Optcache_t;
+
+typedef struct Optstate_s
+{
+ Sfio_t* mp; /* opt_info.msg string stream */
+ Sfio_t* vp; /* translation string stream */
+ Sfio_t* xp; /* translation string stream */
+ Sfio_t* cp; /* compatibility string stream */
+ Optpass_t pass[8]; /* optjoin() list */
+ char* argv[2]; /* initial argv copy */
+ char* strv[3]; /* optstr() argv */
+ char* str; /* optstr() string */
+ Sfio_t* strp; /* optstr() stream */
+ int force; /* force this style */
+ int pindex; /* prev index for backup */
+ int poffset; /* prev offset for backup */
+ int npass; /* # optjoin() passes */
+ int join; /* optjoin() pass # */
+ int plus; /* + ok */
+ int style; /* default opthelp() style */
+ int width; /* format line width */
+ int flags; /* display flags */
+ int emphasis; /* ansi term emphasis ok */
+ int localized; /* locale initialized */
+ Dtdisc_t msgdisc; /* msgdict discipline */
+ Dt_t* msgdict; /* default ast.id catalog msgs */
+ Optcache_t* cache; /* OPT_cache cache */
+ char** conformance; /* conformance id vector */
+} Optstate_t;
+
+#define _OPT_PRIVATE_ \
+ char pad[2*sizeof(void*)]; \
+ Optstate_t* state;
+
+#include <error.h>
+
+extern Optstate_t* optstate(Opt_t*);
+
+#endif
diff --git a/src/lib/libast/misc/procclose.c b/src/lib/libast/misc/procclose.c
new file mode 100644
index 0000000..a492454
--- /dev/null
+++ b/src/lib/libast/misc/procclose.c
@@ -0,0 +1,98 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * close a proc opened by procopen()
+ * otherwise exit() status of process is returned
+ */
+
+#include "proclib.h"
+
+int
+procclose(register Proc_t* p)
+{
+ int pid;
+ int flags = 0;
+ int status = -1;
+
+ if (p)
+ {
+ if (p->rfd >= 0)
+ close(p->rfd);
+ if (p->wfd >= 0 && p->wfd != p->rfd)
+ close(p->wfd);
+ if (p->flags & PROC_ORPHAN)
+ status = 0;
+ else
+ {
+ if (p->flags & PROC_ZOMBIE)
+ {
+ /*
+ * process may leave a zombie behind
+ * give it a chance to do that but
+ * don't hang waiting for it
+ */
+
+ flags |= WNOHANG;
+ sleep(1);
+ }
+ if (!(p->flags & PROC_FOREGROUND))
+ sigcritical(SIG_REG_EXEC|SIG_REG_PROC);
+ while ((pid = waitpid(p->pid, &status, flags)) == -1 && errno == EINTR);
+ if (pid != p->pid && (flags & WNOHANG))
+ status = 0;
+ if (!(p->flags & PROC_FOREGROUND))
+ sigcritical(0);
+ else
+ {
+ if (p->sigint != SIG_IGN)
+ signal(SIGINT, p->sigint);
+ if (p->sigquit != SIG_IGN)
+ signal(SIGQUIT, p->sigquit);
+#if defined(SIGCHLD)
+#if _lib_sigprocmask
+ sigprocmask(SIG_SETMASK, &p->mask, NiL);
+#else
+#if _lib_sigsetmask
+ sigsetmask(p->mask);
+#else
+ if (p->sigchld != SIG_DFL)
+ signal(SIGCHLD, p->sigchld);
+#endif
+#endif
+#endif
+ }
+ status = status == -1 ?
+ EXIT_QUIT :
+ WIFSIGNALED(status) ?
+ EXIT_TERM(WTERMSIG(status)) :
+ EXIT_CODE(WEXITSTATUS(status));
+ }
+ procfree(p);
+ }
+ else
+ status = errno == ENOENT ? EXIT_NOTFOUND : EXIT_NOEXEC;
+ return status;
+}
diff --git a/src/lib/libast/misc/procfree.c b/src/lib/libast/misc/procfree.c
new file mode 100644
index 0000000..d14ff35
--- /dev/null
+++ b/src/lib/libast/misc/procfree.c
@@ -0,0 +1,43 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * free a proc opened by procopen()
+ * skipping wait() and close()
+ */
+
+#include "proclib.h"
+
+int
+procfree(register Proc_t* p)
+{
+ if (!p)
+ return -1;
+ if (p == &proc_default)
+ p->pid = -1;
+ else
+ free(p);
+ return 0;
+}
diff --git a/src/lib/libast/misc/proclib.h b/src/lib/libast/misc/proclib.h
new file mode 100644
index 0000000..45fc242
--- /dev/null
+++ b/src/lib/libast/misc/proclib.h
@@ -0,0 +1,64 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * process library definitions
+ */
+
+#ifndef _PROCLIB_H
+#define _PROCLIB_H
+
+#include <ast.h>
+#include <errno.h>
+#include <sig.h>
+#include <wait.h>
+
+#if _lib_sigprocmask
+typedef sigset_t Sig_mask_t;
+#else
+typedef unsigned long Sig_mask_t;
+#endif
+
+struct Mods_s;
+
+#define _PROC_PRIVATE_ \
+ struct Mod_s* mods; /* process modification state */ \
+ long flags; /* original PROC_* flags */ \
+ Sig_mask_t mask; /* original blocked sig mask */ \
+ Sig_handler_t sigchld; /* PROC_FOREGROUND SIG_DFL */ \
+ Sig_handler_t sigint; /* PROC_FOREGROUND SIG_IGN */ \
+ Sig_handler_t sigquit; /* PROC_FOREGROUND SIG_IGN */
+
+#include <proc.h>
+
+#define proc_default _proc_info_ /* hide external symbol */
+
+extern Proc_t proc_default; /* first proc */
+
+#ifndef errno
+extern int errno;
+#endif
+
+#endif
diff --git a/src/lib/libast/misc/procopen.c b/src/lib/libast/misc/procopen.c
new file mode 100644
index 0000000..aa8240a
--- /dev/null
+++ b/src/lib/libast/misc/procopen.c
@@ -0,0 +1,941 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * common process execution support with
+ * proper sfio, signal and wait() syncronization
+ *
+ * _ contains the process path name and is
+ * placed at the top of the environment
+ */
+
+#include "proclib.h"
+
+#include <ls.h>
+#include <ast_tty.h>
+
+/*
+ * not quite ready for _use_spawnveg
+ */
+
+#if _use_spawnveg
+#if _lib_fork
+#undef _use_spawnveg
+#else
+#if _WINIX
+#define _lib_fork 1
+#endif
+#endif
+#endif
+
+#ifndef DEBUG_PROC
+#define DEBUG_PROC 1
+#endif
+
+#if _lib_socketpair
+#if _sys_socket
+#include <sys/types.h>
+#include <sys/socket.h>
+#else
+#undef _lib_socketpair
+#endif
+#endif
+
+Proc_t proc_default = { -1 };
+
+#if DEBUG_PROC
+
+#include <namval.h>
+
+#define PROC_ENV_OPTIONS "PROC_OPTIONS"
+
+#define PROC_OPT_ENVIRONMENT (1<<0)
+#define PROC_OPT_EXEC (1<<1)
+#define PROC_OPT_TRACE (1<<2)
+#define PROC_OPT_VERBOSE (1<<3)
+
+static const Namval_t options[] =
+{
+ "debug", PROC_OPT_VERBOSE,
+ "environment", PROC_OPT_ENVIRONMENT,
+ "exec", PROC_OPT_EXEC,
+ "trace", PROC_OPT_TRACE,
+ "verbose", PROC_OPT_VERBOSE,
+ 0, 0
+};
+
+/*
+ * called by stropt() to set options
+ */
+
+static int
+setopt(register void* a, register const void* p, register int n, const char* v)
+{
+ NoP(v);
+ if (p)
+ {
+ if (n)
+ *((int*)a) |= ((Namval_t*)p)->value;
+ else
+ *((int*)a) &= ~((Namval_t*)p)->value;
+ }
+ return 0;
+}
+
+#endif
+
+#if _use_spawnveg
+
+typedef struct Fd_s
+{
+ short fd;
+ short flag;
+} Fd_t;
+
+typedef struct Mod_s
+{
+ struct Mod_s* next;
+ short op;
+ short save;
+
+ union
+ {
+
+ struct
+ {
+ Fd_t parent;
+ Fd_t child;
+ } fd;
+
+ Handler_t handler;
+
+ } arg;
+
+} Modify_t;
+
+#endif
+
+#ifdef SIGPIPE
+
+/*
+ * catch but ignore sig
+ * avoids SIG_IGN being passed to children
+ */
+
+static void
+ignoresig(int sig)
+{
+ signal(sig, ignoresig);
+}
+
+#endif
+
+/*
+ * do modification op and save previous state for restore()
+ */
+
+static int
+modify(Proc_t* proc, int forked, int op, long arg1, long arg2)
+{
+#if _lib_fork
+ if (forked)
+ {
+ int i;
+ int k;
+#ifndef TIOCSCTTY
+ char* s;
+#endif
+
+ switch (op)
+ {
+ case PROC_fd_dup:
+ case PROC_fd_dup|PROC_FD_PARENT:
+ case PROC_fd_dup|PROC_FD_CHILD:
+ case PROC_fd_dup|PROC_FD_PARENT|PROC_FD_CHILD:
+ if (arg1 != arg2)
+ {
+ if (arg2 != PROC_ARG_NULL)
+ {
+ close(arg2);
+ if (fcntl(arg1, F_DUPFD, arg2) != arg2)
+ return -1;
+ }
+ if (op & PROC_FD_CHILD)
+ close(arg1);
+ }
+ break;
+ case PROC_fd_ctty:
+ setsid();
+ for (i = 0; i <= 2; i++)
+ if (arg1 != i)
+ close(i);
+ arg2 = -1;
+#ifdef TIOCSCTTY
+ if (ioctl(arg1, TIOCSCTTY, NiL) < 0)
+ return -1;
+#else
+ if (!(s = ttyname(arg1)))
+ return -1;
+ if ((arg2 = open(s, O_RDWR)) < 0)
+ return -1;
+#endif
+ for (i = 0; i <= 2; i++)
+ if (arg1 != i && arg2 != i && (k = fcntl(arg1, F_DUPFD, i)) != i)
+ return -1;
+ if (arg1 > 2)
+ close(arg1);
+ if (arg2 > 2)
+ close(arg2);
+ break;
+ case PROC_sig_dfl:
+ signal(arg1, SIG_DFL);
+ break;
+ case PROC_sig_ign:
+ signal(arg1, SIG_IGN);
+ break;
+ case PROC_sys_pgrp:
+ if (arg1 < 0)
+ setsid();
+ else if (arg1 > 0)
+ {
+ if (arg1 == 1)
+ arg1 = 0;
+ if (setpgid(0, arg1) < 0 && arg1 && errno == EPERM)
+ setpgid(0, 0);
+ }
+ break;
+ case PROC_sys_umask:
+ umask(arg1);
+ break;
+ default:
+ return -1;
+ }
+ }
+#if _use_spawnveg
+ else
+#endif
+#else
+ NoP(forked);
+#endif
+#if _use_spawnveg
+ {
+ register Modify_t* m;
+
+ if (!(m = newof(NiL, Modify_t, 1, 0)))
+ return -1;
+ m->next = proc->mods;
+ proc->mods = m;
+ switch (m->op = op)
+ {
+ case PROC_fd_dup:
+ case PROC_fd_dup|PROC_FD_PARENT:
+ case PROC_fd_dup|PROC_FD_CHILD:
+ case PROC_fd_dup|PROC_FD_PARENT|PROC_FD_CHILD:
+ m->arg.fd.parent.fd = (short)arg1;
+ m->arg.fd.parent.flag = fcntl(arg1, F_GETFD, 0);
+ if ((m->arg.fd.child.fd = (short)arg2) != arg1)
+ {
+ if (arg2 != PROC_ARG_NULL)
+ {
+ m->arg.fd.child.flag = fcntl(arg2, F_GETFD, 0);
+ if ((m->save = fcntl(arg2, F_DUPFD, 3)) < 0)
+ {
+ m->op = 0;
+ return -1;
+ }
+ fcntl(m->save, F_SETFD, FD_CLOEXEC);
+ close(arg2);
+ if (fcntl(arg1, F_DUPFD, arg2) != arg2)
+ return -1;
+ if (op & PROC_FD_CHILD)
+ close(arg1);
+ }
+ else if (op & PROC_FD_CHILD)
+ {
+ if (m->arg.fd.parent.flag)
+ break;
+ fcntl(arg1, F_SETFD, FD_CLOEXEC);
+ }
+ else if (!m->arg.fd.parent.flag)
+ break;
+ else
+ fcntl(arg1, F_SETFD, 0);
+ return 0;
+ }
+ break;
+ case PROC_sig_dfl:
+ if ((m->arg.handler = signal(arg1, SIG_DFL)) == SIG_DFL)
+ break;
+ m->save = (short)arg1;
+ return 0;
+ case PROC_sig_ign:
+ if ((m->arg.handler = signal(arg1, SIG_IGN)) == SIG_IGN)
+ break;
+ m->save = (short)arg1;
+ return 0;
+ case PROC_sys_pgrp:
+ proc->pgrp = arg1;
+ break;
+ case PROC_sys_umask:
+ if ((m->save = (short)umask(arg1)) == arg1)
+ break;
+ return 0;
+ default:
+ proc->mods = m->next;
+ free(m);
+ return -1;
+ }
+ proc->mods = m->next;
+ free(m);
+ }
+#else
+ NoP(proc);
+#endif
+ return 0;
+}
+
+#if _use_spawnveg
+
+/*
+ * restore modifications
+ */
+
+static void
+restore(Proc_t* proc)
+{
+ register Modify_t* m;
+ register Modify_t* p;
+ int oerrno;
+
+ NoP(proc);
+ oerrno = errno;
+ m = proc->mods;
+ proc->mods = 0;
+ while (m)
+ {
+ switch (m->op)
+ {
+ case PROC_fd_dup:
+ case PROC_fd_dup|PROC_FD_PARENT:
+ case PROC_fd_dup|PROC_FD_CHILD:
+ case PROC_fd_dup|PROC_FD_PARENT|PROC_FD_CHILD:
+ if (m->op & PROC_FD_PARENT)
+ close(m->arg.fd.parent.fd);
+ if (m->arg.fd.child.fd != m->arg.fd.parent.fd && m->arg.fd.child.fd != PROC_ARG_NULL)
+ {
+ if (!(m->op & PROC_FD_PARENT))
+ {
+ if (m->op & PROC_FD_CHILD)
+ {
+ close(m->arg.fd.parent.fd);
+ fcntl(m->arg.fd.child.fd, F_DUPFD, m->arg.fd.parent.fd);
+ }
+ fcntl(m->arg.fd.parent.fd, F_SETFD, m->arg.fd.parent.flag);
+ }
+ close(m->arg.fd.child.fd);
+ fcntl(m->save, F_DUPFD, m->arg.fd.child.fd);
+ close(m->save);
+ if (m->arg.fd.child.flag)
+ fcntl(m->arg.fd.child.fd, F_SETFD, FD_CLOEXEC);
+ }
+ else if ((m->op & (PROC_FD_PARENT|PROC_FD_CHILD)) == PROC_FD_CHILD)
+ fcntl(m->arg.fd.parent.fd, F_SETFD, 0);
+ break;
+ case PROC_sig_dfl:
+ case PROC_sig_ign:
+ signal(m->save, m->arg.handler);
+ break;
+ case PROC_sys_umask:
+ umask(m->save);
+ break;
+ }
+ p = m;
+ m = m->next;
+ free(p);
+ }
+ errno = oerrno;
+}
+
+#else
+
+#define restore(p)
+
+#endif
+
+/*
+ * fork and exec or spawn proc(argv) and return a Proc_t handle
+ *
+ * pipe not used when PROC_READ|PROC_WRITE omitted
+ * argv==0 duplicates current process if possible
+ * cmd==0 names the current shell
+ * cmd=="" does error cleanup
+ * envv is the child environment
+ * modv is the child modification vector of PROC_*() ops
+ */
+
+Proc_t*
+procopen(const char* cmd, char** argv, char** envv, long* modv, int flags)
+{
+ register Proc_t* proc = 0;
+ register int procfd;
+ register char** p;
+ char** v;
+ int i;
+ int forked = 0;
+ int signalled = 0;
+ long n;
+ char path[PATH_MAX];
+ char env[PATH_MAX + 2];
+ int pio[2];
+#if _lib_fork
+ int pop[2];
+#endif
+#if !_pipe_rw && !_lib_socketpair
+ int poi[2];
+#endif
+#if defined(SIGCHLD) && ( _lib_sigprocmask || _lib_sigsetmask )
+ Sig_mask_t mask;
+#endif
+#if _use_spawnveg
+ int newenv = 0;
+#endif
+#if DEBUG_PROC
+ int debug = PROC_OPT_EXEC;
+#endif
+
+#if _lib_fork
+ if (!argv && (flags & (PROC_ORPHAN|PROC_OVERLAY)))
+#else
+ if (!argv || (flags & PROC_ORPHAN))
+#endif
+ {
+ errno = ENOEXEC;
+ return 0;
+ }
+ pio[0] = pio[1] = -1;
+#if _lib_fork
+ pop[0] = pop[1] = -1;
+#endif
+#if !_pipe_rw && !_lib_socketpair
+ poi[0] = poi[1] = -1;
+#endif
+ if (cmd && (!*cmd || !pathpath(cmd, NiL, PATH_REGULAR|PATH_EXECUTE, path, sizeof(path))))
+ goto bad;
+ switch (flags & (PROC_READ|PROC_WRITE))
+ {
+ case 0:
+ procfd = -1;
+ break;
+ case PROC_READ:
+ procfd = 1;
+ break;
+ case PROC_WRITE:
+ procfd = 0;
+ break;
+ case PROC_READ|PROC_WRITE:
+ procfd = 2;
+ break;
+ }
+ if (proc_default.pid == -1)
+ proc = &proc_default;
+ else if (!(proc = newof(0, Proc_t, 1, 0)))
+ goto bad;
+ proc->pid = -1;
+ proc->pgrp = 0;
+ proc->rfd = -1;
+ proc->wfd = -1;
+ proc->flags = flags;
+ sfsync(NiL);
+ if (environ && envv != (char**)environ && (envv || (flags & PROC_PARANOID) || argv && (environ[0][0] != '_' || environ[0][1] != '=')))
+ {
+ if (!setenviron(NiL))
+ goto bad;
+#if _use_spawnveg
+ if (!(flags & PROC_ORPHAN))
+ newenv = 1;
+#endif
+ }
+ if (procfd >= 0)
+ {
+#if _pipe_rw
+ if (pipe(pio))
+ goto bad;
+#else
+ if (procfd > 1)
+ {
+#if _lib_socketpair
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, pio))
+ goto bad;
+#else
+ if (pipe(pio) || pipe(poi))
+ goto bad;
+#endif
+ }
+ else if (pipe(pio))
+ goto bad;
+#endif
+ }
+ if (flags & PROC_OVERLAY)
+ {
+ proc->pid = 0;
+ forked = 1;
+ }
+#if _use_spawnveg
+ else if (argv && !(flags & PROC_ORPHAN))
+ proc->pid = 0;
+#endif
+#if _lib_fork
+ else
+ {
+ if (!(flags & PROC_FOREGROUND))
+ sigcritical(SIG_REG_EXEC|SIG_REG_PROC);
+ else
+ {
+ signalled = 1;
+ proc->sigint = signal(SIGINT, SIG_IGN);
+ proc->sigquit = signal(SIGQUIT, SIG_IGN);
+#if defined(SIGCHLD)
+#if _lib_sigprocmask
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &mask, &proc->mask);
+#else
+#if _lib_sigsetmask
+ mask = sigmask(SIGCHLD);
+ proc->mask = sigblock(mask);
+#else
+ proc->sigchld = signal(SIGCHLD, SIG_DFL);
+#endif
+#endif
+#endif
+ }
+ if ((flags & PROC_ORPHAN) && pipe(pop))
+ goto bad;
+ proc->pid = fork();
+ if (!(flags & PROC_FOREGROUND))
+ sigcritical(0);
+ else if (!proc->pid)
+ {
+ if (proc->sigint != SIG_IGN)
+ {
+ proc->sigint = SIG_DFL;
+ signal(SIGINT, proc->sigint);
+ }
+ if (proc->sigquit != SIG_IGN)
+ {
+ proc->sigquit = SIG_DFL;
+ signal(SIGQUIT, proc->sigquit);
+ }
+#if defined(SIGCHLD)
+#if _lib_sigprocmask
+ sigprocmask(SIG_SETMASK, &proc->mask, NiL);
+#else
+#if _lib_sigsetmask
+ sigsetmask(proc->mask);
+#else
+ if (proc->sigchld != SIG_IGN)
+ signal(SIGCHLD, SIG_DFL);
+#endif
+#endif
+#endif
+ }
+ else if (proc->pid == -1)
+ goto bad;
+ forked = 1;
+ }
+#endif
+ if (!proc->pid)
+ {
+#if _use_spawnveg
+ char** oenviron = 0;
+ char* oenviron0 = 0;
+
+ v = 0;
+#endif
+#if _lib_fork
+ if (flags & PROC_ORPHAN)
+ {
+ if (!(proc->pid = fork()))
+ {
+ close(pop[0]);
+ close(pop[1]);
+ }
+ else
+ {
+ if (proc->pid > 0)
+ write(pop[1], &proc->pid, sizeof(proc->pid));
+ _exit(EXIT_NOEXEC);
+ }
+ }
+#endif
+#if DEBUG_PROC
+ stropt(getenv(PROC_ENV_OPTIONS), options, sizeof(*options), setopt, &debug);
+#if _lib_fork
+ if (debug & PROC_OPT_TRACE)
+ {
+ if (!fork())
+ {
+ sfsprintf(path, sizeof(path), "%d", getppid());
+ execlp("trace", "trace", "-p", path, NiL);
+ _exit(EXIT_NOTFOUND);
+ }
+ sleep(2);
+ }
+#endif
+#endif
+ if (flags & PROC_DAEMON)
+ {
+#ifdef SIGHUP
+ modify(proc, forked, PROC_sig_ign, SIGHUP, 0);
+#endif
+ modify(proc, forked, PROC_sig_dfl, SIGTERM, 0);
+#ifdef SIGTSTP
+ modify(proc, forked, PROC_sig_ign, SIGTSTP, 0);
+#endif
+#ifdef SIGTTIN
+ modify(proc, forked, PROC_sig_ign, SIGTTIN, 0);
+#endif
+#ifdef SIGTTOU
+ modify(proc, forked, PROC_sig_ign, SIGTTOU, 0);
+#endif
+ }
+ if (flags & (PROC_BACKGROUND|PROC_DAEMON))
+ {
+ modify(proc, forked, PROC_sig_ign, SIGINT, 0);
+#ifdef SIGQUIT
+ modify(proc, forked, PROC_sig_ign, SIGQUIT, 0);
+#endif
+ }
+ if (flags & (PROC_DAEMON|PROC_SESSION))
+ modify(proc, forked, PROC_sys_pgrp, -1, 0);
+ if (forked || (flags & PROC_OVERLAY))
+ {
+ if ((flags & PROC_PRIVELEGED) && !geteuid())
+ {
+ setuid(geteuid());
+ setgid(getegid());
+ }
+ if (flags & (PROC_PARANOID|PROC_GID))
+ setgid(getgid());
+ if (flags & (PROC_PARANOID|PROC_UID))
+ setuid(getuid());
+ }
+ if (procfd > 1)
+ {
+ if (modify(proc, forked, PROC_fd_dup|PROC_FD_CHILD, pio[0], PROC_ARG_NULL))
+ goto cleanup;
+ if (modify(proc, forked, PROC_fd_dup|PROC_FD_CHILD, pio[1], 1))
+ goto cleanup;
+#if _pipe_rw || _lib_socketpair
+ if (modify(proc, forked, PROC_fd_dup, 1, 0))
+ goto cleanup;
+#else
+ if (modify(proc, forked, PROC_fd_dup|PROC_FD_CHILD, poi[0], 0))
+ goto cleanup;
+ if (poi[1] != 0 && modify(proc, forked, PROC_fd_dup|PROC_FD_CHILD, poi[1], PROC_ARG_NULL))
+ goto cleanup;
+#endif
+ }
+ else if (procfd >= 0)
+ {
+ if (modify(proc, forked, PROC_fd_dup|PROC_FD_CHILD, pio[!!procfd], !!procfd))
+ goto cleanup;
+ if (pio[!procfd] != !!procfd && modify(proc, forked, PROC_fd_dup|PROC_FD_CHILD, pio[!procfd], PROC_ARG_NULL))
+ goto cleanup;
+ }
+ if (modv)
+ for (i = 0; n = modv[i]; i++)
+ switch (PROC_OP(n))
+ {
+ case PROC_fd_dup:
+ case PROC_fd_dup|PROC_FD_PARENT:
+ case PROC_fd_dup|PROC_FD_CHILD:
+ case PROC_fd_dup|PROC_FD_PARENT|PROC_FD_CHILD:
+ if (modify(proc, forked, PROC_OP(n), PROC_ARG(n, 1), PROC_ARG(n, 2)))
+ goto cleanup;
+ break;
+ default:
+ if (modify(proc, forked, PROC_OP(n), PROC_ARG(n, 1), 0))
+ goto cleanup;
+ break;
+ }
+#if _lib_fork
+ if (forked && (flags & PROC_ENVCLEAR))
+ environ = 0;
+#if _use_spawnveg
+ else
+#endif
+#endif
+#if _use_spawnveg
+ if (newenv)
+ {
+ p = environ;
+ while (*p++);
+ if (!(oenviron = (char**)memdup(environ, (p - environ) * sizeof(char*))))
+ goto cleanup;
+ }
+#endif
+ if (argv && envv != (char**)environ)
+ {
+#if _use_spawnveg
+ if (!newenv && environ[0][0] == '_' && environ[0][1] == '=')
+ oenviron0 = environ[0];
+#endif
+ env[0] = '_';
+ env[1] = '=';
+ env[2] = 0;
+ if (!setenviron(env))
+ goto cleanup;
+ }
+ if ((flags & PROC_PARANOID) && setenv("PATH", astconf("PATH", NiL, NiL), 1))
+ goto cleanup;
+ if ((p = envv) && p != (char**)environ)
+ while (*p)
+ if (!setenviron(*p++))
+ goto cleanup;
+ p = argv;
+#if _lib_fork
+ if (forked && !p)
+ return proc;
+#endif
+#if DEBUG_PROC
+ if (!(debug & PROC_OPT_EXEC) || (debug & PROC_OPT_VERBOSE))
+ {
+ if ((debug & PROC_OPT_ENVIRONMENT) && (p = environ))
+ while (*p)
+ sfprintf(sfstderr, "%s\n", *p++);
+ sfprintf(sfstderr, "+ %s", cmd ? path : "sh");
+ if ((p = argv) && *p)
+ while (*++p)
+ sfprintf(sfstderr, " %s", *p);
+ sfprintf(sfstderr, "\n");
+sfsync(sfstderr);
+ if (!(debug & PROC_OPT_EXEC))
+ _exit(0);
+ p = argv;
+ }
+#endif
+ if (cmd)
+ {
+ strcpy(env + 2, path);
+ if (forked || (flags & PROC_OVERLAY))
+ execve(path, p, environ);
+#if _use_spawnveg
+ else if ((proc->pid = spawnveg(path, p, environ, proc->pgrp)) != -1)
+ goto cleanup;
+#endif
+ if (errno != ENOEXEC)
+ goto cleanup;
+
+ /*
+ * try cmd as a shell script
+ */
+
+ if (!(flags & PROC_ARGMOD))
+ {
+ while (*p++);
+ if (!(v = newof(0, char*, p - argv + 2, 0)))
+ goto cleanup;
+ p = v + 2;
+ if (*argv)
+ argv++;
+ while (*p++ = *argv++);
+ p = v + 1;
+ }
+ *p = path;
+ *--p = "sh";
+ }
+ strcpy(env + 2, (flags & PROC_PARANOID) ? astconf("SH", NiL, NiL) : pathshell());
+ if (forked || (flags & PROC_OVERLAY))
+ execve(env + 2, p, environ);
+#if _use_spawnveg
+ else
+ proc->pid = spawnveg(env + 2, p, environ, proc->pgrp);
+#endif
+ cleanup:
+ if (forked)
+ {
+ if (!(flags & PROC_OVERLAY))
+ _exit(errno == ENOENT ? EXIT_NOTFOUND : EXIT_NOEXEC);
+ goto bad;
+ }
+#if _use_spawnveg
+ if (v)
+ free(v);
+ if (p = oenviron)
+ {
+ environ = 0;
+ while (*p)
+ if (!setenviron(*p++))
+ goto bad;
+ free(oenviron);
+ }
+ else if (oenviron0)
+ environ[0] = oenviron0;
+ restore(proc);
+ if (flags & PROC_OVERLAY)
+ exit(0);
+#endif
+ }
+ if (proc->pid != -1)
+ {
+ if (!forked)
+ {
+ if (flags & PROC_FOREGROUND)
+ {
+ signalled = 1;
+ proc->sigint = signal(SIGINT, SIG_IGN);
+ proc->sigquit = signal(SIGQUIT, SIG_IGN);
+#if defined(SIGCHLD)
+#if _lib_sigprocmask
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &mask, &proc->mask);
+#else
+#if _lib_sigsetmask
+ mask = sigmask(SIGCHLD);
+ proc->mask = sigblock(mask);
+#else
+ proc->sigchld = signal(SIGCHLD, SIG_DFL);
+#endif
+#endif
+#endif
+ }
+ }
+ else if (modv)
+ for (i = 0; n = modv[i]; i++)
+ switch (PROC_OP(n))
+ {
+ case PROC_fd_dup|PROC_FD_PARENT:
+ case PROC_fd_dup|PROC_FD_PARENT|PROC_FD_CHILD:
+ close(PROC_ARG(n, 1));
+ break;
+ case PROC_sys_pgrp:
+ if (proc->pgrp < 0)
+ proc->pgrp = proc->pid;
+ else if (proc->pgrp > 0)
+ {
+ if (proc->pgrp == 1)
+ proc->pgrp = proc->pid;
+ if (setpgid(proc->pid, proc->pgrp) < 0 && proc->pid != proc->pgrp && errno == EPERM)
+ setpgid(proc->pid, proc->pid);
+ }
+ break;
+ }
+ if (procfd >= 0)
+ {
+#ifdef SIGPIPE
+ if ((flags & (PROC_WRITE|PROC_IGNORE)) == (PROC_WRITE|PROC_IGNORE))
+ {
+ Handler_t handler;
+
+ if ((handler = signal(SIGPIPE, ignoresig)) != SIG_DFL && handler != ignoresig)
+ signal(SIGPIPE, handler);
+ }
+#endif
+ switch (procfd)
+ {
+ case 0:
+ proc->wfd = pio[1];
+ close(pio[0]);
+ break;
+ default:
+#if _pipe_rw || _lib_socketpair
+ proc->wfd = pio[0];
+#else
+ proc->wfd = poi[1];
+ close(poi[0]);
+#endif
+ /*FALLTHROUGH*/
+ case 1:
+ proc->rfd = pio[0];
+ close(pio[1]);
+ break;
+ }
+ if (proc->rfd > 2)
+ fcntl(proc->rfd, F_SETFD, FD_CLOEXEC);
+ if (proc->wfd > 2)
+ fcntl(proc->wfd, F_SETFD, FD_CLOEXEC);
+ }
+ if (!proc->pid)
+ proc->pid = getpid();
+ else if (flags & PROC_ORPHAN)
+ {
+ while (waitpid(proc->pid, &i, 0) == -1 && errno == EINTR);
+ if (read(pop[0], &proc->pid, sizeof(proc->pid)) != sizeof(proc->pid))
+ goto bad;
+ close(pop[0]);
+ }
+ return proc;
+ }
+ bad:
+ if (signalled)
+ {
+ if (proc->sigint != SIG_IGN)
+ signal(SIGINT, proc->sigint);
+ if (proc->sigquit != SIG_IGN)
+ signal(SIGQUIT, proc->sigquit);
+#if defined(SIGCHLD)
+#if _lib_sigprocmask
+ sigprocmask(SIG_SETMASK, &proc->mask, NiL);
+#else
+#if _lib_sigsetmask
+ sigsetmask(proc->mask);
+#else
+ if (proc->sigchld != SIG_DFL)
+ signal(SIGCHLD, proc->sigchld);
+#endif
+#endif
+#endif
+ }
+ if ((flags & PROC_CLEANUP) && modv)
+ for (i = 0; n = modv[i]; i++)
+ switch (PROC_OP(n))
+ {
+ case PROC_fd_dup:
+ case PROC_fd_dup|PROC_FD_PARENT:
+ case PROC_fd_dup|PROC_FD_CHILD:
+ case PROC_fd_dup|PROC_FD_PARENT|PROC_FD_CHILD:
+ if (PROC_ARG(n, 2) != PROC_ARG_NULL)
+ close(PROC_ARG(n, 1));
+ break;
+ }
+ if (pio[0] >= 0)
+ close(pio[0]);
+ if (pio[1] >= 0)
+ close(pio[1]);
+ if (pop[0] >= 0)
+ close(pop[0]);
+ if (pop[1] >= 0)
+ close(pop[1]);
+#if !_pipe_rw && !_lib_socketpair
+ if (poi[0] >= 0)
+ close(poi[0]);
+ if (poi[1] >= 0)
+ close(poi[1]);
+#endif
+ procfree(proc);
+ return 0;
+}
diff --git a/src/lib/libast/misc/procrun.c b/src/lib/libast/misc/procrun.c
new file mode 100644
index 0000000..a37e067
--- /dev/null
+++ b/src/lib/libast/misc/procrun.c
@@ -0,0 +1,49 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * procopen() + procclose()
+ * no env changes
+ * no modifications
+ * effective=real
+ * parent ignores INT & QUIT
+ */
+
+#include "proclib.h"
+
+int
+procrun(const char* path, char** argv, int flags)
+{
+#if __OBSOLETE__ < 20090101
+ flags &= argv ? PROC_ARGMOD : PROC_CHECK;
+#endif
+ if (flags & PROC_CHECK)
+ {
+ char buf[PATH_MAX];
+
+ return pathpath(path, NiL, PATH_REGULAR|PATH_EXECUTE, buf, sizeof(buf)) ? 0 : -1;
+ }
+ return procclose(procopen(path, argv, NiL, NiL, flags|PROC_FOREGROUND|PROC_GID|PROC_UID));
+}
diff --git a/src/lib/libast/misc/recfmt.c b/src/lib/libast/misc/recfmt.c
new file mode 100644
index 0000000..09c3220
--- /dev/null
+++ b/src/lib/libast/misc/recfmt.c
@@ -0,0 +1,165 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * determine record format by sampling data in <buf,size>
+ * total is the total file size, <=0 if not available
+ * return r:
+ * -1 could not determine
+ * RECTYPE(r)==REC_fixed fixed length REC_F_SIZE(r)
+ * RECTYPE(r)==REC_delimited variable length delimiter=REC_D_DELIMITER(r)
+ * RECTYPE(r)==REC_variable variable length
+ */
+
+#include <recfmt.h>
+
+typedef struct
+{
+ unsigned int rep[4 * 1024];
+ unsigned int hit[UCHAR_MAX + 1];
+} Sample_t;
+
+Recfmt_t
+recfmt(const void* buf, size_t size, off_t total)
+{
+ register unsigned char* s;
+ register unsigned char* t;
+ register Sample_t* q;
+ register unsigned int* h;
+ register unsigned int i;
+ unsigned int j;
+ unsigned int k;
+ unsigned int n;
+ unsigned int m;
+ unsigned int x;
+ unsigned long f;
+ unsigned long g;
+
+ static unsigned char terminators[] = { '\n', 0x15, 0x25 };
+
+ /*
+ * check for V format
+ */
+
+ s = (unsigned char*)buf;
+ t = s + size;
+ while ((k = (t - s)) >= 4 && !s[2] && !s[3])
+ {
+ if ((i = (s[0]<<8)|s[1]) > k)
+ break;
+ s += i;
+ }
+ if (!k || size > 2 * k)
+ return REC_V_TYPE(4, 0, 2, 0, 1);
+ s = (unsigned char*)buf;
+
+ /*
+ * check for terminated records
+ */
+
+ for (i = 0; i < elementsof(terminators); i++)
+ if ((t = (unsigned char*)memchr((void*)s, k = terminators[i], size / 2)) && (n = t - s + 1) > 1 && (total <= 0 || !(total % n)))
+ {
+ for (j = n - 1; j < size; j += n)
+ if (s[j] != k)
+ {
+ n = 0;
+ break;
+ }
+ if (n)
+ return REC_D_TYPE(terminators[i]);
+ }
+
+ /*
+ * check fixed length record frequencies
+ */
+
+ if (!(q = newof(0, Sample_t, 1, 0)))
+ return REC_N_TYPE();
+ x = 0;
+ for (i = 0; i < size; i++)
+ {
+ h = q->hit + s[i];
+ m = i - *h;
+ *h = i;
+ if (m < elementsof(q->rep))
+ {
+ if (m > x)
+ x = m;
+ q->rep[m]++;
+ }
+ }
+ n = 0;
+ m = 0;
+ f = ~0;
+ for (i = x; i > 1; i--)
+ {
+ if ((total <= 0 || !(total % i)) && q->rep[i] > q->rep[n])
+ {
+ m++;
+ g = 0;
+ for (j = i; j < size - i; j += i)
+ for (k = 0; k < i; k++)
+ if (s[j + k] != s[j + k - i])
+ g++;
+ g = (((g * 100) / i) * 100) / q->rep[i];
+ if (g <= f)
+ {
+ f = g;
+ n = i;
+ }
+ }
+ }
+ if (m <= 1 && n <= 2 && total > 1 && total < 256)
+ {
+ n = 0;
+ for (i = 0; i < size; i++)
+ for (j = 0; j < elementsof(terminators); j++)
+ if (s[i] == terminators[j])
+ n++;
+ n = n ? 0 : total;
+ }
+ free(q);
+ return n ? REC_F_TYPE(n) : REC_N_TYPE();
+}
+
+#if MAIN
+
+main()
+{
+ void* s;
+ size_t size;
+ off_t total;
+
+ if (!(s = sfreserve(sfstdin, SF_UNBOUND, 0)))
+ {
+ sfprintf(sfstderr, "read error\n");
+ return 1;
+ }
+ size = sfvalue(sfstdin);
+ total = sfsize(sfstdin);
+ sfprintf(sfstdout, "%d\n", recfmt(s, size, total));
+ return 0;
+}
+
+#endif
diff --git a/src/lib/libast/misc/reclen.c b/src/lib/libast/misc/reclen.c
new file mode 100644
index 0000000..ec927f8
--- /dev/null
+++ b/src/lib/libast/misc/reclen.c
@@ -0,0 +1,71 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * return the length of the current record at b, size n, according to f
+ * -1 returned on error
+ * 0 returned if more data is required
+ */
+
+#include <recfmt.h>
+#include <ctype.h>
+
+ssize_t
+reclen(Recfmt_t f, const void* b, size_t n)
+{
+ register unsigned char* s = (unsigned char*)b;
+ register unsigned char* e;
+ size_t h;
+ size_t z;
+
+ switch (RECTYPE(f))
+ {
+ case REC_delimited:
+ if (e = (unsigned char*)memchr(s, REC_D_DELIMITER(f), n))
+ return e - s + 1;
+ return 0;
+ case REC_fixed:
+ return REC_F_SIZE(f);
+ case REC_variable:
+ h = REC_V_HEADER(f);
+ if (n < h)
+ return 0;
+ z = 0;
+ s += REC_V_OFFSET(f);
+ e = s + REC_V_LENGTH(f);
+ if (REC_V_LITTLE(f))
+ while (e > s)
+ z = (z<<8)|*--e;
+ else
+ while (s < e)
+ z = (z<<8)|*s++;
+ if (!REC_V_INCLUSIVE(f))
+ z += h;
+ else if (z < h)
+ z = h;
+ return z;
+ case REC_method:
+ return -1;
+ }
+ return -1;
+}
diff --git a/src/lib/libast/misc/recstr.c b/src/lib/libast/misc/recstr.c
new file mode 100644
index 0000000..8ba8337
--- /dev/null
+++ b/src/lib/libast/misc/recstr.c
@@ -0,0 +1,206 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * return the record format descriptor given a format string
+ * e!=0 set to the first unrecognized char after the format
+ * REC_N_TYPE() returned on error
+ *
+ * d[0xNN|delimiter] (delimited, newline default)
+ * [f][+]size (fixed length)
+ * v hN oN zN b|l i|n (variable length with size header)
+ * h header size in bytes (ibm V 4)
+ * o size offset in bytes (ibm V 0)
+ * z size length in bytes (ibm V 2)
+ * l|b little-endian or big-endian size (ibm V b (0))
+ * i|n header included/not-included in size (ibm V i (1))
+ */
+
+#include <recfmt.h>
+#include <ctype.h>
+
+Recfmt_t
+recstr(register const char* s, char** e)
+{
+ char* t;
+ int n;
+ long v;
+ int a[6];
+
+ while (*s == ' ' || *s == '\t' || *s == ',')
+ s++;
+ switch (*s)
+ {
+ case 'd':
+ case 'D':
+ if (!*++s)
+ n = '\n';
+ else
+ {
+ if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))
+ n = (int)strtol(s, &t, 0);
+ else
+ n = chresc(s, &t);
+ s = (const char*)t;
+ }
+ if (e)
+ *e = (char*)s;
+ return REC_D_TYPE(n);
+ case 'f':
+ case 'F':
+ while (*++s == ' ' || *s == '\t' || *s == ',');
+ /*FALLTHROUGH*/
+ case '+':
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ n = strton(s, &t, NiL, 0);
+ if (n > 0 && t > (char*)s)
+ {
+ if (e)
+ *e = t;
+ return REC_F_TYPE(n);
+ }
+ break;
+ case 'm':
+ case 'M':
+ while (*++s == ' ' || *s == '\t' || *s == ',');
+ for (t = (char*)s; *t && *t != ' ' && *t != '\t' && *t != ','; t++);
+ if ((t - s) == 4)
+ {
+ if (strneq(s, "data", 4))
+ {
+ if (e)
+ *e = t;
+ return REC_M_TYPE(REC_M_data);
+ }
+ else if (strneq(s, "path", 4))
+ {
+ if (e)
+ *e = t;
+ return REC_M_TYPE(REC_M_path);
+ }
+ }
+
+ /*
+ * TBD: look up name in method libraries
+ * and assign an integer index
+ */
+
+ break;
+ case 'u':
+ case 'U':
+ while (*++s == ' ' || *s == '\t' || *s == ',');
+ n = strtol(s, &t, 0);
+ if (n < 0 || n > 15 || *t++ != '.')
+ break;
+ v = strtol(t, &t, 0);
+ if (*t)
+ break;
+ if (e)
+ *e = t;
+ return REC_U_TYPE(n, v);
+ case 'v':
+ case 'V':
+ a[0] = 0;
+ a[1] = 4;
+ a[2] = 0;
+ a[3] = 2;
+ a[4] = 0;
+ a[5] = 1;
+ n = 0;
+ for (;;)
+ {
+ switch (*++s)
+ {
+ case 0:
+ break;
+ case 'm':
+ case 'M':
+ n = 0;
+ continue;
+ case 'h':
+ case 'H':
+ n = 1;
+ continue;
+ case 'o':
+ case 'O':
+ n = 2;
+ continue;
+ case 'z':
+ case 'Z':
+ n = 3;
+ continue;
+ case 'b':
+ case 'B':
+ n = 4;
+ a[n++] = 0;
+ continue;
+ case 'l':
+ case 'L':
+ n = 4;
+ a[n++] = 1;
+ continue;
+ case 'n':
+ case 'N':
+ n = 0;
+ a[5] = 0;
+ continue;
+ case 'i':
+ case 'I':
+ n = 0;
+ a[5] = 1;
+ continue;
+ case ' ':
+ case '\t':
+ case ',':
+ case '-':
+ case '+':
+ continue;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ v = 0;
+ a[n++] = strtol(s, &t, 0);
+ s = (const char*)t - 1;
+ continue;
+ }
+ break;
+ }
+ if (e)
+ *e = (char*)s;
+ if (a[3] > (a[1] - a[2]))
+ a[3] = a[1] - a[2];
+ return REC_V_RECORD(REC_V_TYPE(a[1], a[2], a[3], a[4], a[5]), a[0]);
+ case '%':
+ if (e)
+ *e = (char*)s + 1;
+ return REC_M_TYPE(REC_M_path);
+ case '-':
+ case '?':
+ if (e)
+ *e = (char*)s + 1;
+ return REC_M_TYPE(REC_M_data);
+ }
+ if (e)
+ *e = (char*)s;
+ return REC_N_TYPE();
+}
diff --git a/src/lib/libast/misc/setenviron.c b/src/lib/libast/misc/setenviron.c
new file mode 100644
index 0000000..c67477e
--- /dev/null
+++ b/src/lib/libast/misc/setenviron.c
@@ -0,0 +1,147 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "intercepts.h"
+
+#include <fs3d.h>
+
+/*
+ * put name=value in the environment
+ * pointer to value returned
+ * environ==0 is ok
+ *
+ * setenviron("N=V") add N=V
+ * setenviron("N") delete N
+ * setenviron(0) expect more (pre-fork optimization)
+ *
+ * _ always placed at the top
+ */
+
+#define INCREMENT 16 /* environ increment */
+
+char*
+setenviron(const char* akey)
+{
+#undef setenviron
+ static char** envv; /* recorded environ */
+ static char** next; /* next free slot */
+ static char** last; /* last free slot (0) */
+ static char ok[] = ""; /* delete/optimization ok return*/
+
+ char* key = (char*)akey;
+ register char** v = environ;
+ register char** p = envv;
+ register char* s;
+ register char* t;
+ int n;
+
+ ast.env_serial++;
+ if (intercepts.intercept_setenviron)
+ return (*intercepts.intercept_setenviron)(akey);
+ if (p && !v)
+ {
+ environ = next = p;
+ *++next = 0;
+ }
+ else if (p != v || !v)
+ {
+ if (v)
+ {
+ while (*v++);
+ n = v - environ + INCREMENT;
+ v = environ;
+ }
+ else
+ n = INCREMENT;
+ if (!p || (last - p + 1) < n)
+ {
+ if (!p && fs3d(FS3D_TEST))
+ {
+ /*
+ * kick 3d initialization
+ */
+
+ close(open(".", O_RDONLY));
+ v = environ;
+ }
+ if (!(p = newof(p, char*, n, 0)))
+ return 0;
+ last = p + n - 1;
+ }
+ envv = environ = p;
+ if (v && v[0] && v[0][0] == '_' && v[0][1] == '=')
+ *p++ = *v++;
+ else
+ *p++ = "_=";
+ if (!v)
+ *p = 0;
+ else
+ while (*p = *v++)
+ if (p[0][0] == '_' && p[0][1] == '=')
+ envv[0] = *p;
+ else
+ p++;
+ next = p;
+ p = envv;
+ }
+ else if (next == last)
+ {
+ n = last - v + INCREMENT + 1;
+ if (!(p = newof(p, char*, n, 0)))
+ return 0;
+ last = p + n - 1;
+ next = last - INCREMENT;
+ envv = environ = p;
+ }
+ if (!key)
+ return ok;
+ for (; s = *p; p++)
+ {
+ t = key;
+ do
+ {
+ if (!*t || *t == '=')
+ {
+ if (*s == '=')
+ {
+ if (!*t)
+ {
+ v = p++;
+ while (*v++ = *p++);
+ next--;
+ return ok;
+ }
+ *p = key;
+ return (s = strchr(key, '=')) ? s + 1 : (char*)0;
+ }
+ break;
+ }
+ } while (*t++ == *s++);
+ }
+ if (!(s = strchr(key, '=')))
+ return ok;
+ p = next;
+ *++next = 0;
+ *p = key;
+ return s + 1;
+}
diff --git a/src/lib/libast/misc/sigcrit.c b/src/lib/libast/misc/sigcrit.c
new file mode 100644
index 0000000..243c478
--- /dev/null
+++ b/src/lib/libast/misc/sigcrit.c
@@ -0,0 +1,199 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * signal critical region support
+ */
+
+#include <ast.h>
+#include <sig.h>
+
+static struct
+{
+ int sig;
+ int op;
+}
+signals[] = /* held inside critical region */
+{
+ SIGINT, SIG_REG_EXEC,
+#ifdef SIGPIPE
+ SIGPIPE, SIG_REG_EXEC,
+#endif
+#ifdef SIGQUIT
+ SIGQUIT, SIG_REG_EXEC,
+#endif
+#ifdef SIGHUP
+ SIGHUP, SIG_REG_EXEC,
+#endif
+#if defined(SIGCHLD) && ( !defined(SIGCLD) || SIGCHLD != SIGCLD || _lib_sigprocmask || _lib_sigsetmask )
+ SIGCHLD, SIG_REG_PROC,
+#endif
+#ifdef SIGTSTP
+ SIGTSTP, SIG_REG_TERM,
+#endif
+#ifdef SIGTTIN
+ SIGTTIN, SIG_REG_TERM,
+#endif
+#ifdef SIGTTOU
+ SIGTTOU, SIG_REG_TERM,
+#endif
+};
+
+#ifndef SIG_SETMASK
+#undef _lib_sigprocmask
+#endif
+
+#if !_lib_sigprocmask && !_lib_sigsetmask
+
+static long hold; /* held signal mask */
+
+/*
+ * hold last signal for later delivery
+ */
+
+static void
+interrupt(int sig)
+{
+ signal(sig, interrupt);
+ hold |= sigmask(sig);
+}
+
+#endif
+
+/*
+ * critical signal region handler
+ *
+ * op>0 new region according to SIG_REG_*, return region level
+ * op==0 pop region, return region level
+ * op<0 return non-zero if any signals held in current region
+ *
+ * signals[] held until region popped
+ */
+
+int
+sigcritical(int op)
+{
+ register int i;
+ static int region;
+ static int level;
+#if _lib_sigprocmask
+ static sigset_t mask;
+ sigset_t nmask;
+#else
+#if _lib_sigsetmask
+ static long mask;
+#else
+ static Sig_handler_t handler[elementsof(signals)];
+#endif
+#endif
+
+ if (op > 0)
+ {
+ if (!level++)
+ {
+ region = op;
+ if (op & SIG_REG_SET)
+ level--;
+#if _lib_sigprocmask
+ sigemptyset(&nmask);
+ for (i = 0; i < elementsof(signals); i++)
+ if (op & signals[i].op)
+ sigaddset(&nmask, signals[i].sig);
+ sigprocmask(SIG_BLOCK, &nmask, &mask);
+#else
+#if _lib_sigsetmask
+ mask = 0;
+ for (i = 0; i < elementsof(signals); i++)
+ if (op & signals[i].op)
+ mask |= sigmask(signals[i].sig);
+ mask = sigblock(mask);
+#else
+ hold = 0;
+ for (i = 0; i < elementsof(signals); i++)
+ if ((op & signals[i].op) && (handler[i] = signal(signals[i].sig, interrupt)) == SIG_IGN)
+ {
+ signal(signals[i].sig, handler[i]);
+ hold &= ~sigmask(signals[i].sig);
+ }
+#endif
+#endif
+ }
+ return level;
+ }
+ else if (op < 0)
+ {
+#if _lib_sigprocmask
+ sigpending(&nmask);
+ for (i = 0; i < elementsof(signals); i++)
+ if (region & signals[i].op)
+ {
+ if (sigismember(&nmask, signals[i].sig))
+ return 1;
+ }
+ return 0;
+#else
+#if _lib_sigsetmask
+ /* no way to get pending signals without installing handler */
+ return 0;
+#else
+ return hold != 0;
+#endif
+#endif
+ }
+ else
+ {
+ /*
+ * a vfork() may have intervened so we
+ * allow apparent nesting mismatches
+ */
+
+ if (--level <= 0)
+ {
+ level = 0;
+#if _lib_sigprocmask
+ sigprocmask(SIG_SETMASK, &mask, NiL);
+#else
+#if _lib_sigsetmask
+ sigsetmask(mask);
+#else
+ for (i = 0; i < elementsof(signals); i++)
+ if (region & signals[i].op)
+ signal(signals[i].sig, handler[i]);
+ if (hold)
+ {
+ for (i = 0; i < elementsof(signals); i++)
+ if (region & signals[i].op)
+ {
+ if (hold & sigmask(signals[i].sig))
+ kill(getpid(), signals[i].sig);
+ }
+ pause();
+ }
+#endif
+#endif
+ }
+ return level;
+ }
+}
diff --git a/src/lib/libast/misc/sigdata.c b/src/lib/libast/misc/sigdata.c
new file mode 100644
index 0000000..657aeed
--- /dev/null
+++ b/src/lib/libast/misc/sigdata.c
@@ -0,0 +1,40 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * signal name and text data
+ */
+
+#include <ast.h>
+#include <sig.h>
+
+#include "FEATURE/signal"
+
+Sig_info_t _sig_info_ = { (char**)sig_name, (char**)sig_text, SIG_MAX };
+
+__EXTERN__(Sig_info_t, _sig_info_);
+
+#ifdef NoF
+NoF(sigdata)
+#endif
diff --git a/src/lib/libast/misc/signal.c b/src/lib/libast/misc/signal.c
new file mode 100644
index 0000000..0d5fe9d
--- /dev/null
+++ b/src/lib/libast/misc/signal.c
@@ -0,0 +1,136 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * signal that disables syscall restart on interrupt with clear signal mask
+ * fun==SIG_DFL also unblocks signal
+ */
+
+#if !_UWIN
+
+#undef signal
+#define signal ______signal
+
+#endif
+
+#include <ast.h>
+#include <sig.h>
+
+#if !_UWIN
+
+#undef signal
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#endif
+
+#if defined(SV_ABORT)
+#undef SV_INTERRUPT
+#define SV_INTERRUPT SV_ABORT
+#endif
+
+#if !_std_signal && (_lib_sigaction && defined(SA_NOCLDSTOP) || _lib_sigvec && defined(SV_INTERRUPT))
+
+#if !defined(SA_NOCLDSTOP) || !defined(SA_INTERRUPT) && defined(SV_INTERRUPT)
+#undef SA_INTERRUPT
+#define SA_INTERRUPT SV_INTERRUPT
+#undef sigaction
+#define sigaction sigvec
+#undef sigemptyset
+#define sigemptyset(p) (*(p)=0)
+#undef sa_flags
+#define sa_flags sv_flags
+#undef sa_handler
+#define sa_handler sv_handler
+#undef sa_mask
+#define sa_mask sv_mask
+#endif
+
+extern Sig_handler_t
+signal(int sig, Sig_handler_t fun)
+{
+ struct sigaction na;
+ struct sigaction oa;
+ int unblock;
+#ifdef SIGNO_MASK
+ unsigned int flags;
+#endif
+
+ if (sig < 0)
+ {
+ sig = -sig;
+ unblock = 0;
+ }
+ else
+ unblock = fun == SIG_DFL;
+#ifdef SIGNO_MASK
+ flags = sig & ~SIGNO_MASK;
+ sig &= SIGNO_MASK;
+#endif
+ memzero(&na, sizeof(na));
+ na.sa_handler = fun;
+#if defined(SA_INTERRUPT) || defined(SA_RESTART)
+ switch (sig)
+ {
+#if defined(SIGIO) || defined(SIGTSTP) || defined(SIGTTIN) || defined(SIGTTOU)
+#if defined(SIGIO)
+ case SIGIO:
+#endif
+#if defined(SIGTSTP)
+ case SIGTSTP:
+#endif
+#if defined(SIGTTIN)
+ case SIGTTIN:
+#endif
+#if defined(SIGTTOU)
+ case SIGTTOU:
+#endif
+#if defined(SA_RESTART)
+ na.sa_flags = SA_RESTART;
+#endif
+ break;
+#endif
+ default:
+#if defined(SA_INTERRUPT)
+ na.sa_flags = SA_INTERRUPT;
+#endif
+ break;
+ }
+#endif
+ if (sigaction(sig, &na, &oa))
+ return 0;
+ if (unblock)
+ sigunblock(sig);
+ return oa.sa_handler;
+}
+
+#else
+
+NoN(signal)
+
+#endif
diff --git a/src/lib/libast/misc/stack.c b/src/lib/libast/misc/stack.c
new file mode 100644
index 0000000..fdad3ff
--- /dev/null
+++ b/src/lib/libast/misc/stack.c
@@ -0,0 +1,172 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * pointer stack routines
+ */
+
+static const char id_stack[] = "\n@(#)$Id: stack (AT&T Bell Laboratories) 1984-05-01 $\0\n";
+
+#include <ast.h>
+#include <stack.h>
+
+/*
+ * create a new stack
+ */
+
+STACK
+stackalloc(register int size, void* error)
+{
+ register STACK stack;
+ register struct stackblock *b;
+
+ if (size <= 0) size = 100;
+ if (!(stack = newof(0, struct stacktable, 1, 0))) return(0);
+ if (!(b = newof(0, struct stackblock, 1, 0)))
+ {
+ free(stack);
+ return(0);
+ }
+ if (!(b->stack = newof(0, void*, size, 0)))
+ {
+ free(b);
+ free(stack);
+ return(0);
+ }
+ stack->blocks = b;
+ stack->size = size;
+ stack->error = error;
+ stack->position.block = b;
+ stack->position.index = -1;
+ b->next = 0;
+ b->prev = 0;
+ return(stack);
+}
+
+/*
+ * remove a stack
+ */
+
+void
+stackfree(register STACK stack)
+{
+ register struct stackblock* b;
+ register struct stackblock* p;
+
+ b = stack->blocks;
+ while (p = b)
+ {
+ b = p->next;
+ free(p->stack);
+ free(p);
+ }
+ free(stack);
+}
+
+/*
+ * clear stack
+ */
+
+void
+stackclear(register STACK stack)
+{
+ stack->position.block = stack->blocks;
+ stack->position.index = -1;
+}
+
+/*
+ * get value on top of stack
+ */
+
+void*
+stackget(register STACK stack)
+{
+ if (stack->position.index < 0) return(stack->error);
+ else return(stack->position.block->stack[stack->position.index]);
+}
+
+/*
+ * push value on to stack
+ */
+
+int
+stackpush(register STACK stack, void* value)
+{
+ register struct stackblock *b;
+
+ if (++stack->position.index >= stack->size)
+ {
+ b = stack->position.block;
+ if (b->next) b = b->next;
+ else
+ {
+ if (!(b->next = newof(0, struct stackblock, 1, 0)))
+ return(-1);
+ b = b->next;
+ if (!(b->stack = newof(0, void*, stack->size, 0)))
+ return(-1);
+ b->prev = stack->position.block;
+ b->next = 0;
+ }
+ stack->position.block = b;
+ stack->position.index = 0;
+ }
+ stack->position.block->stack[stack->position.index] = value;
+ return(0);
+}
+
+/*
+ * pop value off stack
+ */
+
+int
+stackpop(register STACK stack)
+{
+ /*
+ * return:
+ *
+ * -1 if stack empty before pop
+ * 0 if stack empty after pop
+ * 1 if stack not empty before & after pop
+ */
+
+ if (stack->position.index < 0) return(-1);
+ else if (--stack->position.index < 0)
+ {
+ if (!stack->position.block->prev) return(0);
+ stack->position.block = stack->position.block->prev;
+ stack->position.index = stack->size - 1;
+ return(1);
+ }
+ else return(1);
+}
+
+/*
+ * set|get stack position
+ */
+
+void
+stacktell(register STACK stack, int set, STACKPOS* position)
+{
+ if (set) stack->position = *position;
+ else *position = stack->position;
+}
diff --git a/src/lib/libast/misc/state.c b/src/lib/libast/misc/state.c
new file mode 100644
index 0000000..0e73be4
--- /dev/null
+++ b/src/lib/libast/misc/state.c
@@ -0,0 +1,42 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+static const char id[] = "\n@(#)$Id: ast (AT&T Research) 2010-01-02 $\0\n";
+
+#include <ast.h>
+
+#undef strcmp
+
+_Ast_info_t _ast_info =
+{
+ "libast", /* id */
+ { 0 },
+ 0,0,0,0,0,
+ strcmp, /* collate */
+ 0,0,
+ 1, /* mb_cur_max */
+ 0,0,0,0,0,0,0,
+ 20100102 /* version */
+};
+
+__EXTERN__(_Ast_info_t, _ast_info);
diff --git a/src/lib/libast/misc/stk.c b/src/lib/libast/misc/stk.c
new file mode 100644
index 0000000..1abc28d
--- /dev/null
+++ b/src/lib/libast/misc/stk.c
@@ -0,0 +1,553 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Routines to implement a stack-like storage library
+ *
+ * A stack consists of a link list of variable size frames
+ * The beginning of each frame is initialized with a frame structure
+ * that contains a pointer to the previous frame and a pointer to the
+ * end of the current frame.
+ *
+ * This is a rewrite of the stk library that uses sfio
+ *
+ * David Korn
+ * AT&T Research
+ * dgk@research.att.com
+ *
+ */
+
+#include <sfio_t.h>
+#include <ast.h>
+#include <align.h>
+#include <stk.h>
+
+/*
+ * A stack is a header and a linked list of frames
+ * The first frame has structure
+ * Sfio_t
+ * Sfdisc_t
+ * struct stk
+ * Frames have structure
+ * struct frame
+ * data
+ */
+
+#define STK_ALIGN ALIGN_BOUND
+#define STK_FSIZE (1024*sizeof(char*))
+#define STK_HDRSIZE (sizeof(Sfio_t)+sizeof(Sfdisc_t))
+
+typedef char* (*_stk_overflow_)(int);
+
+static int stkexcept(Sfio_t*,int,void*,Sfdisc_t*);
+static Sfdisc_t stkdisc = { 0, 0, 0, stkexcept };
+
+Sfio_t _Stak_data = SFNEW((char*)0,0,-1,SF_STATIC|SF_WRITE|SF_STRING,&stkdisc,0);
+
+__EXTERN__(Sfio_t, _Stak_data);
+
+struct frame
+{
+ char *prev; /* address of previous frame */
+ char *end; /* address of end this frame */
+ char **aliases; /* address aliases */
+ int nalias; /* number of aliases */
+};
+
+struct stk
+{
+ _stk_overflow_ stkoverflow; /* called when malloc fails */
+ short stkref; /* reference count; */
+ short stkflags; /* stack attributes */
+ char *stkbase; /* beginning of current stack frame */
+ char *stkend; /* end of current stack frame */
+};
+
+static size_t init; /* 1 when initialized */
+static struct stk *stkcur; /* pointer to current stk */
+static char *stkgrow(Sfio_t*, size_t);
+
+#define stream2stk(stream) ((stream)==stkstd? stkcur:\
+ ((struct stk*)(((char*)(stream))+STK_HDRSIZE)))
+#define stk2stream(sp) ((Sfio_t*)(((char*)(sp))-STK_HDRSIZE))
+#define stkleft(stream) ((stream)->_endb-(stream)->_data)
+
+
+#ifdef STKSTATS
+ static struct
+ {
+ int create;
+ int delete;
+ int install;
+ int alloc;
+ int copy;
+ int puts;
+ int seek;
+ int set;
+ int grow;
+ int addsize;
+ int delsize;
+ int movsize;
+ } _stkstats;
+# define increment(x) (_stkstats.x++)
+# define count(x,n) (_stkstats.x += (n))
+#else
+# define increment(x)
+# define count(x,n)
+#endif /* STKSTATS */
+
+static const char Omsg[] = "malloc failed while growing stack\n";
+
+/*
+ * default overflow exception
+ */
+static char *overflow(int n)
+{
+ NoP(n);
+ write(2,Omsg, sizeof(Omsg)-1);
+ exit(2);
+ /* NOTREACHED */
+ return(0);
+}
+
+/*
+ * initialize stkstd, sfio operations may have already occcured
+ */
+static void stkinit(size_t size)
+{
+ register Sfio_t *sp;
+ init = size;
+ sp = stkopen(0);
+ init = 1;
+ stkinstall(sp,overflow);
+}
+
+static int stkexcept(register Sfio_t *stream, int type, void* val, Sfdisc_t* dp)
+{
+ NoP(dp);
+ NoP(val);
+ switch(type)
+ {
+ case SF_CLOSING:
+ {
+ register struct stk *sp = stream2stk(stream);
+ register char *cp = sp->stkbase;
+ register struct frame *fp;
+ if(--sp->stkref<=0)
+ {
+ increment(delete);
+ if(stream==stkstd)
+ stkset(stream,(char*)0,0);
+ else
+ {
+ while(1)
+ {
+ fp = (struct frame*)cp;
+ if(fp->prev)
+ {
+ cp = fp->prev;
+ free(fp);
+ }
+ else
+ {
+ free(fp);
+ break;
+ }
+ }
+ }
+ }
+ stream->_data = stream->_next = 0;
+ }
+ return(0);
+ case SF_FINAL:
+ free(stream);
+ return(1);
+ case SF_DPOP:
+ return(-1);
+ case SF_WRITE:
+ case SF_SEEK:
+ {
+ long size = sfvalue(stream);
+ if(init)
+ {
+ Sfio_t *old = 0;
+ if(stream!=stkstd)
+ old = stkinstall(stream,NiL);
+ if(!stkgrow(stkstd,size-(stkstd->_endb-stkstd->_data)))
+ return(-1);
+ if(old)
+ stkinstall(old,NiL);
+ }
+ else
+ stkinit(size);
+ }
+ return(1);
+ case SF_NEW:
+ return(-1);
+ }
+ return(0);
+}
+
+/*
+ * create a stack
+ */
+Sfio_t *stkopen(int flags)
+{
+ register size_t bsize;
+ register Sfio_t *stream;
+ register struct stk *sp;
+ register struct frame *fp;
+ register Sfdisc_t *dp;
+ register char *cp;
+ if(!(stream=newof((char*)0,Sfio_t, 1, sizeof(*dp)+sizeof(*sp))))
+ return(0);
+ increment(create);
+ count(addsize,sizeof(*stream)+sizeof(*dp)+sizeof(*sp));
+ dp = (Sfdisc_t*)(stream+1);
+ dp->exceptf = stkexcept;
+ sp = (struct stk*)(dp+1);
+ sp->stkref = 1;
+ sp->stkflags = (flags&STK_SMALL);
+ if(flags&STK_NULL) sp->stkoverflow = 0;
+ else sp->stkoverflow = stkcur?stkcur->stkoverflow:overflow;
+ bsize = init+sizeof(struct frame);
+#ifndef USE_REALLOC
+ if(flags&STK_SMALL)
+ bsize = roundof(bsize,STK_FSIZE/16);
+ else
+#endif /* USE_REALLOC */
+ bsize = roundof(bsize,STK_FSIZE);
+ bsize -= sizeof(struct frame);
+ if(!(fp=newof((char*)0,struct frame, 1,bsize)))
+ {
+ free(stream);
+ return(0);
+ }
+ count(addsize,sizeof(*fp)+bsize);
+ cp = (char*)(fp+1);
+ sp->stkbase = (char*)fp;
+ fp->prev = 0;
+ fp->nalias = 0;
+ fp->aliases = 0;
+ fp->end = sp->stkend = cp+bsize;
+ if(!sfnew(stream,cp,bsize,-1,SF_STRING|SF_WRITE|SF_STATIC|SF_EOF))
+ return((Sfio_t*)0);
+ sfdisc(stream,dp);
+ return(stream);
+}
+
+/*
+ * return a pointer to the current stack
+ * if <stream> is not null, it becomes the new current stack
+ * <oflow> becomes the new overflow function
+ */
+Sfio_t *stkinstall(Sfio_t *stream, _stk_overflow_ oflow)
+{
+ Sfio_t *old;
+ register struct stk *sp;
+ if(!init)
+ {
+ stkinit(1);
+ if(oflow)
+ stkcur->stkoverflow = oflow;
+ return((Sfio_t*)0);
+ }
+ increment(install);
+ old = stkcur?stk2stream(stkcur):0;
+ if(stream)
+ {
+ sp = stream2stk(stream);
+ while(sfstack(stkstd, SF_POPSTACK));
+ if(stream!=stkstd)
+ sfstack(stkstd,stream);
+ stkcur = sp;
+#ifdef USE_REALLOC
+ /*** someday ***/
+#endif /* USE_REALLOC */
+ }
+ else
+ sp = stkcur;
+ if(oflow)
+ sp->stkoverflow = oflow;
+ return(old);
+}
+
+/*
+ * increase the reference count on the given <stack>
+ */
+int stklink(register Sfio_t* stream)
+{
+ register struct stk *sp = stream2stk(stream);
+ return(sp->stkref++);
+}
+
+/*
+ * terminate a stack and free up the space
+ * >0 returned if reference decremented but still > 0
+ * 0 returned on last close
+ * <0 returned on error
+ */
+int stkclose(Sfio_t* stream)
+{
+ register struct stk *sp = stream2stk(stream);
+ if(sp->stkref>1)
+ {
+ sp->stkref--;
+ return(1);
+ }
+ return(sfclose(stream));
+}
+
+/*
+ * returns 1 if <loc> is on this stack
+ */
+int stkon(register Sfio_t * stream, register char* loc)
+{
+ register struct stk *sp = stream2stk(stream);
+ register struct frame *fp;
+ for(fp=(struct frame*)sp->stkbase; fp; fp=(struct frame*)fp->prev)
+ if(loc>=((char*)(fp+1)) && loc< fp->end)
+ return(1);
+ return(0);
+}
+/*
+ * reset the bottom of the current stack back to <loc>
+ * if <loc> is not in this stack, then the stack is reset to the beginning
+ * otherwise, the top of the stack is set to stkbot+<offset>
+ *
+ */
+char *stkset(register Sfio_t * stream, register char* loc, size_t offset)
+{
+ register struct stk *sp = stream2stk(stream);
+ register char *cp;
+ register struct frame *fp;
+ register int frames = 0;
+ int n;
+ if(!init)
+ stkinit(offset+1);
+ increment(set);
+ while(1)
+ {
+ fp = (struct frame*)sp->stkbase;
+ cp = sp->stkbase + roundof(sizeof(struct frame), STK_ALIGN);
+ n = fp->nalias;
+ while(n-->0)
+ {
+ if(loc==fp->aliases[n])
+ {
+ loc = cp;
+ break;
+ }
+ }
+ /* see whether <loc> is in current stack frame */
+ if(loc>=cp && loc<=sp->stkend)
+ {
+ if(frames)
+ sfsetbuf(stream,cp,sp->stkend-cp);
+ stream->_data = (unsigned char*)(cp + roundof(loc-cp,STK_ALIGN));
+ stream->_next = (unsigned char*)loc+offset;
+ goto found;
+ }
+ if(fp->prev)
+ {
+ sp->stkbase = fp->prev;
+ sp->stkend = ((struct frame*)(fp->prev))->end;
+ free((void*)fp);
+ }
+ else
+ break;
+ frames++;
+ }
+ /* set stack back to the beginning */
+ cp = (char*)(fp+1);
+ if(frames)
+ sfsetbuf(stream,cp,sp->stkend-cp);
+ else
+ stream->_data = stream->_next = (unsigned char*)cp;
+found:
+ return((char*)stream->_data);
+}
+
+/*
+ * allocate <n> bytes on the current stack
+ */
+char *stkalloc(register Sfio_t *stream, register size_t n)
+{
+ register unsigned char *old;
+ if(!init)
+ stkinit(n);
+ increment(alloc);
+ n = roundof(n,STK_ALIGN);
+ if(stkleft(stream) <= (int)n && !stkgrow(stream,n))
+ return(0);
+ old = stream->_data;
+ stream->_data = stream->_next = old+n;
+ return((char*)old);
+}
+
+/*
+ * begin a new stack word of at least <n> bytes
+ */
+char *_stkseek(register Sfio_t *stream, register ssize_t n)
+{
+ if(!init)
+ stkinit(n);
+ increment(seek);
+ if(stkleft(stream) <= n && !stkgrow(stream,n))
+ return(0);
+ stream->_next = stream->_data+n;
+ return((char*)stream->_data);
+}
+
+/*
+ * advance the stack to the current top
+ * if extra is non-zero, first add a extra bytes and zero the first
+ */
+char *stkfreeze(register Sfio_t *stream, register size_t extra)
+{
+ register unsigned char *old, *top;
+ if(!init)
+ stkinit(extra);
+ old = stream->_data;
+ top = stream->_next;
+ if(extra)
+ {
+ if(extra > (stream->_endb-stream->_next))
+ {
+ if (!(top = (unsigned char*)stkgrow(stream,extra)))
+ return(0);
+ old = stream->_data;
+ }
+ *top = 0;
+ top += extra;
+ }
+ stream->_next = stream->_data += roundof(top-old,STK_ALIGN);
+ return((char*)old);
+}
+
+/*
+ * copy string <str> onto the stack as a new stack word
+ */
+char *stkcopy(Sfio_t *stream, const char* str)
+{
+ register unsigned char *cp = (unsigned char*)str;
+ register size_t n;
+ register int off=stktell(stream);
+ char buff[40], *tp=buff;
+ if(off)
+ {
+ if(off > sizeof(buff))
+ {
+ if(!(tp = malloc(off)))
+ {
+ struct stk *sp = stream2stk(stream);
+ if(!sp->stkoverflow || !(tp = (*sp->stkoverflow)(off)))
+ return(0);
+ }
+ }
+ memcpy(tp, stream->_data, off);
+ }
+ while(*cp++);
+ n = roundof(cp-(unsigned char*)str,STK_ALIGN);
+ if(!init)
+ stkinit(n);
+ increment(copy);
+ if(stkleft(stream) <= n && !stkgrow(stream,n))
+ cp = 0;
+ else
+ {
+ strcpy((char*)(cp=stream->_data),str);
+ stream->_data = stream->_next = cp+n;
+ if(off)
+ {
+ _stkseek(stream,off);
+ memcpy(stream->_data, tp, off);
+ }
+ }
+ if(tp!=buff)
+ free((void*)tp);
+ return((char*)cp);
+}
+
+/*
+ * add a new stack frame of size >= <n> to the current stack.
+ * if <n> > 0, copy the bytes from stkbot to stktop to the new stack
+ * if <n> is zero, then copy the remainder of the stack frame from stkbot
+ * to the end is copied into the new stack frame
+ */
+
+static char *stkgrow(register Sfio_t *stream, size_t size)
+{
+ register size_t n = size;
+ register struct stk *sp = stream2stk(stream);
+ register struct frame *fp= (struct frame*)sp->stkbase;
+ register char *cp, *dp=0;
+ register size_t m = stktell(stream);
+ char *end=0;
+ int nn=0,add=1;
+ n += (m + sizeof(struct frame)+1);
+ if(sp->stkflags&STK_SMALL)
+#ifndef USE_REALLOC
+ n = roundof(n,STK_FSIZE/16);
+ else
+#endif /* !USE_REALLOC */
+ n = roundof(n,STK_FSIZE);
+ /* see whether current frame can be extended */
+ if(stkptr(stream,0)==sp->stkbase+sizeof(struct frame))
+ {
+ nn = fp->nalias+1;
+ dp=sp->stkbase;
+ sp->stkbase = ((struct frame*)dp)->prev;
+ end = fp->end;
+ }
+ cp = newof(dp, char, n, nn*sizeof(char*));
+ if(!cp && (!sp->stkoverflow || !(cp = (*sp->stkoverflow)(n))))
+ return(0);
+ increment(grow);
+ count(addsize,n - (dp?m:0));
+ if(dp && cp==dp)
+ {
+ nn--;
+ add=0;
+ }
+ fp = (struct frame*)cp;
+ fp->prev = sp->stkbase;
+ sp->stkbase = cp;
+ sp->stkend = fp->end = cp+n;
+ cp = (char*)(fp+1);
+ cp = sp->stkbase + roundof((cp-sp->stkbase),STK_ALIGN);
+ if(fp->nalias=nn)
+ {
+ fp->aliases = (char**)fp->end;
+ if(end)
+ memmove(fp->aliases,end,nn*sizeof(char*));
+ if(add)
+ fp->aliases[nn-1] = dp + roundof(sizeof(struct frame),STK_ALIGN);
+ }
+ if(m && !dp)
+ {
+ memcpy(cp,(char*)stream->_data,m);
+ count(movsize,m);
+ }
+ sfsetbuf(stream,cp,sp->stkend-cp);
+ return((char*)(stream->_next = stream->_data+m));
+}
diff --git a/src/lib/libast/misc/systrace.c b/src/lib/libast/misc/systrace.c
new file mode 100644
index 0000000..a084c29
--- /dev/null
+++ b/src/lib/libast/misc/systrace.c
@@ -0,0 +1,68 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * trace systems calls if possible
+ */
+
+#include <ast.h>
+#include <error.h>
+#include <proc.h>
+#include <debug.h>
+
+void
+systrace(const char* id)
+{
+ register int n;
+ register char* out;
+ char* s;
+ char buf[PATH_MAX];
+ char* av[7];
+ long ov[2];
+
+ static char* trace[] = { "trace", "truss", "strace", "traces" };
+
+ if (!(s = getenv("HOME")))
+ return;
+ if (!id && !(id = (const char*)error_info.id))
+ id = (const char*)trace[0];
+ out = buf;
+ out += sfsprintf(out, sizeof(buf), "%s/.%s/%s", s, trace[0], id);
+ if (access(buf, F_OK))
+ return;
+ av[1] = trace[0];
+ av[2] = "-o";
+ av[3] = buf;
+ av[4] = "-p";
+ av[5] = out + 1;
+ av[6] = 0;
+ ov[0] = PROC_FD_DUP(open("/dev/null", O_WRONLY), 2, PROC_FD_PARENT|PROC_FD_CHILD);
+ ov[1] = 0;
+ sfsprintf(out, &buf[sizeof(buf)] - out, ".%d", getpid());
+ for (n = 0; n < elementsof(trace); n++)
+ if (!procfree(procopen(trace[n], av + 1, NiL, ov, PROC_ARGMOD|PROC_GID|PROC_UID|(n == (elementsof(trace) - 1) ? PROC_CLEANUP : 0))))
+ {
+ sleep(1);
+ break;
+ }
+}
diff --git a/src/lib/libast/misc/translate.c b/src/lib/libast/misc/translate.c
new file mode 100644
index 0000000..0c9fbe3
--- /dev/null
+++ b/src/lib/libast/misc/translate.c
@@ -0,0 +1,437 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * AT&T Research and SCO
+ * ast l10n message translation
+ */
+
+#include "lclib.h"
+
+#include <cdt.h>
+#include <error.h>
+#include <mc.h>
+#include <nl_types.h>
+
+#ifndef DEBUG_trace
+#define DEBUG_trace 0
+#endif
+
+#define NOCAT ((nl_catd)-1)
+#define GAP 100
+
+typedef struct
+{
+ Dtlink_t link; /* dictionary link */
+ Dt_t* messages; /* message dictionary handle */
+ nl_catd cat; /* message catalog handle */
+ int debug; /* special debug locale */
+ const char* locale; /* message catalog locale */
+ const char* nlspath; /* message catalog NLSPATH */
+ char name[1]; /* catalog name */
+} Catalog_t;
+
+typedef struct
+{
+ Dtlink_t link; /* dictionary link */
+ Catalog_t* cat; /* current catalog pointer */
+ int set; /* set number */
+ int seq; /* sequence number */
+ char text[1]; /* message text */
+} Message_t;
+
+typedef struct
+{
+ Sfio_t* sp; /* temp string stream */
+ int off; /* string base offset */
+} Temp_t;
+
+typedef struct
+{
+ Dtdisc_t message_disc; /* message dict discipline */
+ Dtdisc_t catalog_disc; /* catalog dict discipline */
+ Dt_t* catalogs; /* catalog dictionary handle */
+ Sfio_t* tmp; /* temporary string stream */
+ int error; /* no dictionaries! */
+ char null[1]; /* null string */
+} State_t;
+
+static State_t state =
+{
+ { offsetof(Message_t, text), 0, 0 },
+ { offsetof(Catalog_t, name), 0, 0 },
+};
+
+static int
+tempget(Sfio_t* sp)
+{
+ if (sfstrtell(sp) > sfstrsize(sp) / 2)
+ sfstrseek(sp, 0, SEEK_SET);
+ return sfstrtell(sp);
+}
+
+static char*
+tempuse(Sfio_t* sp, int off)
+{
+ sfputc(sp, 0);
+ return sfstrbase(sp) + off;
+}
+
+/*
+ * add msg to dict
+ */
+
+static int
+entry(Dt_t* dict, int set, int seq, const char* msg)
+{
+ Message_t* mp;
+
+ if (!(mp = newof(0, Message_t, 1, strlen(msg))))
+ return 0;
+ strcpy(mp->text, msg);
+ mp->set = set;
+ mp->seq = seq;
+ if (!dtinsert(dict, mp))
+ {
+ free(mp);
+ return 0;
+ }
+#if DEBUG_trace > 1
+sfprintf(sfstderr, "AHA#%d:%s set %d seq %d msg `%s'\n", __LINE__, __FILE__, set, seq, msg);
+#endif
+ return 1;
+}
+
+/*
+ * find catalog in locale and return catopen() descriptor
+ */
+
+static nl_catd
+find(const char* locale, const char* catalog)
+{
+ char* o;
+ nl_catd d;
+ char path[PATH_MAX];
+
+ if (!mcfind(locale, catalog, LC_MESSAGES, 0, path, sizeof(path)) || (d = catopen(path, NL_CAT_LOCALE)) == NOCAT)
+ {
+ if (locale == (const char*)lc_categories[AST_LC_MESSAGES].prev)
+ o = 0;
+ else if (o = setlocale(LC_MESSAGES, NiL))
+ {
+ ast.locale.set |= AST_LC_internal;
+ setlocale(LC_MESSAGES, locale);
+ }
+ d = catopen(catalog, NL_CAT_LOCALE);
+ if (o)
+ {
+ setlocale(LC_MESSAGES, o);
+ ast.locale.set &= ~AST_LC_internal;
+ }
+ }
+ return d;
+}
+
+/*
+ * initialize the catalog s by loading in the default locale messages
+ */
+
+static Catalog_t*
+init(register char* s)
+{
+ register Catalog_t* cp;
+ register char* u;
+ register int n;
+ register int m;
+ register int set;
+ nl_catd d;
+
+ static const int sets[] = { AST_MESSAGE_SET, 1 };
+
+ /*
+ * insert into the catalog dictionary
+ */
+
+ if (!(cp = newof(0, Catalog_t, 1, strlen(s))))
+ return 0;
+ strcpy(cp->name, s);
+ if (!dtinsert(state.catalogs, cp))
+ {
+ free(cp);
+ return 0;
+ }
+ cp->cat = NOCAT;
+
+ /*
+ * locate the default locale catalog
+ */
+
+ if ((d = find("C", s)) != NOCAT)
+ {
+ /*
+ * load the default locale messages
+ * this assumes one mesage set for ast (AST_MESSAGE_SET or fallback to 1)
+ * different packages can share the same message catalog
+ * name by using different message set numbers
+ * see <mc.h> mcindex()
+ *
+ * this method requires a scan of each catalog, and the
+ * catalogs do not advertise the max message number, so
+ * we assume there are no messages after a gap of GAP
+ * missing messages
+ */
+
+ if (cp->messages = dtopen(&state.message_disc, Dtset))
+ {
+ n = m = 0;
+ for (;;)
+ {
+ n++;
+ if (((s = catgets(d, set = AST_MESSAGE_SET, n, state.null)) && *s || (s = catgets(d, set = 1, n, state.null)) && *s) && entry(cp->messages, set, n, s))
+ m = n;
+ else if ((n - m) > GAP)
+ break;
+ }
+ if (!m)
+ {
+ dtclose(cp->messages);
+ cp->messages = 0;
+ }
+ }
+ catclose(d);
+ }
+ return cp;
+}
+
+/*
+ * return the C locale message pointer for msg in cat
+ * cat may be a : separated list of candidate names
+ */
+
+static Message_t*
+match(const char* cat, const char* msg)
+{
+ register char* s;
+ register char* t;
+ Catalog_t* cp;
+ Message_t* mp;
+ size_t n;
+
+ char buf[1024];
+
+ s = (char*)cat;
+ for (;;)
+ {
+ if (t = strchr(s, ':'))
+ {
+ if (s == (char*)cat)
+ {
+ if ((n = strlen(s)) >= sizeof(buf))
+ n = sizeof(buf) - 1;
+ s = (char*)memcpy(buf, s, n);
+ s[n] = 0;
+ t = strchr(s, ':');
+ }
+ *t = 0;
+ }
+ if (*s && ((cp = (Catalog_t*)dtmatch(state.catalogs, s)) || (cp = init(s))) && cp->messages && (mp = (Message_t*)dtmatch(cp->messages, msg)))
+ {
+ mp->cat = cp;
+ return mp;
+ }
+ if (!t)
+ break;
+ s = t + 1;
+ }
+ return 0;
+}
+
+/*
+ * translate() is called with four arguments:
+ *
+ * loc the LC_MESSAGES locale name
+ * cmd the calling command name
+ * cat the catalog name, possibly a : separated list
+ * "libFOO" FOO library messages
+ * "libshell" ksh command messages
+ * "SCRIPT" script SCRIPT application messages
+ * msg message text to be translated
+ *
+ * the translated message text is returned on success
+ * otherwise the original msg is returned
+ *
+ * The first time translate() is called (for a non-C locale)
+ * it creates the state.catalogs dictionary. A dictionary entry
+ * (Catalog_t) is made each time translate() is called with a new
+ * cmd:cat argument.
+ *
+ * The X/Open interface catgets() is used to obtain a translated
+ * message. Its arguments include the message catalog name
+ * and the set/sequence numbers within the catalog. An additional
+ * dictionary, with entries of type Message_t, is needed for
+ * mapping untranslated message strings to the set/sequence numbers
+ * needed by catgets(). A separate Message_t dictionary is maintained
+ * for each Catalog_t.
+ */
+
+char*
+translate(const char* loc, const char* cmd, const char* cat, const char* msg)
+{
+ register char* r;
+ char* t;
+ int p;
+ int oerrno;
+ Catalog_t* cp;
+ Message_t* mp;
+
+ static uint32_t serial;
+ static char* nlspath;
+
+ oerrno = errno;
+ r = (char*)msg;
+
+ /*
+ * quick out
+ */
+
+ if (!cmd && !cat)
+ goto done;
+ if (cmd && (t = strrchr(cmd, '/')))
+ cmd = (const char*)(t + 1);
+
+ /*
+ * initialize the catalogs dictionary
+ */
+
+ if (!state.catalogs)
+ {
+ if (state.error)
+ goto done;
+ if (!(state.tmp = sfstropen()))
+ {
+ state.error = 1;
+ goto done;
+ }
+ if (!(state.catalogs = dtopen(&state.catalog_disc, Dtset)))
+ {
+ sfclose(state.tmp);
+ state.error = 1;
+ goto done;
+ }
+ }
+
+ /*
+ * get the message
+ * or do we have to spell it out for you
+ */
+
+ if ((!cmd || !(mp = match(cmd, msg))) &&
+ (!cat || !(mp = match(cat, msg))) &&
+ (!error_info.catalog || !(mp = match(error_info.catalog, msg))) &&
+ (!ast.id || !(mp = match(ast.id, msg))) ||
+ !(cp = mp->cat))
+ {
+#if DEBUG_trace > 1
+sfprintf(sfstderr, "AHA#%d:%s cmd %s cat %s:%s id %s msg `%s'\n", __LINE__, __FILE__, cmd, cat, error_info.catalog, ast.id, msg);
+#endif
+ cp = 0;
+ goto done;
+ }
+
+ /*
+ * adjust for the current locale
+ */
+
+#if DEBUG_trace
+sfprintf(sfstderr, "AHA#%d:%s cp->locale `%s' %p loc `%s' %p\n", __LINE__, __FILE__, cp->locale, cp->locale, loc, loc);
+#endif
+ if (serial != ast.env_serial)
+ {
+ serial = ast.env_serial;
+ nlspath = getenv("NLSPATH");
+ }
+ if (cp->locale != loc || cp->nlspath != nlspath)
+ {
+ cp->locale = loc;
+ cp->nlspath = nlspath;
+ if (cp->cat != NOCAT)
+ catclose(cp->cat);
+ if ((cp->cat = find(cp->locale, cp->name)) == NOCAT)
+ cp->debug = streq(cp->locale, "debug");
+ else
+ cp->debug = 0;
+#if DEBUG_trace
+sfprintf(sfstderr, "AHA#%d:%s cp->cat %p cp->debug %d NOCAT %p\n", __LINE__, __FILE__, cp->cat, cp->debug, NOCAT);
+#endif
+ }
+ if (cp->cat == NOCAT)
+ {
+ if (cp->debug)
+ {
+ p = tempget(state.tmp);
+ sfprintf(state.tmp, "(%s,%d,%d)", cp->name, mp->set, mp->seq);
+ r = tempuse(state.tmp, p);
+ }
+ else if (ast.locale.set & AST_LC_debug)
+ {
+ p = tempget(state.tmp);
+ sfprintf(state.tmp, "(%s,%d,%d)%s", cp->name, mp->set, mp->seq, r);
+ r = tempuse(state.tmp, p);
+ }
+ }
+ else
+ {
+ /*
+ * get the translated message
+ */
+
+ r = catgets(cp->cat, mp->set, mp->seq, msg);
+ if (r != (char*)msg)
+ {
+ if (streq(r, (char*)msg))
+ r = (char*)msg;
+ else if (strcmp(fmtfmt(r), fmtfmt(msg)))
+ {
+ sfprintf(sfstderr, "locale %s catalog %s message %d.%d \"%s\" does not match \"%s\"\n", cp->locale, cp->name, mp->set, mp->seq, r, msg);
+ r = (char*)msg;
+ }
+ }
+ if (ast.locale.set & AST_LC_debug)
+ {
+ p = tempget(state.tmp);
+ sfprintf(state.tmp, "(%s,%d,%d)%s", cp->name, mp->set, mp->seq, r);
+ r = tempuse(state.tmp, p);
+ }
+ }
+ if (ast.locale.set & AST_LC_translate)
+ sfprintf(sfstderr, "translate locale=%s catalog=%s set=%d seq=%d \"%s\" => \"%s\"\n", cp->locale, cp->name, mp->set, mp->seq, msg, r == (char*)msg ? "NOPE" : r);
+ done:
+ if (r == (char*)msg && (!cp && streq(loc, "debug") || cp && cp->debug))
+ {
+ p = tempget(state.tmp);
+ sfprintf(state.tmp, "(%s,%s,%s,%s)", loc, cmd, cat, r);
+ r = tempuse(state.tmp, p);
+ }
+ errno = oerrno;
+ return r;
+}
diff --git a/src/lib/libast/misc/univdata.c b/src/lib/libast/misc/univdata.c
new file mode 100644
index 0000000..0cc04df
--- /dev/null
+++ b/src/lib/libast/misc/univdata.c
@@ -0,0 +1,58 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * universe common data
+ */
+
+#include "univlib.h"
+
+#ifndef UNIV_MAX
+
+char univ_env[] = "__UNIVERSE__";
+
+#else
+
+#ifndef NUMUNIV
+
+#if !_lib_universe
+#undef U_GET
+#endif
+
+#ifdef U_GET
+char* univ_name[] = { "ucb", "att" };
+#else
+char* univ_name[] = { "att", "ucb" };
+#endif
+
+int univ_max = sizeof(univ_name) / sizeof(univ_name[0]);
+
+#endif
+
+char univ_cond[] = "$(UNIVERSE)";
+
+int univ_size = sizeof(univ_cond) - 1;
+
+#endif
diff --git a/src/lib/libast/misc/univlib.h b/src/lib/libast/misc/univlib.h
new file mode 100644
index 0000000..ba319c5
--- /dev/null
+++ b/src/lib/libast/misc/univlib.h
@@ -0,0 +1,93 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * universe support
+ *
+ * symbolic link external representation has trailing '\0' and $(...) style
+ * conditionals where $(...) corresponds to a kernel object (i.e., probably
+ * not environ)
+ *
+ * universe symlink conditionals use $(UNIVERSE)
+ */
+
+#ifndef _UNIVLIB_H
+#define _UNIVLIB_H
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide getuniverse readlink setuniverse symlink universe
+#else
+#define getuniverse ______getuniverse
+#define readlink ______readlink
+#define setuniverse ______setuniverse
+#define symlink ______symlink
+#define universe ______universe
+#endif
+
+#include <ast.h>
+#include <ls.h>
+#include <errno.h>
+
+#define UNIV_SIZE 9
+
+#if _cmd_universe && _sys_universe
+#include <sys/universe.h>
+#endif
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide getuniverse readlink setuniverse symlink universe
+#else
+#undef getuniverse
+#undef readlink
+#undef setuniverse
+#undef symlink
+#undef universe
+#endif
+
+#if _cmd_universe
+#ifdef NUMUNIV
+#define UNIV_MAX NUMUNIV
+#else
+#define UNIV_MAX univ_max
+extern char* univ_name[];
+extern int univ_max;
+#endif
+
+extern char univ_cond[];
+extern int univ_size;
+
+#else
+
+extern char univ_env[];
+
+#endif
+
+extern int getuniverse(char*);
+extern int readlink(const char*, char*, int);
+extern int setuniverse(int);
+extern int symlink(const char*, const char*);
+extern int universe(int);
+
+#endif
diff --git a/src/lib/libast/obsolete/spawn.c b/src/lib/libast/obsolete/spawn.c
new file mode 100644
index 0000000..282ec3a
--- /dev/null
+++ b/src/lib/libast/obsolete/spawn.c
@@ -0,0 +1,152 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * OBSOLETE 20030321 -- use spawnveg()
+ */
+
+#include <ast_lib.h>
+
+#if !_lib_spawnve
+#define spawnve ______spawnve
+#endif
+#if !_lib_spawnvpe
+#define spawnvpe ______spawnvpe
+#endif
+#if !_lib_spawnvp
+#define spawnvp ______spawnvp
+#endif
+#if !_lib_spawnlp
+#define spawnlp ______spawnlp
+#endif
+
+#include <ast.h>
+#include <error.h>
+
+#if !_lib_spawnve
+#undef spawnve
+#endif
+#if !_lib_spawnvpe
+#undef spawnvpe
+#endif
+#if !_lib_spawnvp
+#undef spawnvp
+#endif
+#if !_lib_spawnlp
+#undef spawnlp
+#endif
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#if _lib_spawnve
+
+NoN(spawnve)
+
+#else
+
+extern pid_t
+spawnve(const char* cmd, char* const argv[], char* const envv[])
+{
+ return spawnveg(cmd, argv, envv, 0);
+}
+
+#endif
+
+#if _lib_spawnvpe
+
+NoN(spawnvpe)
+
+#else
+
+extern pid_t
+spawnvpe(const char* name, char* const argv[], char* const envv[])
+{
+ register const char* path = name;
+ pid_t pid;
+ char buffer[PATH_MAX];
+
+ if (*path != '/')
+ path = pathpath(name, NULL, PATH_REGULAR|PATH_EXECUTE, buffer, sizeof(buffer));
+ if ((pid = spawnve(path, argv, envv)) >= 0)
+ return pid;
+ if (errno == ENOEXEC)
+ {
+ register char** newargv;
+ register char** ov;
+ register char** nv;
+
+ for (ov = (char**)argv; *ov++;);
+ if (newargv = newof(0, char*, ov + 1 - (char**)argv, 0))
+ {
+ nv = newargv;
+ *nv++ = "sh";
+ *nv++ = (char*)path;
+ ov = (char**)argv;
+ while (*nv++ = *++ov);
+ path = pathshell();
+ pid = spawnve(path, newargv, environ);
+ free(newargv);
+ }
+ else
+ errno = ENOMEM;
+ }
+ return pid;
+}
+
+#endif
+
+#if _lib_spawnvp
+
+NoN(spawnvp)
+
+#else
+
+extern pid_t
+spawnvp(const char* name, char* const argv[])
+{
+ return spawnvpe(name, argv, environ);
+}
+
+#endif
+
+#if _lib_spawnlp
+
+NoN(spawnlp)
+
+#else
+
+extern pid_t
+spawnlp(const char* name, const char* arg, ...)
+{
+ va_list ap;
+ pid_t pid;
+
+ va_start(ap, arg);
+ pid = spawnvp(name, (char* const*)&arg);
+ va_end(ap);
+ return pid;
+}
+
+#endif
diff --git a/src/lib/libast/path/pathaccess.c b/src/lib/libast/path/pathaccess.c
new file mode 100644
index 0000000..7bbec12
--- /dev/null
+++ b/src/lib/libast/path/pathaccess.c
@@ -0,0 +1,69 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * return path to file a/b with access mode using : separated dirs
+ * both a and b may be 0
+ * if a==".." then relative paths in dirs are ignored
+ * if (mode&PATH_REGULAR) then path must not be a directory
+ * if (mode&PATH_ABSOLUTE) then path must be rooted
+ * path returned in path buffer
+ */
+
+#define _AST_API_H 1
+
+#include <ast.h>
+
+char*
+pathaccess(char* path, const char* dirs, const char* a, const char* b, int mode)
+{
+ return pathaccess_20100601(dirs, a, b, mode, path, PATH_MAX);
+}
+
+#undef _AST_API_H
+
+#include <ast_api.h>
+
+char*
+pathaccess_20100601(register const char* dirs, const char* a, const char* b, register int mode, register char* path, size_t size)
+{
+ int sib = a && a[0] == '.' && a[1] == '.' && a[2] == 0;
+ int sep = ':';
+ char cwd[PATH_MAX];
+
+ do
+ {
+ dirs = pathcat(dirs, sep, a, b, path, size);
+ pathcanon(path, size, 0);
+ if ((!sib || *path == '/') && pathexists(path, mode))
+ {
+ if (*path == '/' || !(mode & PATH_ABSOLUTE))
+ return path;
+ dirs = getcwd(cwd, sizeof(cwd));
+ sep = 0;
+ }
+ } while (dirs);
+ return 0;
+}
diff --git a/src/lib/libast/path/pathbin.c b/src/lib/libast/path/pathbin.c
new file mode 100644
index 0000000..cc9cdfa
--- /dev/null
+++ b/src/lib/libast/path/pathbin.c
@@ -0,0 +1,46 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * return current PATH
+ */
+
+#include <ast.h>
+
+char*
+pathbin(void)
+{
+ register char* bin;
+
+ static char* val;
+
+ if ((!(bin = getenv("PATH")) || !*bin) && !(bin = val))
+ {
+ if (!*(bin = astconf("PATH", NiL, NiL)) || !(bin = strdup(bin)))
+ bin = "/bin:/usr/bin:/usr/local/bin";
+ val = bin;
+ }
+ return bin;
+}
diff --git a/src/lib/libast/path/pathcanon.c b/src/lib/libast/path/pathcanon.c
new file mode 100644
index 0000000..8d3cfa6
--- /dev/null
+++ b/src/lib/libast/path/pathcanon.c
@@ -0,0 +1,222 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * in-place path name canonicalization -- preserves the logical view
+ * pointer to trailing 0 in path returned
+ *
+ * remove redundant .'s and /'s
+ * move ..'s to the front
+ * /.. preserved (for pdu and newcastle hacks)
+ * FS_3D handles ...
+ * if (flags&PATH_PHYSICAL) then symlinks resolved at each component
+ * if (flags&PATH_DOTDOT) then each .. checked for access
+ * if (flags&PATH_EXISTS) then path must exist at each component
+ * if (flags&PATH_VERIFIED(n)) then first n chars of path exist
+ *
+ * longer pathname possible if (flags&PATH_PHYSICAL) or FS_3D ... involved
+ * 0 returned on error and if (flags&(PATH_DOTDOT|PATH_EXISTS)) then path
+ * will contain the components following the failure point
+ */
+
+#define _AST_API_H 1
+
+#include <ast.h>
+#include <ls.h>
+#include <fs3d.h>
+#include <error.h>
+
+char*
+pathcanon(char* path, int flags)
+{
+ return pathcanon_20100601(path, PATH_MAX, flags);
+}
+
+#undef _AST_API_H
+
+#include <ast_api.h>
+
+char*
+pathcanon_20100601(char* path, size_t size, int flags)
+{
+ register char* p;
+ register char* r;
+ register char* s;
+ register char* t;
+ register int dots;
+ char* phys;
+ char* v;
+ int loop;
+ int oerrno;
+#if defined(FS_3D)
+ long visits = 0;
+#endif
+
+ oerrno = errno;
+ dots = loop = 0;
+ phys = path;
+ v = path + ((flags >> 5) & 01777);
+ if (!size)
+ size = strlen(path) + 1;
+ if (*path == '/')
+ {
+ if (*(path + 1) == '/' && *astconf("PATH_LEADING_SLASHES", NiL, NiL) == '1')
+ do path++; while (*path == '/' && *(path + 1) == '/');
+ if (!*(path + 1))
+ return path + 1;
+ }
+ p = r = s = t = path;
+ for (;;)
+ switch (*t++ = *s++)
+ {
+ case '.':
+ dots++;
+ break;
+ case 0:
+ s--;
+ /*FALLTHROUGH*/
+ case '/':
+ while (*s == '/') s++;
+ switch (dots)
+ {
+ case 1:
+ t -= 2;
+ break;
+ case 2:
+ if ((flags & (PATH_DOTDOT|PATH_EXISTS)) == PATH_DOTDOT && (t - 2) >= v)
+ {
+ struct stat st;
+
+ *(t - 2) = 0;
+ if (stat(phys, &st))
+ {
+ strcpy(path, s);
+ return 0;
+ }
+ *(t - 2) = '.';
+ }
+#if PRESERVE_TRAILING_SLASH
+ if (t - 5 < r) r = t;
+#else
+ if (t - 5 < r)
+ {
+ if (t - 4 == r) t = r + 1;
+ else r = t;
+ }
+#endif
+ else for (t -= 5; t > r && *(t - 1) != '/'; t--);
+ break;
+ case 3:
+#if defined(FS_3D)
+ {
+ char* x;
+ char* o;
+ int c;
+
+ o = t;
+ if ((t -= 5) <= path) t = path + 1;
+ c = *t;
+ *t = 0;
+ if (x = pathnext(phys, s - (*s != 0), &visits))
+ {
+ r = path;
+ if (t == r + 1) x = r;
+ v = s = t = x;
+ }
+ else
+ {
+ *t = c;
+ t = o;
+ }
+ }
+#else
+ r = t;
+#endif
+ break;
+ default:
+ if ((flags & PATH_PHYSICAL) && loop < 32 && (t - 1) > path)
+ {
+ int c;
+ char buf[PATH_MAX];
+
+ c = *(t - 1);
+ *(t - 1) = 0;
+ dots = pathgetlink(phys, buf, sizeof(buf));
+ *(t - 1) = c;
+ if (dots > 0)
+ {
+ loop++;
+ strcpy(buf + dots, s - (*s != 0));
+ if (*buf == '/') p = r = path;
+ v = s = t = p;
+ strcpy(p, buf);
+ }
+ else if (dots < 0 && errno == ENOENT)
+ {
+ if (flags & PATH_EXISTS)
+ {
+ strcpy(path, s);
+ return 0;
+ }
+ flags &= ~(PATH_PHYSICAL|PATH_DOTDOT);
+ }
+ dots = 4;
+ }
+ break;
+ }
+ if (dots >= 4 && (flags & PATH_EXISTS) && (t - 1) >= v && (t > path + 1 || t > path && *(t - 1) && *(t - 1) != '/'))
+ {
+ struct stat st;
+
+ *(t - 1) = 0;
+ if (stat(phys, &st))
+ {
+ strcpy(path, s);
+ return 0;
+ }
+ v = t;
+ if (*s) *(t - 1) = '/';
+ }
+ if (!*s)
+ {
+ if (t > path && !*(t - 1)) t--;
+ if (t == path) *t++ = '.';
+#if DONT_PRESERVE_TRAILING_SLASH
+ else if (t > path + 1 && *(t - 1) == '/') t--;
+#else
+ else if ((s <= path || *(s - 1) != '/') && t > path + 1 && *(t - 1) == '/') t--;
+#endif
+ *t = 0;
+ errno = oerrno;
+ return t;
+ }
+ dots = 0;
+ p = t;
+ break;
+ default:
+ dots = 4;
+ break;
+ }
+}
diff --git a/src/lib/libast/path/pathcat.c b/src/lib/libast/path/pathcat.c
new file mode 100644
index 0000000..2fa9cde
--- /dev/null
+++ b/src/lib/libast/path/pathcat.c
@@ -0,0 +1,98 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * single dir support for pathaccess()
+ */
+
+#define _AST_API_H 1
+
+#include <ast.h>
+
+/*
+ * building 3d flirts with the dark side
+ */
+
+#if _BLD_3d
+
+#undef pathcat
+#define pathcat_20100601 _3d_pathcat
+
+#else
+
+char*
+pathcat(char* path, const char* dirs, int sep, const char* a, const char* b)
+{
+ return pathcat_20100601(dirs, sep, a, b, path, PATH_MAX);
+}
+
+#endif
+
+#undef _AST_API
+
+#include <ast_api.h>
+
+char*
+pathcat_20100601(register const char* dirs, int sep, const char* a, register const char* b, char* path, size_t size)
+{
+ register char* s;
+ register char* e;
+
+ s = path;
+ e = path + size;
+ while (*dirs && *dirs != sep)
+ {
+ if (s >= e)
+ return 0;
+ *s++ = *dirs++;
+ }
+ if (s != path)
+ {
+ if (s >= e)
+ return 0;
+ *s++ = '/';
+ }
+ if (a)
+ {
+ while (*s = *a++)
+ if (++s >= e)
+ return 0;
+ if (b)
+ {
+ if (s >= e)
+ return 0;
+ *s++ = '/';
+ }
+ }
+ else if (!b)
+ b = ".";
+ if (b)
+ do
+ {
+ if (s >= e)
+ return 0;
+ } while (*s++ = *b++);
+ return *dirs ? (char*)++dirs : 0;
+}
diff --git a/src/lib/libast/path/pathcd.c b/src/lib/libast/path/pathcd.c
new file mode 100644
index 0000000..340a115
--- /dev/null
+++ b/src/lib/libast/path/pathcd.c
@@ -0,0 +1,142 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * K. P. Vo
+ * G. S. Fowler
+ * AT&T Research
+ */
+
+#include <ast.h>
+#include <error.h>
+#include <stk.h>
+
+#if DEBUG
+
+#undef PATH_MAX
+
+#define PATH_MAX 16
+
+static int
+vchdir(const char* path)
+{
+ int n;
+
+ if (strlen(path) >= PATH_MAX)
+ {
+ errno = ENAMETOOLONG;
+ n = -1;
+ }
+ else n = chdir(path);
+ return n;
+}
+
+#define chdir(p) vchdir(p)
+
+#endif
+
+/*
+ * set the current directory to path
+ * if path is long and home!=0 then pathcd(home,0)
+ * is called on intermediate chdir errors
+ */
+
+int
+pathcd(const char* path, const char* home)
+{
+ register char* p = (char*)path;
+ register char* s;
+ register int n;
+ int i;
+ int r;
+
+ r = 0;
+ for (;;)
+ {
+ /*
+ * this should work 99% of the time
+ */
+
+ if (!chdir(p))
+ return r;
+
+ /*
+ * chdir failed
+ */
+
+ if ((n = strlen(p)) < PATH_MAX)
+ return -1;
+#ifdef ENAMETOOLONG
+ if (errno != ENAMETOOLONG)
+ return -1;
+#endif
+
+ /*
+ * path is too long -- copy so it can be modified in place
+ */
+
+ i = stktell(stkstd);
+ sfputr(stkstd, p, 0);
+ stkseek(stkstd, i);
+ p = stkptr(stkstd, i);
+ for (;;)
+ {
+ /*
+ * get a short prefix component
+ */
+
+ s = p + PATH_MAX;
+ while (--s >= p && *s != '/');
+ if (s <= p)
+ break;
+
+ /*
+ * chdir to the prefix
+ */
+
+ *s++ = 0;
+ if (chdir(p))
+ break;
+
+ /*
+ * do the remainder
+ */
+
+ if ((n -= s - p) < PATH_MAX)
+ {
+ if (chdir(s))
+ break;
+ return r;
+ }
+ p = s;
+ }
+
+ /*
+ * try to recover back to home
+ */
+
+ if (!(p = (char*)home))
+ return -1;
+ home = 0;
+ r = -1;
+ }
+}
diff --git a/src/lib/libast/path/pathcheck.c b/src/lib/libast/path/pathcheck.c
new file mode 100644
index 0000000..4ff79f6
--- /dev/null
+++ b/src/lib/libast/path/pathcheck.c
@@ -0,0 +1,91 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * check if package+tool is ok to run
+ * a no-op here except for PARANOID packages
+ * this allows PARANOID_COMPANY to post PARANOID binaries to the www
+ *
+ * warn that the user should pay up if
+ *
+ * (1) the tool matches PARANOID
+ * (2) $_ is more than 90 days old
+ * (3) running on an PARANOID_PAY machine
+ * (4) (1)-(3) have not been defeated
+ *
+ * hows that
+ */
+
+#define PARANOID_TOOLS PARANOID
+#define PARANOID_COMPANY "Lucent Technologies"
+#define PARANOID_MAIL "stc@lucent.com"
+#define PARANOID_PAY "135.*&!(135.104.*)"
+#define PARANOID_FREE "(192|224).*"
+
+#include <ast.h>
+#include <ls.h>
+#include <error.h>
+#include <times.h>
+#include <ctype.h>
+
+int
+pathcheck(const char* package, const char* tool, Pathcheck_t* pc)
+{
+#ifdef PARANOID
+ register char* s;
+ struct stat st;
+
+ if (strmatch(tool, PARANOID) && environ && (s = *environ) && *s++ == '_' && *s++ == '=' && !stat(s, &st))
+ {
+ unsigned long n;
+ unsigned long o;
+ Sfio_t* sp;
+
+ n = time(NiL);
+ o = st.st_ctime;
+ if (n > o && (n - o) > (unsigned long)(60 * 60 * 24 * 90) && (sp = sfopen(NiL, "/etc/hosts", "r")))
+ {
+ /*
+ * this part is infallible
+ */
+
+ n = 0;
+ o = 0;
+ while (n++ < 64 && (s = sfgetr(sp, '\n', 0)))
+ if (strmatch(s, PARANOID_PAY))
+ {
+ error(1, "licensed for external use -- %s employees should contact %s for the internal license", PARANOID_COMPANY, PARANOID_MAIL);
+ break;
+ }
+ else if (*s != '#' && !isspace(*s) && !strneq(s, "127.", 4) && !strmatch(s, PARANOID_FREE) && o++ > 4)
+ break;
+ sfclose(sp);
+ }
+ }
+#else
+ NoP(tool);
+#endif
+ NoP(package);
+ if (pc) memzero(pc, sizeof(*pc));
+ return(0);
+}
diff --git a/src/lib/libast/path/pathexists.c b/src/lib/libast/path/pathexists.c
new file mode 100644
index 0000000..90b4ae7
--- /dev/null
+++ b/src/lib/libast/path/pathexists.c
@@ -0,0 +1,134 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return 1 if path exisis
+ * maintains a cache to minimize stat(2) calls
+ * path is modified in-place but restored on return
+ * path components checked in pairs to cut stat()'s
+ * in half by checking ENOTDIR vs. ENOENT
+ * case ignorance infection unavoidable here
+ */
+
+#include "lclib.h"
+
+#include <ls.h>
+#include <error.h>
+
+typedef struct Tree_s
+{
+ struct Tree_s* next;
+ struct Tree_s* tree;
+ int mode;
+ char name[1];
+} Tree_t;
+
+int
+pathexists(char* path, int mode)
+{
+ register char* s;
+ register char* e;
+ register Tree_t* p;
+ register Tree_t* t;
+ register int c;
+ char* ee;
+ int cc;
+ int x;
+ struct stat st;
+ int (*cmp)(const char*, const char*);
+
+ static Tree_t tree;
+
+ t = &tree;
+ e = (c = *path) == '/' ? path + 1 : path;
+ cmp = strchr(astconf("PATH_ATTRIBUTES", path, NiL), 'c') ? strcasecmp : strcmp;
+ if ((ast.locale.set & (AST_LC_debug|AST_LC_find)) == (AST_LC_debug|AST_LC_find))
+ sfprintf(sfstderr, "locale test %s\n", path);
+ while (c)
+ {
+ p = t;
+ for (s = e; *e && *e != '/'; e++);
+ c = *e;
+ *e = 0;
+ for (t = p->tree; t && (*cmp)(s, t->name); t = t->next);
+ if (!t)
+ {
+ if (!(t = newof(0, Tree_t, 1, strlen(s))))
+ {
+ *e = c;
+ return 0;
+ }
+ strcpy(t->name, s);
+ t->next = p->tree;
+ p->tree = t;
+ if (c)
+ {
+ *e = c;
+ for (s = ee = e + 1; *ee && *ee != '/'; ee++);
+ cc = *ee;
+ *ee = 0;
+ }
+ else
+ ee = 0;
+ if ((ast.locale.set & (AST_LC_debug|AST_LC_find)) == (AST_LC_debug|AST_LC_find))
+ sfprintf(sfstderr, "locale stat %s\n", path);
+ x = stat(path, &st);
+ if (ee)
+ {
+ e = ee;
+ c = cc;
+ if (!x || errno == ENOENT)
+ t->mode = PATH_READ|PATH_EXECUTE;
+ if (!(p = newof(0, Tree_t, 1, strlen(s))))
+ {
+ *e = c;
+ return 0;
+ }
+ strcpy(p->name, s);
+ p->next = t->tree;
+ t->tree = p;
+ t = p;
+ }
+ if (x)
+ {
+ *e = c;
+ return 0;
+ }
+ if (st.st_mode & (S_IRUSR|S_IRGRP|S_IROTH))
+ t->mode |= PATH_READ;
+ if (st.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))
+ t->mode |= PATH_WRITE;
+ if (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))
+ t->mode |= PATH_EXECUTE;
+ if (!S_ISDIR(st.st_mode))
+ t->mode |= PATH_REGULAR;
+ }
+ *e++ = c;
+ if (!t->mode || c && (t->mode & PATH_REGULAR))
+ return 0;
+ }
+ mode &= (PATH_READ|PATH_WRITE|PATH_EXECUTE|PATH_REGULAR);
+ return (t->mode & mode) == mode;
+}
diff --git a/src/lib/libast/path/pathfind.c b/src/lib/libast/path/pathfind.c
new file mode 100644
index 0000000..54dc140
--- /dev/null
+++ b/src/lib/libast/path/pathfind.c
@@ -0,0 +1,168 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * include style search support
+ */
+
+#include <ast.h>
+#include <error.h>
+#include <ls.h>
+
+#define directory(p,s) (stat((p),(s))>=0&&S_ISDIR((s)->st_mode))
+#define regular(p,s) (stat((p),(s))>=0&&(S_ISREG((s)->st_mode)||streq(p,"/dev/null")))
+
+typedef struct Dir_s /* directory list element */
+{
+ struct Dir_s* next; /* next in list */
+ char dir[1]; /* directory path */
+} Dir_t;
+
+static struct /* directory list state */
+{
+ Dir_t* head; /* directory list head */
+ Dir_t* tail; /* directory list tail */
+} state;
+
+/*
+ * append dir to pathfind() include list
+ */
+
+int
+pathinclude(const char* dir)
+{
+ register Dir_t* dp;
+ struct stat st;
+
+ if (dir && *dir && !streq(dir, ".") && directory(dir, &st))
+ {
+ for (dp = state.head; dp; dp = dp->next)
+ if (streq(dir, dp->dir))
+ return 0;
+ if (!(dp = oldof(0, Dir_t, 1, strlen(dir))))
+ return -1;
+ strcpy(dp->dir, dir);
+ dp->next = 0;
+ if (state.tail)
+ state.tail = state.tail->next = dp;
+ else
+ state.head = state.tail = dp;
+ }
+ return 0;
+}
+
+/*
+ * return path to name using pathinclude() list
+ * path placed in <buf,size>
+ * if lib!=0 then pathpath() attempted after include search
+ * if type!=0 and name has no '.' then file.type also attempted
+ * any *: prefix in lib is ignored (discipline library dictionary support)
+ */
+
+char*
+pathfind(const char* name, const char* lib, const char* type, char* buf, size_t size)
+{
+ register Dir_t* dp;
+ register char* s;
+ char tmp[PATH_MAX];
+ struct stat st;
+
+ if (((s = strrchr(name, '/')) || (s = (char*)name)) && strchr(s, '.'))
+ type = 0;
+
+ /*
+ * always check the unadorned path first
+ * this handles . and absolute paths
+ */
+
+ if (regular(name, &st))
+ {
+ strncopy(buf, name, size);
+ return buf;
+ }
+ if (type)
+ {
+ sfsprintf(buf, size, "%s.%s", name, type);
+ if (regular(buf, &st))
+ return buf;
+ }
+ if (*name == '/')
+ return 0;
+
+ /*
+ * check the directory of the including file
+ * on the assumption that error_info.file is properly stacked
+ */
+
+ if (error_info.file && (s = strrchr(error_info.file, '/')))
+ {
+ sfsprintf(buf, size, "%-.*s%s", s - error_info.file + 1, error_info.file, name);
+ if (regular(buf, &st))
+ return buf;
+ if (type)
+ {
+ sfsprintf(buf, size, "%-.*s%s%.s", s - error_info.file + 1, error_info.file, name, type);
+ if (regular(buf, &st))
+ return buf;
+ }
+ }
+
+ /*
+ * check the include dir list
+ */
+
+ for (dp = state.head; dp; dp = dp->next)
+ {
+ sfsprintf(tmp, sizeof(tmp), "%s/%s", dp->dir, name);
+ if (pathpath(tmp, "", PATH_REGULAR, buf, size))
+ return buf;
+ if (type)
+ {
+ sfsprintf(tmp, sizeof(tmp), "%s/%s.%s", dp->dir, name, type);
+ if (pathpath(tmp, "", PATH_REGULAR, buf, size))
+ return buf;
+ }
+ }
+
+ /*
+ * finally a lib related search on PATH
+ */
+
+ if (lib)
+ {
+ if (s = strrchr((char*)lib, ':'))
+ lib = (const char*)s + 1;
+ sfsprintf(tmp, sizeof(tmp), "lib/%s/%s", lib, name);
+ if (pathpath(tmp, "", PATH_REGULAR, buf, size))
+ return buf;
+ if (type)
+ {
+ sfsprintf(tmp, sizeof(tmp), "lib/%s/%s.%s", lib, name, type);
+ if (pathpath(tmp, "", PATH_REGULAR, buf, size))
+ return buf;
+ }
+ }
+ return 0;
+}
diff --git a/src/lib/libast/path/pathgetlink.c b/src/lib/libast/path/pathgetlink.c
new file mode 100644
index 0000000..0022594
--- /dev/null
+++ b/src/lib/libast/path/pathgetlink.c
@@ -0,0 +1,102 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+* Glenn Fowler
+* AT&T Bell Laboratories
+*/
+
+#include "univlib.h"
+
+#ifdef UNIV_MAX
+
+#include <ctype.h>
+
+#endif
+
+/*
+ * return external representation for symbolic link text of name in buf
+ * the link text string length is returned
+ */
+
+int
+pathgetlink(const char* name, char* buf, int siz)
+{
+ int n;
+
+ if ((n = readlink(name, buf, siz)) < 0) return(-1);
+ if (n >= siz)
+ {
+ errno = EINVAL;
+ return(-1);
+ }
+ buf[n] = 0;
+#ifdef UNIV_MAX
+ if (isspace(*buf))
+ {
+ register char* s;
+ register char* t;
+ register char* u;
+ register char* v;
+ int match = 0;
+ char tmp[PATH_MAX];
+
+ s = buf;
+ t = tmp;
+ while (isalnum(*++s) || *s == '_' || *s == '.');
+ if (*s++)
+ {
+ for (;;)
+ {
+ if (!*s || isspace(*s))
+ {
+ if (match)
+ {
+ *t = 0;
+ n = t - tmp;
+ strcpy(buf, tmp);
+ }
+ break;
+ }
+ if (t >= &tmp[sizeof(tmp)]) break;
+ *t++ = *s++;
+ if (!match && t < &tmp[sizeof(tmp) - univ_size + 1]) for (n = 0; n < UNIV_MAX; n++)
+ {
+ if (*(v = s - 1) == *(u = univ_name[n]))
+ {
+ while (*u && *v++ == *u) u++;
+ if (!*u)
+ {
+ match = 1;
+ strcpy(t - 1, univ_cond);
+ t += univ_size - 1;
+ s = v;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+#endif
+ return(n);
+}
diff --git a/src/lib/libast/path/pathkey.c b/src/lib/libast/path/pathkey.c
new file mode 100644
index 0000000..2432d83
--- /dev/null
+++ b/src/lib/libast/path/pathkey.c
@@ -0,0 +1,320 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * generate 14 char lookup key for lang path in key
+ * based on 32-bit checksum on path
+ *
+ * if key==0 then space is malloc'd
+ * if attr != 0 then attribute var assignments placed here:
+ * ATTRIBUTES list of attribute names
+ */
+
+#define _AST_API_H 1
+
+#include <ast.h>
+#include <ctype.h>
+#include <fs3d.h>
+#include <preroot.h>
+#include <ls.h>
+
+char*
+pathkey(char* key, char* attr, const char* lang, const char* tool, const char* path)
+{
+ return pathkey_20100601(lang, tool, path, key, 16, attr, PATH_MAX);
+}
+
+#undef _AST_API_H
+
+#include <ast_api.h>
+
+char*
+pathkey_20100601(const char* lang, const char* tool, const char* apath, char* key, size_t keysize, char* attr, size_t attrsize)
+{
+ register char* path = (char*)apath;
+ register char* s;
+ register char* k;
+ char* t;
+ char* flags;
+ char** p;
+ int c;
+ unsigned long n;
+ char buf[15];
+ char* usr[16];
+ char* env[elementsof(usr) + 3];
+ char* ver[2];
+ char tmp[PATH_MAX];
+#if _UWIN
+ struct stat st;
+#endif
+
+ static char let[] = "ABCDEFGHIJKLMNOP";
+
+ if (!key)
+ key = buf;
+ if (tool && streq(tool, "mam"))
+ {
+ for (n = 0; *path; path++)
+ n = n * 0x63c63cd9L + *path + 0x9c39c33dL;
+ k = key;
+ for (n &= 0xffffffffL; n; n >>= 4)
+ *k++ = let[n & 0xf];
+ *k = 0;
+ }
+ else
+ {
+ for (c = 0; c < elementsof(env); c++)
+ env[c] = 0;
+ n = 0;
+
+ /*
+ * trailing flags in path
+ */
+
+ if (flags = strchr(path, ' '))
+ {
+ if (flags == path)
+ flags = 0;
+ else
+ {
+ strlcpy(tmp, path, sizeof(tmp));
+ *(flags = tmp + (flags - path)) = 0;
+ path = tmp;
+ }
+ }
+
+ /*
+ * 3D
+ */
+
+ if (!flags && fs3d(FS3D_TEST) && (c = mount(path, tmp, FS3D_GET|FS3D_ALL|FS3D_SIZE(PATH_MAX), NiL)) > 1 && c < PATH_MAX)
+ path = tmp;
+
+ /*
+ * preroot
+ */
+
+ if (attr)
+ attr = strcopy(attr, "PREROOT='");
+#if FS_PREROOT
+ if (k = getenv(PR_BASE))
+ {
+ if (s = strrchr(k, '/'))
+ k = s + 1;
+ n = memsum(k, strlen(k), n);
+ }
+ if (attr && (getpreroot(attr, path) || getpreroot(attr, NiL)))
+ attr += strlen(attr);
+#else
+ if ((k = getenv("VIRTUAL_ROOT")) && *k == '/')
+ {
+ n = memsum(k, strlen(k), n);
+ if (attr)
+ attr = strcopy(attr, k);
+ }
+#endif
+#if _UWIN
+ if (!stat("/", &st) && st.st_ino == 64)
+ {
+ k = "/64";
+ n = memsum(k, strlen(k), n);
+ if (attr)
+ attr = strcopy(attr, k);
+ }
+#endif
+
+ /*
+ * universe
+ */
+
+ if (attr)
+ attr = strcopy(attr, "' UNIVERSE='");
+ if (k = astconf("UNIVERSE", NiL, NiL))
+ {
+ n = memsum(k, strlen(k), n);
+ if (attr)
+ attr = strcopy(attr, k);
+ }
+
+ /*
+ * environment
+ *
+ * ${PROBE_ATTRIBUTES} || ${VERSION_ENVIRONMENT} : list of alternate env vars
+ * ${VERSION_ENVIRONMENT} : list of alternate env vars
+ * ${VERSION_<lang>}
+ * ${VERSION_<base(path)>}
+ * ${<toupper(base(path))>VER}
+ * ${OBJTYPE}
+ */
+
+ if (attr)
+ *attr++ = '\'';
+ c = 0;
+ usr[c++] = "OBJTYPE";
+ if (!(k = getenv("PROBE_ATTRIBUTES")))
+ k = getenv("VERSION_ENVIRONMENT");
+ if (k)
+ while (c < (elementsof(usr) - 1))
+ {
+ while (*k && (*k == ':' || *k == ' '))
+ k++;
+ if (!*k)
+ break;
+ usr[c++] = k;
+ while (*k && *k != ':' && *k != ' ')
+ k++;
+ }
+ usr[c] = 0;
+ ver[0] = (char*)lang;
+ ver[1] = k = (s = strrchr(path, '/')) ? s + 1 : path;
+ s = buf;
+ if (isdigit(*k))
+ {
+ if (*k == '3' && *(k + 1) == 'b')
+ {
+ /*
+ * cuteness never pays
+ */
+
+ k += 2;
+ *s++ = 'B';
+ *s++ = 'B';
+ *s++ = 'B';
+ }
+ else
+ *s++ = 'U';
+ }
+ for (; (c = *k) && s < &buf[sizeof(buf) - 1]; k++)
+ {
+ if (!isalnum(c))
+ c = '_';
+ else if (islower(c))
+ c = toupper(c);
+ *s++ = c;
+ }
+ *s = 0;
+ for (p = environ; *p; p++)
+ {
+ s = "VERSION_";
+ for (k = *p; *k && *k == *s; k++, s++);
+ if (*k && !*s)
+ {
+ for (c = 0; c < elementsof(ver); c++)
+ if (!env[c] && (s = ver[c]))
+ {
+ for (t = k; *t && *t != '=' && *t++ == *s; s++);
+ if (*t == '=' && (!*s || (s - ver[c]) > 1))
+ {
+ env[c] = *p;
+ goto found;
+ }
+ }
+ }
+ if (!env[2])
+ {
+ s = buf;
+ for (k = *p; *k && *s++ == *k; k++);
+ if ((s - buf) > 2 && k[0] == 'V' && k[1] == 'E' && k[2] == 'R' && k[3] == '=')
+ {
+ env[2] = *p;
+ goto found;
+ }
+ }
+ for (c = 0; c < elementsof(usr) && (s = usr[c]); c++)
+ if (!env[c + elementsof(env) - elementsof(usr)])
+ {
+ for (k = *p; *k && *k == *s; k++, s++);
+ if (*k == '=' && (!*s || *s == ':' || *s == ' '))
+ {
+ env[c + elementsof(env) - elementsof(usr)] = *p;
+ goto found;
+ }
+ }
+ found: ;
+ }
+ for (c = 0; c < elementsof(env); c++)
+ if (k = env[c])
+ {
+ if (attr)
+ {
+ *attr++ = ' ';
+ while ((*attr++ = *k++) != '=');
+ *attr++ = '\'';
+ attr = strcopy(attr, k);
+ *attr++ = '\'';
+ }
+ else
+ while (*k && *k++ != '=');
+ n = memsum(k, strlen(k), n);
+ }
+ if (attr)
+ {
+ attr = strcopy(attr, " ATTRIBUTES='PREROOT UNIVERSE");
+ for (c = 0; c < elementsof(env); c++)
+ if (k = env[c])
+ {
+ *attr++ = ' ';
+ while ((*attr = *k++) != '=')
+ attr++;
+ }
+ *attr++ = '\'';
+ *attr = 0;
+ }
+
+ /*
+ * now the normal stuff
+ */
+
+ if (flags)
+ *flags = ' ';
+ s = path + strlen(path);
+ sfsprintf(key, 15, "%08lX", memsum(path, s - path, n));
+ k = key + 14;
+ *k = 0;
+ if (!flags)
+ t = path;
+ else if ((t = s - 4) < flags)
+ t = flags + 1;
+ for (;;)
+ {
+ if (--s < t)
+ {
+ if (t == path)
+ break;
+ s = flags - 2;
+ t = path;
+ }
+ if (*s != '/' && *s != ' ')
+ {
+ *--k = *s;
+ if (k <= key + 8)
+ break;
+ }
+ }
+ while (k > key + 8)
+ *--k = '.';
+ }
+ return key == buf ? strdup(key) : key;
+}
diff --git a/src/lib/libast/path/pathnative.c b/src/lib/libast/path/pathnative.c
new file mode 100644
index 0000000..c683d17
--- /dev/null
+++ b/src/lib/libast/path/pathnative.c
@@ -0,0 +1,126 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * convert path to native fs representation in <buf,siz>
+ * length of converted path returned
+ * if return length >= siz then buf is indeterminate, but another call
+ * with siz=length+1 would work
+ * if buf==0 then required size is returned
+ */
+
+#include <ast.h>
+
+#if _UWIN
+
+extern int uwin_path(const char*, char*, int);
+
+size_t
+pathnative(const char* path, char* buf, size_t siz)
+{
+ return uwin_path(path, buf, siz);
+}
+
+#else
+
+#if __CYGWIN__
+
+extern void cygwin_conv_to_win32_path(const char*, char*);
+
+size_t
+pathnative(const char* path, char* buf, size_t siz)
+{
+ size_t n;
+
+ if (!buf || siz < PATH_MAX)
+ {
+ char tmp[PATH_MAX];
+
+ cygwin_conv_to_win32_path(path, tmp);
+ if ((n = strlen(tmp)) < siz && buf)
+ memcpy(buf, tmp, n + 1);
+ return n;
+ }
+ cygwin_conv_to_win32_path(path, buf);
+ return strlen(buf);
+}
+
+#else
+
+#if __EMX__
+
+size_t
+pathnative(const char* path, char* buf, size_t siz)
+{
+ char* s;
+ size_t n;
+
+ if (!_fullpath(buf, path, siz))
+ {
+ for (s = buf; *s; s++)
+ if (*s == '/')
+ *s = '\\';
+ }
+ else if ((n = strlen(path)) < siz && buf)
+ memcpy(buf, path, n + 1);
+ return n;
+}
+
+#else
+
+#if __INTERIX
+
+#include <interix/interix.h>
+
+size_t
+pathnative(const char* path, char* buf, size_t siz)
+{
+ *buf = 0;
+ if (path[1] == ':')
+ strlcpy(buf, path, siz);
+ else
+ unixpath2win(path, 0, buf, siz);
+ return strlen(buf);
+}
+
+#else
+
+size_t
+pathnative(const char* path, char* buf, size_t siz)
+{
+ size_t n;
+
+ if ((n = strlen(path)) < siz && buf)
+ memcpy(buf, path, n + 1);
+ return n;
+}
+
+#endif
+
+#endif
+
+#endif
+
+#endif
diff --git a/src/lib/libast/path/pathpath.c b/src/lib/libast/path/pathpath.c
new file mode 100644
index 0000000..4c0831d
--- /dev/null
+++ b/src/lib/libast/path/pathpath.c
@@ -0,0 +1,127 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return full path to p with mode access using $PATH
+ * a!=0 enables related root search
+ * a!=0 && a!="" searches a dir first
+ * the related root must have a bin subdir
+ * p==0 sets the cached relative dir to a
+ * full path returned in path buffer
+ * if path==0 then the space is malloc'd
+ */
+
+#define _AST_API_H 1
+
+#include <ast.h>
+
+char*
+pathpath(char* path, const char* p, const char* a, int mode)
+{
+ return pathpath_20100601(p, a, mode, path, PATH_MAX);
+}
+
+#undef _AST_API_H
+
+#include <ast_api.h>
+
+char*
+pathpath_20100601(const char* p, const char* a, int mode, register char* path, size_t size)
+{
+ register char* s;
+ char* x;
+ char buf[PATH_MAX];
+
+ static char* cmd;
+
+ if (!path)
+ {
+ path = buf;
+ if (!size || size > sizeof(buf))
+ size = sizeof(buf);
+ }
+ if (!p)
+ {
+ if (cmd)
+ free(cmd);
+ cmd = a ? strdup(a) : (char*)0;
+ return 0;
+ }
+ if (strlen(p) < size)
+ {
+ strcpy(path, p);
+ if (pathexists(path, mode))
+ {
+ if (*p != '/' && (mode & PATH_ABSOLUTE))
+ {
+ getcwd(buf, sizeof(buf));
+ s = buf + strlen(buf);
+ sfsprintf(s, sizeof(buf) - (s - buf), "/%s", p);
+ if (path != buf)
+ strcpy(path, buf);
+ }
+ return (path == buf) ? strdup(path) : path;
+ }
+ }
+ if (*p == '/')
+ a = 0;
+ else if (s = (char*)a)
+ {
+ x = s;
+ if (strchr(p, '/'))
+ {
+ a = p;
+ p = "..";
+ }
+ else
+ a = 0;
+ if ((!cmd || *cmd) && (strchr(s, '/') || (s = cmd)))
+ {
+ if (!cmd && *s == '/')
+ cmd = strdup(s);
+ if (strlen(s) < (sizeof(buf) - 6))
+ {
+ s = strcopy(path, s);
+ for (;;)
+ {
+ do if (s <= path) goto normal; while (*--s == '/');
+ do if (s <= path) goto normal; while (*--s != '/');
+ strcpy(s + 1, "bin");
+ if (pathexists(path, PATH_EXECUTE))
+ {
+ if (s = pathaccess(path, p, a, mode, path, size))
+ return path == buf ? strdup(s) : s;
+ goto normal;
+ }
+ }
+ normal: ;
+ }
+ }
+ }
+ x = !a && strchr(p, '/') ? "" : pathbin();
+ if (!(s = pathaccess(x, p, a, mode, path, size)) && !*x && (x = getenv("FPATH")))
+ s = pathaccess(x, p, a, mode, path, size);
+ return (s && path == buf) ? strdup(s) : s;
+}
diff --git a/src/lib/libast/path/pathposix.c b/src/lib/libast/path/pathposix.c
new file mode 100644
index 0000000..d220591
--- /dev/null
+++ b/src/lib/libast/path/pathposix.c
@@ -0,0 +1,128 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * convert native path to posix fs representation in <buf,siz>
+ * length of converted path returned
+ * if return length >= siz then buf is indeterminate, but another call
+ * with siz=length+1 would work
+ * if buf==0 then required size is returned
+ */
+
+#include <ast.h>
+
+#if _UWIN
+
+#include <uwin.h>
+
+size_t
+pathposix(const char* path, char* buf, size_t siz)
+{
+ return uwin_unpath(path, buf, siz);
+}
+
+#else
+
+#if __CYGWIN__
+
+extern void cygwin_conv_to_posix_path(const char*, char*);
+
+size_t
+pathposix(const char* path, char* buf, size_t siz)
+{
+ size_t n;
+
+ if (!buf || siz < PATH_MAX)
+ {
+ char tmp[PATH_MAX];
+
+ cygwin_conv_to_posix_path(path, tmp);
+ if ((n = strlen(tmp)) < siz && buf)
+ memcpy(buf, tmp, n + 1);
+ return n;
+ }
+ cygwin_conv_to_posix_path(path, buf);
+ return strlen(buf);
+}
+
+#else
+
+#if __EMX__ && 0 /* show me the docs */
+
+size_t
+pathposix(const char* path, char* buf, size_t siz)
+{
+ char* s;
+ size_t n;
+
+ if (!_posixpath(buf, path, siz))
+ {
+ for (s = buf; *s; s++)
+ if (*s == '/')
+ *s = '\\';
+ }
+ else if ((n = strlen(path)) < siz && buf)
+ memcpy(buf, path, n + 1);
+ return n;
+}
+
+#else
+
+#if __INTERIX
+
+#include <interix/interix.h>
+
+size_t
+pathposix(const char* path, char *buf, size_t siz)
+{
+ static const char pfx[] = "/dev/fs";
+
+ *buf = 0;
+ if (!strncasecmp(path, pfx, sizeof(pfx) - 1))
+ strlcpy(buf, path, siz);
+ else
+ winpath2unix(path, PATH_NONSTRICT, buf, siz);
+ return strlen(buf);
+}
+
+#else
+
+size_t
+pathposix(const char* path, char* buf, size_t siz)
+{
+ size_t n;
+
+ if ((n = strlen(path)) < siz && buf)
+ memcpy(buf, path, n + 1);
+ return n;
+}
+
+#endif
+
+#endif
+
+#endif
+
+#endif
diff --git a/src/lib/libast/path/pathprobe.c b/src/lib/libast/path/pathprobe.c
new file mode 100644
index 0000000..26d1fe3
--- /dev/null
+++ b/src/lib/libast/path/pathprobe.c
@@ -0,0 +1,316 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return in path the full path name of the probe(1)
+ * information for lang and tool using proc
+ * if attr != 0 then path attribute assignments placed here
+ *
+ * if path==0 then the space is malloc'd
+ *
+ * op:
+ *
+ * -3 return non-writable path name with no generation
+ * -2 return path name with no generation
+ * -1 return no $HOME path name with no generation
+ * 0 verbose probe
+ * 1 silent probe
+ *
+ * 0 returned if the info does not exist and cannot be generated
+ */
+
+#define _AST_API_H 1
+
+#include <ast.h>
+#include <error.h>
+#include <ls.h>
+#include <proc.h>
+
+char*
+pathprobe(char* path, char* attr, const char* lang, const char* tool, const char* proc, int op)
+{
+ return pathprobe_20100601(lang, tool, proc, op, path, PATH_MAX, attr, PATH_MAX);
+}
+
+#undef _AST_API_H
+
+#include <ast_api.h>
+
+#ifndef PROBE
+#define PROBE "probe"
+#endif
+
+#if defined(ST_RDONLY) || defined(ST_NOSUID)
+
+/*
+ * return non-0 if path is in a readonly or non-setuid fs
+ */
+
+static int
+rofs(const char* path)
+{
+ struct statvfs vfs;
+ struct stat st;
+
+ if (!statvfs(path, &vfs))
+ {
+#if defined(ST_RDONLY)
+ if (vfs.f_flag & ST_RDONLY)
+ return 1;
+#endif
+#if defined(ST_NOSUID)
+ if ((vfs.f_flag & ST_NOSUID) && (stat(path, &st) || st.st_uid != getuid() && st.st_uid != geteuid()))
+ return 1;
+#endif
+ }
+ return 0;
+}
+
+#else
+
+#define rofs(p) 0
+
+#endif
+
+char*
+pathprobe_20100601(const char* lang, const char* tool, const char* aproc, int op, char* path, size_t pathsize, char* attr, size_t attrsize)
+{
+ char* proc = (char*)aproc;
+ register char* p;
+ register char* k;
+ register char* x;
+ register char** ap;
+ int n;
+ int v;
+ int force;
+ ssize_t r;
+ char* e;
+ char* np;
+ char* nx;
+ char* probe;
+ const char* dirs;
+ const char* dir;
+ Proc_t* pp;
+ Sfio_t* sp;
+ char buf[PATH_MAX];
+ char cmd[PATH_MAX];
+ char exe[PATH_MAX];
+ char lib[PATH_MAX];
+ char ver[PATH_MAX];
+ char key[16];
+ char* arg[8];
+ long ops[2];
+ unsigned long ptime;
+ struct stat st;
+ struct stat ps;
+
+ if (*proc != '/')
+ {
+ if (p = strchr(proc, ' '))
+ {
+ strncopy(buf, proc, p - proc + 1);
+ proc = buf;
+ }
+ if (!(proc = pathpath(proc, NiL, PATH_ABSOLUTE|PATH_REGULAR|PATH_EXECUTE, cmd, sizeof(cmd))))
+ proc = (char*)aproc;
+ else if (p)
+ {
+ n = strlen(proc);
+ strncopy(proc + n, p, PATH_MAX - n - 1);
+ }
+ }
+ if (!path)
+ {
+ path = buf;
+ pathsize = sizeof(buf);
+ }
+ probe = PROBE;
+ x = lib + sizeof(lib) - 1;
+ k = lib + sfsprintf(lib, x - lib, "lib/%s/", probe);
+ p = k + sfsprintf(k, x - k, "%s/%s/", lang, tool);
+ pathkey(lang, tool, proc, key, sizeof(key), attr, attrsize);
+ if (op >= -2)
+ {
+ strncopy(p, key, x - p);
+ if (pathpath(lib, "", PATH_ABSOLUTE, path, pathsize) && !stat(path, &st) && (st.st_mode & S_IWUSR))
+ return path == buf ? strdup(path) : path;
+ }
+ e = strncopy(p, probe, x - p);
+ if (!pathpath(lib, "", PATH_ABSOLUTE|PATH_EXECUTE, path, pathsize) || stat(path, &ps))
+ return 0;
+ for (;;)
+ {
+ ptime = ps.st_mtime;
+ n = strlen(path);
+ if (n < (PATH_MAX - 5))
+ {
+ strcpy(path + n, ".ini");
+ if (!stat(path, &st) && st.st_size && ptime < (unsigned long)st.st_mtime)
+ ptime = st.st_mtime;
+ path[n] = 0;
+ }
+ np = path + n - (e - k);
+ nx = path + PATH_MAX - 1;
+ strncopy(np, probe, nx - np);
+ if (!stat(path, &st))
+ break;
+
+ /*
+ * yes lib/probe/<lang>/<proc>/probe
+ * no lib/probe/probe
+ *
+ * do a manual pathaccess() to find a dir with both
+ */
+
+ sfsprintf(exe, sizeof(exe), "lib/%s/%s", probe, probe);
+ dirs = pathbin();
+ for (;;)
+ {
+ if (!(dir = dirs))
+ return 0;
+ dirs = pathcat(dir, ':', "..", exe, path, pathsize);
+ pathcanon(path, pathsize, 0);
+ if (*path == '/' && pathexists(path, PATH_REGULAR|PATH_EXECUTE))
+ {
+ pathcat(dir, ':', "..", lib, path, pathsize);
+ pathcanon(path, pathsize, 0);
+ if (*path == '/' && pathexists(path, PATH_REGULAR|PATH_EXECUTE) && !stat(path, &ps))
+ break;
+ }
+ }
+ }
+ strncopy(p, key, x - p);
+ p = np;
+ x = nx;
+ strcpy(exe, path);
+ if (op >= -1 && (!(st.st_mode & S_ISUID) && ps.st_uid != geteuid() || rofs(path)))
+ {
+ if (!(p = getenv("HOME")))
+ return 0;
+ p = path + sfsprintf(path, PATH_MAX - 1, "%s/.%s/%s/", p, probe, HOSTTYPE);
+ }
+ strncopy(p, k, x - p);
+ force = 0;
+ if (op >= 0 && !stat(path, &st))
+ {
+ if (ptime <= (unsigned long)st.st_mtime || ptime <= (unsigned long)st.st_ctime)
+ {
+ /*
+ * verify (<sep><name><sep><option><sep><value>)* header
+ */
+
+ if (sp = sfopen(NiL, path, "r"))
+ {
+ if (x = sfgetr(sp, '\n', 1))
+ {
+ while (*x && *x != ' ')
+ x++;
+ while (*x == ' ')
+ x++;
+ if (n = *x++)
+ for (;;)
+ {
+ for (k = x; *x && *x != n; x++);
+ if (!*x)
+ break;
+ *x++ = 0;
+ for (p = x; *x && *x != n; x++);
+ if (!*x)
+ break;
+ *x++ = 0;
+ for (e = x; *x && *x != n; x++);
+ if (!*x)
+ break;
+ *x++ = 0;
+ if (streq(k, "VERSION"))
+ {
+ ap = arg;
+ *ap++ = proc;
+ *ap++ = p;
+ *ap = 0;
+ ops[0] = PROC_FD_DUP(1, 2, 0);
+ ops[1] = 0;
+ if (pp = procopen(proc, arg, NiL, ops, PROC_READ))
+ {
+ if ((v = x - e) >= sizeof(ver))
+ v = sizeof(ver) - 1;
+ for (k = p = ver;; k++)
+ {
+ if (k >= p)
+ {
+ if (v <= 0 || (r = read(pp->rfd, k, v)) <= 0)
+ break;
+ v -= r;
+ p = k + r;
+ }
+ if (*k == '\n' || *k == '\r')
+ break;
+ if (*k == n)
+ *k = ' ';
+ }
+ *k = 0;
+ if (strcmp(ver, e))
+ {
+ force = 1;
+ error(0, "probe processor %s version \"%s\" changed -- expected \"%s\"", proc, ver, e);
+ }
+ procclose(pp);
+ }
+ break;
+ }
+ }
+ }
+ sfclose(sp);
+ }
+ if (!force)
+ op = -1;
+ }
+ if (op >= 0 && (st.st_mode & S_IWUSR))
+ {
+ if (op == 0)
+ error(0, "%s probe information for %s language processor %s must be manually regenerated", tool, lang, proc);
+ op = -1;
+ force = 0;
+ }
+ }
+ if (op >= 0)
+ {
+ ap = arg;
+ *ap++ = exe;
+ if (force)
+ *ap++ = "-f";
+ if (op > 0)
+ *ap++ = "-s";
+ *ap++ = (char*)lang;
+ *ap++ = (char*)tool;
+ *ap++ = proc;
+ *ap = 0;
+ if (procrun(exe, arg, 0))
+ return 0;
+ if (eaccess(path, R_OK))
+ return 0;
+ }
+ return path == buf ? strdup(path) : path;
+}
diff --git a/src/lib/libast/path/pathprog.c b/src/lib/libast/path/pathprog.c
new file mode 100644
index 0000000..ac29427
--- /dev/null
+++ b/src/lib/libast/path/pathprog.c
@@ -0,0 +1,128 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return the full path of the current program in path
+ * command!=0 is used as a default
+ */
+
+#include <ast.h>
+
+#if _WINIX
+#include <ast_windows.h>
+#include <ctype.h>
+#endif
+
+#include "FEATURE/prog"
+
+#if _hdr_macho_o_dyld && _lib__NSGetExecutablePath
+#include <mach-o/dyld.h>
+#else
+#undef _lib__NSGetExecutablePath
+#endif
+
+static size_t
+prog(const char* command, char* path, size_t size)
+{
+ ssize_t n;
+ char* s;
+#if _WINIX
+ char* t;
+ char* e;
+ int c;
+ int q;
+#endif
+#if _lib__NSGetExecutablePath
+ uint32_t z;
+#endif
+
+#ifdef _PROC_PROG
+ if ((n = readlink(_PROC_PROG, path, size)) > 0 && *path == '/')
+ {
+ if (n < size)
+ path[n] = 0;
+ return n;
+ }
+#endif
+#if _lib_getexecname
+ if ((s = (char*)getexecname()) && *s == '/')
+ goto found;
+#endif
+#if _lib__NSGetExecutablePath
+ z = size;
+ if (!_NSGetExecutablePath(path, &z) && *s == '/')
+ return strlen(s);
+#endif
+#if _WINIX
+ if (s = GetCommandLine())
+ {
+ n = 0;
+ q = 0;
+ t = path;
+ e = path + size - 1;
+ while (c = *s++)
+ {
+ if (c == q)
+ q = 0;
+ else if (!q && c == '"')
+ q = c;
+ else if (!q && isspace(c))
+ break;
+ else if (t < e)
+ *t++ = c == '\\' ? '/' : c;
+ else
+ n++;
+ }
+ if (t < e)
+ *t = 0;
+ return (t - path) + n;
+ }
+#endif
+ if (command)
+ {
+ s = (char*)command;
+ goto found;
+ }
+ return 0;
+ found:
+ n = strlen(s);
+ if (n < size)
+ memcpy(path, s, n + 1);
+ return n;
+}
+
+size_t
+pathprog(const char* command, char* path, size_t size)
+{
+ char* rel;
+ ssize_t n;
+
+ if ((n = prog(command, path, size)) > 0 && n < size && *path != '/' && (rel = strdup(path)))
+ {
+ n = pathpath(rel, NiL, PATH_REGULAR|PATH_EXECUTE, path, size) ? strlen(path) : 0;
+ free(rel);
+ }
+ return n;
+}
diff --git a/src/lib/libast/path/pathrepl.c b/src/lib/libast/path/pathrepl.c
new file mode 100644
index 0000000..d16a390
--- /dev/null
+++ b/src/lib/libast/path/pathrepl.c
@@ -0,0 +1,93 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * in place replace of first occurrence of /match/ with /replace/ in path
+ * end of path returned
+ */
+
+#define _AST_API_H 1
+
+#include <ast.h>
+
+char*
+pathrepl(char* path, const char* match, const char* replace)
+{
+ return pathrepl_20100601(path, PATH_MAX, match, replace);
+}
+
+#undef _AST_API_H
+
+#include <ast_api.h>
+
+char*
+pathrepl_20100601(register char* path, size_t size, const char* match, register const char* replace)
+{
+ register const char* m = match;
+ register const char* r;
+ char* t;
+
+ if (!match)
+ match = "";
+ if (!replace)
+ replace = "";
+ if (streq(match, replace))
+ return(path + strlen(path));
+ if (!size)
+ size = strlen(path) + 1;
+ for (;;)
+ {
+ while (*path && *path++ != '/');
+ if (!*path) break;
+ if (*path == *m)
+ {
+ t = path;
+ while (*m && *m++ == *path) path++;
+ if (!*m && *path == '/')
+ {
+ register char* p;
+
+ p = t;
+ r = replace;
+ while (p < path && *r) *p++ = *r++;
+ if (p < path) while (*p++ = *path++);
+ else if (*r && p >= path)
+ {
+ register char* u;
+
+ t = path + strlen(path);
+ u = t + strlen(r);
+ while (t >= path) *u-- = *t--;
+ while (*r) *p++ = *r++;
+ }
+ else p += strlen(p) + 1;
+ return(p - 1);
+ }
+ path = t;
+ m = match;
+ }
+ }
+ return(path);
+}
diff --git a/src/lib/libast/path/pathsetlink.c b/src/lib/libast/path/pathsetlink.c
new file mode 100644
index 0000000..48aa4fe
--- /dev/null
+++ b/src/lib/libast/path/pathsetlink.c
@@ -0,0 +1,72 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+* Glenn Fowler
+* AT&T Bell Laboratories
+*/
+
+#include "univlib.h"
+
+/*
+ * create symbolic name from external representation text in buf
+ * the arg order matches link(2)
+ */
+
+int
+pathsetlink(const char* buf, const char* name)
+{
+ register char* t = (char*)buf;
+#ifdef UNIV_MAX
+ register char* s = (char*)buf;
+ register char* v;
+ int n;
+ char tmp[PATH_MAX];
+
+ while (*s)
+ {
+ if (*s++ == univ_cond[0] && !strncmp(s - 1, univ_cond, univ_size))
+ {
+ s--;
+ t = tmp;
+ for (n = 0; n < UNIV_MAX; n++)
+ if (*univ_name[n])
+ {
+ *t++ = ' ';
+#ifdef ATT_UNIV
+ *t++ = '1' + n;
+ *t++ = ':';
+#else
+ for (v = univ_name[n]; *t = *v++; t++);
+ *t++ = '%';
+#endif
+ for (v = (char*)buf; v < s; *t++ = *v++);
+ for (v = univ_name[n]; *t = *v++; t++);
+ for (v = s + univ_size; *t = *v++; t++);
+ }
+ t = tmp;
+ break;
+ }
+ }
+#endif
+ return(symlink(t, name));
+}
diff --git a/src/lib/libast/path/pathshell.c b/src/lib/libast/path/pathshell.c
new file mode 100644
index 0000000..f4b2557
--- /dev/null
+++ b/src/lib/libast/path/pathshell.c
@@ -0,0 +1,112 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * G. S. Fowler
+ * D. G. Korn
+ * AT&T Bell Laboratories
+ *
+ * shell library support
+ */
+
+#include <ast.h>
+#include <sys/stat.h>
+
+/*
+ * return pointer to the full path name of the shell
+ *
+ * SHELL is read from the environment and must start with /
+ *
+ * if set-uid or set-gid then the executable and its containing
+ * directory must not be owned by the real user/group
+ *
+ * root/administrator has its own test
+ *
+ * astconf("SH",NiL,NiL) is returned by default
+ *
+ * NOTE: csh is rejected because the bsh/csh differentiation is
+ * not done for `csh script arg ...'
+ */
+
+char*
+pathshell(void)
+{
+ register char* sh;
+ int ru;
+ int eu;
+ int rg;
+ int eg;
+ struct stat st;
+
+ static char* val;
+
+ if ((sh = getenv("SHELL")) && *sh == '/' && strmatch(sh, "*/(sh|*[!cC]sh)*([[:digit:]])?(-+([.[:alnum:]]))?(.exe)"))
+ {
+ if (!(ru = getuid()) || !eaccess("/bin", W_OK))
+ {
+ if (stat(sh, &st))
+ goto defshell;
+ if (ru != st.st_uid && !strmatch(sh, "?(/usr)?(/local)/?([ls])bin/?([[:lower:]])sh?(.exe)"))
+ goto defshell;
+ }
+ else
+ {
+ eu = geteuid();
+ rg = getgid();
+ eg = getegid();
+ if (ru != eu || rg != eg)
+ {
+ char* s;
+ char dir[PATH_MAX];
+
+ s = sh;
+ for (;;)
+ {
+ if (stat(s, &st))
+ goto defshell;
+ if (ru != eu && st.st_uid == ru)
+ goto defshell;
+ if (rg != eg && st.st_gid == rg)
+ goto defshell;
+ if (s != sh)
+ break;
+ if (strlen(s) >= sizeof(dir))
+ goto defshell;
+ strcpy(dir, s);
+ if (!(s = strrchr(dir, '/')))
+ break;
+ *s = 0;
+ s = dir;
+ }
+ }
+ }
+ return sh;
+ }
+ defshell:
+ if (!(sh = val))
+ {
+ if (!*(sh = astconf("SH", NiL, NiL)) || *sh != '/' || eaccess(sh, X_OK) || !(sh = strdup(sh)))
+ sh = "/bin/sh";
+ val = sh;
+ }
+ return sh;
+}
diff --git a/src/lib/libast/path/pathstat.c b/src/lib/libast/path/pathstat.c
new file mode 100644
index 0000000..6d414ca
--- /dev/null
+++ b/src/lib/libast/path/pathstat.c
@@ -0,0 +1,45 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+#include <ls.h>
+#include <error.h>
+
+/*
+ * physical stat if logical fails
+ */
+
+int
+pathstat(const char* path, struct stat* st)
+{
+#if _lib_lstat
+ int oerrno;
+
+ oerrno = errno;
+ if (!stat(path, st)) return(0);
+ errno = oerrno;
+ return(lstat(path, st));
+#else
+ return(stat(path, st));
+#endif
+}
diff --git a/src/lib/libast/path/pathtemp.c b/src/lib/libast/path/pathtemp.c
new file mode 100644
index 0000000..844c86a
--- /dev/null
+++ b/src/lib/libast/path/pathtemp.c
@@ -0,0 +1,337 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Research
+ *
+ * generate a temp file / name
+ *
+ * [<dir>/][<pfx>]<bas>.<suf>
+ *
+ * length(<pfx>)<=5
+ * length(<bas>)==3
+ * length(<suf>)==3
+ *
+ * pathtmp(a,b,c,d) pathtemp(a,L_tmpnam,b,c,0)
+ * tmpfile() char*p=pathtemp(0,0,0,"tf",&sp);
+ * remove(p);
+ * free(p)
+ * tmpnam(0) static char p[L_tmpnam];
+ * pathtemp(p,sizeof(p),0,"tn",0)
+ * tmpnam(p) pathtemp(p,L_tmpnam,0,"tn",0)
+ * tempnam(d,p) pathtemp(0,d,p,0)
+ * mktemp(p) pathtemp(0,0,p,0)
+ *
+ * if buf==0 then space is malloc'd
+ * buf size is size
+ * dir and pfx may be 0
+ * if pfx contains trailing X's then it is a mktemp(3) template
+ * otherwise only first 5 chars of pfx are used
+ * if fdp!=0 then the path is opened O_EXCL and *fdp is the open fd
+ * malloc'd space returned by successful pathtemp() calls
+ * must be freed by the caller
+ *
+ * generated names are pseudo-randomized to avoid both
+ * collisions and predictions (same alg in sfio/sftmp.c)
+ *
+ * / as first pfx char provides tmp file generation control
+ * 0 returned for unknown ops
+ *
+ * /cycle dir specifies TMPPATH cycle control
+ * automatic (default) cycled with each tmp file
+ * manual cycled by application with dir=(nil)
+ * (nil) cycle TMPPATH
+ * /prefix dir specifies the default prefix (default ast)
+ * /private private file/dir modes
+ * /public public file/dir modes
+ * /seed dir specifies pseudo-random generator seed
+ * 0 or "0" to re-initialize
+ * /TMPPATH dir overrides the env value
+ * /TMPDIR dir overrides the env value
+ */
+
+#include <ast.h>
+#include <ls.h>
+#include <tv.h>
+#include <tm.h>
+
+#define ATTEMPT 10
+
+#define TMP_ENV "TMPDIR"
+#define TMP_PATH_ENV "TMPPATH"
+#define TMP1 "/tmp"
+#define TMP2 "/usr/tmp"
+
+#define VALID(d) (*(d)&&!eaccess(d,W_OK|X_OK))
+
+static struct
+{
+ mode_t mode;
+ char** vec;
+ char** dir;
+ uint32_t key;
+ uint32_t rng;
+ pid_t pid;
+ int manual;
+ int seed;
+ char* pfx;
+ char* tmpdir;
+ char* tmppath;
+} tmp = { S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH };
+
+char*
+pathtemp(char* buf, size_t len, const char* dir, const char* pfx, int* fdp)
+{
+ register char* d;
+ register char* b;
+ register char* s;
+ register char* x;
+ uint32_t key;
+ int m;
+ int n;
+ int l;
+ int r;
+ int z;
+ int attempt;
+ Tv_t tv;
+ char keybuf[16];
+
+ if (pfx && *pfx == '/')
+ {
+ pfx++;
+ if (streq(pfx, "cycle"))
+ {
+ if (!dir)
+ {
+ tmp.manual = 1;
+ if (tmp.dir && !*tmp.dir++)
+ tmp.dir = tmp.vec;
+ }
+ else
+ tmp.manual = streq(dir, "manual");
+ return (char*)pfx;
+ }
+ else if (streq(pfx, "prefix"))
+ {
+ if (tmp.pfx)
+ free(tmp.pfx);
+ tmp.pfx = dir ? strdup(dir) : (char*)0;
+ return (char*)pfx;
+ }
+ else if (streq(pfx, "private"))
+ {
+ tmp.mode = S_IRUSR|S_IWUSR;
+ return (char*)pfx;
+ }
+ else if (streq(pfx, "public"))
+ {
+ tmp.mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
+ return (char*)pfx;
+ }
+ else if (streq(pfx, "seed"))
+ {
+ tmp.key = (tmp.seed = (tmp.rng = dir ? (uint32_t)strtoul(dir, NiL, 0) : (uint32_t)1) != 0)? (uint32_t)0x63c63cd9L : 0;
+ return (char*)pfx;
+ }
+ else if (streq(pfx, TMP_ENV))
+ {
+ if (tmp.vec)
+ {
+ free(tmp.vec);
+ tmp.vec = 0;
+ }
+ if (tmp.tmpdir)
+ free(tmp.tmpdir);
+ tmp.tmpdir = dir ? strdup(dir) : (char*)0;
+ return (char*)pfx;
+ }
+ else if (streq(pfx, TMP_PATH_ENV))
+ {
+ if (tmp.vec)
+ {
+ free(tmp.vec);
+ tmp.vec = 0;
+ }
+ if (tmp.tmppath)
+ free(tmp.tmppath);
+ tmp.tmppath = dir ? strdup(dir) : (char*)0;
+ return (char*)pfx;
+ }
+ return 0;
+ }
+ if (tmp.seed)
+ tv.tv_nsec = 0;
+ else
+ tvgettime(&tv);
+ if (!(d = (char*)dir) || *d && eaccess(d, W_OK|X_OK))
+ {
+ if (!tmp.vec)
+ {
+ if ((x = tmp.tmppath) || (x = getenv(TMP_PATH_ENV)))
+ {
+ n = 2;
+ s = x;
+ while (s = strchr(s, ':'))
+ {
+ s++;
+ n++;
+ }
+ if (!(tmp.vec = newof(0, char*, n, strlen(x) + 1)))
+ return 0;
+ tmp.dir = tmp.vec;
+ x = strcpy((char*)(tmp.dir + n), x);
+ *tmp.dir++ = x;
+ while (x = strchr(x, ':'))
+ {
+ *x++ = 0;
+ if (!VALID(*(tmp.dir - 1)))
+ tmp.dir--;
+ *tmp.dir++ = x;
+ }
+ if (!VALID(*(tmp.dir - 1)))
+ tmp.dir--;
+ *tmp.dir = 0;
+ }
+ else
+ {
+ if (((d = tmp.tmpdir) || (d = getenv(TMP_ENV))) && !VALID(d))
+ d = 0;
+ if (!(tmp.vec = newof(0, char*, 2, d ? (strlen(d) + 1) : 0)))
+ return 0;
+ if (d)
+ *tmp.vec = strcpy((char*)(tmp.vec + 2), d);
+ }
+ tmp.dir = tmp.vec;
+ }
+ if (!(d = *tmp.dir++))
+ {
+ tmp.dir = tmp.vec;
+ d = *tmp.dir++;
+ }
+ if (!d && (!*(d = astconf("TMP", NiL, NiL)) || eaccess(d, W_OK|X_OK)) && eaccess(d = TMP1, W_OK|X_OK) && eaccess(d = TMP2, W_OK|X_OK))
+ return 0;
+ }
+ if (!len)
+ len = PATH_MAX;
+ len--;
+ if (!(b = buf) && !(b = newof(0, char, len, 1)))
+ return 0;
+ z = 0;
+ if (!pfx && !(pfx = tmp.pfx))
+ pfx = "ast";
+ m = strlen(pfx);
+ if (buf && dir && (buf == (char*)dir && (buf + strlen(buf) + 1) == (char*)pfx || buf == (char*)pfx && !*dir) && !strcmp((char*)pfx + m + 1, "XXXXX"))
+ {
+ d = (char*)dir;
+ len = m += strlen(d) + 8;
+ l = 3;
+ r = 3;
+ }
+ else if (*pfx && pfx[m - 1] == 'X')
+ {
+ for (l = m; l && pfx[l - 1] == 'X'; l--);
+ r = m - l;
+ m = l;
+ l = r / 2;
+ r -= l;
+ }
+ else if (strchr(pfx, '.'))
+ {
+ m = 5;
+ l = 3;
+ r = 3;
+ }
+ else
+ {
+ z = '.';
+ m = 5;
+ l = 2;
+ r = 3;
+ }
+ x = b + len;
+ s = b;
+ if (d)
+ {
+ while (s < x && (n = *d++))
+ *s++ = n;
+ if (s < x && s > b && *(s - 1) != '/')
+ *s++ = '/';
+ }
+ if ((x - s) > m)
+ x = s + m;
+ while (s < x && (n = *pfx++))
+ {
+ if (n == '/' || n == '\\' || n == z)
+ n = '_';
+ *s++ = n;
+ }
+ *s = 0;
+ len -= (s - b);
+ for (attempt = 0; attempt < ATTEMPT; attempt++)
+ {
+ if (!tmp.rng || !tmp.seed && (attempt || tmp.pid != getpid()))
+ {
+ register int r;
+
+ /*
+ * get a quasi-random coefficient
+ */
+
+ tmp.pid = getpid();
+ tmp.rng = (uint32_t)tmp.pid * ((uint32_t)time(NiL) ^ (((uint32_t)integralof(&attempt)) >> 3) ^ (((uint32_t)integralof(tmp.dir)) >> 3));
+ if (!tmp.key)
+ tmp.key = (tmp.rng >> 16) | ((tmp.rng & 0xffff) << 16);
+ tmp.rng ^= tmp.key;
+
+ /*
+ * Knuth vol.2, page.16, Thm.A
+ */
+
+ if ((r = (tmp.rng - 1) & 03))
+ tmp.rng += 4 - r;
+ }
+
+ /*
+ * generate a pseudo-random name
+ */
+
+ key = tmp.rng * tmp.key + tv.tv_nsec;
+ if (!tmp.seed)
+ tvgettime(&tv);
+ tmp.key = tmp.rng * key + tv.tv_nsec;
+ sfsprintf(keybuf, sizeof(keybuf), "%07.7.32I*u%07.7.32I*u", sizeof(key), key, sizeof(tmp.key), tmp.key);
+ sfsprintf(s, len, "%-.*s%s%-.*s", l, keybuf, z ? "." : "", r, keybuf + sizeof(keybuf) / 2);
+ if (fdp)
+ {
+ if ((n = open(b, O_CREAT|O_RDWR|O_EXCL|O_TEMPORARY, tmp.mode)) >= 0)
+ {
+ *fdp = n;
+ return b;
+ }
+ }
+ else if (access(b, F_OK))
+ return b;
+ }
+ if (!buf)
+ free(b);
+ return 0;
+}
diff --git a/src/lib/libast/path/pathtmp.c b/src/lib/libast/path/pathtmp.c
new file mode 100644
index 0000000..aac0243
--- /dev/null
+++ b/src/lib/libast/path/pathtmp.c
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * obsolete -- use pathtemp()
+ */
+
+#include <ast.h>
+#include <stdio.h>
+
+#ifndef L_tmpnam
+#define L_tmpnam 25
+#endif
+
+char*
+pathtmp(char* buf, const char* dir, const char* pfx, int* fdp)
+{
+ size_t len;
+
+ len = !buf ? 0 : !dir ? L_tmpnam : (strlen(dir) + 14);
+ return pathtemp(buf, len, dir, pfx, fdp);
+}
diff --git a/src/lib/libast/port/astconf.c b/src/lib/libast/port/astconf.c
new file mode 100644
index 0000000..ee199fa
--- /dev/null
+++ b/src/lib/libast/port/astconf.c
@@ -0,0 +1,1718 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * string interface to confstr(),pathconf(),sysconf(),sysinfo()
+ * extended to allow some features to be set per-process
+ */
+
+static const char id[] = "\n@(#)$Id: getconf (AT&T Research) 2011-05-18 $\0\n";
+
+#include "univlib.h"
+
+#include <ast.h>
+#include <error.h>
+#include <fs3d.h>
+#include <ctype.h>
+#include <regex.h>
+#include <proc.h>
+#include <ls.h>
+#include <sys/utsname.h>
+
+#include "conftab.h"
+#include "FEATURE/libpath"
+
+#ifndef DEBUG_astconf
+#define DEBUG_astconf 0
+#endif
+
+#ifndef _pth_getconf
+#undef ASTCONF_system
+#define ASTCONF_system 0
+#endif
+
+#if _sys_systeminfo
+# if !_lib_sysinfo
+# if _lib_systeminfo
+# define _lib_sysinfo 1
+# define sysinfo(a,b,c) systeminfo(a,b,c)
+# else
+# if _lib_syscall && _sys_syscall
+# include <sys/syscall.h>
+# if defined(SYS_systeminfo)
+# define _lib_sysinfo 1
+# define sysinfo(a,b,c) syscall(SYS_systeminfo,a,b,c)
+# endif
+# endif
+# endif
+# endif
+#else
+# undef _lib_sysinfo
+#endif
+
+#define CONF_ERROR (CONF_USER<<0)
+#define CONF_READONLY (CONF_USER<<1)
+#define CONF_ALLOC (CONF_USER<<2)
+#define CONF_GLOBAL (CONF_USER<<3)
+
+#define DEFAULT(o) ((state.std||!dynamic[o].ast)?dynamic[o].std:dynamic[o].ast)
+#define INITIALIZE() do{if(!state.data)synthesize(NiL,NiL,NiL);}while(0)
+#define STANDARD(v) (streq(v,"standard")||streq(v,"strict")||streq(v,"posix")||streq(v,"xopen"))
+
+#define MAXVAL 256
+
+#if MAXVAL <= UNIV_SIZE
+#undef MAXVAL
+#define MAXVAL (UNIV_SIZE+1)
+#endif
+
+#ifndef _UNIV_DEFAULT
+#define _UNIV_DEFAULT "att"
+#endif
+
+static char null[1];
+static char root[2] = "/";
+
+typedef struct Feature_s
+{
+ struct Feature_s*next;
+ const char* name;
+ char* value;
+ char* std;
+ char* ast;
+ short length;
+ short standard;
+ unsigned int flags;
+ short op;
+} Feature_t;
+
+typedef struct Lookup_s
+{
+ Conf_t* conf;
+ const char* name;
+ unsigned int flags;
+ short call;
+ short standard;
+ short section;
+} Lookup_t;
+
+static Feature_t dynamic[] =
+{
+#define OP_architecture 0
+ {
+ &dynamic[OP_architecture+1],
+ "ARCHITECTURE",
+ &null[0],
+ 0,
+ 0,
+ 12,
+ CONF_AST,
+ 0,
+ OP_architecture
+ },
+#define OP_conformance 1
+ {
+ &dynamic[OP_conformance+1],
+ "CONFORMANCE",
+ "ast",
+ "standard",
+ "ast",
+ 11,
+ CONF_AST,
+ 0,
+ OP_conformance
+ },
+#define OP_fs_3d 2
+ {
+ &dynamic[OP_fs_3d+1],
+ "FS_3D",
+ &null[0],
+ "0",
+ 0,
+ 5,
+ CONF_AST,
+ 0,
+ OP_fs_3d
+ },
+#define OP_getconf 3
+ {
+ &dynamic[OP_getconf+1],
+ "GETCONF",
+#ifdef _pth_getconf
+ _pth_getconf,
+#else
+ &null[0],
+#endif
+ 0,
+ 0,
+ 7,
+ CONF_AST,
+ CONF_READONLY,
+ OP_getconf
+ },
+#define OP_hosttype 4
+ {
+ &dynamic[OP_hosttype+1],
+ "HOSTTYPE",
+ HOSTTYPE,
+ 0,
+ 0,
+ 8,
+ CONF_AST,
+ CONF_READONLY,
+ OP_hosttype
+ },
+#define OP_libpath 5
+ {
+ &dynamic[OP_libpath+1],
+ "LIBPATH",
+#ifdef CONF_LIBPATH
+ CONF_LIBPATH,
+#else
+ &null[0],
+#endif
+ 0,
+ 0,
+ 7,
+ CONF_AST,
+ 0,
+ OP_libpath
+ },
+#define OP_libprefix 6
+ {
+ &dynamic[OP_libprefix+1],
+ "LIBPREFIX",
+#ifdef CONF_LIBPREFIX
+ CONF_LIBPREFIX,
+#else
+ "lib",
+#endif
+ 0,
+ 0,
+ 9,
+ CONF_AST,
+ 0,
+ OP_libprefix
+ },
+#define OP_libsuffix 7
+ {
+ &dynamic[OP_libsuffix+1],
+ "LIBSUFFIX",
+#ifdef CONF_LIBSUFFIX
+ CONF_LIBSUFFIX,
+#else
+ ".so",
+#endif
+ 0,
+ 0,
+ 9,
+ CONF_AST,
+ 0,
+ OP_libsuffix
+ },
+#define OP_path_attributes 8
+ {
+ &dynamic[OP_path_attributes+1],
+ "PATH_ATTRIBUTES",
+#if _WINIX
+ "c",
+#else
+ &null[0],
+#endif
+ &null[0],
+ 0,
+ 15,
+ CONF_AST,
+ CONF_READONLY,
+ OP_path_attributes
+ },
+#define OP_path_resolve 9
+ {
+ &dynamic[OP_path_resolve+1],
+ "PATH_RESOLVE",
+ &null[0],
+ "physical",
+ "metaphysical",
+ 12,
+ CONF_AST,
+ 0,
+ OP_path_resolve
+ },
+#define OP_universe 10
+ {
+ 0,
+ "UNIVERSE",
+ &null[0],
+ "att",
+ 0,
+ 8,
+ CONF_AST,
+ 0,
+ OP_universe
+ },
+ {
+ 0
+ }
+};
+
+typedef struct State_s
+{
+
+ const char* id;
+ const char* name;
+ const char* standard;
+ const char* strict;
+ Feature_t* features;
+
+ int std;
+
+ /* default initialization from here down */
+
+ int prefix;
+ int synthesizing;
+
+ char* data;
+ char* last;
+
+ Feature_t* recent;
+
+ Ast_confdisc_f notify;
+
+} State_t;
+
+static State_t state = { "getconf", "_AST_FEATURES", "CONFORMANCE = standard", "POSIXLY_CORRECT", dynamic, -1 };
+
+static char* feature(Feature_t*, const char*, const char*, const char*, unsigned int, Error_f);
+
+/*
+ * return fmtbuf() copy of s
+ */
+
+static char*
+buffer(char* s)
+{
+ return strcpy(fmtbuf(strlen(s) + 1), s);
+}
+
+/*
+ * synthesize state for fp
+ * fp==0 initializes from getenv(state.name)
+ * value==0 just does lookup
+ * otherwise state is set to value
+ */
+
+static char*
+synthesize(register Feature_t* fp, const char* path, const char* value)
+{
+ register char* s;
+ register char* d;
+ register char* v;
+ register char* p;
+ register int n;
+
+#if DEBUG_astconf
+ if (fp)
+ error(-2, "astconf synthesize name=%s path=%s value=%s fp=%p%s", fp->name, path, value, fp, state.synthesizing ? " SYNTHESIZING" : "");
+#endif
+ if (state.synthesizing)
+ return null;
+ if (!state.data)
+ {
+ char* se;
+ char* de;
+ char* ve;
+
+ state.prefix = strlen(state.name) + 1;
+ n = state.prefix + 3 * MAXVAL;
+ if ((s = getenv(state.name)) || getenv(state.strict) && (s = (char*)state.standard))
+ n += strlen(s) + 1;
+ n = roundof(n, 32);
+ if (!(state.data = newof(0, char, n, 0)))
+ return 0;
+ state.last = state.data + n - 1;
+ strcpy(state.data, state.name);
+ state.data += state.prefix - 1;
+ *state.data++ = '=';
+ if (s)
+ strcpy(state.data, s);
+ ve = state.data;
+ state.synthesizing = 1;
+ for (;;)
+ {
+ for (s = ve; isspace(*s); s++);
+ for (d = s; *d && !isspace(*d); d++);
+ for (se = d; isspace(*d); d++);
+ for (v = d; *v && !isspace(*v); v++);
+ for (de = v; isspace(*v); v++);
+ if (!*v)
+ break;
+ for (ve = v; *ve && !isspace(*ve); ve++);
+ if (*ve)
+ *ve = 0;
+ else
+ ve = 0;
+ *de = 0;
+ *se = 0;
+ feature(0, s, d, v, 0, 0);
+ *se = ' ';
+ *de = ' ';
+ if (!ve)
+ break;
+ *ve++ = ' ';
+ }
+ state.synthesizing = 0;
+ }
+ if (!fp)
+ return state.data;
+ if (!state.last)
+ {
+ if (!value)
+ return 0;
+ n = strlen(value);
+ goto ok;
+ }
+ s = (char*)fp->name;
+ n = fp->length;
+ d = state.data;
+ for (;;)
+ {
+ while (isspace(*d))
+ d++;
+ if (!*d)
+ break;
+ if (strneq(d, s, n) && isspace(d[n]))
+ {
+ if (!value)
+ {
+ for (d += n + 1; *d && !isspace(*d); d++);
+ for (; isspace(*d); d++);
+ for (s = d; *s && !isspace(*s); s++);
+ n = s - d;
+ value = (const char*)d;
+ goto ok;
+ }
+ for (s = p = d + n + 1; *s && !isspace(*s); s++);
+ for (; isspace(*s); s++);
+ for (v = s; *s && !isspace(*s); s++);
+ n = s - v;
+ if ((!path || *path == *p && strlen(path) == (v - p - 1) && !memcmp(path, p, v - p - 1)) && strneq(v, value, n))
+ goto ok;
+ for (; isspace(*s); s++);
+ if (*s)
+ for (; *d = *s++; d++);
+ else if (d != state.data)
+ d--;
+ break;
+ }
+ for (; *d && !isspace(*d); d++);
+ for (; isspace(*d); d++);
+ for (; *d && !isspace(*d); d++);
+ for (; isspace(*d); d++);
+ for (; *d && !isspace(*d); d++);
+ }
+ if (!value)
+ {
+ if (!fp->op)
+ {
+ if (fp->flags & CONF_ALLOC)
+ fp->value[0] = 0;
+ else
+ fp->value = null;
+ }
+ return 0;
+ }
+ if (!value[0])
+ value = "0";
+ if (!path || !path[0] || path[0] == '/' && !path[1])
+ path = "-";
+ n += strlen(path) + strlen(value) + 3;
+ if (d + n >= state.last)
+ {
+ int c;
+ int i;
+
+ i = d - state.data;
+ state.data -= state.prefix;
+ c = n + state.last - state.data + 3 * MAXVAL;
+ c = roundof(c, 32);
+ if (!(state.data = newof(state.data, char, c, 0)))
+ return 0;
+ state.last = state.data + c - 1;
+ state.data += state.prefix;
+ d = state.data + i;
+ }
+ if (d != state.data)
+ *d++ = ' ';
+ for (s = (char*)fp->name; *d = *s++; d++);
+ *d++ = ' ';
+ for (s = (char*)path; *d = *s++; d++);
+ *d++ = ' ';
+ for (s = (char*)value; *d = *s++; d++);
+#if DEBUG_astconf
+ error(-3, "astconf synthesize %s", state.data - state.prefix);
+#endif
+ setenviron(state.data - state.prefix);
+ if (state.notify)
+ (*state.notify)(NiL, NiL, state.data - state.prefix);
+ n = s - (char*)value - 1;
+ ok:
+ if (!(fp->flags & CONF_ALLOC))
+ fp->value = 0;
+ if (n == 1 && (*value == '0' || *value == '-'))
+ n = 0;
+ if (!(fp->value = newof(fp->value, char, n, 1)))
+ fp->value = null;
+ else
+ {
+ fp->flags |= CONF_ALLOC;
+ memcpy(fp->value, value, n);
+ fp->value[n] = 0;
+ }
+ return fp->value;
+}
+
+/*
+ * initialize the value for fp
+ * if command!=0 then it is checked for on $PATH
+ * synthesize(fp,path,succeed) called on success
+ * otherwise synthesize(fp,path,fail) called
+ */
+
+static void
+initialize(register Feature_t* fp, const char* path, const char* command, const char* succeed, const char* fail)
+{
+ register char* p;
+ register int ok = 1;
+
+#if DEBUG_astconf
+ error(-2, "astconf initialize name=%s path=%s command=%s succeed=%s fail=%s fp=%p%s", fp->name, path, command, succeed, fail, fp, state.synthesizing ? " SYNTHESIZING" : "");
+#endif
+ switch (fp->op)
+ {
+ case OP_architecture:
+ ok = 1;
+ break;
+ case OP_conformance:
+ ok = getenv(state.strict) != 0;
+ break;
+ case OP_hosttype:
+ ok = 1;
+ break;
+ case OP_path_attributes:
+ ok = 1;
+ break;
+ case OP_path_resolve:
+ ok = fs3d(FS3D_TEST);
+ break;
+ case OP_universe:
+ ok = streq(_UNIV_DEFAULT, DEFAULT(OP_universe));
+ /*FALLTHROUGH...*/
+ default:
+ if (p = getenv("PATH"))
+ {
+ register int r = 1;
+ register char* d = p;
+ Sfio_t* tmp;
+
+#if DEBUG_astconf
+ error(-2, "astconf initialize name=%s ok=%d PATH=%s", fp->name, ok, p);
+#endif
+ if (tmp = sfstropen())
+ {
+ for (;;)
+ {
+ switch (*p++)
+ {
+ case 0:
+ break;
+ case ':':
+ if (command && fp->op != OP_universe)
+ {
+ if (r = p - d - 1)
+ {
+ sfwrite(tmp, d, r);
+ sfputc(tmp, '/');
+ sfputr(tmp, command, 0);
+ if ((d = sfstruse(tmp)) && !eaccess(d, X_OK))
+ {
+ ok = 1;
+ if (fp->op != OP_universe)
+ break;
+ }
+ }
+ d = p;
+ }
+ r = 1;
+ continue;
+ case '/':
+ if (r)
+ {
+ r = 0;
+ if (fp->op == OP_universe)
+ {
+ if (p[0] == 'u' && p[1] == 's' && p[2] == 'r' && p[3] == '/')
+ for (p += 4; *p == '/'; p++);
+ if (p[0] == 'b' && p[1] == 'i' && p[2] == 'n')
+ {
+ for (p += 3; *p == '/'; p++);
+ if (!*p || *p == ':')
+ break;
+ }
+ }
+ }
+ if (fp->op == OP_universe)
+ {
+ if (strneq(p, "xpg", 3) || strneq(p, "5bin", 4))
+ {
+ ok = 1;
+ break;
+ }
+ if (strneq(p, "bsd", 3) || strneq(p, "ucb", 3))
+ {
+ ok = 0;
+ break;
+ }
+ }
+ continue;
+ default:
+ r = 0;
+ continue;
+ }
+ break;
+ }
+ sfclose(tmp);
+ }
+ else
+ ok = 1;
+ }
+ break;
+ }
+#if DEBUG_astconf
+ error(-1, "AHA#%d state.std=%d %s [%s] std=%s ast=%s value=%s ok=%d", __LINE__, state.std, fp->name, ok ? succeed : fail, fp->std, fp->ast, fp->value, ok);
+#endif
+ synthesize(fp, path, ok ? succeed : fail);
+}
+
+/*
+ * format synthesized value
+ */
+
+static char*
+format(register Feature_t* fp, const char* path, const char* value, unsigned int flags, Error_f conferror)
+{
+ register Feature_t* sp;
+ register int n;
+#if _UWIN && ( _X86_ || _X64_ )
+ struct stat st;
+#else
+ static struct utsname uts;
+#endif
+
+#if DEBUG_astconf
+ error(-2, "astconf format name=%s path=%s value=%s flags=%04x fp=%p%s", fp->name, path, value, flags, fp, state.synthesizing ? " SYNTHESIZING" : "");
+#endif
+ if (value)
+ fp->flags &= ~CONF_GLOBAL;
+ else if (fp->flags & CONF_GLOBAL)
+ return fp->value;
+ switch (fp->op)
+ {
+
+ case OP_architecture:
+#if _UWIN && ( _X86_ || _X64_ )
+ if (!stat("/", &st))
+ {
+ if (st.st_ino == 64)
+ {
+ fp->value = "x64";
+ break;
+ }
+ if (st.st_ino == 32)
+ {
+ fp->value = "x86";
+ break;
+ }
+ }
+#if _X64_
+ fp->value = "x64";
+#else
+ fp->value = "x86";
+#endif
+#else
+ if (!uname(&uts))
+ return fp->value = uts.machine;
+ if (!(fp->value = getenv("HOSTNAME")))
+ fp->value = "unknown";
+#endif
+ break;
+
+ case OP_conformance:
+ if (value && STANDARD(value))
+ value = fp->std;
+ state.std = streq(fp->value, fp->std);
+#if DEBUG_astconf
+ error(-1, "AHA#%d state.std=%d %s [%s] std=%s ast=%s value=%s", __LINE__, state.std, fp->name, value, fp->std, fp->ast, fp->value);
+#endif
+ if (state.synthesizing && value == (char*)fp->std)
+ fp->value = (char*)value;
+ else if (!synthesize(fp, path, value))
+ initialize(fp, path, NiL, fp->std, fp->value);
+#if DEBUG_astconf
+ error(-1, "AHA#%d state.std=%d %s [%s] std=%s ast=%s value=%s", __LINE__, state.std, fp->name, value, fp->std, fp->ast, fp->value);
+#endif
+ if (!state.std && value == fp->std)
+ {
+ state.std = 1;
+ for (sp = state.features; sp; sp = sp->next)
+ if (sp->std && sp->op && sp->op != OP_conformance)
+ feature(sp, 0, path, sp->std, 0, 0);
+ }
+#if DEBUG_astconf
+ error(-1, "AHA#%d state.std=%d %s [%s] std=%s ast=%s value=%s", __LINE__, state.std, fp->name, value, fp->std, fp->ast, fp->value);
+#endif
+ break;
+
+ case OP_fs_3d:
+ fp->value = fs3d(value ? value[0] ? FS3D_ON : FS3D_OFF : FS3D_TEST) ? "1" : null;
+ break;
+
+ case OP_hosttype:
+ break;
+
+ case OP_path_attributes:
+#ifdef _PC_PATH_ATTRIBUTES
+ {
+ register char* s;
+ register char* e;
+ intmax_t v;
+
+ /*
+ * _PC_PATH_ATTRIBUTES is a bitmap for 'a' to 'z'
+ */
+
+ if ((v = pathconf(path, _PC_PATH_ATTRIBUTES)) == -1L)
+ return 0;
+ s = fp->value;
+ e = s + sizeof(fp->value) - 1;
+ for (n = 'a'; n <= 'z'; n++)
+ if (v & (1 << (n - 'a')))
+ {
+ *s++ = n;
+ if (s >= e)
+ break;
+ }
+ *s = 0;
+ }
+#endif
+ break;
+
+ case OP_path_resolve:
+ if (state.synthesizing && value == (char*)fp->std)
+ fp->value = (char*)value;
+ else if (!synthesize(fp, path, value))
+ initialize(fp, path, NiL, "logical", DEFAULT(OP_path_resolve));
+ break;
+
+ case OP_universe:
+#if _lib_universe
+ if (getuniverse(fp->value) < 0)
+ strcpy(fp->value, DEFAULT(OP_universe));
+ if (value)
+ setuniverse(value);
+#else
+#ifdef UNIV_MAX
+ n = 0;
+ if (value)
+ {
+ while (n < univ_max && !streq(value, univ_name[n]))
+ n++;
+ if (n >= univ_max)
+ {
+ if (conferror)
+ (*conferror)(&state, &state, 2, "%s: %s: universe value too large", fp->name, value);
+ return 0;
+ }
+ }
+#ifdef ATT_UNIV
+ n = setuniverse(n + 1);
+ if (!value && n > 0)
+ setuniverse(n);
+#else
+ n = universe(value ? n + 1 : U_GET);
+#endif
+ if (n <= 0 || n >= univ_max)
+ n = 1;
+ strcpy(fp->value, univ_name[n - 1]);
+#else
+ if (value && streq(path, "="))
+ {
+ if (state.synthesizing)
+ {
+ if (!(fp->flags & CONF_ALLOC))
+ fp->value = 0;
+ n = strlen(value);
+ if (!(fp->value = newof(fp->value, char, n, 1)))
+ fp->value = null;
+ else
+ {
+ fp->flags |= CONF_ALLOC;
+ memcpy(fp->value, value, n);
+ fp->value[n] = 0;
+ }
+ }
+ else
+ synthesize(fp, path, value);
+ }
+ else
+ initialize(fp, path, "echo", DEFAULT(OP_universe), "ucb");
+#endif
+#endif
+ break;
+
+ default:
+ if (state.synthesizing && value == (char*)fp->std)
+ fp->value = (char*)value;
+ else
+ synthesize(fp, path, value);
+ break;
+
+ }
+ if (streq(path, "="))
+ fp->flags |= CONF_GLOBAL;
+ return fp->value;
+}
+
+/*
+ * value==0 get feature name
+ * value!=0 set feature name
+ * 0 returned if error or not defined; otherwise previous value
+ */
+
+static char*
+feature(register Feature_t* fp, const char* name, const char* path, const char* value, unsigned int flags, Error_f conferror)
+{
+ register int n;
+
+ if (value && (streq(value, "-") || streq(value, "0")))
+ value = null;
+ if (!fp)
+ for (fp = state.features; fp && !streq(fp->name, name); fp = fp->next);
+#if DEBUG_astconf
+ error(-2, "astconf feature name=%s path=%s value=%s flags=%04x fp=%p%s", name, path, value, flags, fp, state.synthesizing ? " SYNTHESIZING" : "");
+#endif
+ if (!fp)
+ {
+ if (!value)
+ return 0;
+ if (state.notify && !(*state.notify)(name, path, value))
+ return 0;
+ n = strlen(name);
+ if (!(fp = newof(0, Feature_t, 1, n + 1)))
+ {
+ if (conferror)
+ (*conferror)(&state, &state, 2, "%s: out of space", name);
+ return 0;
+ }
+ fp->op = -1;
+ fp->name = (const char*)fp + sizeof(Feature_t);
+ strcpy((char*)fp->name, name);
+ fp->length = n;
+ fp->std = &null[0];
+ fp->next = state.features;
+ state.features = fp;
+ }
+ else if (value)
+ {
+ if (fp->flags & CONF_READONLY)
+ {
+ if (conferror)
+ (*conferror)(&state, &state, 2, "%s: cannot set readonly symbol", fp->name);
+ return 0;
+ }
+ if (state.notify && !streq(fp->value, value) && !(*state.notify)(name, path, value))
+ return 0;
+ }
+ else
+ state.recent = fp;
+ return format(fp, path, value, flags, conferror);
+}
+
+/*
+ * binary search for name in conf[]
+ */
+
+static int
+lookup(register Lookup_t* look, const char* name, unsigned int flags)
+{
+ register Conf_t* mid = (Conf_t*)conf;
+ register Conf_t* lo = mid;
+ register Conf_t* hi = mid + conf_elements;
+ register int v;
+ register int c;
+ char* e;
+ const Prefix_t* p;
+
+ static Conf_t num;
+
+ look->flags = 0;
+ look->call = -1;
+ look->standard = (flags & ASTCONF_AST) ? CONF_AST : -1;
+ look->section = -1;
+ while (*name == '_')
+ name++;
+ again:
+ for (p = prefix; p < &prefix[prefix_elements]; p++)
+ if (strneq(name, p->name, p->length) && ((c = name[p->length] == '_' || name[p->length] == '(' || name[p->length] == '#') || (v = isdigit(name[p->length]) && name[p->length + 1] == '_')))
+ {
+ if (p->call < 0)
+ {
+ if (look->standard >= 0)
+ break;
+ look->standard = p->standard;
+ }
+ else
+ {
+ if (look->call >= 0)
+ break;
+ look->call = p->call;
+ }
+ if (name[p->length] == '(' || name[p->length] == '#')
+ {
+ look->conf = &num;
+ strlcpy((char*)num.name, name, sizeof(num.name));
+ num.call = p->call;
+ num.flags = *name == 'C' ? CONF_STRING : 0;
+ num.op = (short)strtol(name + p->length + 1, &e, 10);
+ if (name[p->length] == '(' && *e == ')')
+ e++;
+ if (*e)
+ break;
+ return 1;
+ }
+ name += p->length + c;
+ if (look->section < 0 && !c && v)
+ {
+ look->section = name[0] - '0';
+ name += 2;
+ }
+ goto again;
+ }
+#if HUH_2006_02_10
+ if (look->section < 0)
+ look->section = 1;
+#endif
+ look->name = name;
+#if DEBUG_astconf
+ error(-2, "astconf normal name=%s standard=%d section=%d call=%d flags=%04x elements=%d", look->name, look->standard, look->section, look->call, flags, conf_elements);
+#endif
+ c = *((unsigned char*)name);
+ while (lo <= hi)
+ {
+ mid = lo + (hi - lo) / 2;
+#if DEBUG_astconf
+ error(-3, "astconf lookup name=%s mid=%s", name, mid->name);
+#endif
+ if (!(v = c - *((unsigned char*)mid->name)) && !(v = strcmp(name, mid->name)))
+ {
+ hi = mid;
+ lo = (Conf_t*)conf;
+ do
+ {
+ if ((look->standard < 0 || look->standard == mid->standard) &&
+ (look->section < 0 || look->section == mid->section) &&
+ (look->call < 0 || look->call == mid->call))
+ goto found;
+ } while (mid-- > lo && streq(mid->name, look->name));
+ mid = hi;
+ hi = lo + conf_elements - 1;
+ while (++mid < hi && streq(mid->name, look->name))
+ {
+ if ((look->standard < 0 || look->standard == mid->standard) &&
+ (look->section < 0 || look->section == mid->section) &&
+ (look->call < 0 || look->call == mid->call))
+ goto found;
+ }
+ break;
+ }
+ else if (v > 0)
+ lo = mid + 1;
+ else
+ hi = mid - 1;
+ }
+ return 0;
+ found:
+ if (look->call < 0 && look->standard >= 0 && (look->section <= 1 || (mid->flags & CONF_MINMAX)))
+ look->flags |= CONF_MINMAX;
+ look->conf = mid;
+#if DEBUG_astconf
+ error(-2, "astconf lookup name=%s standard=%d:%d section=%d:%d call=%d:%d", look->name, look->standard, mid->standard, look->section, mid->section, look->call, mid->call);
+#endif
+ return 1;
+}
+
+/*
+ * return a tolower'd copy of s
+ */
+
+static char*
+fmtlower(register const char* s)
+{
+ register int c;
+ register char* t;
+ char* b;
+
+ b = t = fmtbuf(strlen(s) + 1);
+ while (c = *s++)
+ {
+ if (isupper(c))
+ c = tolower(c);
+ *t++ = c;
+ }
+ *t = 0;
+ return b;
+}
+
+/*
+ * print value line for p
+ * if !name then value prefixed by "p->name="
+ * if (flags & CONF_MINMAX) then default minmax value used
+ */
+
+static char*
+print(Sfio_t* sp, register Lookup_t* look, const char* name, const char* path, int listflags, Error_f conferror)
+{
+ register Conf_t* p = look->conf;
+ register unsigned int flags = look->flags;
+ Feature_t* fp;
+ char* call;
+ char* f;
+ const char* s;
+ int i;
+ int n;
+ int olderrno;
+ int drop;
+ int defined;
+ intmax_t v;
+ char buf[PATH_MAX];
+ char flg[16];
+
+ if (!name && !(p->flags & CONF_STRING) && (p->flags & (CONF_FEATURE|CONF_LIMIT|CONF_MINMAX)) && (p->flags & (CONF_LIMIT|CONF_PREFIXED)) != CONF_LIMIT)
+ flags |= CONF_PREFIXED;
+ olderrno = errno;
+ errno = 0;
+#if DEBUG_astconf
+ error(-1, "astconf name=%s:%s:%s standard=%d section=%d call=%s op=%d flags=|%s%s%s%s%s:|%s%s%s%s%s%s%s%s%s%s"
+ , name, look->name, p->name, p->standard, p->section, prefix[p->call + CONF_call].name, p->op
+ , (flags & CONF_FEATURE) ? "FEATURE|" : ""
+ , (flags & CONF_LIMIT) ? "LIMIT|" : ""
+ , (flags & CONF_MINMAX) ? "MINMAX|" : ""
+ , (flags & CONF_PREFIXED) ? "PREFIXED|" : ""
+ , (flags & CONF_STRING) ? "STRING|" : ""
+ , (p->flags & CONF_DEFER_CALL) ? "DEFER_CALL|" : ""
+ , (p->flags & CONF_DEFER_MM) ? "DEFER_MM|" : ""
+ , (p->flags & CONF_FEATURE) ? "FEATURE|" : ""
+ , (p->flags & CONF_LIMIT_DEF) ? "LIMIT_DEF|" : (p->flags & CONF_LIMIT) ? "LIMIT|" : ""
+ , (p->flags & CONF_MINMAX_DEF) ? "MINMAX_DEF|" : (p->flags & CONF_MINMAX) ? "MINMAX|" : ""
+ , (p->flags & CONF_NOUNDERSCORE) ? "NOUNDERSCORE|" : ""
+ , (p->flags & CONF_PREFIXED) ? "PREFIXED|" : ""
+ , (p->flags & CONF_PREFIX_ONLY) ? "PREFIX_ONLY|" : ""
+ , (p->flags & CONF_STANDARD) ? "STANDARD|" : ""
+ , (p->flags & CONF_STRING) ? "STRING|" : ""
+ , (p->flags & CONF_UNDERSCORE) ? "UNDERSCORE|" : ""
+ );
+#endif
+ flags |= CONF_LIMIT_DEF|CONF_MINMAX_DEF;
+ if (conferror && name)
+ {
+ if ((p->flags & CONF_PREFIX_ONLY) && look->standard < 0)
+ goto bad;
+ if (!(flags & CONF_MINMAX) || !(p->flags & CONF_MINMAX))
+ {
+ switch (p->call)
+ {
+ case CONF_pathconf:
+ if (path == root)
+ {
+ (*conferror)(&state, &state, 2, "%s: path expected", name);
+ goto bad;
+ }
+ break;
+ default:
+ if (path != root)
+ {
+ (*conferror)(&state, &state, 2, "%s: path not expected", name);
+ goto bad;
+ }
+ break;
+ }
+#ifdef _pth_getconf
+ if (p->flags & CONF_DEFER_CALL)
+ goto bad;
+#endif
+ }
+ else
+ {
+ if (path != root)
+ {
+ (*conferror)(&state, &state, 2, "%s: path not expected", name);
+ goto bad;
+ }
+#ifdef _pth_getconf
+ if ((p->flags & CONF_DEFER_MM) || !(p->flags & CONF_MINMAX_DEF))
+ goto bad;
+#endif
+ }
+ if (look->standard >= 0 && (name[0] != '_' && ((p->flags & CONF_UNDERSCORE) || look->section <= 1) || name[0] == '_' && (p->flags & CONF_NOUNDERSCORE)) || look->standard < 0 && name[0] == '_')
+ goto bad;
+ }
+ s = 0;
+ defined = 1;
+ switch (i = (p->op < 0 || (flags & CONF_MINMAX) && (p->flags & CONF_MINMAX_DEF)) ? 0 : p->call)
+ {
+ case CONF_confstr:
+ call = "confstr";
+#if _lib_confstr
+ if (!(v = confstr(p->op, buf, sizeof(buf))))
+ {
+ defined = 0;
+ v = -1;
+ errno = EINVAL;
+ }
+ else if (v > 0)
+ {
+ buf[sizeof(buf) - 1] = 0;
+ s = (const char*)buf;
+ }
+ else
+ defined = 0;
+ break;
+#else
+ goto predef;
+#endif
+ case CONF_pathconf:
+ call = "pathconf";
+#if _lib_pathconf
+ if ((v = pathconf(path, p->op)) < 0)
+ defined = 0;
+ break;
+#else
+ goto predef;
+#endif
+ case CONF_sysconf:
+ call = "sysconf";
+#if _lib_sysconf
+ if ((v = sysconf(p->op)) < 0)
+ defined = 0;
+ break;
+#else
+ goto predef;
+#endif
+ case CONF_sysinfo:
+ call = "sysinfo";
+#if _lib_sysinfo
+ if ((v = sysinfo(p->op, buf, sizeof(buf))) >= 0)
+ {
+ buf[sizeof(buf) - 1] = 0;
+ s = (const char*)buf;
+ }
+ else
+ defined = 0;
+ break;
+#else
+ goto predef;
+#endif
+ default:
+ call = "synthesis";
+ errno = EINVAL;
+ v = -1;
+ defined = 0;
+ break;
+ case 0:
+ call = 0;
+ if (p->standard == CONF_AST)
+ {
+ if (streq(p->name, "RELEASE") && (i = open("/proc/version", O_RDONLY)) >= 0)
+ {
+ n = read(i, buf, sizeof(buf) - 1);
+ close(i);
+ if (n > 0 && buf[n - 1] == '\n')
+ n--;
+ if (n > 0 && buf[n - 1] == '\r')
+ n--;
+ buf[n] = 0;
+ if (buf[0])
+ {
+ v = 0;
+ s = buf;
+ break;
+ }
+ }
+ }
+ if (p->flags & CONF_MINMAX_DEF)
+ {
+ if (!((p->flags & CONF_LIMIT_DEF)))
+ flags |= CONF_MINMAX;
+ listflags &= ~ASTCONF_system;
+ }
+ predef:
+ if (look->standard == CONF_AST)
+ {
+ if (streq(p->name, "VERSION"))
+ {
+ v = ast.version;
+ break;
+ }
+ }
+ if (flags & CONF_MINMAX)
+ {
+ if ((p->flags & CONF_MINMAX_DEF) && (!(listflags & ASTCONF_system) || !(p->flags & CONF_DEFER_MM)))
+ {
+ v = p->minmax.number;
+ s = p->minmax.string;
+ break;
+ }
+ }
+ else if ((p->flags & CONF_LIMIT_DEF) && (!(listflags & ASTCONF_system) || !(p->flags & CONF_DEFER_CALL)))
+ {
+ v = p->limit.number;
+ s = p->limit.string;
+ break;
+ }
+ flags &= ~(CONF_LIMIT_DEF|CONF_MINMAX_DEF);
+ v = -1;
+ errno = EINVAL;
+ defined = 0;
+ break;
+ }
+ if (!defined)
+ {
+ if (!errno)
+ {
+ if ((p->flags & CONF_FEATURE) || !(p->flags & (CONF_LIMIT|CONF_MINMAX)))
+ flags &= ~(CONF_LIMIT_DEF|CONF_MINMAX_DEF);
+ }
+ else if (flags & CONF_PREFIXED)
+ flags &= ~(CONF_LIMIT_DEF|CONF_MINMAX_DEF);
+ else if (errno != EINVAL || !i)
+ {
+ if (!sp)
+ {
+ if (conferror)
+ {
+ if (call)
+ (*conferror)(&state, &state, ERROR_SYSTEM|2, "%s: %s error", p->name, call);
+ else if (!(listflags & ASTCONF_system))
+ (*conferror)(&state, &state, 2, "%s: unknown name", p->name);
+ }
+ goto bad;
+ }
+ else
+ {
+ flags &= ~(CONF_LIMIT_DEF|CONF_MINMAX_DEF);
+ flags |= CONF_ERROR;
+ }
+ }
+ }
+ errno = olderrno;
+ if ((listflags & ASTCONF_defined) && !(flags & (CONF_LIMIT_DEF|CONF_MINMAX_DEF)))
+ goto bad;
+ if ((drop = !sp) && !(sp = sfstropen()))
+ goto bad;
+ if (listflags & ASTCONF_table)
+ {
+ f = flg;
+ if (p->flags & CONF_DEFER_CALL)
+ *f++ = 'C';
+ if (p->flags & CONF_DEFER_MM)
+ *f++ = 'D';
+ if (p->flags & CONF_FEATURE)
+ *f++ = 'F';
+ if (p->flags & CONF_LIMIT)
+ *f++ = 'L';
+ if (p->flags & CONF_MINMAX)
+ *f++ = 'M';
+ if (p->flags & CONF_NOSECTION)
+ *f++ = 'N';
+ if (p->flags & CONF_PREFIXED)
+ *f++ = 'P';
+ if (p->flags & CONF_STANDARD)
+ *f++ = 'S';
+ if (p->flags & CONF_UNDERSCORE)
+ *f++ = 'U';
+ if (p->flags & CONF_NOUNDERSCORE)
+ *f++ = 'V';
+ if (p->flags & CONF_PREFIX_ONLY)
+ *f++ = 'W';
+ if (f == flg)
+ *f++ = 'X';
+ *f = 0;
+ sfprintf(sp, "%*s %*s %d %2s %4d %6s ", sizeof(p->name), p->name, sizeof(prefix[p->standard].name), prefix[p->standard].name, p->section, prefix[p->call + CONF_call].name, p->op, flg);
+ if (p->flags & CONF_LIMIT_DEF)
+ {
+ if (p->limit.string)
+ sfprintf(sp, "L[%s] ", (listflags & ASTCONF_quote) ? fmtquote(p->limit.string, "\"", "\"", strlen(p->limit.string), FMT_SHELL) : p->limit.string);
+ else
+ sfprintf(sp, "L[%I*d] ", sizeof(p->limit.number), p->limit.number);
+ }
+ if (p->flags & CONF_MINMAX_DEF)
+ {
+ if (p->minmax.string)
+ sfprintf(sp, "M[%s] ", (listflags & ASTCONF_quote) ? fmtquote(p->minmax.string, "\"", "\"", strlen(p->minmax.string), FMT_SHELL) : p->minmax.string);
+ else
+ sfprintf(sp, "M[%I*d] ", sizeof(p->minmax.number), p->minmax.number);
+ }
+ if (flags & CONF_ERROR)
+ sfprintf(sp, "error");
+ else if (defined)
+ {
+ if (s)
+ sfprintf(sp, "%s", (listflags & ASTCONF_quote) ? fmtquote(s, "\"", "\"", strlen(s), FMT_SHELL) : s);
+ else if (v != -1)
+ sfprintf(sp, "%I*d", sizeof(v), v);
+ else
+ sfprintf(sp, "%I*u", sizeof(v), v);
+ }
+ sfprintf(sp, "\n");
+ }
+ else
+ {
+ if (!(flags & CONF_PREFIXED) || (listflags & ASTCONF_base))
+ {
+ if (!name)
+ {
+ if ((p->flags & (CONF_PREFIXED|CONF_STRING)) == (CONF_PREFIXED|CONF_STRING) && (!(listflags & ASTCONF_base) || p->standard != CONF_POSIX))
+ {
+ if ((p->flags & CONF_UNDERSCORE) && !(listflags & ASTCONF_base))
+ sfprintf(sp, "_");
+ sfprintf(sp, "%s", (listflags & ASTCONF_lower) ? fmtlower(prefix[p->standard].name) : prefix[p->standard].name);
+ if (p->section > 1)
+ sfprintf(sp, "%d", p->section);
+ sfprintf(sp, "_");
+ }
+ sfprintf(sp, "%s=", (listflags & ASTCONF_lower) ? fmtlower(p->name) : p->name);
+ }
+ if (flags & CONF_ERROR)
+ sfprintf(sp, "error");
+ else if (defined)
+ {
+ if (s)
+ sfprintf(sp, "%s", (listflags & ASTCONF_quote) ? fmtquote(s, "\"", "\"", strlen(s), FMT_SHELL) : s);
+ else if (v != -1)
+ sfprintf(sp, "%I*d", sizeof(v), v);
+ else
+ sfprintf(sp, "%I*u", sizeof(v), v);
+ }
+ else
+ sfprintf(sp, "undefined");
+ if (!name)
+ sfprintf(sp, "\n");
+ }
+ if (!name && !(listflags & ASTCONF_base) && !(p->flags & CONF_STRING) && (p->flags & (CONF_FEATURE|CONF_MINMAX)))
+ {
+ if (p->flags & CONF_UNDERSCORE)
+ sfprintf(sp, "_");
+ sfprintf(sp, "%s", (listflags & ASTCONF_lower) ? fmtlower(prefix[p->standard].name) : prefix[p->standard].name);
+ if (p->section > 1)
+ sfprintf(sp, "%d", p->section);
+ sfprintf(sp, "_%s=", (listflags & ASTCONF_lower) ? fmtlower(p->name) : p->name);
+ if (v != -1)
+ sfprintf(sp, "%I*d", sizeof(v), v);
+ else if (defined)
+ sfprintf(sp, "%I*u", sizeof(v), v);
+ else
+ sfprintf(sp, "undefined");
+ sfprintf(sp, "\n");
+ }
+ }
+ if (drop)
+ {
+ if (call = sfstruse(sp))
+ call = buffer(call);
+ else
+ call = "[ out of space ]";
+ sfclose(sp);
+ return call;
+ }
+ bad:
+ if (!(listflags & ~(ASTCONF_error|ASTCONF_system)))
+ for (fp = state.features; fp; fp = fp->next)
+ if (streq(name, fp->name))
+ return format(fp, path, 0, listflags, conferror);
+ return (listflags & ASTCONF_error) ? (char*)0 : null;
+}
+
+/*
+ * return read stream to native getconf utility
+ */
+
+static Sfio_t*
+nativeconf(Proc_t** pp, const char* operand)
+{
+#ifdef _pth_getconf
+ Sfio_t* sp;
+ char* cmd[3];
+ long ops[2];
+
+#if DEBUG_astconf
+ error(-2, "astconf defer %s %s", _pth_getconf, operand);
+#endif
+ cmd[0] = (char*)state.id;
+ cmd[1] = (char*)operand;
+ cmd[2] = 0;
+ ops[0] = PROC_FD_DUP(open("/dev/null",O_WRONLY,0), 2, PROC_FD_CHILD);
+ ops[1] = 0;
+ if (*pp = procopen(_pth_getconf, cmd, environ, ops, PROC_READ))
+ {
+ if (sp = sfnew(NiL, NiL, SF_UNBOUND, (*pp)->rfd, SF_READ))
+ {
+ sfdisc(sp, SF_POPDISC);
+ return sp;
+ }
+ procclose(*pp);
+ }
+#endif
+ return 0;
+}
+
+/*
+ * value==0 gets value for name
+ * value!=0 sets value for name and returns previous value
+ * path==0 implies path=="/"
+ *
+ * settable return values are in permanent store
+ * non-settable return values copied to a tmp fmtbuf() buffer
+ *
+ * if (streq(astgetconf("PATH_RESOLVE", NiL, NiL, 0, 0), "logical"))
+ * our_way();
+ *
+ * universe = astgetconf("UNIVERSE", NiL, "att", 0, 0);
+ * astgetconf("UNIVERSE", NiL, universe, 0, 0);
+ *
+ * if (flags&ASTCONF_error)!=0 then error return value is 0
+ * otherwise 0 not returned
+ */
+
+#define ALT 16
+
+char*
+astgetconf(const char* name, const char* path, const char* value, int flags, Error_f conferror)
+{
+ register char* s;
+ int n;
+ Lookup_t look;
+ Sfio_t* tmp;
+
+#if __OBSOLETE__ < 20080101
+ if (pointerof(flags) == (void*)errorf)
+ {
+ conferror = errorf;
+ flags = ASTCONF_error;
+ }
+ else if (conferror && conferror != errorf)
+ conferror = 0;
+#endif
+ if (!name)
+ {
+ if (path)
+ return null;
+ if (!(name = value))
+ {
+ if (state.data)
+ {
+ Ast_confdisc_f notify;
+
+#if _HUH20000515 /* doesn't work for shell builtins */
+ free(state.data - state.prefix);
+#endif
+ state.data = 0;
+ notify = state.notify;
+ state.notify = 0;
+ INITIALIZE();
+ state.notify = notify;
+ }
+ return null;
+ }
+ value = 0;
+ }
+ INITIALIZE();
+ if (!path)
+ path = root;
+ if (state.recent && streq(name, state.recent->name) && (s = format(state.recent, path, value, flags, conferror)))
+ return s;
+ if (lookup(&look, name, flags))
+ {
+ if (value)
+ {
+ ro:
+ errno = EINVAL;
+ if (conferror)
+ (*conferror)(&state, &state, 2, "%s: cannot set value", name);
+ return (flags & ASTCONF_error) ? (char*)0 : null;
+ }
+ return print(NiL, &look, name, path, flags, conferror);
+ }
+ if ((n = strlen(name)) > 3 && n < (ALT + 3))
+ {
+ if (streq(name + n - 3, "DEV"))
+ {
+ if (tmp = sfstropen())
+ {
+ sfprintf(tmp, "/dev/");
+ for (s = (char*)name; s < (char*)name + n - 3; s++)
+ sfputc(tmp, isupper(*s) ? tolower(*s) : *s);
+ if ((s = sfstruse(tmp)) && !access(s, F_OK))
+ {
+ if (value)
+ goto ro;
+ s = buffer(s);
+ sfclose(tmp);
+ return s;
+ }
+ sfclose(tmp);
+ }
+ }
+ else if (streq(name + n - 3, "DIR"))
+ {
+ Lookup_t altlook;
+ char altname[ALT];
+
+ static const char* dirs[] = { "/usr/lib", "/usr", null };
+
+ strcpy(altname, name);
+ altname[n - 3] = 0;
+ if (lookup(&altlook, altname, flags))
+ {
+ if (value)
+ {
+ errno = EINVAL;
+ if (conferror)
+ (*conferror)(&state, &state, 2, "%s: cannot set value", altname);
+ return (flags & ASTCONF_error) ? (char*)0 : null;
+ }
+ return print(NiL, &altlook, altname, path, flags, conferror);
+ }
+ for (s = altname; *s; s++)
+ if (isupper(*s))
+ *s = tolower(*s);
+ if (tmp = sfstropen())
+ {
+ for (n = 0; n < elementsof(dirs); n++)
+ {
+ sfprintf(tmp, "%s/%s/.", dirs[n], altname);
+ if ((s = sfstruse(tmp)) && !access(s, F_OK))
+ {
+ if (value)
+ goto ro;
+ s = buffer(s);
+ sfclose(tmp);
+ return s;
+ }
+ }
+ sfclose(tmp);
+ }
+ }
+ }
+ if ((look.standard < 0 || look.standard == CONF_AST) && look.call <= 0 && look.section <= 1 && (s = feature(0, look.name, path, value, flags, conferror)))
+ return s;
+ errno = EINVAL;
+ if (conferror && !(flags & ASTCONF_system))
+ (*conferror)(&state, &state, 2, "%s: unknown name", name);
+ return (flags & ASTCONF_error) ? (char*)0 : null;
+}
+
+/*
+ * astconf() never returns 0
+ */
+
+char*
+astconf(const char* name, const char* path, const char* value)
+{
+ return astgetconf(name, path, value, 0, 0);
+}
+
+/*
+ * set discipline function to be called when features change
+ * old discipline function returned
+ */
+
+Ast_confdisc_f
+astconfdisc(Ast_confdisc_f new_notify)
+{
+ Ast_confdisc_f old_notify;
+
+ INITIALIZE();
+ old_notify = state.notify;
+ state.notify = new_notify;
+ return old_notify;
+}
+
+/*
+ * list all name=value entries on sp
+ * path==0 implies path=="/"
+ */
+
+void
+astconflist(Sfio_t* sp, const char* path, int flags, const char* pattern)
+{
+ char* s;
+ char* f;
+ char* call;
+ Feature_t* fp;
+ Lookup_t look;
+ regex_t re;
+ regdisc_t redisc;
+ int olderrno;
+ char flg[8];
+#ifdef _pth_getconf_a
+ Proc_t* proc;
+ Sfio_t* pp;
+#endif
+
+ INITIALIZE();
+ if (!path)
+ path = root;
+ else if (access(path, F_OK))
+ {
+ errorf(&state, &state, 2, "%s: not found", path);
+ return;
+ }
+ olderrno = errno;
+ look.flags = 0;
+ if (!(flags & (ASTCONF_read|ASTCONF_write|ASTCONF_parse)))
+ flags |= ASTCONF_read|ASTCONF_write;
+ else if (flags & ASTCONF_parse)
+ flags |= ASTCONF_write;
+ if (!(flags & (ASTCONF_matchcall|ASTCONF_matchname|ASTCONF_matchstandard)))
+ pattern = 0;
+ if (pattern)
+ {
+ memset(&redisc, 0, sizeof(redisc));
+ redisc.re_version = REG_VERSION;
+ redisc.re_errorf = (regerror_t)errorf;
+ re.re_disc = &redisc;
+ if (regcomp(&re, pattern, REG_DISCIPLINE|REG_EXTENDED|REG_LENIENT|REG_NULL))
+ return;
+ }
+ if (flags & ASTCONF_read)
+ {
+ for (look.conf = (Conf_t*)conf; look.conf < (Conf_t*)&conf[conf_elements]; look.conf++)
+ {
+ if (pattern)
+ {
+ if (flags & ASTCONF_matchcall)
+ {
+ if (regexec(&re, prefix[look.conf->call + CONF_call].name, 0, NiL, 0))
+ continue;
+ }
+ else if (flags & ASTCONF_matchname)
+ {
+ if (regexec(&re, look.conf->name, 0, NiL, 0))
+ continue;
+ }
+ else if (flags & ASTCONF_matchstandard)
+ {
+ if (regexec(&re, prefix[look.conf->standard].name, 0, NiL, 0))
+ continue;
+ }
+ }
+ look.standard = look.conf->standard;
+ look.section = look.conf->section;
+ print(sp, &look, NiL, path, flags, errorf);
+ }
+#ifdef _pth_getconf_a
+ if (pp = nativeconf(&proc, _pth_getconf_a))
+ {
+ call = "GC";
+ while (f = sfgetr(pp, '\n', 1))
+ {
+ for (s = f; *s && *s != '=' && *s != ':' && !isspace(*s); s++);
+ if (*s)
+ for (*s++ = 0; isspace(*s); s++);
+ if (!lookup(&look, f, flags))
+ {
+ if (flags & ASTCONF_table)
+ {
+ if (look.standard < 0)
+ look.standard = 0;
+ if (look.section < 1)
+ look.section = 1;
+ sfprintf(sp, "%*s %*s %d %2s %4d %5s %s\n", sizeof(conf[0].name), f, sizeof(prefix[look.standard].name), prefix[look.standard].name, look.section, call, 0, "N", s);
+ }
+ else if (flags & ASTCONF_parse)
+ sfprintf(sp, "%s %s - %s\n", state.id, f, s);
+ else
+ sfprintf(sp, "%s=%s\n", f, (flags & ASTCONF_quote) ? fmtquote(s, "\"", "\"", strlen(s), FMT_SHELL) : s);
+ }
+ }
+ sfclose(pp);
+ procclose(proc);
+ }
+#endif
+ }
+ if (flags & ASTCONF_write)
+ {
+ call = "AC";
+ for (fp = state.features; fp; fp = fp->next)
+ {
+ if (pattern)
+ {
+ if (flags & ASTCONF_matchcall)
+ {
+ if (regexec(&re, call, 0, NiL, 0))
+ continue;
+ }
+ else if (flags & ASTCONF_matchname)
+ {
+ if (regexec(&re, fp->name, 0, NiL, 0))
+ continue;
+ }
+ else if (flags & ASTCONF_matchstandard)
+ {
+ if (regexec(&re, prefix[fp->standard].name, 0, NiL, 0))
+ continue;
+ }
+ }
+ if (!(s = feature(fp, 0, path, NiL, 0, 0)) || !*s)
+ s = "0";
+ if (flags & ASTCONF_table)
+ {
+ f = flg;
+ if (fp->flags & CONF_ALLOC)
+ *f++ = 'A';
+ if (fp->flags & CONF_READONLY)
+ *f++ = 'R';
+ if (f == flg)
+ *f++ = 'X';
+ *f = 0;
+ sfprintf(sp, "%*s %*s %d %2s %4d %5s %s\n", sizeof(conf[0].name), fp->name, sizeof(prefix[fp->standard].name), prefix[fp->standard].name, 1, call, 0, flg, s);
+ }
+ else if (flags & ASTCONF_parse)
+ sfprintf(sp, "%s %s - %s\n", state.id, (flags & ASTCONF_lower) ? fmtlower(fp->name) : fp->name, fmtquote(s, "\"", "\"", strlen(s), FMT_SHELL));
+ else
+ sfprintf(sp, "%s=%s\n", (flags & ASTCONF_lower) ? fmtlower(fp->name) : fp->name, (flags & ASTCONF_quote) ? fmtquote(s, "\"", "\"", strlen(s), FMT_SHELL) : s);
+ }
+ }
+ if (pattern)
+ regfree(&re);
+ errno = olderrno;
+}
diff --git a/src/lib/libast/port/astcopy.c b/src/lib/libast/port/astcopy.c
new file mode 100644
index 0000000..853eb9a
--- /dev/null
+++ b/src/lib/libast/port/astcopy.c
@@ -0,0 +1,90 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * copy from rfd to wfd (with conditional mmap hacks)
+ */
+
+#include <ast.h>
+#include <ast_mmap.h>
+
+#if _mmap_worthy > 1
+
+#include <ls.h>
+
+#define MAPSIZE (1024*256)
+
+#endif
+
+#undef BUFSIZ
+#define BUFSIZ 4096
+
+/*
+ * copy n bytes from rfd to wfd
+ * actual byte count returned
+ * if n<=0 then ``good'' size is used
+ */
+
+off_t
+astcopy(int rfd, int wfd, off_t n)
+{
+ register off_t c;
+#ifdef MAPSIZE
+ off_t pos;
+ off_t mapsize;
+ char* mapbuf;
+ struct stat st;
+#endif
+
+ static int bufsiz;
+ static char* buf;
+
+ if (n <= 0 || n >= BUFSIZ * 2)
+ {
+#if MAPSIZE
+ if (!fstat(rfd, &st) && S_ISREG(st.st_mode) && (pos = lseek(rfd, (off_t)0, 1)) != ((off_t)-1))
+ {
+ if (pos >= st.st_size) return(0);
+ mapsize = st.st_size - pos;
+ if (mapsize > MAPSIZE) mapsize = (mapsize > n && n > 0) ? n : MAPSIZE;
+ if (mapsize >= BUFSIZ * 2 && (mapbuf = (char*)mmap(NiL, mapsize, PROT_READ, MAP_SHARED, rfd, pos)) != ((caddr_t)-1))
+ {
+ if (write(wfd, mapbuf, mapsize) != mapsize || lseek(rfd, mapsize, 1) == ((off_t)-1)) return(-1);
+ munmap((caddr_t)mapbuf, mapsize);
+ return(mapsize);
+ }
+ }
+#endif
+ if (n <= 0) n = BUFSIZ;
+ }
+ if (n > bufsiz)
+ {
+ if (buf) free(buf);
+ bufsiz = roundof(n, BUFSIZ);
+ if (!(buf = newof(0, char, bufsiz, 0))) return(-1);
+ }
+ if ((c = read(rfd, buf, (size_t)n)) > 0 && write(wfd, buf, (size_t)c) != c) c = -1;
+ return(c);
+}
diff --git a/src/lib/libast/port/astdynamic.c b/src/lib/libast/port/astdynamic.c
new file mode 100644
index 0000000..c3035a8
--- /dev/null
+++ b/src/lib/libast/port/astdynamic.c
@@ -0,0 +1,132 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * ast dynamic data initialization
+ */
+
+#ifdef _UWIN
+
+#define _std_def_cfree 1
+
+#include <sfio_t.h>
+#include <ast.h>
+
+#undef strcoll
+
+#include <ast_windows.h>
+
+extern Sfio_t _Sfstdin;
+extern Sfio_t _Sfstdout;
+extern Sfio_t _Sfstderr;
+
+#include "sfhdr.h"
+
+#undef sfstdin
+#undef sfstdout
+#undef sfstderr
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+/*
+ * for backward compatibility with early UNIX
+ */
+
+extern void
+cfree(void* addr)
+{
+ free(addr);
+}
+
+extern void
+_ast_libinit(void* in, void* out, void* err)
+{
+ Sfio_t* sp;
+
+ sp = (Sfio_t*)in;
+ *sp = _Sfstdin;
+ sfstdin = sp;
+ sp = (Sfio_t*)out;
+ *sp = _Sfstdout;
+ sfstdout = sp;
+ sp = (Sfio_t*)err;
+ *sp = _Sfstderr;
+ sfstderr = sp;
+}
+
+extern void
+_ast_init(void)
+{
+ struct _astdll* ap = _ast_getdll();
+
+ _ast_libinit(ap->_ast_stdin,ap->_ast_stdout,ap->_ast_stderr);
+}
+
+extern void
+_ast_exit(void)
+{
+ if (_Sfcleanup)
+ (*_Sfcleanup)();
+}
+
+BOOL WINAPI
+DllMain(HINSTANCE hinst, DWORD reason, VOID* reserved)
+{
+ switch (reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ break;
+ case DLL_PROCESS_DETACH:
+ _ast_exit();
+ break;
+ }
+ return 1;
+}
+
+#else
+
+#include <ast.h>
+
+#if _dll_data_intercept && ( _DLL_BLD || _BLD_DLL )
+
+#undef environ
+
+extern char** environ;
+
+struct _astdll _ast_dll = { &environ };
+
+struct _astdll*
+_ast_getdll(void)
+{
+ return &_ast_dll;
+}
+
+#else
+
+NoN(astdynamic)
+
+#endif
+
+#endif
diff --git a/src/lib/libast/port/astlicense.c b/src/lib/libast/port/astlicense.c
new file mode 100644
index 0000000..913e9ca
--- /dev/null
+++ b/src/lib/libast/port/astlicense.c
@@ -0,0 +1,1292 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * generate a license comment -- see proto(1)
+ *
+ * NOTE: coded for minimal library dependence
+ * not so for the legal department
+ */
+
+#ifndef _PPLIB_H
+#include <ast.h>
+#include <time.h>
+#endif
+
+#undef copy
+#undef BSD /* guess who defines this */
+#undef END
+#undef INLINE
+#undef TEST
+#undef VERBOSE
+
+#define NONE 0
+#define INLINE 1
+#define TEST 2
+#define VERBOSE 3
+#define USAGE 4
+#define OPEN 5
+#define CPL 6
+#define EPL 7
+#define BSD 8
+#define ZLIB 9
+#define MIT 10
+#define GPL 11
+#define SPECIAL 12
+#define NONEXCLUSIVE 13
+#define NONCOMMERCIAL 14
+#define PROPRIETARY 15
+
+#define AUTHOR 0
+#define CLASS 1
+#define COMPANY 2
+#define COMPONENT 3
+#define CONTRIBUTOR 4
+#define CORPORATION 5
+#define DOMAIN 6
+#define ID 7
+#define INCORPORATION 8
+#define LICENSE 9
+#define LOCATION 10
+#define NAME 11
+#define NOTICE 12
+#define ORGANIZATION 13
+#define PACKAGE 14
+#define PARENT 15
+#define QUERY 16
+#define SINCE 17
+#define SOURCE 18
+#define START 19
+#define STYLE 20
+#define URL 21
+#define URLMD5 22
+#define VERSION 23
+
+#define IDS 64
+
+#define COMDATA 70
+#define COMLINE (COMDATA+4)
+#define COMLONG (COMDATA-32)
+#define COMMENT(x,b,s,u) comment(x,b,s,sizeof(s)-1,u)
+
+#define PUT(b,c) (((b)->nxt<(b)->end)?(*(b)->nxt++=(c)):((c),(-1)))
+#define BUF(b) ((b)->buf)
+#define USE(b) ((b)->siz=(b)->nxt-(b)->buf,(b)->nxt=(b)->buf,(b)->siz)
+#define SIZ(b) ((b)->nxt-(b)->buf)
+#define END(b) (*((b)->nxt>=(b)->end?((b)->nxt=(b)->end-1):(b)->nxt)=0,(b)->nxt-(b)->buf)
+
+#ifndef NiL
+#define NiL ((char*)0)
+#endif
+
+typedef struct Buffer_s
+{
+ char* buf;
+ char* nxt;
+ char* end;
+ int siz;
+} Buffer_t;
+
+typedef struct Item_s
+{
+ char* data;
+ int size;
+ int quote;
+} Item_t;
+
+typedef struct Id_s
+{
+ Item_t name;
+ Item_t value;
+} Id_t;
+
+/*
+ * NOTE: key[] element order must match the corresponding macro
+ */
+
+#define KEY(s) {s,sizeof(s)-1,0}
+
+static const Item_t key[] =
+{
+ KEY("author"),
+ KEY("class"),
+ KEY("company"),
+ KEY("component"),
+ KEY("contributor"),
+ KEY("corporation"),
+ KEY("domain"),
+ KEY("id"),
+ KEY("incorporation"),
+ KEY("license"),
+ KEY("location"),
+ KEY("name"),
+ KEY("notice"),
+ KEY("organization"),
+ KEY("package"),
+ KEY("parent"),
+ KEY("query"),
+ KEY("since"),
+ KEY("source"),
+ KEY("start"),
+ KEY("type"),
+ KEY("url"),
+ KEY("urlmd5"),
+ KEY("version"),
+ {0}
+};
+
+#define ITEMS (sizeof(key)/sizeof(key[0])-1)
+
+#define LIC(s,c) {s,sizeof(s)-1,c}
+
+static const Item_t lic[] =
+{
+ LIC("none", NONE),
+ LIC("inline", SPECIAL),
+ LIC("test", TEST),
+ LIC("verbose", VERBOSE),
+ LIC("usage", USAGE),
+ LIC("open", OPEN),
+ LIC("cpl", OPEN),
+ LIC("epl", OPEN),
+ LIC("bsd", OPEN),
+ LIC("zlib", OPEN),
+ LIC("mit", OPEN),
+ LIC("gpl", GPL),
+ LIC("special", SPECIAL),
+ LIC("nonexclusive", SPECIAL),
+ LIC("noncommercial", SPECIAL),
+ LIC("proprietary", PROPRIETARY),
+ {0}
+};
+
+typedef struct Notice_s
+{
+ int test;
+ int type;
+ int verbose;
+ int ids;
+ Item_t item[ITEMS];
+ Id_t id[IDS];
+ char cc[3];
+} Notice_t;
+
+/*
+ * return index given <name,size>
+ */
+
+static int
+lookup(register const Item_t* item, const char* name, int size)
+{
+ register int c;
+ register int i;
+
+ c = name[0];
+ for (i = 0; item[i].data; i++)
+ if (c == item[i].data[0] && size == item[i].size && !strncmp(name, item[i].data, size))
+ return i;
+ return -1;
+}
+
+/*
+ * copy s of size n to b
+ * n<0 means 0 terminated string
+ */
+
+static void
+copy(register Buffer_t* b, register char* s, int n)
+{
+ if (n < 0)
+ n = strlen(s);
+ while (n--)
+ PUT(b, *s++);
+}
+
+/*
+ * center and copy comment line s to p
+ * if s==0 then
+ * n>0 first frame line
+ * n=0 blank line
+ * n<0 last frame line
+ * if u>0 then s converted to upper case
+ * if u<0 then s is left justified
+ */
+
+static void
+comment(Notice_t* notice, register Buffer_t* b, register char* s, register int n, int u)
+{
+ register int i;
+ register int m;
+ register int x;
+ int cc;
+
+ cc = notice->cc[1];
+ if (!s)
+ {
+ if (n)
+ {
+ PUT(b, notice->cc[n > 0 ? 0 : 1]);
+ for (i = 0; i < COMDATA; i++)
+ PUT(b, cc);
+ PUT(b, notice->cc[n > 0 ? 1 : 2]);
+ }
+ else
+ s = "";
+ }
+ if (s)
+ {
+ if (n > COMDATA)
+ n = COMDATA;
+ PUT(b, cc);
+ m = (u < 0) ? 1 : (COMDATA - n) / 2;
+ if ((x = COMDATA - m - n) < 0)
+ n--;
+ while (m-- > 0)
+ PUT(b, ' ');
+ while (n-- > 0)
+ {
+ i = *s++;
+ if (u > 0 && i >= 'a' && i <= 'z')
+ i = i - 'a' + 'A';
+ PUT(b, i);
+ }
+ while (x-- > 0)
+ PUT(b, ' ');
+ PUT(b, cc);
+ }
+ PUT(b, '\n');
+}
+
+/*
+ * expand simple ${...}
+ */
+
+static void
+expand(Notice_t* notice, register Buffer_t* b, const Item_t* item)
+{
+ register char* t;
+ register char* e;
+ register int q;
+ register char* x;
+ register char* z;
+ register int c;
+ int m;
+ int i;
+ int k;
+
+ if (t = item->data)
+ {
+ q = item->quote;
+ e = t + item->size;
+ i = 0;
+ while (t < e)
+ {
+ if (*t == '$' && t < (e + 2) && *(t + 1) == '{')
+ {
+ k = m = 0;
+ x = t += 2;
+ while (t < e && (c = *t++) != '}')
+ if (c == '.')
+ x = t;
+ else if (c == '-')
+ {
+ k = 1;
+ break;
+ }
+ else if (c == '/')
+ {
+ m = 1;
+ break;
+ }
+ if ((c = lookup(key, x, t - x - 1)) >= 0 && (x = notice->item[c].data))
+ {
+ z = x + notice->item[c].size;
+ while (x < z)
+ {
+ c = *x++;
+ if (!m || c >= '0' && c <= '9')
+ PUT(b, c);
+ }
+ }
+ else if (k)
+ {
+ k = 0;
+ i++;
+ }
+ if (k || m)
+ {
+ k = 1;
+ while (t < e)
+ if ((c = *t++) == '{')
+ k++;
+ else if (c == '}' && !--k)
+ break;
+ }
+ }
+ else if (q > 0 && *t == '\\' && (*(t + 1) == q || *(t + 1) == '\\'))
+ t++;
+ else if (*t == '}' && i)
+ {
+ t++;
+ i--;
+ }
+ else
+ PUT(b, *t++);
+ }
+ }
+}
+
+/*
+ * generate a copright notice
+ */
+
+static void
+copyright(Notice_t* notice, register Buffer_t* b)
+{
+ register char* x;
+ register char* t;
+ time_t clock;
+
+ copy(b, "Copyright (c) ", -1);
+ if (notice->test)
+ clock = (time_t)1000212300;
+ else if (!(t = notice->item[SOURCE].data))
+ {
+ time(&clock);
+ t = ctime(&clock) + 20;
+ }
+ if ((x = notice->item[START].data) && strncmp(t, x, 4) < 0)
+ t = x;
+ if ((x = notice->item[SINCE].data) && strncmp(x, t, 4) < 0)
+ {
+ expand(notice, b, &notice->item[SINCE]);
+ PUT(b, '-');
+ }
+ copy(b, t, 4);
+ if (notice->item[PARENT].data)
+ {
+ PUT(b, ' ');
+ expand(notice, b, &notice->item[PARENT]);
+ }
+ if (notice->item[CORPORATION].data)
+ {
+ PUT(b, ' ');
+ expand(notice, b, &notice->item[CORPORATION]);
+ if (notice->item[INCORPORATION].data)
+ {
+ PUT(b, ' ');
+ expand(notice, b, &notice->item[INCORPORATION]);
+ }
+ }
+ else if (notice->item[COMPANY].data)
+ {
+ PUT(b, ' ');
+ expand(notice, b, &notice->item[COMPANY]);
+ }
+}
+
+typedef struct Stack_s
+{
+ char* info;
+ char* file;
+ int line;
+ int size;
+} Stack_t;
+
+static int
+push(Stack_t* sp, char* file, char* parent, char* info, int size, Buffer_t* buf)
+{
+ char* s;
+ char* t;
+ int i;
+ int n;
+ char path[1024];
+
+ if (size <= 8)
+ {
+ copy(buf, file, -1);
+ copy(buf, ": no space", -1);
+ PUT(buf, 0);
+ return -1;
+ }
+ if (*file != '/' && parent && (s = strrchr(parent, '/')))
+ {
+ n = s - parent + 1;
+ if ((strlen(file) + n + 1) <= sizeof(path))
+ {
+ memcpy(path, parent, n);
+ strcpy(path + n, file);
+ file = path;
+ }
+ }
+ if ((i = open(file, O_RDONLY)) < 0)
+ {
+ /* this hack viewpath lookup works for default package setups */
+ if (file == path)
+ for (s = path; *s; s++)
+ if (s[0] == '/' && s[1] == 'a' && s[2] == 'r' && s[3] == 'c' && s[4] == 'h' && s[5] == '/')
+ {
+ t = s;
+ for (s += 6; *s && *s != '/'; s++);
+ while (*t++ = *s++);
+ i = open(file, O_RDONLY);
+ }
+ if (i < 0)
+ {
+ copy(buf, file, -1);
+ copy(buf, ": cannot open", -1);
+ PUT(buf, 0);
+ return -1;
+ }
+ }
+ n = read(i, info, size - 1);
+ close(i);
+ if (n < 0)
+ {
+ copy(buf, file, -1);
+ copy(buf, ": cannot read", -1);
+ PUT(buf, 0);
+ return -1;
+ }
+ info[n++] = 0;
+ sp->file = file;
+ sp->info = info;
+ sp->line = 0;
+ sp->size = n;
+ return 0;
+}
+
+/*
+ * read the license file and generate a comment in p, length size
+ * license length in p returned, -1 on error
+ * -1 return places 0 terminated error string in p
+ */
+
+int
+astlicense(char* p, int size, char* file, char* options, int cc1, int cc2, int cc3)
+{
+ register char* s;
+ register char* v;
+ register char* x;
+ register int c;
+ int i;
+ int h;
+ int k;
+ int n;
+ int q;
+ int contributor;
+ int first;
+ int level;
+ int quote;
+ char* data;
+ char tmpbuf[COMLINE];
+ char info[8 * 1024];
+ Stack_t input[4];
+ Notice_t notice;
+ Item_t item;
+ Buffer_t buf;
+ Buffer_t tmp;
+
+ buf.end = (buf.buf = buf.nxt = p) + size;
+ tmp.end = (tmp.buf = tmp.nxt = tmpbuf) + sizeof(tmpbuf);
+ level = 0;
+ data = info;
+ level = -1;
+ if (options)
+ {
+ level++;
+ input[level].file = "<options>";
+ input[level].info = options;
+ input[level].line = 0;
+ }
+ if (file && *file)
+ {
+ if (push(&input[++level], file, 0, data, &info[sizeof(info)] - data, &buf))
+ return -1;
+ data += input[level].size;
+ }
+ if (level < 0)
+ return 0;
+ s = input[level].info;
+ notice.test = 0;
+ notice.type = NONE;
+ notice.verbose = 0;
+ notice.ids = 0;
+ notice.cc[0] = cc1;
+ notice.cc[1] = cc2;
+ notice.cc[2] = cc3;
+ for (i = 0; i < ITEMS; i++)
+ notice.item[i].data = 0;
+ notice.item[STYLE] = notice.item[CLASS] = lic[notice.type];
+ notice.item[STYLE].quote = notice.item[CLASS].quote = 0;
+ contributor = i = k = 0;
+ for (;;)
+ {
+ first = 1;
+ while (c = *s)
+ {
+ while (c == ' ' || c == '\t' || c == '\n' && ++input[level].line || c == '\r' || c == ',' || c == ';' || c == ')')
+ c = *++s;
+ if (!c)
+ break;
+ if (c == '#')
+ {
+ while (*++s && *s != '\n');
+ if (*s)
+ s++;
+ input[level].line++;
+ continue;
+ }
+ if (c == '.')
+ {
+ while ((c = *++s) && (c == ' ' || c == '\t'));
+ file = s;
+ while (c && c != ' ' && c != '\t' && c != '\r' && c != '\n')
+ c = *++s;
+ *s = 0;
+ while (c && c != '\n')
+ c = *++s;
+ if (*file)
+ {
+ input[level].info = s + (c != 0);
+ if (++level >= (sizeof(input) / sizeof(input[0])) || push(&input[level], file, input[level-1].file, data, &info[sizeof(info)] - data, &buf))
+ return -1;
+ data += input[level].size;
+ s = input[level].info;
+ }
+ continue;
+ }
+ if (c == '\n')
+ {
+ s++;
+ input[level].line++;
+ continue;
+ }
+ if (c == '[')
+ c = *++s;
+ x = s;
+ n = 0;
+ while (c && c != '+' && c != '=' && c != ']' && c != ')' && c != ',' && c != ' ' && c != '\t' && c != '\n' && c != '\r')
+ c = *++s;
+ n = s - x;
+ h = lookup(key, x, n);
+ if (c == '+' || c == ']')
+ c = *++s;
+ quote = 0;
+ if (c == '=' || first)
+ {
+ if (c == '=')
+ {
+ q = ((c = *++s) == '"' || c == '\'') ? *s++ : 0;
+ if (c == '(')
+ {
+ s++;
+ if (h == LICENSE)
+ contributor = 0;
+ else if (h == CONTRIBUTOR)
+ contributor = 1;
+ else
+ {
+ q = 1;
+ i = 0;
+ for (;;)
+ {
+ switch (*s++)
+ {
+ case 0:
+ s--;
+ break;
+ case '(':
+ if (!i)
+ q++;
+ continue;
+ case ')':
+ if (!i && !--q)
+ break;
+ continue;
+ case '"':
+ case '\'':
+ if (!i)
+ i = *(s - 1);
+ else if (i == *(s - 1))
+ i = 0;
+ continue;
+ case '\\':
+ if (*s == i && i == '"')
+ i++;
+ continue;
+ case '\n':
+ input[level].line++;
+ continue;
+ default:
+ continue;
+ }
+ break;
+ }
+ }
+ continue;
+ }
+ v = s;
+ while ((c = *s) && (q == '"' && (c == '\\' && (*(s + 1) == '"' || *(s + 1) == '\\') && s++ && (quote = q)) || q && c != q || !q && c != ' ' && c != '\t' && c != '\n' && c != '\r' && c != ',' && c != ';'))
+ {
+ if (c == '\n')
+ input[level].line++;
+ s++;
+ }
+ }
+ else
+ {
+ h = STYLE;
+ v = x;
+ }
+ if (c == '\n')
+ input[level].line++;
+ if (contributor)
+ {
+ for (i = 0; i < notice.ids; i++)
+ if (n == notice.id[i].name.size && !strncmp(x, notice.id[i].name.data, n))
+ break;
+ if (i < IDS)
+ {
+ notice.id[i].name.data = x;
+ notice.id[i].name.size = n;
+ notice.id[i].name.quote = 0;
+ notice.id[i].value.data = v;
+ notice.id[i].value.size = s - v;
+ notice.id[i].value.quote = quote;
+ if (notice.ids <= i)
+ notice.ids = i + 1;
+ }
+ }
+ else if (h == QUERY)
+ {
+ if ((s - v) == 3 && v[0] == 'a' && v[1] == 'l' && v[2] == 'l')
+ {
+ for (i = 0; i < ITEMS; i++)
+ if (notice.item[i].size)
+ {
+ expand(&notice, &buf, &key[i]);
+ PUT(&buf, '=');
+ for (h = 0;; h++)
+ if (h >= notice.item[i].size)
+ {
+ h = 0;
+ break;
+ }
+ else if (notice.item[i].data[h] == ' ' || notice.item[i].data[h] == '\t')
+ break;
+ if (h)
+ PUT(&buf, '\'');
+ expand(&notice, &buf, &notice.item[i]);
+ if (h)
+ PUT(&buf, '\'');
+ PUT(&buf, '\n');
+ }
+ }
+ else
+ {
+ if ((h = lookup(key, v, s - v)) < 0)
+ {
+ item.data = v;
+ item.size = s - v;
+ item.quote = 0;
+ expand(&notice, &buf, &item);
+ }
+ else
+ expand(&notice, &buf, &notice.item[h]);
+ PUT(&buf, '\n');
+ }
+ return END(&buf);
+ }
+ else
+ {
+ if (h == STYLE)
+ switch (c = lookup(lic, v, s - v))
+ {
+ case NONE:
+ return 0;
+ case TEST:
+ notice.test = 1;
+ h = -1;
+ break;
+ case VERBOSE:
+ notice.verbose = 1;
+ h = -1;
+ break;
+ case USAGE:
+ notice.type = c;
+ h = -1;
+ break;
+ case -1:
+ c = SPECIAL;
+ /*FALLTHROUGH*/
+ default:
+ notice.type = c;
+ notice.item[CLASS].data = lic[lic[c].quote].data;
+ notice.item[CLASS].size = lic[lic[c].quote].size;
+ if (notice.item[STYLE].data != lic[NONE].data)
+ h = -1;
+ break;
+ }
+ if (h >= 0)
+ {
+ notice.item[h].data = (notice.item[h].size = s - v) ? v : (char*)0;
+ notice.item[h].quote = quote;
+ k = 1;
+ }
+ }
+ }
+ else
+ {
+ if (input[level].file)
+ {
+ copy(&buf, "\"", -1);
+ copy(&buf, input[level].file, -1);
+ copy(&buf, "\", line ", -1);
+ x = &tmpbuf[sizeof(tmpbuf)];
+ *--x = 0;
+ n = ++input[level].line;
+ do *--x = ("0123456789")[n % 10]; while (n /= 10);
+ copy(&buf, x, -1);
+ copy(&buf, ": ", -1);
+ }
+ copy(&buf, "option error: assignment expected", -1);
+ PUT(&buf, 0);
+ return -1;
+ }
+ if (*s)
+ s++;
+ first = 0;
+ }
+ if (!level--)
+ break;
+ s = input[level].info;
+ }
+ if (!k)
+ return 0;
+ if (notice.type == INLINE && (!notice.verbose || !notice.item[NOTICE].data))
+ return 0;
+ if (notice.type != USAGE)
+ {
+ if (!notice.type)
+ notice.type = SPECIAL;
+ comment(&notice, &buf, NiL, 1, 0);
+ comment(&notice, &buf, NiL, 0, 0);
+ if (notice.item[PACKAGE].data)
+ {
+ copy(&tmp, "This software is part of the ", -1);
+ expand(&notice, &tmp, &notice.item[PACKAGE]);
+ copy(&tmp, " package", -1);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ }
+ if (notice.type >= OPEN)
+ {
+ copyright(&notice, &tmp);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ if (notice.type >= SPECIAL)
+ COMMENT(&notice, &buf, "All Rights Reserved", 0);
+ }
+ if (notice.type == CPL || notice.type == EPL)
+ {
+ copy(&tmp, notice.item[PACKAGE].data ? "and" : "This software", -1);
+ copy(&tmp, " is licensed under the", -1);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ if (notice.type == EPL)
+ copy(&tmp, "Eclipse Public License", -1);
+ else
+ copy(&tmp, "Common Public License", -1);
+ if (notice.item[VERSION].data)
+ {
+ copy(&tmp, ", Version ", -1);
+ expand(&notice, &tmp, &notice.item[VERSION]);
+ }
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ if (notice.item[CORPORATION].data || notice.item[COMPANY].data)
+ {
+ copy(&tmp, "by ", -1);
+ if (notice.item[PARENT].data)
+ {
+ expand(&notice, &tmp, &notice.item[PARENT]);
+ copy(&tmp, " ", -1);
+ }
+ if (notice.item[CORPORATION].data)
+ {
+ expand(&notice, &tmp, &notice.item[CORPORATION]);
+ if (notice.item[INCORPORATION].data)
+ {
+ copy(&tmp, " ", -1);
+ expand(&notice, &tmp, &notice.item[INCORPORATION]);
+ }
+ }
+ else if (notice.item[COMPANY].data)
+ expand(&notice, &tmp, &notice.item[COMPANY]);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ }
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, "A copy of the License is available at", 0);
+ if (notice.item[URL].data)
+ {
+ expand(&notice, &tmp, &notice.item[URL]);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ if (notice.item[URLMD5].data)
+ {
+ copy(&tmp, "(with md5 checksum ", -1);
+ expand(&notice, &tmp, &notice.item[URLMD5]);
+ copy(&tmp, ")", -1);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ }
+ }
+ else if (notice.type == EPL)
+ COMMENT(&notice, &buf, "http://www.eclipse.org/org/documents/epl-v10.html", 0);
+ else
+ COMMENT(&notice, &buf, "http://www.opensource.org/licenses/cpl", 0);
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ else if (notice.type == OPEN)
+ {
+ copy(&tmp, notice.item[PACKAGE].data ? "and it" : "This software", -1);
+ copy(&tmp, " may only be used by you under license from", -1);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ if (notice.item[i = CORPORATION].data)
+ {
+ if (notice.item[PARENT].data)
+ {
+ expand(&notice, &tmp, &notice.item[i = PARENT]);
+ copy(&tmp, " ", -1);
+ }
+ expand(&notice, &tmp, &notice.item[CORPORATION]);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ }
+ else if (notice.item[i = COMPANY].data)
+ {
+ if (notice.item[PARENT].data)
+ {
+ expand(&notice, &tmp, &notice.item[i = PARENT]);
+ copy(&tmp, " ", -1);
+ }
+ expand(&notice, &tmp, &notice.item[COMPANY]);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ }
+ else
+ i = -1;
+ if (notice.item[URL].data)
+ {
+ COMMENT(&notice, &buf, "A copy of the Source Code Agreement is available", 0);
+ copy(&tmp, "at the ", -1);
+ if (i >= 0)
+ expand(&notice, &tmp, &notice.item[i]);
+ copy(&tmp, " Internet web site URL", -1);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ comment(&notice, &buf, NiL, 0, 0);
+ expand(&notice, &tmp, &notice.item[URL]);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ if (notice.item[URLMD5].data)
+ {
+ copy(&tmp, "(with an md5 checksum of ", -1);
+ expand(&notice, &tmp, &notice.item[URLMD5]);
+ copy(&tmp, ")", -1);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ }
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ COMMENT(&notice, &buf, "If you have copied or used this software without agreeing", 0);
+ COMMENT(&notice, &buf, "to the terms of the license you are infringing on", 0);
+ COMMENT(&notice, &buf, "the license and copyright and are violating", 0);
+ if (i >= 0)
+ expand(&notice, &tmp, &notice.item[i]);
+ copy(&tmp, "'s", -1);
+ if (n >= COMLONG)
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ else
+ PUT(&tmp, ' ');
+ copy(&tmp, "intellectual property rights.", -1);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ else if (notice.type == GPL)
+ {
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, "This is free software; you can redistribute it and/or", 0);
+ COMMENT(&notice, &buf, "modify it under the terms of the GNU General Public License", 0);
+ COMMENT(&notice, &buf, "as published by the Free Software Foundation;", 0);
+ COMMENT(&notice, &buf, "either version 2, or (at your option) any later version.", 0);
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, "This software is distributed in the hope that it", 0);
+ COMMENT(&notice, &buf, "will be useful, but WITHOUT ANY WARRANTY;", 0);
+ COMMENT(&notice, &buf, "without even the implied warranty of MERCHANTABILITY", 0);
+ COMMENT(&notice, &buf, "or FITNESS FOR A PARTICULAR PURPOSE.", 0);
+ COMMENT(&notice, &buf, "See the GNU General Public License for more details.", 0);
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, "You should have received a copy of the", 0);
+ COMMENT(&notice, &buf, "GNU General Public License", 0);
+ COMMENT(&notice, &buf, "along with this software (see the file COPYING.)", 0);
+ COMMENT(&notice, &buf, "If not, a copy is available at", 0);
+ COMMENT(&notice, &buf, "http://www.gnu.org/copyleft/gpl.html", 0);
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ else if (notice.type == BSD)
+ {
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, "Redistribution and use in source and binary forms, with or", -1);
+ COMMENT(&notice, &buf, "without modification, are permitted provided that the following", -1);
+ COMMENT(&notice, &buf, "conditions are met:", -1);
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, " 1. Redistributions of source code must retain the above", -1);
+ COMMENT(&notice, &buf, " copyright notice, this list of conditions and the", -1);
+ COMMENT(&notice, &buf, " following disclaimer.", -1);
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, " 2. Redistributions in binary form must reproduce the above", -1);
+ COMMENT(&notice, &buf, " copyright notice, this list of conditions and the", -1);
+ COMMENT(&notice, &buf, " following disclaimer in the documentation and/or other", -1);
+ COMMENT(&notice, &buf, " materials provided with the distribution.", -1);
+ comment(&notice, &buf, NiL, 0, 0);
+ copy(&tmp, " 3. Neither the name of ", -1);
+ if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data || notice.item[i = COMPANY].data)
+ expand(&notice, &tmp, &notice.item[i]);
+ else
+ copy(&tmp, "the copyright holder", -1);
+ copy(&tmp, " nor the", -1);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), -1);
+ COMMENT(&notice, &buf, " names of its contributors may be used to endorse or", -1);
+ COMMENT(&notice, &buf, " promote products derived from this software without", -1);
+ COMMENT(&notice, &buf, " specific prior written permission.", -1);
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND", -1);
+ COMMENT(&notice, &buf, "CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES,", -1);
+ COMMENT(&notice, &buf, "INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF", -1);
+ COMMENT(&notice, &buf, "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE", -1);
+ COMMENT(&notice, &buf, "DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS", -1);
+ COMMENT(&notice, &buf, "BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,", -1);
+ COMMENT(&notice, &buf, "EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED", -1);
+ COMMENT(&notice, &buf, "TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,", -1);
+ COMMENT(&notice, &buf, "DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON", -1);
+ COMMENT(&notice, &buf, "ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,", -1);
+ COMMENT(&notice, &buf, "OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY", -1);
+ COMMENT(&notice, &buf, "OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE", -1);
+ COMMENT(&notice, &buf, "POSSIBILITY OF SUCH DAMAGE.", -1);
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ else if (notice.type == ZLIB)
+ {
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, "This software is provided 'as-is', without any express or implied", -1);
+ COMMENT(&notice, &buf, "warranty. In no event will the authors be held liable for any", -1);
+ COMMENT(&notice, &buf, "damages arising from the use of this software.", -1);
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, "Permission is granted to anyone to use this software for any", -1);
+ COMMENT(&notice, &buf, "purpose, including commercial applications, and to alter it and", -1);
+ COMMENT(&notice, &buf, "redistribute it freely, subject to the following restrictions:", -1);
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, " 1. The origin of this software must not be misrepresented;", -1);
+ COMMENT(&notice, &buf, " you must not claim that you wrote the original software. If", -1);
+ COMMENT(&notice, &buf, " you use this software in a product, an acknowledgment in the", -1);
+ COMMENT(&notice, &buf, " product documentation would be appreciated but is not", -1);
+ COMMENT(&notice, &buf, " required.", -1);
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, " 2. Altered source versions must be plainly marked as such,", -1);
+ COMMENT(&notice, &buf, " and must not be misrepresented as being the original", -1);
+ COMMENT(&notice, &buf, " software.", -1);
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, " 3. This notice may not be removed or altered from any source", -1);
+ COMMENT(&notice, &buf, " distribution.", -1);
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ else if (notice.type == MIT)
+ {
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, "Permission is hereby granted, free of charge, to any person", 0);
+ COMMENT(&notice, &buf, "obtaining a copy of this software and associated", 0);
+ COMMENT(&notice, &buf, "documentation files (the \"Software\"), to deal in the", 0);
+ COMMENT(&notice, &buf, "Software without restriction, including without limitation", 0);
+ COMMENT(&notice, &buf, "the rights to use, copy, modify, merge, publish, distribute,", 0);
+ COMMENT(&notice, &buf, "sublicense, and/or sell copies of the Software, and to", 0);
+ COMMENT(&notice, &buf, "permit persons to whom the Software is furnished to do so,", 0);
+ COMMENT(&notice, &buf, "subject to the following conditions:", 0);
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, "The above copyright notice and this permission notice shall", 0);
+ COMMENT(&notice, &buf, "be included in all copies or substantial portions of the", 0);
+ COMMENT(&notice, &buf, "Software.", 0);
+ comment(&notice, &buf, NiL, 0, 0);
+ COMMENT(&notice, &buf, "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY", 0);
+ COMMENT(&notice, &buf, "KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE", 0);
+ COMMENT(&notice, &buf, "WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR", 0);
+ COMMENT(&notice, &buf, "PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS", 0);
+ COMMENT(&notice, &buf, "OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR", 0);
+ COMMENT(&notice, &buf, "OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR", 0);
+ COMMENT(&notice, &buf, "OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE", 0);
+ COMMENT(&notice, &buf, "SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.", 0);
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ else
+ {
+ if (notice.type == PROPRIETARY)
+ {
+ if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data || notice.item[i = COMPANY].data)
+ {
+ expand(&notice, &tmp, &notice.item[i]);
+ copy(&tmp, " - ", -1);
+ }
+ else
+ i = -1;
+ copy(&tmp, "Proprietary", -1);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
+ comment(&notice, &buf, NiL, 0, 0);
+ if (notice.item[URL].data)
+ {
+ copy(&tmp, "This is proprietary source code", -1);
+ if (i >= 0)
+ copy(&tmp, " licensed by", -1);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
+ if (notice.item[PARENT].data)
+ {
+ expand(&notice, &tmp, &notice.item[PARENT]);
+ copy(&tmp, " ", -1);
+ }
+ if (notice.item[CORPORATION].data)
+ {
+ expand(&notice, &tmp, &notice.item[CORPORATION]);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
+ }
+ else if (notice.item[COMPANY].data)
+ {
+ expand(&notice, &tmp, &notice.item[COMPANY]);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
+ }
+ }
+ else
+ {
+ copy(&tmp, "This is unpublished proprietary source code", -1);
+ if (i >= 0)
+ copy(&tmp, " of", -1);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
+ if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data)
+ expand(&notice, &tmp, &notice.item[i]);
+ if (notice.item[COMPANY].data)
+ {
+ if (SIZ(&tmp))
+ PUT(&tmp, ' ');
+ expand(&notice, &tmp, &notice.item[COMPANY]);
+ }
+ if (SIZ(&tmp))
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 1);
+ COMMENT(&notice, &buf, "and is not to be disclosed or used except in", 1);
+ COMMENT(&notice, &buf, "accordance with applicable agreements", 1);
+ }
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ else if (notice.type == NONEXCLUSIVE)
+ {
+ COMMENT(&notice, &buf, "For nonexclusive individual use", 1);
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ else if (notice.type == NONCOMMERCIAL)
+ {
+ COMMENT(&notice, &buf, "For noncommercial use", 1);
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ if (notice.type >= PROPRIETARY && !notice.item[URL].data)
+ {
+ COMMENT(&notice, &buf, "Unpublished & Not for Publication", 0);
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ if (notice.item[URL].data)
+ {
+ copy(&tmp, "This software is licensed", -1);
+ if (notice.item[CORPORATION].data || notice.item[COMPANY].data)
+ {
+ copy(&tmp, " by", -1);
+ if ((notice.item[PARENT].size + (notice.item[CORPORATION].data ? (notice.item[CORPORATION].size + notice.item[INCORPORATION].size) : notice.item[COMPANY].size)) >= (COMLONG - 6))
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ else
+ PUT(&tmp, ' ');
+ if (notice.item[PARENT].data)
+ {
+ expand(&notice, &tmp, &notice.item[PARENT]);
+ copy(&tmp, " ", -1);
+ }
+ if (notice.item[CORPORATION].data)
+ {
+ expand(&notice, &tmp, &notice.item[CORPORATION]);
+ if (notice.item[INCORPORATION].data)
+ {
+ copy(&tmp, " ", -1);
+ expand(&notice, &tmp, &notice.item[INCORPORATION]);
+ }
+ }
+ else if (notice.item[COMPANY].data)
+ expand(&notice, &tmp, &notice.item[COMPANY]);
+ }
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ COMMENT(&notice, &buf, "under the terms and conditions of the license in", 0);
+ expand(&notice, &tmp, &notice.item[URL]);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ if (notice.item[URLMD5].data)
+ {
+ copy(&tmp, "(with an md5 checksum of ", -1);
+ expand(&notice, &tmp, &notice.item[URLMD5]);
+ copy(&tmp, ")", -1);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ }
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ else if (notice.type == PROPRIETARY)
+ {
+ COMMENT(&notice, &buf, "The copyright notice above does not evidence any", 0);
+ COMMENT(&notice, &buf, "actual or intended publication of such source code", 0);
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ }
+ if (v = notice.item[NOTICE].data)
+ {
+ x = v + notice.item[NOTICE].size;
+ if (*v == '\n')
+ v++;
+ item.quote = notice.item[NOTICE].quote;
+ do
+ {
+ for (item.data = v; v < x && *v != '\n'; v++);
+ if ((item.size = v - item.data) && *item.data == '\t')
+ {
+ item.data++;
+ item.size--;
+ h = 0;
+ }
+ else
+ h = -1;
+ expand(&notice, &tmp, &item);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), h);
+ } while (v++ < x);
+ if (item.size)
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ if (notice.item[ORGANIZATION].data)
+ {
+ expand(&notice, &tmp, &notice.item[ORGANIZATION]);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ if (notice.item[i = PARENT].data || notice.item[i = CORPORATION].data)
+ expand(&notice, &tmp, &notice.item[i]);
+ if (notice.item[COMPANY].data)
+ {
+ if (SIZ(&tmp))
+ PUT(&tmp, ' ');
+ expand(&notice, &tmp, &notice.item[COMPANY]);
+ }
+ if (SIZ(&tmp))
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ if (notice.item[LOCATION].data)
+ {
+ expand(&notice, &tmp, &notice.item[LOCATION]);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ }
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ }
+ if (v = notice.item[AUTHOR].data)
+ {
+ x = v + notice.item[AUTHOR].size;
+ q = (x - v) == 1 && (*v == '*' || *v == '-');
+ k = q && notice.type != USAGE ? -1 : 0;
+ for (;;)
+ {
+ if (!q)
+ {
+ while (v < x && (*v == ' ' || *v == '\t' || *v == '\r' || *v == '\n' || *v == ',' || *v == '+'))
+ v++;
+ if (v >= x)
+ break;
+ item.data = v;
+ while (v < x && *v != ',' && *v != '+' && *v++ != '>');
+ item.size = v - item.data;
+ item.quote = notice.item[AUTHOR].quote;
+ }
+ h = 0;
+ for (i = 0; i < notice.ids; i++)
+ if (q || item.size == notice.id[i].name.size && !strncmp(item.data, notice.id[i].name.data, item.size))
+ {
+ h = 1;
+ if (notice.type == USAGE)
+ {
+ copy(&buf, "[-author?", -1);
+ expand(&notice, &buf, &notice.id[i].value);
+ PUT(&buf, ']');
+ }
+ else
+ {
+ if (k < 0)
+ {
+ COMMENT(&notice, &buf, "CONTRIBUTORS", 0);
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ k = 1;
+ expand(&notice, &tmp, &notice.id[i].value);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ }
+ if (!q)
+ break;
+ }
+ if (q)
+ break;
+ if (!h)
+ {
+ if (notice.type == USAGE)
+ {
+ copy(&buf, "[-author?", -1);
+ expand(&notice, &buf, &item);
+ PUT(&buf, ']');
+ }
+ else
+ {
+ if (k < 0)
+ {
+ COMMENT(&notice, &buf, "CONTRIBUTORS", 0);
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ k = 1;
+ expand(&notice, &tmp, &item);
+ comment(&notice, &buf, BUF(&tmp), USE(&tmp), 0);
+ }
+ }
+ }
+ if (k > 0)
+ comment(&notice, &buf, NiL, 0, 0);
+ }
+ if (notice.type == USAGE)
+ {
+ copy(&buf, "[-copyright?", -1);
+ copyright(&notice, &buf);
+ PUT(&buf, ']');
+ if (notice.item[URL].data)
+ {
+ copy(&buf, "[-license?", -1);
+ expand(&notice, &buf, &notice.item[URL]);
+ PUT(&buf, ']');
+ }
+ PUT(&buf, '\n');
+ }
+ else
+ comment(&notice, &buf, NiL, -1, 0);
+ return END(&buf);
+}
diff --git a/src/lib/libast/port/astmath.c b/src/lib/libast/port/astmath.c
new file mode 100644
index 0000000..395312e
--- /dev/null
+++ b/src/lib/libast/port/astmath.c
@@ -0,0 +1,72 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * used to test if -last requires -lm
+ *
+ * arch -last -lm
+ * ---- ----- ---
+ * linux.sparc sfdlen,sfputd frexp,ldexp
+ */
+
+#if N >= 8
+#define _ISOC99_SOURCE 1
+#endif
+
+#include <math.h>
+
+int
+main()
+{
+#if N & 1
+ long double value = 0;
+#else
+ double value = 0;
+#endif
+#if N < 5
+ int exp = 0;
+#endif
+
+#if N == 1
+ return ldexpl(value, exp) != 0;
+#endif
+#if N == 2
+ return ldexp(value, exp) != 0;
+#endif
+#if N == 3
+ return frexpl(value, &exp) != 0;
+#endif
+#if N == 4
+ return frexp(value, &exp) != 0;
+#endif
+#if N == 5
+ return isnan(value);
+#endif
+#if N == 6
+ return isnan(value);
+#endif
+#if N == 7
+ return copysign(1.0, value) < 0;
+#endif
+#if N == 8
+ return signbit(value);
+#endif
+}
diff --git a/src/lib/libast/port/astquery.c b/src/lib/libast/port/astquery.c
new file mode 100644
index 0000000..d0d87db
--- /dev/null
+++ b/src/lib/libast/port/astquery.c
@@ -0,0 +1,114 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Research
+ *
+ * output printf prompt and read response
+ * if format==0 then verify that interaction is possible
+ *
+ * return:
+ *
+ * 0 [1yY+]
+ * -1 [qQ] or EOF
+ * 1 otherwise
+ *
+ * if (quit&ERROR_PROMPT) then tty forced for IO
+ * if quit>=0 then [qQ] or EOF calls exit(quit)
+ */
+
+#include <ast.h>
+#include <error.h>
+
+int
+astquery(int quit, const char* format, ...)
+{
+ va_list ap;
+ register int n;
+ register int c;
+ int r;
+ Sfio_t* ip;
+ Sfio_t* op;
+
+ static Sfio_t* rfp;
+ static Sfio_t* wfp;
+
+ r = 0;
+ va_start(ap, format);
+ if (!format)
+ goto done;
+ r = -1;
+ if (!rfp)
+ {
+ c = errno;
+ if (isatty(sffileno(sfstdin)))
+ rfp = sfstdin;
+ else if (!(rfp = sfopen(NiL, "/dev/tty", "r")))
+ goto done;
+ if (isatty(sffileno(sfstderr)))
+ wfp = sfstderr;
+ else if (!(wfp = sfopen(NiL, "/dev/tty", "w")))
+ goto done;
+ errno = c;
+ }
+ if (quit & ERROR_PROMPT)
+ {
+ quit &= ~ERROR_PROMPT;
+ ip = rfp;
+ op = wfp;
+ }
+ else
+ {
+ ip = sfstdin;
+ op = sfstderr;
+ }
+ sfsync(sfstdout);
+ sfvprintf(op, format, ap);
+ sfsync(op);
+ for (n = c = sfgetc(ip);; c = sfgetc(ip))
+ switch (c)
+ {
+ case EOF:
+ n = c;
+ /*FALLTHROUGH*/
+ case '\n':
+ switch (n)
+ {
+ case EOF:
+ case 'q':
+ case 'Q':
+ if (quit >= 0)
+ exit(quit);
+ goto done;
+ case '1':
+ case 'y':
+ case 'Y':
+ case '+':
+ r = 0;
+ goto done;
+ }
+ return 1;
+ }
+ done:
+ va_end(ap);
+ return r;
+}
diff --git a/src/lib/libast/port/aststatic.c b/src/lib/libast/port/aststatic.c
new file mode 100644
index 0000000..7517572
--- /dev/null
+++ b/src/lib/libast/port/aststatic.c
@@ -0,0 +1,44 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * ast static data initialization
+ */
+
+#include <ast.h>
+
+#if _dll_data_intercept && ( _DLL_BLD || _BLD_DLL )
+
+void
+_ast_init(void)
+{
+ struct _astdll* ap = _ast_getdll();
+
+ ap->_dll_environ = &environ;
+}
+
+#else
+
+NoN(aststatic)
+
+#endif
diff --git a/src/lib/libast/port/astwinsize.c b/src/lib/libast/port/astwinsize.c
new file mode 100644
index 0000000..66f4e09
--- /dev/null
+++ b/src/lib/libast/port/astwinsize.c
@@ -0,0 +1,143 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * AT&T Research
+ * return terminal rows and cols
+ */
+
+#include <ast.h>
+#include <ast_tty.h>
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide ioctl sleep
+#else
+#define ioctl ______ioctl
+#define sleep ______sleep
+#endif
+
+#if _sys_ioctl
+#include <sys/ioctl.h>
+#endif
+
+#if defined(TIOCGWINSZ)
+#if _sys_stream && _sys_ptem
+#include <sys/stream.h>
+#include <sys/ptem.h>
+#endif
+#else
+#if !defined(TIOCGSIZE) && !defined(TIOCGWINSZ)
+#if _hdr_jioctl
+#define jwinsize winsize
+#include <jioctl.h>
+#else
+#if _sys_jioctl
+#define jwinsize winsize
+#include <sys/jioctl.h>
+#endif
+#endif
+#endif
+#endif
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide ioctl sleep
+#else
+#undef ioctl
+#undef sleep
+#endif
+
+static int ttctl(int, int, void*);
+
+void
+astwinsize(int fd, register int* rows, register int* cols)
+{
+#ifdef TIOCGWINSZ
+#define NEED_ttctl
+ struct winsize ws;
+
+ if (!ttctl(fd, TIOCGWINSZ, &ws) && ws.ws_col > 0 && ws.ws_row > 0)
+ {
+ if (rows) *rows = ws.ws_row;
+ if (cols) *cols = ws.ws_col;
+ }
+ else
+#else
+#ifdef TIOCGSIZE
+#define NEED_ttctl
+ struct ttysize ts;
+
+ if (!ttctl(fd, TIOCGSIZE, &ts) && ts.ts_lines > 0 && ts.ts_cols > 0)
+ {
+ if (rows) *rows = ts.ts_lines;
+ if (cols) *cols = ts.ts_cols;
+ }
+ else
+#else
+#ifdef JWINSIZE
+#define NEED_ttctl
+ struct winsize ws;
+
+ if (!ttctl(fd, JWINSIZE, &ws) && ws.bytesx > 0 && ws.bytesy > 0)
+ {
+ if (rows) *rows = ws.bytesy;
+ if (cols) *cols = ws.bytesx;
+ }
+ else
+#endif
+#endif
+#endif
+ {
+ char* s;
+
+ if (rows) *rows = (s = getenv("LINES")) ? strtol(s, NiL, 0) : 0;
+ if (cols) *cols = (s = getenv("COLUMNS")) ? strtol(s, NiL, 0) : 0;
+ }
+}
+
+#ifdef NEED_ttctl
+
+/*
+ * tty ioctl() -- no cache
+ */
+
+static int
+ttctl(register int fd, int op, void* tt)
+{
+ register int v;
+
+ if (fd < 0)
+ {
+ for (fd = 0; fd <= 2; fd++)
+ if (!ioctl(fd, op, tt)) return(0);
+ if ((fd = open("/dev/tty", O_RDONLY)) >= 0)
+ {
+ v = ioctl(fd, op, tt);
+ close(fd);
+ return(v);
+ }
+ }
+ else if (!ioctl(fd, op, tt)) return(0);
+ return(-1);
+}
+
+#endif
diff --git a/src/lib/libast/port/atmain.C b/src/lib/libast/port/atmain.C
new file mode 100644
index 0000000..b6d7560
--- /dev/null
+++ b/src/lib/libast/port/atmain.C
@@ -0,0 +1,37 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if ! __MVS__
+
+void _STUB_atmain(){}
+
+#else
+
+extern "C" void _ast_init();
+
+class Atmain_t
+{
+public: Atmain_t() { _ast_init(); }
+};
+
+static Atmain_t atmain();
+
+#endif
diff --git a/src/lib/libast/port/iblocks.c b/src/lib/libast/port/iblocks.c
new file mode 100644
index 0000000..a768b84
--- /dev/null
+++ b/src/lib/libast/port/iblocks.c
@@ -0,0 +1,95 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * aux function for <ls.h> iblocks() macro
+ *
+ * return number of blocks, including indirect block count
+ * given stat info
+ *
+ * mail gsf@research.att.com when you figure out the stat.st_blocks units
+ * until then we assume LS_BLOCKSIZE (512)
+ */
+
+#include <ast.h>
+#if _AIX /* XXX */
+#undef major
+#undef minor
+#undef makedev
+#endif
+#include <ast_param.h>
+#include <ls.h>
+
+#if !_mem_st_blocks_stat
+
+#ifndef B_DIRECT
+#define B_DIRECT 10
+#endif
+
+#ifdef BITFS
+
+#define B_SIZE BSIZE(st->st_dev)
+#define B_INDIRECT NINDIR(st->st_dev)
+
+#else
+
+#ifdef BSIZE
+#define B_SIZE BSIZE
+#else
+#define B_SIZE 1024
+#endif
+
+#ifdef NINDIR
+#define B_INDIRECT NINDIR
+#else
+#define B_INDIRECT 128
+#endif
+
+#endif
+
+#endif
+
+off_t
+_iblocks(register struct stat* st)
+{
+#if _mem_st_blocks_stat
+
+ return (st->st_blocks <= 0 || st->st_size <= 0) ? 0 : st->st_blocks;
+
+#else
+ unsigned long b;
+ unsigned long t;
+
+ t = b = (st->st_size + B_SIZE - 1) / B_SIZE;
+ if ((b -= B_DIRECT) > 0)
+ {
+ t += (b - 1) / B_INDIRECT + 1;
+ if ((b -= B_INDIRECT) > 0)
+ {
+ t += (b - 1) / (B_INDIRECT * B_INDIRECT) + 1;
+ if (b > B_INDIRECT * B_INDIRECT)
+ t++;
+ }
+ }
+ return t * B_SIZE / LS_BLOCKSIZE;
+#endif
+}
diff --git a/src/lib/libast/port/lc.c b/src/lib/libast/port/lc.c
new file mode 100644
index 0000000..488dd8d
--- /dev/null
+++ b/src/lib/libast/port/lc.c
@@ -0,0 +1,883 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * locale state implementation
+ */
+
+#include "lclib.h"
+#include "lclang.h"
+#include "FEATURE/locale"
+
+#include <ctype.h>
+
+typedef struct Local_s
+{
+ const char* name;
+ int size;
+} Local_t;
+
+#undef setlocale /* this file deals with the system locale */
+
+static Lc_numeric_t default_numeric = { '.', -1 };
+
+static Lc_t default_lc =
+{
+ "C",
+ "POSIX",
+ &lc_languages[0],
+ &lc_territories[0],
+ &lc_charsets[0],
+ 0,
+ LC_default|LC_checked|LC_local,
+ 0,
+ {
+ { &default_lc, 0, 0 },
+ { &default_lc, 0, 0 },
+ { &default_lc, 0, 0 },
+ { &default_lc, 0, 0 },
+ { &default_lc, 0, 0 },
+ { &default_lc, 0, (void*)&default_numeric },
+ { &default_lc, 0, 0 },
+ { &default_lc, 0, 0 },
+ { &default_lc, 0, 0 },
+ { &default_lc, 0, 0 },
+ { &default_lc, 0, 0 },
+ { &default_lc, 0, 0 },
+ { &default_lc, 0, 0 },
+ { &default_lc, 0, 0 }
+ }
+};
+
+static Lc_numeric_t debug_numeric = { ',', '.' };
+
+static Lc_t debug_lc =
+{
+ "debug",
+ "debug",
+ &lc_languages[1],
+ &lc_territories[1],
+ &lc_charsets[0],
+ 0,
+ LC_debug|LC_checked|LC_local,
+ 0,
+ {
+ { &debug_lc, 0, 0 },
+ { &debug_lc, 0, 0 },
+ { &debug_lc, 0, 0 },
+ { &debug_lc, 0, 0 },
+ { &debug_lc, 0, 0 },
+ { &debug_lc, 0, (void*)&debug_numeric },
+ { &debug_lc, 0, 0 },
+ { &debug_lc, 0, 0 },
+ { &debug_lc, 0, 0 },
+ { &debug_lc, 0, 0 },
+ { &debug_lc, 0, 0 },
+ { &debug_lc, 0, 0 },
+ { &debug_lc, 0, 0 },
+ { &debug_lc, 0, 0 }
+ },
+ &default_lc
+};
+
+static Lc_t* lcs = &debug_lc;
+
+Lc_t* locales[] =
+{
+ &default_lc,
+ &default_lc,
+ &default_lc,
+ &default_lc,
+ &default_lc,
+ &default_lc,
+ &default_lc,
+ &default_lc,
+ &default_lc,
+ &default_lc,
+ &default_lc,
+ &default_lc,
+ &default_lc,
+ &default_lc
+};
+
+/*
+ * return the internal category index for category
+ */
+
+int
+lcindex(int category, int min)
+{
+ switch (category)
+ {
+ case LC_ALL: return min ? -1 : AST_LC_ALL;
+ case LC_ADDRESS: return AST_LC_ADDRESS;
+ case LC_COLLATE: return AST_LC_COLLATE;
+ case LC_CTYPE: return AST_LC_CTYPE;
+ case LC_IDENTIFICATION: return AST_LC_IDENTIFICATION;
+ case LC_LANG: return AST_LC_LANG;
+ case LC_MEASUREMENT: return AST_LC_MEASUREMENT;
+ case LC_MESSAGES: return AST_LC_MESSAGES;
+ case LC_MONETARY: return AST_LC_MONETARY;
+ case LC_NAME: return AST_LC_NAME;
+ case LC_NUMERIC: return AST_LC_NUMERIC;
+ case LC_PAPER: return AST_LC_PAPER;
+ case LC_TELEPHONE: return AST_LC_TELEPHONE;
+ case LC_TIME: return AST_LC_TIME;
+ case LC_XLITERATE: return AST_LC_XLITERATE;
+ }
+ return -1;
+}
+
+/*
+ * return the first category table entry
+ */
+
+Lc_category_t*
+lccategories(void)
+{
+ return (Lc_category_t*)&lc_categories[0];
+}
+
+/*
+ * return the current info for category
+ */
+
+Lc_info_t*
+lcinfo(register int category)
+{
+ if ((category = lcindex(category, 0)) < 0)
+ return 0;
+ return LCINFO(category);
+}
+
+/*
+ * return 1 if s matches the alternation pattern p
+ * if minimum!=0 then at least that many chars must match
+ * if standard!=0 and s[0] is a digit leading non-digits are ignored in p
+ */
+
+static int
+match(const char* s, register const char* p, int minimum, int standard)
+{
+ register const char* t;
+ const char* x;
+ int w;
+ int z;
+
+ z = 0;
+ do
+ {
+ t = s;
+ if (standard)
+ {
+ if (isdigit(*t))
+ while (*p && !isdigit(*p))
+ p++;
+ else if (isdigit(*p))
+ while (*t && !isdigit(*t))
+ t++;
+ }
+ if (*p)
+ {
+ w = 0;
+ x = p;
+ while (*p && *p != '|')
+ {
+ if (!*t || *t == ',')
+ break;
+ else if (*t == *p)
+ /*ok*/;
+ else if (*t == '-')
+ {
+ if (standard && isdigit(*p))
+ {
+ t++;
+ continue;
+ }
+ while (*p && *p != '-')
+ p++;
+ if (!*p)
+ break;
+ }
+ else if (*p == '-')
+ {
+ if (standard && isdigit(*t))
+ {
+ p++;
+ continue;
+ }
+ w = 1;
+ while (*t && *t != '-')
+ t++;
+ if (!*t)
+ break;
+ }
+ else
+ break;
+ t++;
+ p++;
+ }
+ if ((!*t || *t == ',') && (!*p || *p == '|' || w))
+ return p - x;
+ if (minimum && z < (p - x) && (p - x) >= minimum)
+ z = p - x;
+ }
+ while (*p && *p != '|')
+ p++;
+ } while (*p++);
+ return z;
+}
+
+/*
+ * return 1 if s matches the charset names in cp
+ */
+
+static int
+match_charset(register const char* s, register const Lc_charset_t* cp)
+{
+ return match(s, cp->code, 0, 1) || match(s, cp->alternates, 3, 1) || cp->ms && match(s, cp->ms, 0, 1);
+}
+
+/*
+ * low level for lccanon
+ */
+
+static size_t
+canonical(const Lc_language_t* lp, const Lc_territory_t* tp, const Lc_charset_t* cp, const Lc_attribute_list_t* ap, unsigned long flags, char* buf, size_t siz)
+{
+ register int c;
+ register int u;
+ register char* s;
+ register char* e;
+ register const char* t;
+ char* p;
+ char* r;
+
+ if (!(flags & (LC_abbreviated|LC_default|LC_local|LC_qualified|LC_verbose)))
+ flags |= LC_abbreviated;
+ s = buf;
+ e = &buf[siz - 3];
+ if (lp)
+ {
+ if (lp->flags & (LC_debug|LC_default))
+ {
+ for (t = lp->code; s < e && (*s = *t++); s++);
+ *s++ = 0;
+ return s - buf;
+ }
+ if (flags & LC_verbose)
+ {
+ u = 1;
+ t = lp->name;
+ while (s < e && (c = *t++))
+ {
+ if (u)
+ {
+ u = 0;
+ c = toupper(c);
+ }
+ else if (!isalnum(c))
+ u = 1;
+ *s++ = c;
+ }
+ }
+ else
+ for (t = lp->code; s < e && (*s = *t++); s++);
+ }
+ if (s < e)
+ {
+ if (tp && tp != &lc_territories[0])
+ {
+ r = 0;
+ if (lp)
+ {
+ if ((flags & (LC_abbreviated|LC_default)) && streq(lp->code, tp->code))
+ r = s;
+ *s++ = '_';
+ }
+ if (flags & LC_verbose)
+ {
+ u = 1;
+ t = tp->name;
+ while (s < e && (c = *t++) && c != '|')
+ {
+ if (u)
+ {
+ u = 0;
+ c = toupper(c);
+ }
+ else if (!isalnum(c))
+ u = 1;
+ *s++ = c;
+ }
+ }
+ else
+ for (t = tp->code; s < e && (*s = toupper(*t++)); s++);
+ if (r)
+ {
+ *s = 0;
+ if ((p = setlocale(LC_MESSAGES, 0)) && (p = strdup(p)))
+ {
+ if (!setlocale(LC_MESSAGES, buf))
+ {
+ *r = 0;
+ if (!setlocale(LC_MESSAGES, buf))
+ *r = '_';
+ }
+ setlocale(LC_MESSAGES, p);
+ free(p);
+ }
+ }
+ }
+ if (lp && (!(flags & (LC_abbreviated|LC_default)) || cp != lp->charset) && s < e)
+ {
+ *s++ = '.';
+ t = cp->code;
+ if (streq(cp->code, "utf8") && (t = _locale_utf8_str))
+ for (; s < e && (c = *t++); s++)
+ *s = c;
+ else
+ for (t = cp->code; s < e && (c = *t++); s++)
+ {
+ if (islower(c))
+ c = toupper(c);
+ *s = c;
+ }
+ }
+ for (c = '@'; ap && s < e; ap = ap->next)
+ if (!(flags & (LC_abbreviated|LC_default|LC_verbose)) || !(ap->attribute->flags & LC_default))
+ {
+ *s++ = c;
+ c = ',';
+ for (t = ap->attribute->name; s < e && (*s = *t++); s++);
+ }
+ }
+ *s++ = 0;
+ return s - buf;
+}
+
+/*
+ * generate a canonical locale name in buf
+ */
+
+size_t
+lccanon(Lc_t* lc, unsigned long flags, char* buf, size_t siz)
+{
+ if ((flags & LC_local) && (!lc->language || !(lc->language->flags & (LC_debug|LC_default))))
+ {
+#if _WINIX
+ char lang[64];
+ char code[64];
+ char ctry[64];
+
+ if (lc->index &&
+ GetLocaleInfo(lc->index, LOCALE_SENGLANGUAGE, lang, sizeof(lang)) &&
+ GetLocaleInfo(lc->index, LOCALE_SENGCOUNTRY, ctry, sizeof(ctry)))
+ {
+ if (!GetLocaleInfo(lc->index, LOCALE_IDEFAULTANSICODEPAGE, code, sizeof(code)))
+ code[0] = 0;
+ if (!lc->charset || !lc->charset->ms)
+ return sfsprintf(buf, siz, "%s_%s", lang, ctry);
+ else if (streq(lc->charset->ms, code))
+ return sfsprintf(buf, siz, "%s_%s.%s", lang, ctry, code);
+ else
+ return sfsprintf(buf, siz, "%s_%s.%s,%s", lang, ctry, code, lc->charset->ms);
+ }
+#endif
+ buf[0] = '-';
+ buf[1] = 0;
+ return 0;
+ }
+ return canonical(lc->language, lc->territory, lc->charset, lc->attributes, flags, buf, siz);
+}
+
+/*
+ * make an Lc_t from a locale name
+ */
+
+Lc_t*
+lcmake(const char* name)
+{
+ register int c;
+ register char* s;
+ register char* e;
+ register const char* t;
+ const char* a;
+ char* w;
+ char* language_name;
+ char* territory_name;
+ char* charset_name;
+ char* attributes_name;
+ Lc_t* lc;
+ const Lc_map_t* mp;
+ const Lc_language_t* lp;
+ const Lc_territory_t* tp;
+ const Lc_territory_t* tpb;
+ const Lc_territory_t* primary;
+ const Lc_charset_t* cp;
+ const Lc_charset_t* ppa;
+ const Lc_attribute_t* ap;
+ Lc_attribute_list_t* ai;
+ Lc_attribute_list_t* al;
+ int i;
+ int n;
+ int z;
+ char buf[PATH_MAX / 2];
+ char tmp[PATH_MAX / 2];
+ Local_t local[2];
+
+ if (!(t = name) || !*t)
+ return &default_lc;
+ for (lc = lcs; lc; lc = lc->next)
+ if (!strcasecmp(t, lc->code) || !strcasecmp(t, lc->name))
+ return lc;
+ for (mp = lc_maps; mp->code; mp++)
+ if (streq(t, mp->code))
+ {
+ lp = mp->language;
+ tp = mp->territory;
+ cp = mp->charset;
+ if (!mp->attribute)
+ al = 0;
+ else if (al = newof(0, Lc_attribute_list_t, 1, 0))
+ al->attribute = mp->attribute;
+ goto mapped;
+ }
+ language_name = buf;
+ territory_name = charset_name = attributes_name = 0;
+ s = buf;
+ e = &buf[sizeof(buf)-2];
+ a = 0;
+ n = 0;
+ while (s < e && (c = *t++))
+ {
+ if (isspace(c) || (c == '(' || c == '-' && *t == '-') && ++n)
+ {
+ while ((c = *t++) && (isspace(c) || (c == '-' || c == '(' || c == ')') && ++n))
+ if (!c)
+ break;
+ if (isalnum(c) && !n)
+ *s++ = '-';
+ else
+ {
+ n = 0;
+ if (!a)
+ {
+ a = t - 1;
+ while (c && c != '_' && c != '.' && c != '@')
+ c = *t++;
+ if (!c)
+ break;
+ }
+ }
+ }
+ if (c == '_' && !territory_name)
+ {
+ *s++ = 0;
+ territory_name = s;
+ }
+ else if (c == '.' && !charset_name)
+ {
+ *s++ = 0;
+ charset_name = s;
+ }
+ else if (c == '@' && !attributes_name)
+ {
+ *s++ = 0;
+ attributes_name = s;
+ }
+ else
+ {
+ if (isupper(c))
+ c = tolower(c);
+ *s++ = c;
+ }
+ }
+ if ((t = a) && s < e)
+ {
+ if (attributes_name)
+ *s++ = ',';
+ else
+ {
+ *s++ = 0;
+ attributes_name = s;
+ }
+ while (s < e && (c = *t++))
+ {
+ if (isspace(c) || (c == '(' || c == ')' || c == '-' && *t == '-') && ++n)
+ {
+ while ((c = *t++) && (isspace(c) || (c == '-' || c == '(' || c == ')') && ++n))
+ if (!c)
+ break;
+ if (isalnum(c) && !n)
+ *s++ = '-';
+ else
+ n = 0;
+ }
+ if (c == '_' || c == '.' || c == '@')
+ break;
+ if (isupper(c))
+ c = tolower(c);
+ *s++ = c;
+ }
+ }
+ *s = 0;
+#if AHA
+ if ((ast.locale.set & AST_LC_debug) && !(ast.locale.set & AST_LC_internal))
+ sfprintf(sfstderr, "locale make %s language=%s territory=%s charset=%s attributes=%s\n", name, language_name, territory_name, charset_name, attributes_name);
+#endif
+ tp = 0;
+ cp = ppa = 0;
+ al = 0;
+
+ /*
+ * language
+ */
+
+ n = strlen(s = language_name);
+ if (n == 2)
+ for (lp = lc_languages; lp->code && !streq(s, lp->code); lp++);
+ else if (n == 3)
+ {
+ for (lp = lc_languages; lp->code && (!lp->alternates || !match(s, lp->alternates, n, 0)); lp++);
+ if (!lp->code)
+ {
+ c = s[2];
+ s[2] = 0;
+ for (lp = lc_languages; lp->code && !streq(s, lp->code); lp++);
+ s[2] = c;
+ if (lp->code)
+ n = 1;
+ }
+ }
+ else if (streq(s, "c") || streq(s, "posix"))
+ lp = &lc_languages[0];
+ else
+ lp = 0;
+ if (!lp || !lp->code)
+ {
+ for (lp = lc_languages; lp->code && !match(s, lp->name, 0, 0); lp++);
+ if (!lp || !lp->code)
+ {
+ if (!territory_name)
+ {
+ if (n == 2)
+ for (tp = lc_territories; tp->code && !streq(s, tp->code); tp++);
+ else
+ {
+ z = 0;
+ tpb = 0;
+ for (tp = lc_territories; tp->name; tp++)
+ if ((i = match(s, tp->name, 3, 0)) > z)
+ {
+ tpb = tp;
+ if ((z = i) == n)
+ break;
+ }
+ if (tpb)
+ tp = tpb;
+ }
+ if (tp->code)
+ lp = tp->languages[0];
+ }
+ if (!lp || !lp->code)
+ {
+ /*
+ * name not in the tables so let
+ * _ast_setlocale() and/or setlocale()
+ * handle the validity checks
+ */
+
+ s = (char*)name;
+ z = strlen(s) + 1;
+ if (!(lp = newof(0, Lc_language_t, 1, z)))
+ return 0;
+ name = ((Lc_language_t*)lp)->code = ((Lc_language_t*)lp)->name = (const char*)(lp + 1);
+ memcpy((char*)lp->code, s, z - 1);
+ tp = &lc_territories[0];
+ cp = &lc_charsets[0];
+ if (charset_name)
+ for (ppa = lc_charsets; ppa->code; ppa++)
+ if (match_charset(charset_name, ppa))
+ {
+ cp = ppa;
+ break;
+ }
+ ((Lc_language_t*)lp)->charset = cp;
+ al = 0;
+ goto override;
+ }
+ }
+ }
+
+ /*
+ * territory
+ */
+
+ if (!tp || !tp->code)
+ {
+ if (!(s = territory_name))
+ {
+ n = 0;
+ primary = 0;
+ for (tp = lc_territories; tp->code; tp++)
+ if (tp->languages[0] == lp)
+ {
+ if (tp->flags & LC_primary)
+ {
+ n = 1;
+ primary = tp;
+ break;
+ }
+ n++;
+ primary = tp;
+ }
+ if (n == 1)
+ tp = primary;
+ s = (char*)lp->code;
+ }
+ if (!tp || !tp->code)
+ {
+ n = strlen(s);
+ if (n == 2)
+ {
+ for (tp = lc_territories; tp->code; tp++)
+ if (streq(s, tp->code))
+ {
+ if (lp != &lc_languages[0])
+ {
+ for (i = 0; i < elementsof(tp->languages) && lp != tp->languages[i]; i++);
+ if (i >= elementsof(tp->languages))
+ tp = 0;
+ }
+ break;
+ }
+ }
+ else
+ {
+ for (tp = lc_territories; tp->code; tp++)
+ if (match(s, tp->name, 3, 0))
+ {
+ for (i = 0; i < elementsof(tp->languages) && lp != tp->languages[i]; i++);
+ if (i < elementsof(tp->languages))
+ break;
+ }
+ }
+ if (tp && !tp->code)
+ tp = 0;
+ }
+ }
+
+ /*
+ * attributes -- done here to catch misplaced charset references
+ */
+
+ if (s = attributes_name)
+ {
+ do
+ {
+ for (w = s; *s && *s != ','; s++);
+ c = *s;
+ *s = 0;
+ if (!(cp = lp->charset) || !match_charset(w, cp))
+ for (cp = lc_charsets; cp->code; cp++)
+ if (match_charset(w, cp))
+ {
+ ppa = cp;
+ break;
+ }
+ if (!cp->code)
+ {
+ for (i = 0; i < elementsof(lp->attributes) && (ap = lp->attributes[i]); i++)
+ if (match(w, ap->name, 5, 0))
+ {
+ if (ai = newof(0, Lc_attribute_list_t, 1, 0))
+ {
+ ai->attribute = ap;
+ ai->next = al;
+ al = ai;
+ }
+ break;
+ }
+ if (i >= elementsof(lp->attributes) && (ap = newof(0, Lc_attribute_t, 1, sizeof(Lc_attribute_list_t) + s - w + 1)))
+ {
+ ai = (Lc_attribute_list_t*)(ap + 1);
+ strcpy((char*)(((Lc_attribute_t*)ap)->name = (const char*)(ai + 1)), w);
+ ai->attribute = ap;
+ ai->next = al;
+ al = ai;
+ }
+ }
+ *s = c;
+ } while (*s++);
+ }
+
+ /*
+ * charset
+ */
+
+ if (s = charset_name)
+ for (cp = lc_charsets; cp->code; cp++)
+ if (match_charset(s, cp))
+ break;
+#if AHA
+ if ((ast.locale.set & AST_LC_debug) && !(ast.locale.set & AST_LC_internal))
+ sfprintf(sfstderr, "locale make %s charset_name=%s cp=%s ppa=%s lp=%s\n", name, charset_name, cp ? cp->code : 0, ppa, lp->charset);
+#endif
+ if (!cp || !cp->code)
+ cp = ppa ? ppa : lp->charset;
+ mapped:
+ z = canonical(lp, tp, cp, al, 0, s = tmp, sizeof(tmp));
+
+ /*
+ * add to the list of possibly active locales
+ */
+
+ override:
+ n = strlen(name) + 1;
+ local[0].name = default_lc.name;
+ local[0].size = strlen(local[0].name);
+ local[1].name = default_lc.code;
+ local[1].size = strlen(local[1].name);
+ i = -1;
+ for (c = 0; c < elementsof(local); ++c)
+ if (strneq(name, local[c].name, local[c].size))
+ {
+ switch (name[local[c].size])
+ {
+ case '.':
+ case '_':
+ case 0:
+ i = c;
+ z += local[!i].size + n;
+ break;
+ }
+ break;
+ }
+ if (!(lc = newof(0, Lc_t, 1, n + z)))
+ return 0;
+ strcpy((char*)(lc->name = (const char*)(lc + 1)), name);
+ lc->code = lc->name + n;
+ if (i >= 0)
+ {
+ lc->flags |= LC_local;
+ strcpy((char*)lc->code, local[!i].name);
+ strcpy((char*)lc->code + local[!i].size, name + local[i].size);
+ }
+ else
+ strcpy((char*)lc->code, s);
+ lc->language = lp ? lp : &lc_languages[0];
+ lc->territory = tp ? tp : &lc_territories[0];
+ lc->charset = cp ? cp : &lc_charsets[0];
+ if (streq(lc->charset->code, "utf8"))
+ lc->flags |= LC_utf8;
+ lc->attributes = al;
+ for (i = 0; i < elementsof(lc->info); i++)
+ lc->info[i].lc = lc;
+#if _WINIX
+ n = SUBLANG_DEFAULT;
+ if (tp)
+ for (i = 0; i < elementsof(tp->languages); i++)
+ if (lp == tp->languages[i])
+ {
+ n = tp->indices[i];
+ break;
+ }
+ lc->index = MAKELCID(MAKELANGID(lp->index, n), SORT_DEFAULT);
+#endif
+ lc->next = lcs;
+ lcs = lc;
+ if ((ast.locale.set & AST_LC_debug) && !(ast.locale.set & AST_LC_internal))
+ sfprintf(sfstderr, "locale make %17s %16s %16s %16s language=%s territory=%s charset=%s%s\n", "", lc->name, lc->code, "", lc->language->name, lc->territory->name, lc->charset->code, (lc->flags & LC_local) ? " local" : "");
+ return lc;
+}
+
+/*
+ * return an Lc_t* for each locale in the tables
+ * one Lc_t is allocated on the first call with lc==0
+ * this is freed when 0 returned
+ * the return value is not part of the lcmake() cache
+ */
+
+typedef struct Lc_scan_s
+{
+ Lc_t lc;
+ Lc_attribute_list_t list;
+ int territory;
+ int language;
+ int attribute;
+ char buf[256];
+} Lc_scan_t;
+
+Lc_t*
+lcscan(Lc_t* lc)
+{
+ register Lc_scan_t* ls;
+
+ if (!(ls = (Lc_scan_t*)lc))
+ {
+ if (!(ls = newof(0, Lc_scan_t, 1, 0)))
+ return 0;
+ ls->lc.code = ls->lc.name = ls->buf;
+ ls->territory = -1;
+ ls->language = elementsof(ls->lc.territory->languages);
+ ls->attribute = elementsof(ls->lc.language->attributes);
+ }
+ if (++ls->attribute >= elementsof(ls->lc.language->attributes) || !(ls->list.attribute = ls->lc.language->attributes[ls->attribute]))
+ {
+ if (++ls->language >= elementsof(ls->lc.territory->languages) || !(ls->lc.language = ls->lc.territory->languages[ls->language]))
+ {
+ if (!lc_territories[++ls->territory].code)
+ {
+ free(ls);
+ return 0;
+ }
+ ls->lc.territory = &lc_territories[ls->territory];
+ ls->lc.language = ls->lc.territory->languages[ls->language = 0];
+ }
+ if (ls->lc.language)
+ {
+ ls->lc.charset = ls->lc.language->charset ? ls->lc.language->charset : &lc_charsets[0];
+ ls->list.attribute = ls->lc.language->attributes[ls->attribute = 0];
+ }
+ else
+ {
+ ls->lc.charset = &lc_charsets[0];
+ ls->list.attribute = 0;
+ }
+ }
+ ls->lc.attributes = ls->list.attribute ? &ls->list : (Lc_attribute_list_t*)0;
+#if _WINIX
+ if (!ls->lc.language || !ls->lc.language->index)
+ ls->lc.index = 0;
+ else
+ {
+ if ((!ls->list.attribute || !(ls->lc.index = ls->list.attribute->index)) &&
+ (!ls->lc.territory || !(ls->lc.index = ls->lc.territory->indices[ls->language])))
+ ls->lc.index = SUBLANG_DEFAULT;
+ ls->lc.index = MAKELCID(MAKELANGID(ls->lc.language->index, ls->lc.index), SORT_DEFAULT);
+ }
+#endif
+ canonical(ls->lc.language, ls->lc.territory, ls->lc.charset, ls->lc.attributes, 0, ls->buf, sizeof(ls->buf));
+ return (Lc_t*)ls;
+}
diff --git a/src/lib/libast/port/lc.tab b/src/lib/libast/port/lc.tab
new file mode 100644
index 0000000..87905a1
--- /dev/null
+++ b/src/lib/libast/port/lc.tab
@@ -0,0 +1,275 @@
+#
+# language_territory.charset@attribute tables
+#
+
+:charset:
+
+ iso8859-1 latin1|west-europe 1252
+ iso8859-2 latin2|east-europe 1250
+ iso8859-3 latin3|south-europe 1257
+ iso8859-4 latin4|north-europe
+ iso8859-5 cyrillic 1251
+ iso8859-6 arabic 1256
+ iso8859-7 greek 1253
+ iso8859-8 hebrew 1255
+ iso8859-9 latin5|turkish 1254
+ iso8859-10 latin6|nordic
+ iso8859-13 latin7
+ iso8859-14 latin8|celtic
+ iso8859-15 latin0
+ iso2022 japanese|korean
+ iso4873 japanese-ascii|korean-ascii
+ koi8-r russian
+ utf8 plan9
+
+:language:
+
+ aa afar
+ ab abkhazian
+ af afrikaans afr
+ am amharic
+ ar arabic ara iso8859-6
+ as assamese
+ ay aymara
+ az azerbaijani
+ ba bashkir
+ be belarusian bel
+ bg bulgarian bul iso8859-5
+ bh bihari
+ bi bislama
+ bn bengali-bangla
+ bo tibetan
+ br breton
+ ca catalan cat
+ co corsican
+ cs czech ces|cze iso8859-2
+ cy welsh
+ da danish dan
+ de german deu|ger
+ dz bhutani
+ el greek ell|gre iso8859-7
+ en english eng
+ eo esperanto
+ es spanish spa - traditional:default|modern
+ et estonian est iso8859-3
+ eu basque eus|baq
+ fa persian
+ fi finnish fin
+ fj fiji
+ fo faeroese
+ fr french fra|fre
+ fy frisian
+ ga irish - iso8859-14
+ gd scots-gaelic - iso8859-14
+ gl galician
+ gn guarani
+ gu gujarati
+ ha hausa
+ he hebrew heb iso8859-8
+ hi hindi
+ hr croatian hrv|scr iso8859-2
+ hu hungarian hun iso8859-2
+ hy armenian
+ ia interlingua
+ id indonesian ind
+ ie interlingue
+ ik inupiak
+ in indonesian
+ is icelandic isl|ice
+ it italian ita
+ iw hebrew
+ ja japanese jpn
+ ji yiddish
+ jw javanese
+ ka georgian
+ kk kazakh kaz
+ kl greenlandic
+ km cambodian
+ kn kannada
+ ko korean kor
+ ks kashmiri
+ ku kurdish
+ ky kirghiz
+ la latin
+ ln lingala
+ lo laothian
+ lt lithuanian lit iso8859-13
+ lv latvian lav iso8859-13
+ mg malagasy
+ mi maori
+ mk macedonian mkd|mac
+ ml malayalam mal
+ mn mongolian
+ mo moldavian
+ mr marathi
+ ms malay msa|may
+ mt maltese
+ my burmese
+ na nauru
+ nb norwegian-bokmal nob
+ ne nepali
+ nl dutch nld|dut
+ nn norwegian-nynorsk nno|non
+ no norwegian nor
+ oc occitan
+ om oromo
+ or oriya
+ pa punjabi
+ pl polish pol iso8859-2
+ ps pushto
+ pt portuguese por
+ qu quechua
+ rm rhaeto-romance
+ rn kirundi
+ ro romanian ron|rum iso8859-2
+ ru russian rus iso8859-5
+ rw kinyarwanda
+ sa sanskrit
+ sd sindhi
+ sg sangro
+ sh serbo-croatian
+ si singhalese
+ sk slovak slk|slo iso8859-2
+ sl slovenian slv iso8859-2
+ sm samoan
+ sn shona
+ so somali
+ sq albanian sqi|alb
+ sr serbian srp iso8859-2
+ ss siswati
+ st sesotho
+ su sudanese
+ sv swedish swe
+ sw swahili swa
+ ta tamil
+ te telugu
+ tg tajik
+ th thai tha
+ ti tigrinya
+ tk turkmen
+ tl tagalog
+ tn setswana
+ to tonga
+ tr turkish tur iso8859-9
+ ts tsonga
+ tt tatar tat
+ tw chinese-traditional cht
+ uk ukrainian ukr iso8859-5
+ ur urdu
+ uz uzbek uzb
+ vi vietnamese
+ vo volapuk
+ wo wolof
+ xh xhosa
+ yo yoruba
+ zh chinese-simplified zho|chi|chs
+ zu zulu
+
+:territory:
+
+ al albania
+ an netherlands-antilles nl
+ ar argentina es
+ at austria de
+ au australia en
+ az azerbaijan
+ be belgium nl|fr|de
+ bg bulgaria bg
+ bn brunei-darussalam ar
+ bo bolivia es
+ br brazil pt
+ bw botswana en
+ by belarus ru
+ bz belize en
+ ca canada en|fr
+ ch switzerland fr|de|it
+ cl chile es
+ cn china zh:primary
+ co colombia es
+ cr costa-rica es
+ cz czech-republic cs
+ de germany de
+ dk denmark da|en
+ do dominican-republic es
+ dz algeria
+ ec ecuador es
+ ee estonia et
+ eg egypt ar
+ es spain es|ca|eu|gl
+ fi finland sv
+ fo faroe-islands fo
+ fr france fr
+ gb united-kingdom|great-britain|england en:primary
+ gl greenland kl
+ gr greece el
+ gt guatemala es
+ hk hong-kong zh
+ hn honduras es
+ hr croatia hr
+ hu hungary hu
+ id indonesia id
+ ie ireland en|ga
+ il israel he
+ iq iraq ar
+ is iceland is
+ it italy it
+ jm jamaica en
+ jo jordan ar
+ jp japan ja
+ ke kenya
+ kr south-korea ko
+ kw kuwait ar
+ lb lebanon ar
+ li liechtenstein de|fr
+ lt lithuania lt
+ lu luxembourg de|fr
+ lv latvia lv
+ ly libya ar
+ ma morocco ar
+ mk macedonia mk
+ mo macau zh
+ mx mexico es
+ my malaysia
+ ni nicaragua es
+ nl netherlands nl
+ no norway nb|no|nn
+ nz new-zealand en
+ om oman ar
+ pa panama es
+ pe peru es
+ pl poland pl
+ pr puerto-rico es
+ pt portugal pt
+ py paraguay es
+ ro romania ro
+ ru russia ru
+ sa saudi-arabia ar
+ se sweden sv:primary
+ sg singapore zh
+ si slovenia sl
+ sk slovakia sk
+ sp serbia sr
+ sv el-salvador es
+ sy syria ar
+ th thailand th
+ tn tunisia ar
+ tr turkey tr
+ tt trinidad&tobago en
+ tw taiwan tw
+ ua ukraine uk|ru
+ uk united-kingdom en:primary
+ us united-states|usa en
+ uy uruguay es
+ ve venezuela es
+ yu yugoslavia sr
+ za south-africa af
+ zw zimbabwe en
+
+:map:
+
+ enu en us
+ enz en nz
+ esm es mx
+ esn es es - modern
+ esp es es - traditional
+ usa en us
diff --git a/src/lib/libast/port/lcgen.c b/src/lib/libast/port/lcgen.c
new file mode 100644
index 0000000..82eb88d
--- /dev/null
+++ b/src/lib/libast/port/lcgen.c
@@ -0,0 +1,791 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * generate <lc.h> implementation tables from lc.tab
+ * this must make it through vanilla cc with no -last
+ *
+ * # comment
+ * :charset:
+ * code name ms-codepage
+ * :language:
+ * code name alt1|alt2... charset|... attr1|attr2|...
+ * ...
+ * :territory:
+ * code name lang1|lang2...
+ * :abbreviation:
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+typedef struct Link_s
+{
+ struct Link_s* next;
+ char* code;
+ int index;
+} Link_t;
+
+typedef struct Table_s
+{
+ Link_t* root;
+ int count;
+} Table_t;
+
+typedef struct Abbreviation_s
+{
+ Link_t link;
+ char* value;
+} Abbreviation_t;
+
+typedef struct Attribute_s
+{
+ Link_t link;
+} Attribute_t;
+
+typedef struct Attribute_list_s
+{
+ struct Attribute_list_s*next;
+ Attribute_t* attribute;
+} Attribute_list_t;
+
+typedef struct Charset_s
+{
+ Link_t link;
+ char* alternates;
+ char* ms;
+} Charset_t;
+
+typedef struct Language_s
+{
+ Link_t link;
+ char* name;
+ char* alternates;
+ Charset_t* charset;
+ Attribute_list_t* attributes;
+} Language_t;
+
+typedef struct Language_list_s
+{
+ struct Language_list_s* next;
+ Language_t* language;
+} Language_list_t;
+
+typedef struct Territory_s
+{
+ Link_t link;
+ char* name;
+ Language_list_t* languages;
+ int primary;
+ int index;
+} Territory_t;
+
+typedef struct Map_s
+{
+ Link_t link;
+ Language_t* language;
+ Territory_t* territory;
+ Charset_t* charset;
+ Attribute_t* attribute;
+} Map_t;
+
+static struct State_s
+{
+ Table_t attribute;
+ Table_t charset;
+ Table_t language;
+ Table_t territory;
+ Table_t map;
+} state;
+
+#define INIT 0
+#define CHARSET 1
+#define LANGUAGE 2
+#define TERRITORY 3
+#define MAP 4
+
+#define elementsof(x) (sizeof(x)/sizeof(x[0]))
+#define newof(p,t,n,x) ((t*)malloc(sizeof(t)*(n)+(x)))
+
+static Link_t*
+#if defined(__STDC__) || defined(__cplusplus)
+enter(register Table_t* tab, register Link_t* v)
+#else
+enter(tab, v)
+register Table_t* tab;
+register Link_t* v;
+#endif
+{
+ register Link_t* x;
+ register Link_t* p;
+
+ for (p = 0, x = tab->root; x; p = x, x = x->next)
+ if (!strcmp(x->code, v->code))
+ return x;
+ if (p)
+ p->next = v;
+ else
+ tab->root = v;
+ v->next = 0;
+ v->index = tab->count++;
+ return v;
+}
+
+static Link_t*
+#if defined(__STDC__) || defined(__cplusplus)
+lookup(register Table_t* tab, register char* s)
+#else
+lookup(tab, s)
+register Table_t* tab;
+register char* s;
+#endif
+{
+ register Link_t* x;
+
+ for (x = tab->root; x; x = x->next)
+ if (!strcmp(x->code, s))
+ return x;
+ return 0;
+}
+
+static char*
+#if defined(__STDC__) || defined(__cplusplus)
+copy(char** p, register char* f)
+#else
+copy(p, f)
+char** p;
+register char* f;
+#endif
+{
+ register char* t;
+ char* b;
+
+ if (!f)
+ return 0;
+ b = t = *p;
+ while (*t++ = *f++);
+ *p = t;
+ return b;
+}
+
+static void
+#if defined(__STDC__) || defined(__cplusplus)
+macro(FILE* f, char* p1, char* p2, char* p3)
+#else
+macro(f, p1, p2, p3)
+FILE* f;
+char* p1;
+char* p2;
+char* p3;
+#endif
+{
+ register int c;
+ register char* s;
+ register char* b;
+ register char* e;
+ int i;
+ int m;
+ int n;
+ char* part[4];
+ char buf[128];
+
+ part[0] = p1;
+ part[1] = p2;
+ part[2] = p3;
+ part[3] = 0;
+ n = 0;
+ fprintf(f, "\n");
+ do
+ {
+ i = m = 0;
+ b = buf;
+ e = &buf[sizeof(buf)-1];
+ while (b < e)
+ {
+ if (!(s = part[i++]))
+ break;
+ if (i > 1)
+ *b++ = '_';
+ while ((c = *s++) && b < e)
+ {
+ if (c == '|')
+ {
+ part[i-1] = s;
+ m = 1;
+ break;
+ }
+ else if (islower(c))
+ c = toupper(c);
+ else if (!isalnum(c))
+ c = '_';
+ *b++ = c;
+ }
+ }
+ *b = 0;
+ fprintf(f, "#ifdef %s\n%s,\n#else\n", buf, buf);
+ n++;
+ } while (m);
+ fprintf(f, "0,\n");
+ while (n-- > 0)
+ fprintf(f, "#endif\n");
+}
+
+#if defined(__STDC__) || defined(__cplusplus)
+int
+main(int argc, char** argv)
+#else
+int
+main(argc, argv)
+int argc;
+char** argv;
+#endif
+{
+ register char* s;
+ register char** vp;
+ register char** ve;
+ Attribute_t* ap;
+ Attribute_list_t* al;
+ Attribute_list_t* az;
+ Charset_t* cp;
+ Territory_t* tp;
+ Language_t* lp;
+ Language_list_t* ll;
+ Language_list_t* lz;
+ Map_t* mp;
+ char* b;
+ char* f;
+ char* command;
+ char* hdr;
+ char* lib;
+ FILE* hf;
+ FILE* lf;
+ int c;
+ int i;
+ int line;
+ int type;
+ int language_attribute_max;
+ int territory_language_max;
+ char* arg[5];
+ char buf[1024];
+
+ command = *argv++;
+ line = 0;
+ if (!(hdr = *argv++) || !(lib = *argv++) || *argv)
+ {
+ fprintf(stderr, "%s: { hdr lib tab } arguments expected\n", command);
+ return 1;
+ }
+ if (!(hf = fopen(hdr, "w")))
+ {
+ fprintf(stderr, "%s: %s: cannot write\n", command, hdr);
+ return 1;
+ }
+ if (!(lf = fopen(lib, "w")))
+ {
+ fprintf(stderr, "%s: %s: cannot write\n", command, lib);
+ return 1;
+ }
+ type = 0;
+ language_attribute_max = 0;
+ territory_language_max = 0;
+ state.language.count = 2;
+ state.territory.count = 3;
+ ve = &arg[elementsof(arg)];
+ fprintf(hf, "/* : : generated by %s : : */\n", command);
+ fprintf(hf, "#pragma prototyped\n");
+ fprintf(hf, "\n");
+ fprintf(hf, "#ifndef _LC_H\n");
+ fprintf(hf, "#define _LC_H\t\t\t1\n");
+ fprintf(hf, "\n");
+ fprintf(hf, "#include <ast.h>\n");
+ fprintf(hf, "\n");
+ fprintf(hf, "#define LC_abbreviated\t\t0x00001\n");
+ fprintf(hf, "#define LC_checked\t\t0x00002\n");
+ fprintf(hf, "#define LC_debug\t\t0x00004\n");
+ fprintf(hf, "#define LC_default\t\t0x00008\n");
+ fprintf(hf, "#define LC_defined\t\t0x00010\n");
+ fprintf(hf, "#define LC_local\t\t0x00020\n");
+ fprintf(hf, "#define LC_primary\t\t0x00040\n");
+ fprintf(hf, "#define LC_qualified\t\t0x00080\n");
+ fprintf(hf, "#define LC_undefined\t\t0x00100\n");
+ fprintf(hf, "#define LC_utf8\t\t\t0x00200\n");
+ fprintf(hf, "#define LC_verbose\t\t0x00400\n");
+ fprintf(hf, "#define LC_setlocale\t\t0x10000\n");
+ fprintf(hf, "#define LC_setenv\t\t0x20000\n");
+ fprintf(hf, "#define LC_user\t\t\t0x40000\n");
+ fprintf(lf, "/* : : generated by %s : : */\n", command);
+ fprintf(lf, "\n");
+ fprintf(lf, "#include \"lclib.h\"\n");
+ fprintf(lf, "#include \"lclang.h\"\n");
+ fprintf(lf, "\n");
+ while (s = fgets(buf, sizeof(buf), stdin))
+ {
+ line++;
+ while (isspace(*s))
+ s++;
+ if (!*s || *s == '#')
+ continue;
+ b = s;
+ vp = arg;
+ for (;;)
+ {
+ for (*vp++ = s; *s && !isspace(*s); s++);
+ if (!*s)
+ break;
+ for (*s++ = 0; isspace(*s); s++);
+ if (!strcmp(*(vp - 1), "-"))
+ *(vp - 1) = 0;
+ if (!*s || vp >= ve)
+ break;
+ }
+ while (vp < ve)
+ *vp++ = 0;
+ if (*arg[0] == ':')
+ {
+ if (!strcmp(arg[0], ":map:"))
+ {
+ if (type != TERRITORY)
+ {
+ fprintf(stderr, "%s: %d: %s: must be specified after :territory:\n", command, line, arg[0]);
+ return 1;
+ }
+ type = MAP;
+ continue;
+ }
+ else if (!strcmp(arg[0], ":charset:"))
+ {
+ if (type != INIT)
+ {
+ fprintf(stderr, "%s: %d: %s must be specified first\n", command, line, arg[0]);
+ return 1;
+ }
+ type = CHARSET;
+ continue;
+ }
+ else if (!strcmp(arg[0], ":territory:"))
+ {
+ if (type != LANGUAGE)
+ {
+ fprintf(stderr, "%s: %d: %s: must be specified after :language:\n", command, line, arg[0]);
+ return 1;
+ }
+ type = TERRITORY;
+ continue;
+ }
+ else if (!strcmp(arg[0], ":language:"))
+ {
+ if (type != CHARSET)
+ {
+ fprintf(stderr, "%s: %d: %s must be specified after :charset:\n", command, line, arg[0]);
+ return 1;
+ }
+ type = LANGUAGE;
+ continue;
+ }
+ else
+ {
+ fprintf(stderr, "%s: %d: %s invalid\n", command, line, arg[0]);
+ return 1;
+ }
+ }
+ if (!arg[1])
+ {
+ fprintf(stderr, "%s: %d: at least two arguments expected\n", command, line);
+ return 1;
+ }
+ switch (type)
+ {
+ case CHARSET:
+ if (!(cp = newof(0, Charset_t, 1, s - b + 1)))
+ {
+ fprintf(stderr, "%s: %d: out of space\n", command, line);
+ return 1;
+ }
+ b = (char*)(cp + 1);
+ cp->link.code = copy(&b, arg[0]);
+ cp->alternates = copy(&b, arg[1]);
+ cp->ms = copy(&b, arg[2]);
+ if (cp != (Charset_t*)enter(&state.charset, (Link_t*)cp))
+ {
+ fprintf(stderr, "%s: %d: %s: duplicate charset\n", command, line, cp->link.code);
+ return 1;
+ }
+ break;
+ case TERRITORY:
+ if (!(tp = newof(0, Territory_t, 1, s - b + 1)))
+ {
+ fprintf(stderr, "%s: %d: out of space\n", command, line);
+ return 1;
+ }
+ b = (char*)(tp + 1);
+ tp->link.code = copy(&b, arg[0]);
+ tp->name = copy(&b, arg[1]);
+ tp->languages = 0;
+ if (s = copy(&b, arg[2]))
+ {
+ i = 0;
+ while (*(b = s))
+ {
+ for (; *s && *s != ':' && *s != '|'; s++);
+ if (c = *s)
+ *s++ = 0;
+ if (!(lp = (Language_t*)lookup(&state.language, b)))
+ {
+ fprintf(stderr, "%s: %d: %s: unknown language\n", command, line, b);
+ return 1;
+ }
+ if (!(ll = newof(0, Language_list_t, 1, 0)))
+ {
+ fprintf(stderr, "%s: %d: out of space\n", command, line);
+ return 1;
+ }
+ if (!tp->languages)
+ tp->languages = ll;
+ else
+ lz->next = ll;
+ lz = ll;
+ ll->language = lp;
+ ll->next = 0;
+ i++;
+ if (c == ':')
+ {
+ for (b = s; *s && *s != '|'; s++);
+ if (*s)
+ *s++ = 0;
+ if (!strcmp(b, "primary"))
+ tp->primary = 1;
+ }
+ }
+ if (territory_language_max < i)
+ territory_language_max = i;
+ }
+ if (tp != (Territory_t*)enter(&state.territory, (Link_t*)tp))
+ {
+ fprintf(stderr, "%s: %d: %s: duplicate territory\n", command, line, tp->link.code);
+ return 1;
+ }
+ break;
+ case LANGUAGE:
+ if (!(lp = newof(0, Language_t, 1, s - b + 1)))
+ {
+ fprintf(stderr, "%s: %d: out of space\n", command, line);
+ return 1;
+ }
+ b = (char*)(lp + 1);
+ lp->link.code = copy(&b, arg[0]);
+ lp->name = copy(&b, arg[1]);
+ lp->alternates = copy(&b, arg[2]);
+ if (!arg[3])
+ lp->charset = 0;
+ else if (!(lp->charset = (Charset_t*)lookup(&state.charset, arg[3])))
+ {
+ fprintf(stderr, "%s: %d: %s: unknown charset\n", command, line, arg[3]);
+ return 1;
+ }
+ lp->attributes = 0;
+ if (s = copy(&b, arg[4]))
+ {
+ i = 0;
+ fprintf(lf, "\nconst Lc_attribute_t attribute_%s[] =\n{\n", lp->link.code);
+ while (*(b = s))
+ {
+ for (f = 0; *s && *s != '|'; s++)
+ if (*s == ':')
+ {
+ *s++ = 0;
+ f = s;
+ }
+ if (*s)
+ *s++ = 0;
+ fprintf(lf, "{\"%s\",", b);
+ if (f)
+ fprintf(lf, "LC_%s,", f);
+ else
+ fprintf(lf, "0,");
+ if (!(ap = newof(0, Attribute_t, 1, 0)))
+ {
+ fprintf(stderr, "%s: %d: out of space\n", command, line);
+ return 1;
+ }
+ ap->link.code = b;
+ ap->link.index = i++;
+ if (!(al = newof(0, Attribute_list_t, 1, 0)))
+ {
+ fprintf(stderr, "%s: %d: out of space\n", command, line);
+ return 1;
+ }
+ if (!lp->attributes)
+ lp->attributes = al;
+ else
+ az->next = al;
+ az = al;
+ al->attribute = ap;
+ al->next = 0;
+ macro(lf, "SUBLANG", lp->name, b);
+ fprintf(lf, "\n},\n");
+ }
+ if (language_attribute_max < i)
+ language_attribute_max = i;
+ fprintf(lf, "};\n");
+ }
+ if (lp != (Language_t*)enter(&state.language, (Link_t*)lp))
+ {
+ fprintf(stderr, "%s: %d: %s: duplicate language\n", command, line, lp->link.code);
+ return 1;
+ }
+ break;
+ case MAP:
+ if (!(mp = newof(0, Map_t, 1, s - b + 1)))
+ {
+ fprintf(stderr, "%s: %d: out of space\n", command, line);
+ return 1;
+ }
+ b = (char*)(mp + 1);
+ mp->link.code = copy(&b, arg[0]);
+ if (!arg[2])
+ {
+ fprintf(stderr, "%s: %d: territory code expected\n", command, line);
+ return 1;
+ }
+ if (!(mp->language = (Language_t*)lookup(&state.language, arg[1])))
+ {
+ fprintf(stderr, "%s: %d: %s: unknown language\n", command, line, arg[1]);
+ return 1;
+ }
+ if (!(mp->territory = (Territory_t*)lookup(&state.territory, arg[2])))
+ {
+ fprintf(stderr, "%s: %d: %s: unknown territory\n", command, line, arg[2]);
+ return 1;
+ }
+ if (!arg[3])
+ mp->charset = 0;
+ else if (!(mp->charset = (Charset_t*)lookup(&state.charset, arg[3])))
+ {
+ fprintf(stderr, "%s: %d: %s: unknown charset\n", command, line, arg[3]);
+ return 1;
+ }
+ mp->attribute = 0;
+ if (arg[4])
+ {
+ for (al = mp->language->attributes; al; al = al->next)
+ if (!strcmp(al->attribute->link.code, arg[4]))
+ {
+ mp->attribute = al->attribute;
+ break;
+ }
+ if (!mp->attribute)
+ {
+ fprintf(stderr, "%s: %d: %s: unknown attribute\n", command, line, arg[4]);
+ return 1;
+ }
+ }
+ if (mp != (Map_t*)enter(&state.map, (Link_t*)mp))
+ {
+ fprintf(stderr, "%s: %d: %s: duplicate map\n", command, line, mp->link.code);
+ return 1;
+ }
+ break;
+ }
+ }
+ if (!language_attribute_max)
+ language_attribute_max = 1;
+ if (!territory_language_max)
+ territory_language_max = 1;
+ fprintf(hf, "\n#define LC_language_attribute_max\t%d\n", language_attribute_max);
+ fprintf(hf, "#define LC_territory_language_max\t%d\n", territory_language_max);
+ fprintf(hf, "\nstruct Lc_s;\n");
+ fprintf(hf, "\ntypedef struct Lc_info_s\n{\n");
+ fprintf(hf, "\tconst struct Lc_s*\tlc;\n");
+ fprintf(hf, "\tunsigned long\t\tnumber;\n");
+ fprintf(hf, "\tvoid*\t\t\tdata;\n");
+ fprintf(hf, "} Lc_info_t;\n");
+ fprintf(hf, "\ntypedef struct Lc_attribute_s\n{\n");
+ fprintf(hf, "\tconst char*\t\tname;\n");
+ fprintf(hf, "\tunsigned long\t\tflags;\n");
+ fprintf(hf, "\tunsigned long\t\tindex;\n");
+ fprintf(hf, "} Lc_attribute_t;\n");
+ fprintf(hf, "\ntypedef struct Lc_charset_s\n{\n");
+ fprintf(hf, "\tconst char*\t\tcode;\n");
+ fprintf(hf, "\tconst char*\t\talternates;\n");
+ fprintf(hf, "\tconst char*\t\tms;\n");
+ fprintf(hf, "\tunsigned long\t\tindex;\n");
+ fprintf(hf, "} Lc_charset_t;\n");
+ fprintf(hf, "\ntypedef struct Lc_language_s\n{\n");
+ fprintf(hf, "\tconst char*\t\tcode;\n");
+ fprintf(hf, "\tconst char*\t\tname;\n");
+ fprintf(hf, "\tconst char*\t\talternates;\n");
+ fprintf(hf, "\tconst Lc_charset_t*\tcharset;\n");
+ fprintf(hf, "\tunsigned long\t\tflags;\n");
+ fprintf(hf, "\tunsigned long\t\tindex;\n");
+ fprintf(hf, "\tconst Lc_attribute_t*\tattributes[LC_language_attribute_max];\n");
+ fprintf(hf, "} Lc_language_t;\n");
+ fprintf(hf, "\ntypedef struct Lc_territory_s\n{\n");
+ fprintf(hf, "\tconst char*\t\tcode;\n");
+ fprintf(hf, "\tconst char*\t\tname;\n");
+ fprintf(hf, "\tunsigned long\t\tflags;\n");
+ fprintf(hf, "\tunsigned long\t\tindex;\n");
+ fprintf(hf, "\tconst Lc_language_t*\tlanguages[LC_territory_language_max];\n");
+ fprintf(hf, "#ifdef _LC_TERRITORY_PRIVATE_\n");
+ fprintf(hf, "\t_LC_TERRITORY_PRIVATE_\n");
+ fprintf(hf, "#endif\n");
+ fprintf(hf, "} Lc_territory_t;\n");
+ fprintf(hf, "\ntypedef struct Lc_map_s\n{\n");
+ fprintf(hf, "\tconst char*\t\tcode;\n");
+ fprintf(hf, "\tconst Lc_language_t*\tlanguage;\n");
+ fprintf(hf, "\tconst Lc_territory_t*\tterritory;\n");
+ fprintf(hf, "\tconst Lc_charset_t*\tcharset;\n");
+ fprintf(hf, "\tconst Lc_attribute_t*\tattribute;\n");
+ fprintf(hf, "} Lc_map_t;\n");
+ fprintf(hf, "\ntypedef struct Lc_attribute_list_s\n{\n");
+ fprintf(hf, "\tstruct Lc_attribute_list_s*\tnext;\n");
+ fprintf(hf, "\tconst Lc_attribute_t*\t\tattribute;\n");
+ fprintf(hf, "} Lc_attribute_list_t;\n");
+ fprintf(hf, "\ntypedef struct Lc_s\n{\n");
+ fprintf(hf, "\tconst char*\t\tname;\n");
+ fprintf(hf, "\tconst char*\t\tcode;\n");
+ fprintf(hf, "\tconst Lc_language_t*\tlanguage;\n");
+ fprintf(hf, "\tconst Lc_territory_t*\tterritory;\n");
+ fprintf(hf, "\tconst Lc_charset_t*\tcharset;\n");
+ fprintf(hf, "\tconst Lc_attribute_list_t*\tattributes;\n");
+ fprintf(hf, "\tunsigned long\t\tflags;\n");
+ fprintf(hf, "\tunsigned long\t\tindex;\n");
+ fprintf(hf, "#ifdef _LC_PRIVATE_\n");
+ fprintf(hf, "\t_LC_PRIVATE_\n");
+ fprintf(hf, "#endif\n");
+ fprintf(hf, "} Lc_t;\n");
+ fprintf(hf, "\nstruct Lc_category_s;\n");
+ fprintf(hf, "\ntypedef int (*Lc_category_set_f)(struct Lc_category_s*);\n");
+ fprintf(hf, "\ntypedef struct Lc_category_s\n{\n");
+ fprintf(hf, "\tconst char*\t\tname;\n");
+ fprintf(hf, "\tint\t\t\texternal;\n");
+ fprintf(hf, "\tint\t\t\tinternal;\n");
+ fprintf(hf, "\tLc_category_set_f\tsetf;\n");
+ fprintf(hf, "\tLc_t*\t\t\tprev;\n");
+ fprintf(hf, "\tunsigned int\t\tflags;\n");
+ fprintf(hf, "} Lc_category_t;\n");
+ fprintf(hf, "\n");
+ fprintf(hf, "#if _BLD_ast && defined(__EXPORT__)\n");
+ fprintf(hf, "#define extern\t\t__EXPORT__\n");
+ fprintf(hf, "#endif\n");
+ fprintf(hf, "\n");
+ fprintf(hf, "extern size_t\t\tlccanon(Lc_t*, unsigned long flags, char*, size_t);\n");
+ fprintf(hf, "extern Lc_category_t*\tlccategories(void);\n");
+ fprintf(hf, "extern int\t\tlcindex(int, int);\n");
+ fprintf(hf, "extern Lc_info_t*\tlcinfo(int);\n");
+ fprintf(hf, "extern Lc_t*\t\tlcmake(const char*);\n");
+ fprintf(hf, "extern Lc_t*\t\tlcscan(Lc_t*);\n");
+ fprintf(hf, "\n");
+ fprintf(hf, "#undef\textern\n");
+ fprintf(lf, "\nconst Lc_charset_t lc_charsets[] =\n{\n");
+ for (cp = (Charset_t*)state.charset.root; cp; cp = (Charset_t*)cp->link.next)
+ {
+ fprintf(lf, "{\"%s\",", cp->link.code);
+ if (cp->alternates)
+ fprintf(lf, "\"%s\",", cp->alternates);
+ else
+ fprintf(lf, "0,");
+ if (cp->ms)
+ fprintf(lf, "\"%s\",", cp->ms);
+ else
+ fprintf(lf, "0");
+ fprintf(lf, "},\n");
+ }
+ fprintf(lf, "\t0\n};\n");
+ fprintf(lf, "\nconst Lc_language_t lc_languages[] =\n{\n");
+ fprintf(lf, "{\"C\",\"C\",\"POSIX\",&lc_charsets[0],LC_default,0,");
+ for (i = 0; i < language_attribute_max; i++)
+ fprintf(lf, "0,");
+ fprintf(lf, "},\n");
+ fprintf(lf, "{\"debug\",\"debug\",0,&lc_charsets[0],LC_debug,0,");
+ for (i = 0; i < language_attribute_max; i++)
+ fprintf(lf, "0,");
+ fprintf(lf, "},\n");
+ for (lp = (Language_t*)state.language.root; lp; lp = (Language_t*)lp->link.next)
+ {
+ fprintf(lf, "{\"%s\",\"%s\",", lp->link.code, lp->name);
+ if (lp->alternates)
+ fprintf(lf, "\"%s\",", lp->alternates);
+ else
+ fprintf(lf, "0,");
+ fprintf(lf, "&lc_charsets[%d],0,", lp->charset ? lp->charset->link.index : 0);
+ macro(lf, "LANG", lp->name, (char*)0);
+ for (i = 0, al = lp->attributes; al; al = al->next, i++)
+ fprintf(lf, "&attribute_%s[%d],", lp->link.code, al->attribute->link.index);
+ for (; i < language_attribute_max; i++)
+ fprintf(lf, "0,");
+ fprintf(lf, "\n},\n");
+ }
+ fprintf(lf, "\t0\n};\n");
+ fprintf(lf, "\nconst Lc_territory_t lc_territories[] =\n{\n");
+ fprintf(lf, "{\"C\",\"C\",LC_default,0,&lc_languages[0],");
+ for (i = 1; i < 2 * territory_language_max; i++)
+ fprintf(lf, "0,");
+ fprintf(lf, "},\n");
+ fprintf(lf, "{\"debug\",\"debug\",LC_debug,0,&lc_languages[1],");
+ for (i = 1; i < 2 * territory_language_max; i++)
+ fprintf(lf, "0,");
+ fprintf(lf, "},\n");
+ fprintf(lf, "{\"eu\",\"euro\",0,0,&lc_languages[0],");
+ for (i = 1; i < 2 * territory_language_max; i++)
+ fprintf(lf, "0,");
+ fprintf(lf, "},\n");
+ for (tp = (Territory_t*)state.territory.root; tp; tp = (Territory_t*)tp->link.next)
+ {
+ fprintf(lf, "{\"%s\",\"%s\",", tp->link.code, tp->name);
+ if (tp->primary)
+ fprintf(lf, "LC_primary,");
+ else
+ fprintf(lf, "0,");
+ macro(lf, "CTRY", tp->name, (char*)0);
+ for (i = 0, ll = tp->languages; ll; ll = ll->next, i++)
+ fprintf(lf, "&lc_languages[%d],", ll->language->link.index);
+ for (; i < territory_language_max; i++)
+ fprintf(lf, "0,");
+ for (i = 0, ll = tp->languages; ll; ll = ll->next, i++)
+ macro(lf, "SUBLANG", ll->language->name, tp->name);
+ for (; i < territory_language_max; i++)
+ fprintf(lf, "0,");
+ fprintf(lf, "\n},\n");
+ }
+ fprintf(lf, "\t0\n};\n");
+ fprintf(lf, "\nconst Lc_map_t lc_maps[] =\n{\n");
+ for (mp = (Map_t*)state.map.root; mp; mp = (Map_t*)mp->link.next)
+ {
+ fprintf(lf, "{\"%s\",", mp->link.code);
+ fprintf(lf, "&lc_languages[%d],", mp->language->link.index);
+ fprintf(lf, "&lc_territories[%d],", mp->territory->link.index);
+ fprintf(lf, "&lc_charsets[%d],", mp->charset ? mp->charset->link.index : 0);
+ if (mp->attribute)
+ fprintf(lf, "&attribute_%s[%d]", mp->language->link.code, mp->attribute->link.index);
+ else
+ fprintf(lf, "0");
+ fprintf(lf, "},\n");
+ }
+ fprintf(lf, "\t0\n};\n");
+ fclose(lf);
+ fprintf(hf, "\n#endif\n");
+ fclose(hf);
+ return 0;
+}
diff --git a/src/lib/libast/port/lclang.h b/src/lib/libast/port/lclang.h
new file mode 100644
index 0000000..356f2b0
--- /dev/null
+++ b/src/lib/libast/port/lclang.h
@@ -0,0 +1,120 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * lc (sub)lang definitions -- very windowsish
+ */
+
+#if _WINIX
+
+#include <ast_windows.h>
+
+#ifndef LANG_CHINESE_SIMPLIFIED
+#define LANG_CHINESE_SIMPLIFIED LANG_CHINESE
+#endif
+#ifndef LANG_CHINESE_TRADITIONAL
+#define LANG_CHINESE_TRADITIONAL LANG_CHINESE
+#endif
+#ifndef LANG_NORWEGIAN_BOKMAL
+#define LANG_NORWEGIAN_BOKMAL LANG_NORWEGIAN
+#endif
+#ifndef LANG_NORWEGIAN_NYNORSK
+#define LANG_NORWEGIAN_NYNORSK LANG_NORWEGIAN
+#endif
+#ifndef LANG_SERBO_CROATIAN
+#define LANG_SERBO_CROATIAN LANG_CROATIAN
+#endif
+
+#ifndef CTRY_CZECH_REPUBLIC
+#define CTRY_CZECH_REPUBLIC CTRY_CZECH
+#endif
+
+#ifndef SUBLANG_CHINESE_SIMPLIFIED_CHINA
+#define SUBLANG_CHINESE_SIMPLIFIED_CHINA SUBLANG_CHINESE_SIMPLIFIED
+#endif
+#ifndef SUBLANG_CHINESE_SIMPLIFIED_HONG_KONG
+#define SUBLANG_CHINESE_SIMPLIFIED_HONG_KONG SUBLANG_CHINESE_HONGKONG
+#endif
+#ifndef SUBLANG_CHINESE_SIMPLIFIED_SINGAPORE
+#define SUBLANG_CHINESE_SIMPLIFIED_SINGAPORE SUBLANG_CHINESE_SINGAPORE
+#endif
+#ifndef SUBLANG_CHINESE_TRADITIONAL_TAIWAN
+#define SUBLANG_CHINESE_TRADITIONAL_TAIWAN SUBLANG_CHINESE_TRADITIONAL
+#endif
+#ifndef SUBLANG_DUTCH_NETHERLANDS_ANTILLES
+#define SUBLANG_DUTCH_NETHERLANDS_ANTILLES SUBLANG_DUTCH
+#endif
+#ifndef SUBLANG_DUTCH_BELGIUM
+#define SUBLANG_DUTCH_BELGIUM SUBLANG_DUTCH_BELGIAN
+#endif
+#ifndef SUBLANG_ENGLISH_AUSTRALIA
+#define SUBLANG_ENGLISH_AUSTRALIA SUBLANG_ENGLISH_AUS
+#endif
+#ifndef SUBLANG_ENGLISH_CANADA
+#define SUBLANG_ENGLISH_CANADA SUBLANG_ENGLISH_CAN
+#endif
+#ifndef SUBLANG_ENGLISH_IRELAND
+#define SUBLANG_ENGLISH_IRELAND SUBLANG_ENGLISH_EIRE
+#endif
+#ifndef SUBLANG_ENGLISH_NEW_ZEALAND
+#define SUBLANG_ENGLISH_NEW_ZEALAND SUBLANG_ENGLISH_NZ
+#endif
+#ifndef SUBLANG_ENGLISH_TRINIDAD_TOBAGO
+#define SUBLANG_ENGLISH_TRINIDAD_TOBAGO SUBLANG_ENGLISH_CARIBBEAN
+#endif
+#ifndef SUBLANG_ENGLISH_UNITED_KINGDOM
+#define SUBLANG_ENGLISH_UNITED_KINGDOM SUBLANG_ENGLISH_UK
+#endif
+#ifndef SUBLANG_ENGLISH_UNITED_STATES
+#define SUBLANG_ENGLISH_UNITED_STATES SUBLANG_ENGLISH_US
+#endif
+#ifndef SUBLANG_FRENCH_BELGIUM
+#define SUBLANG_FRENCH_BELGIUM SUBLANG_FRENCH_BELGIAN
+#endif
+#ifndef SUBLANG_FRENCH_CANADA
+#define SUBLANG_FRENCH_CANADA SUBLANG_FRENCH_CANADIAN
+#endif
+#ifndef SUBLANG_FRENCH_SWITZERLAND
+#define SUBLANG_FRENCH_SWITZERLAND SUBLANG_FRENCH_SWISS
+#endif
+#ifndef SUBLANG_GERMAN_AUSTRIA
+#define SUBLANG_GERMAN_AUSTRIA SUBLANG_GERMAN_AUSTRIAN
+#endif
+#ifndef SUBLANG_GERMAN_SWITZERLAND
+#define SUBLANG_GERMAN_SWITZERLAND SUBLANG_GERMAN_SWISS
+#endif
+#ifndef SUBLANG_ITALIAN_SWITZERLAND
+#define SUBLANG_ITALIAN_SWITZERLAND SUBLANG_ITALIAN_SWISS
+#endif
+#ifndef SUBLANG_NORWEGIAN_BOKMAL_NORWAY
+#define SUBLANG_NORWEGIAN_BOKMAL_NORWAY SUBLANG_NORWEGIAN_BOKMAL
+#endif
+#ifndef SUBLANG_NORWEGIAN_NORWAY
+#define SUBLANG_NORWEGIAN_NORWAY SUBLANG_NORWEGIAN_BOKMAL
+#endif
+#ifndef SUBLANG_NORWEGIAN_NYNORSK_NORWAY
+#define SUBLANG_NORWEGIAN_NYNORSK_NORWAY SUBLANG_NORWEGIAN_NYNORSK
+#endif
+#ifndef SUBLANG_PORTUGUESE_BRAZIL
+#define SUBLANG_PORTUGUESE_BRAZIL SUBLANG_PORTUGUESE_BRAZILIAN
+#endif
+
+#endif
diff --git a/src/lib/libast/port/lclib.h b/src/lib/libast/port/lclib.h
new file mode 100644
index 0000000..5daeb8a
--- /dev/null
+++ b/src/lib/libast/port/lclib.h
@@ -0,0 +1,71 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * locale state private definitions
+ */
+
+#ifndef _LCLIB_H
+#define _LCLIB_H 1
+
+#define locales _ast_locales
+#define translate _ast_translate
+
+#define lc_categories _ast_lc_categories
+#define lc_charsets _ast_lc_charsets
+#define lc_languages _ast_lc_languages
+#define lc_maps _ast_lc_maps
+#define lc_territories _ast_lc_territories
+
+struct Lc_info_s;
+
+#define _LC_PRIVATE_ \
+ struct Lc_info_s info[AST_LC_COUNT]; \
+ struct Lc_s* next;
+
+#define _LC_TERRITORY_PRIVATE_ \
+ unsigned char indices[LC_territory_language_max];
+
+#include <ast.h>
+#include <error.h>
+#include <lc.h>
+
+typedef struct Lc_numeric_s
+{
+ int decimal;
+ int thousand;
+} Lc_numeric_t;
+
+#define LCINFO(c) (&locales[c]->info[c])
+
+extern const Lc_charset_t lc_charsets[];
+extern const Lc_language_t lc_languages[];
+extern const Lc_map_t lc_maps[];
+extern const Lc_territory_t lc_territories[];
+
+extern Lc_category_t lc_categories[];
+extern Lc_t* locales[];
+
+extern char* translate(const char*, const char*, const char*, const char*);
+
+#endif
diff --git a/src/lib/libast/port/mc.c b/src/lib/libast/port/mc.c
new file mode 100644
index 0000000..f2ee65c
--- /dev/null
+++ b/src/lib/libast/port/mc.c
@@ -0,0 +1,675 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * machine independent binary message catalog implementation
+ */
+
+#include "sfhdr.h"
+#include "lclib.h"
+
+#include <iconv.h>
+
+#define _MC_PRIVATE_ \
+ size_t nstrs; \
+ size_t nmsgs; \
+ iconv_t cvt; \
+ Sfio_t* tmp; \
+ Vmalloc_t* vm;
+
+#include <vmalloc.h>
+#include <error.h>
+#include <mc.h>
+#include <nl_types.h>
+
+/*
+ * find the binary message catalog path for <locale,catalog>
+ * result placed in path of size PATH_MAX
+ * pointer to path returned
+ * catalog==0 tests for category directory or file
+ * nls!=0 enables NLSPATH+LANG hack (not implemented yet)
+ */
+
+char*
+mcfind(const char* locale, const char* catalog, int category, int nls, char* path, size_t size)
+{
+ register int c;
+ register char* s;
+ register char* e;
+ register char* p;
+ register const char* v;
+ int i;
+ int first;
+ int next;
+ int last;
+ int oerrno;
+ Lc_t* lc;
+ char file[PATH_MAX];
+ char* paths[5];
+
+ static char lc_messages[] = "LC_MESSAGES";
+
+ if ((category = lcindex(category, 1)) < 0)
+ return 0;
+ if (!(lc = locale ? lcmake(locale) : locales[category]))
+ return 0;
+ oerrno = errno;
+ if (catalog && *catalog == '/')
+ {
+ i = eaccess(catalog, R_OK);
+ errno = oerrno;
+ if (i)
+ return 0;
+ strlcpy(path, catalog, size);
+ return path;
+ }
+ i = 0;
+ if ((p = getenv("NLSPATH")) && *p)
+ paths[i++] = p;
+ paths[i++] = "share/lib/locale/%l/%C/%N";
+ paths[i++] = "share/locale/%l/%C/%N";
+ paths[i++] = "lib/locale/%l/%C/%N";
+ paths[i] = 0;
+ next = 1;
+ for (i = 0; p = paths[i]; i += next)
+ {
+ first = 1;
+ last = 0;
+ e = &file[elementsof(file) - 1];
+ while (*p)
+ {
+ s = file;
+ for (;;)
+ {
+ switch (c = *p++)
+ {
+ case 0:
+ p--;
+ break;
+ case ':':
+ break;
+ case '%':
+ if (s < e)
+ {
+ switch (c = *p++)
+ {
+ case 0:
+ p--;
+ continue;
+ case 'N':
+ v = catalog;
+ break;
+ case 'L':
+ if (first)
+ {
+ first = 0;
+ if (next)
+ {
+ v = lc->code;
+ if (lc->code != lc->language->code)
+ next = 0;
+ }
+ else
+ {
+ next = 1;
+ v = lc->language->code;
+ }
+ }
+ break;
+ case 'l':
+ v = lc->language->code;
+ break;
+ case 't':
+ v = lc->territory->code;
+ break;
+ case 'c':
+ v = lc->charset->code;
+ break;
+ case 'C':
+ case_C:
+ if (!catalog)
+ last = 1;
+ v = lc_categories[category].name;
+ break;
+ default:
+ *s++ = c;
+ continue;
+ }
+ if (v)
+ while (*v && s < e)
+ *s++ = *v++;
+ }
+ continue;
+ case '/':
+ if (last)
+ break;
+ if (category != AST_LC_MESSAGES && strneq(p, lc_messages, sizeof(lc_messages) - 1) && p[sizeof(lc_messages)-1] == '/')
+ {
+ p += sizeof(lc_messages) - 1;
+ goto case_C;
+ }
+ /*FALLTHROUGH*/
+ default:
+ if (s < e)
+ *s++ = c;
+ continue;
+ }
+ break;
+ }
+ if (s > file)
+ *s = 0;
+ else if (!catalog)
+ continue;
+ else
+ strlcpy(file, catalog, elementsof(file));
+ if (ast.locale.set & AST_LC_find)
+ sfprintf(sfstderr, "locale find %s\n", file);
+ if (s = pathpath(file, "", (!catalog && category == AST_LC_MESSAGES) ? PATH_READ : (PATH_REGULAR|PATH_READ|PATH_ABSOLUTE), path, size))
+ {
+ if (ast.locale.set & (AST_LC_find|AST_LC_setlocale))
+ sfprintf(sfstderr, "locale path %s\n", s);
+ errno = oerrno;
+ return s;
+ }
+ }
+ }
+ errno = oerrno;
+ return 0;
+}
+
+/*
+ * allocate and read the binary message catalog ip
+ * if ip==0 then space is allocated for mcput()
+ * 0 returned on any error
+ */
+
+Mc_t*
+mcopen(register Sfio_t* ip)
+{
+ register Mc_t* mc;
+ register char** mp;
+ register char* sp;
+ Vmalloc_t* vm;
+ char* rp;
+ int i;
+ int j;
+ int oerrno;
+ size_t n;
+ char buf[MC_MAGIC_SIZE];
+
+ oerrno = errno;
+ if (ip)
+ {
+ /*
+ * check the magic
+ */
+
+ if (sfread(ip, buf, MC_MAGIC_SIZE) != MC_MAGIC_SIZE)
+ {
+ errno = oerrno;
+ return 0;
+ }
+ if (memcmp(buf, MC_MAGIC, MC_MAGIC_SIZE))
+ return 0;
+ }
+
+ /*
+ * allocate the region
+ */
+
+ if (!(vm = vmopen(Vmdcheap, Vmbest, 0)) || !(mc = vmnewof(vm, 0, Mc_t, 1, 0)))
+ {
+ errno = oerrno;
+ return 0;
+ }
+ mc->vm = vm;
+ mc->cvt = (iconv_t)(-1);
+ if (ip)
+ {
+ /*
+ * read the translation record
+ */
+
+ if (!(sp = sfgetr(ip, 0, 0)) || !(mc->translation = vmstrdup(vm, sp)))
+ goto bad;
+
+ /*
+ * read the optional header records
+ */
+
+ do
+ {
+ if (!(sp = sfgetr(ip, 0, 0)))
+ goto bad;
+ } while (*sp);
+
+ /*
+ * get the component dimensions
+ */
+
+ mc->nstrs = sfgetu(ip);
+ mc->nmsgs = sfgetu(ip);
+ mc->num = sfgetu(ip);
+ if (sfeof(ip))
+ goto bad;
+ }
+ else if (!(mc->translation = vmnewof(vm, 0, char, 1, 0)))
+ goto bad;
+
+ /*
+ * allocate the remaining space
+ */
+
+ if (!(mc->set = vmnewof(vm, 0, Mcset_t, mc->num + 1, 0)))
+ goto bad;
+ if (!ip)
+ return mc;
+ if (!(mp = vmnewof(vm, 0, char*, mc->nmsgs + mc->num + 1, 0)))
+ goto bad;
+ if (!(rp = sp = vmalloc(vm, mc->nstrs + 1)))
+ goto bad;
+
+ /*
+ * get the set dimensions and initialize the msg pointers
+ */
+
+ while (i = sfgetu(ip))
+ {
+ if (i > mc->num)
+ goto bad;
+ n = sfgetu(ip);
+ mc->set[i].num = n;
+ mc->set[i].msg = mp;
+ mp += n + 1;
+ }
+
+ /*
+ * read the msg sizes and set up the msg pointers
+ */
+
+ for (i = 1; i <= mc->num; i++)
+ for (j = 1; j <= mc->set[i].num; j++)
+ if (n = sfgetu(ip))
+ {
+ mc->set[i].msg[j] = sp;
+ sp += n;
+ }
+
+ /*
+ * read the string table
+ */
+
+ if (sfread(ip, rp, mc->nstrs) != mc->nstrs || sfgetc(ip) != EOF)
+ goto bad;
+ if (!(mc->tmp = sfstropen()))
+ goto bad;
+ mc->cvt = iconv_open("", "utf");
+ errno = oerrno;
+ return mc;
+ bad:
+ vmclose(vm);
+ errno = oerrno;
+ return 0;
+}
+
+/*
+ * return the <set,num> message in mc
+ * msg returned on error
+ * utf message text converted to ucs
+ */
+
+char*
+mcget(register Mc_t* mc, int set, int num, const char* msg)
+{
+ char* s;
+ size_t n;
+ int p;
+
+ if (!mc || set < 0 || set > mc->num || num < 1 || num > mc->set[set].num || !(s = mc->set[set].msg[num]))
+ return (char*)msg;
+ if (mc->cvt == (iconv_t)(-1))
+ return s;
+ if ((p = sfstrtell(mc->tmp)) > sfstrsize(mc->tmp) / 2)
+ {
+ p = 0;
+ sfstrseek(mc->tmp, p, SEEK_SET);
+ }
+ n = strlen(s) + 1;
+ iconv_write(mc->cvt, mc->tmp, &s, &n, NiL);
+ return sfstrbase(mc->tmp) + p;
+}
+
+/*
+ * set message <set,num> to msg
+ * msg==0 deletes the message
+ * the message and set counts are adjusted
+ * 0 returned on success, -1 otherwise
+ */
+
+int
+mcput(register Mc_t* mc, int set, int num, const char* msg)
+{
+ register int i;
+ register char* s;
+ register Mcset_t* sp;
+ register char** mp;
+
+ /*
+ * validate the arguments
+ */
+
+ if (!mc || set > MC_SET_MAX || num > MC_NUM_MAX)
+ return -1;
+
+ /*
+ * deletions don't kick in allocations (duh)
+ */
+
+ if (!msg)
+ {
+ if (set <= mc->num && num <= mc->set[set].num && (s = mc->set[set].msg[num]))
+ {
+ /*
+ * decrease the string table size
+ */
+
+ mc->set[set].msg[num] = 0;
+ mc->nstrs -= strlen(s) + 1;
+ if (mc->set[set].num == num)
+ {
+ /*
+ * decrease the max msg num
+ */
+
+ mp = mc->set[set].msg + num;
+ while (num && !mp[--num]);
+ mc->nmsgs -= mc->set[set].num - num;
+ if (!(mc->set[set].num = num) && mc->num == set)
+ {
+ /*
+ * decrease the max set num
+ */
+
+ while (num && !mc->set[--num].num);
+ mc->num = num;
+ }
+ }
+ }
+ return 0;
+ }
+
+ /*
+ * keep track of the highest set and allocate if necessary
+ */
+
+ if (set > mc->num)
+ {
+ if (set > mc->gen)
+ {
+ i = MC_SET_MAX;
+ if (!(sp = vmnewof(mc->vm, 0, Mcset_t, i + 1, 0)))
+ return -1;
+ mc->gen = i;
+ for (i = 1; i <= mc->num; i++)
+ sp[i] = mc->set[i];
+ mc->set = sp;
+ }
+ mc->num = set;
+ }
+ sp = mc->set + set;
+
+ /*
+ * keep track of the highest msg and allocate if necessary
+ */
+
+ if (num > sp->num)
+ {
+ if (num > sp->gen)
+ {
+ if (!mc->gen)
+ {
+ i = (MC_NUM_MAX + 1) / 32;
+ if (i <= num)
+ i = 2 * num;
+ if (i > MC_NUM_MAX)
+ i = MC_NUM_MAX;
+ if (!(mp = vmnewof(mc->vm, 0, char*, i + 1, 0)))
+ return -1;
+ mc->gen = i;
+ sp->msg = mp;
+ for (i = 1; i <= sp->num; i++)
+ mp[i] = sp->msg[i];
+ }
+ else
+ {
+ i = 2 * mc->gen;
+ if (i > MC_NUM_MAX)
+ i = MC_NUM_MAX;
+ if (!(mp = vmnewof(mc->vm, sp->msg, char*, i + 1, 0)))
+ return -1;
+ sp->gen = i;
+ sp->msg = mp;
+ }
+ }
+ mc->nmsgs += num - sp->num;
+ sp->num = num;
+ }
+
+ /*
+ * decrease the string table size
+ */
+
+ if (s = sp->msg[num])
+ {
+ /*
+ * no-op if no change
+ */
+
+ if (streq(s, msg))
+ return 0;
+ mc->nstrs -= strlen(s) + 1;
+ }
+
+ /*
+ * allocate, add and adjust the string table size
+ */
+
+ if (!(s = vmstrdup(mc->vm, msg)))
+ return -1;
+ sp->msg[num] = s;
+ mc->nstrs += strlen(s) + 1;
+ return 0;
+}
+
+/*
+ * dump message catalog mc to op
+ * 0 returned on success, -1 otherwise
+ */
+
+int
+mcdump(register Mc_t* mc, register Sfio_t* op)
+{
+ register int i;
+ register int j;
+ register int n;
+ register char* s;
+ register Mcset_t* sp;
+
+ /*
+ * write the magic
+ */
+
+ if (sfwrite(op, MC_MAGIC, MC_MAGIC_SIZE) != MC_MAGIC_SIZE)
+ return -1;
+
+ /*
+ * write the translation record
+ */
+
+ sfputr(op, mc->translation, 0);
+
+ /* optional header records here */
+
+ /*
+ * end of optional header records
+ */
+
+ sfputu(op, 0);
+
+ /*
+ * write the global dimensions
+ */
+
+ sfputu(op, mc->nstrs);
+ sfputu(op, mc->nmsgs);
+ sfputu(op, mc->num);
+
+ /*
+ * write the set dimensions
+ */
+
+ for (i = 1; i <= mc->num; i++)
+ if (mc->set[i].num)
+ {
+ sfputu(op, i);
+ sfputu(op, mc->set[i].num);
+ }
+ sfputu(op, 0);
+
+ /*
+ * write the message sizes
+ */
+
+ for (i = 1; i <= mc->num; i++)
+ if (mc->set[i].num)
+ {
+ sp = mc->set + i;
+ for (j = 1; j <= sp->num; j++)
+ {
+ n = (s = sp->msg[j]) ? (strlen(s) + 1) : 0;
+ sfputu(op, n);
+ }
+ }
+
+ /*
+ * write the string table
+ */
+
+ for (i = 1; i <= mc->num; i++)
+ if (mc->set[i].num)
+ {
+ sp = mc->set + i;
+ for (j = 1; j <= sp->num; j++)
+ if (s = sp->msg[j])
+ sfputr(op, s, 0);
+ }
+
+ /*
+ * sync and return
+ */
+
+ return sfsync(op);
+}
+
+/*
+ * parse <set,msg> number from s
+ * e!=0 is set to the next char after the parse
+ * set!=0 is set to message set number
+ * msg!=0 is set to message number
+ * the message set number is returned
+ *
+ * the base 36 hash gives reasonable values for these:
+ *
+ * "ast" : ((((36#a^36#s^36#t)-9)&63)+1) = 3
+ * "gnu" : ((((36#g^36#n^36#u)-9)&63)+1) = 17
+ * "sgi" : ((((36#s^36#g^36#i)-9)&63)+1) = 22
+ * "sun" : ((((36#s^36#u^36#n)-9)&63)+1) = 13
+ */
+
+int
+mcindex(register const char* s, char** e, int* set, int* msg)
+{
+ register int c;
+ register int m;
+ register int n;
+ register int r;
+ register unsigned char* cv;
+ char* t;
+
+ m = 0;
+ n = strtol(s, &t, 0);
+ if (t == (char*)s)
+ {
+ SFCVINIT();
+ cv = _Sfcv36;
+ for (n = m = 0; (c = cv[*s]) < 36; s++)
+ {
+ m++;
+ n ^= c;
+ }
+ m = (m <= 3) ? 63 : ((1 << (m + 3)) - 1);
+ n = ((n - 9) & m) + 1;
+ }
+ else
+ s = (const char*)t;
+ r = n;
+ if (*s)
+ m = strtol(s + 1, e, 0);
+ else
+ {
+ if (e)
+ *e = (char*)s;
+ if (m)
+ m = 0;
+ else
+ {
+ m = n;
+ n = 1;
+ }
+ }
+ if (set)
+ *set = n;
+ if (msg)
+ *msg = m;
+ return r;
+}
+
+/*
+ * close the message catalog mc
+ */
+
+int
+mcclose(register Mc_t* mc)
+{
+ if (!mc)
+ return -1;
+ if (mc->tmp)
+ sfclose(mc->tmp);
+ if (mc->cvt != (iconv_t)(-1))
+ iconv_close(mc->cvt);
+ vmclose(mc->vm);
+ return 0;
+}
diff --git a/src/lib/libast/port/mnt.c b/src/lib/libast/port/mnt.c
new file mode 100644
index 0000000..f773ae8
--- /dev/null
+++ b/src/lib/libast/port/mnt.c
@@ -0,0 +1,816 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * mounted filesystem scan support
+ * where are the standards when you really need them
+ */
+
+#include <ast.h>
+#include <mnt.h>
+#include <ls.h>
+
+#if _lib_mntopen && _lib_mntread && _lib_mntclose
+
+NoN(mnt)
+
+#else
+
+/*
+ * the original interface just had mode
+ */
+
+#define FIXARGS(p,m,s) do { \
+ if ((p)&&*(p)!='/') { \
+ mode = p; \
+ path = 0; \
+ } \
+ if (!path) \
+ path = s; \
+ } while (0)
+typedef struct
+{
+ Mnt_t mnt;
+ char buf[128];
+#if __CYGWIN__
+ char typ[128];
+ char opt[128];
+#endif
+} Header_t;
+
+#if __CYGWIN__
+#include <ast_windows.h>
+#endif
+
+static void
+set(register Header_t* hp, const char* fs, const char* dir, const char* type, const char* options)
+{
+ const char* x;
+
+ hp->mnt.flags = 0;
+ if (x = (const char*)strchr(fs, ':'))
+ {
+ if (*++x && *x != '\\')
+ {
+ hp->mnt.flags |= MNT_REMOTE;
+ if (*x == '(')
+ {
+ fs = x;
+ type = "auto";
+ }
+ }
+ }
+ else if (x = (const char*)strchr(fs, '@'))
+ {
+ hp->mnt.flags |= MNT_REMOTE;
+ sfsprintf(hp->buf, sizeof(hp->buf) - 1, "%s:%*.*s", x + 1, x - fs, x - fs, fs);
+ fs = (const char*)hp->buf;
+ }
+ else if (strmatch(type, "[aAnN][fF][sS]*"))
+ hp->mnt.flags |= MNT_REMOTE;
+ if (streq(fs, "none"))
+ fs = dir;
+ hp->mnt.fs = (char*)fs;
+ hp->mnt.dir = (char*)dir;
+ hp->mnt.type = (char*)type;
+ hp->mnt.options = (char*)options;
+#if __CYGWIN__
+ if (streq(type, "system") || streq(type, "user"))
+ {
+ char* s;
+ int mode;
+ DWORD vser;
+ DWORD flags;
+ DWORD len;
+ char drive[4];
+
+ mode = SetErrorMode(SEM_FAILCRITICALERRORS);
+ drive[0] = fs[0];
+ drive[1] = ':';
+ drive[2] = '\\';
+ drive[3] = 0;
+ if (GetVolumeInformation(drive, 0, 0, &vser, &len, &flags, hp->typ, sizeof(hp->typ) - 1))
+ hp->mnt.type = hp->typ;
+ else
+ flags = 0;
+ SetErrorMode(mode);
+ s = strcopy(hp->mnt.options = hp->opt, type);
+ s = strcopy(s, ",ignorecase");
+ if (options)
+ {
+ *s++ = ',';
+ strcpy(s, options);
+ }
+ }
+#endif
+}
+
+#undef MNT_REMOTE
+
+#if _sys_mount && ( _lib_getfsstat || _lib_getmntinfo )
+
+/*
+ * 4.4 bsd getmntinfo
+ *
+ * what a crappy interface
+ * data returned in static buffer -- ok
+ * big chunk of allocated memory that cannot be freed -- come on
+ * *and* netbsd changed the interface somewhere along the line
+ * private interface? my bad -- public interface? par for the bsd course
+ *
+ * we assume getfsstat may suffer the same statfs/statvfs confusion
+ */
+
+#include <sys/param.h> /* expect some macro redefinitions here */
+#include <sys/mount.h>
+
+#if _lib_getfsstat
+#if _lib_getfsstat_statvfs
+#define statfs statvfs
+#define f_flags f_flag
+#endif
+#else
+#if _lib_getmntinfo_statvfs
+#define statfs statvfs
+#define f_flags f_flag
+#endif
+#endif
+
+typedef struct
+{
+ Header_t hdr;
+ struct statfs* next;
+ struct statfs* last;
+ char opt[256];
+#if _lib_getfsstat
+ struct statfs buf[1];
+#endif
+} Handle_t;
+
+#ifdef MFSNAMELEN
+#define TYPE(f) ((f)->f_fstypename)
+#else
+#ifdef INITMOUNTNAMES
+#define TYPE(f) ((char*)type[(f)->f_type])
+static const char* type[] = INITMOUNTNAMES;
+#else
+#if _sys_fs_types
+#define TYPE(f) ((char*)mnt_names[(f)->f_type])
+#include <sys/fs_types.h>
+#else
+#define TYPE(f) (strchr((f)->f_mntfromname,':')?"nfs":"ufs")
+#endif
+#endif
+#endif
+
+static struct Mnt_options_t
+{
+ unsigned long flag;
+ const char* name;
+}
+options[] =
+{
+#ifdef MNT_RDONLY
+ MNT_RDONLY, "rdonly",
+#endif
+#ifdef MNT_SYNCHRONOUS
+ MNT_SYNCHRONOUS,"synchronous",
+#endif
+#ifdef MNT_NOEXEC
+ MNT_NOEXEC, "noexec",
+#endif
+#ifdef MNT_NOSUID
+ MNT_NOSUID, "nosuid",
+#endif
+#ifdef MNT_NODEV
+ MNT_NODEV, "nodev",
+#endif
+#ifdef MNT_UNION
+ MNT_UNION, "union",
+#endif
+#ifdef MNT_ASYNC
+ MNT_ASYNC, "async",
+#endif
+#ifdef MNT_NOCOREDUMP
+ MNT_NOCOREDUMP, "nocoredump",
+#endif
+#ifdef MNT_NOATIME
+ MNT_NOATIME, "noatime",
+#endif
+#ifdef MNT_SYMPERM
+ MNT_SYMPERM, "symperm",
+#endif
+#ifdef MNT_NODEVMTIME
+ MNT_NODEVMTIME, "nodevmtime",
+#endif
+#ifdef MNT_SOFTDEP
+ MNT_SOFTDEP, "softdep",
+#endif
+#ifdef MNT_EXRDONLY
+ MNT_EXRDONLY, "exrdonly",
+#endif
+#ifdef MNT_EXPORTED
+ MNT_EXPORTED, "exported",
+#endif
+#ifdef MNT_DEFEXPORTED
+ MNT_DEFEXPORTED,"defexported",
+#endif
+#ifdef MNT_EXPORTANON
+ MNT_EXPORTANON, "exportanon",
+#endif
+#ifdef MNT_EXKERB
+ MNT_EXKERB, "exkerb",
+#endif
+#ifdef MNT_EXNORESPORT
+ MNT_EXNORESPORT,"exnoresport",
+#endif
+#ifdef MNT_EXPUBLIC
+ MNT_EXPUBLIC, "expublic",
+#endif
+#ifdef MNT_LOCAL
+ MNT_LOCAL, "local",
+#endif
+#ifdef MNT_QUOTA
+ MNT_QUOTA, "quota",
+#endif
+#ifdef MNT_ROOTFS
+ MNT_ROOTFS, "rootfs",
+#endif
+ 0, "unknown",
+};
+
+void*
+mntopen(const char* path, const char* mode)
+{
+ register Handle_t* mp;
+ register int n;
+
+ FIXARGS(path, mode, 0);
+#if _lib_getfsstat
+ if ((n = getfsstat(NiL, 0, MNT_WAIT)) <= 0)
+ return 0;
+ n = (n - 1) * sizeof(struct statfs);
+#else
+ n = 0;
+#endif
+ if (!(mp = newof(0, Handle_t, 1, n)))
+ return 0;
+#if _lib_getfsstat
+ n = getfsstat(mp->next = mp->buf, n + sizeof(struct statfs), MNT_WAIT);
+#else
+ n = getmntinfo(&mp->next, 0);
+#endif
+ if (n <= 0)
+ {
+ free(mp);
+ return 0;
+ }
+ mp->last = mp->next + n;
+ return (void*)mp;
+}
+
+Mnt_t*
+mntread(void* handle)
+{
+ register Handle_t* mp = (Handle_t*)handle;
+ register int i;
+ register int n;
+ register unsigned long flags;
+
+ if (mp->next < mp->last)
+ {
+ flags = mp->next->f_flags;
+ n = 0;
+ for (i = 0; i < elementsof(options); i++)
+ if (flags & options[i].flag)
+ n += sfsprintf(mp->opt + n, sizeof(mp->opt) - n - 1, ",%s", options[i].name);
+ set(&mp->hdr, mp->next->f_mntfromname, mp->next->f_mntonname, TYPE(mp->next), n ? (mp->opt + 1) : (char*)0);
+ mp->next++;
+ return &mp->hdr.mnt;
+ }
+ return 0;
+}
+
+int
+mntclose(void* handle)
+{
+ register Handle_t* mp = (Handle_t*)handle;
+
+ if (!mp)
+ return -1;
+ free(mp);
+ return 0;
+}
+
+#else
+
+#if _lib_mntctl && _sys_vmount
+
+/*
+ * aix
+ */
+
+#include <sys/vmount.h>
+
+#define SIZE (16 * 1024)
+
+static const char* type[] =
+{
+ "aix", "aix#1", "nfs", "jfs", "aix#4", "cdrom"
+};
+
+typedef struct
+{
+ Header_t hdr;
+ long count;
+ struct vmount* next;
+ char remote[128];
+ char type[16];
+ struct vmount info[1];
+} Handle_t;
+
+void*
+mntopen(const char* path, const char* mode)
+{
+ register Handle_t* mp;
+
+ FIXARGS(path, mode, 0);
+ if (!(mp = newof(0, Handle_t, 1, SIZE)))
+ return 0;
+ if ((mp->count = mntctl(MCTL_QUERY, sizeof(Handle_t) + SIZE, &mp->info)) <= 0)
+ {
+ free(mp);
+ return 0;
+ }
+ mp->next = mp->info;
+ return (void*)mp;
+}
+
+Mnt_t*
+mntread(void* handle)
+{
+ register Handle_t* mp = (Handle_t*)handle;
+ register char* s;
+ register char* t;
+ register char* o;
+
+ if (mp->count > 0)
+ {
+ if (vmt2datasize(mp->next, VMT_HOST) && (s = vmt2dataptr(mp->next, VMT_HOST)) && !streq(s, "-"))
+ {
+ sfsprintf(mp->remote, sizeof(mp->remote) - 1, "%s:%s", s, vmt2dataptr(mp->next, VMT_OBJECT));
+ s = mp->remote;
+ }
+ else
+ s = vmt2dataptr(mp->next, VMT_OBJECT);
+ if (vmt2datasize(mp->next, VMT_ARGS))
+ o = vmt2dataptr(mp->next, VMT_ARGS);
+ else
+ o = NiL;
+ switch (mp->next->vmt_gfstype)
+ {
+#ifdef MNT_AIX
+ case MNT_AIX:
+ t = "aix";
+ break;
+#endif
+#ifdef MNT_NFS
+ case MNT_NFS:
+ t = "nfs";
+ break;
+#endif
+#ifdef MNT_JFS
+ case MNT_JFS:
+ t = "jfs";
+ break;
+#endif
+#ifdef MNT_CDROM
+ case MNT_CDROM:
+ t = "cdrom";
+ break;
+#endif
+#ifdef MNT_SFS
+ case MNT_SFS:
+ t = "sfs";
+ break;
+#endif
+#ifdef MNT_CACHEFS
+ case MNT_CACHEFS:
+ t = "cachefs";
+ break;
+#endif
+#ifdef MNT_NFS3
+ case MNT_NFS3:
+ t = "nfs3";
+ break;
+#endif
+#ifdef MNT_AUTOFS
+ case MNT_AUTOFS:
+ t = "autofs";
+ break;
+#endif
+ default:
+ sfsprintf(t = mp->type, sizeof(mp->type), "aix%+d", mp->next->vmt_gfstype);
+ break;
+ }
+ set(&mp->hdr, s, vmt2dataptr(mp->next, VMT_STUB), t, o);
+ if (--mp->count > 0)
+ mp->next = (struct vmount*)((char*)mp->next + mp->next->vmt_length);
+ return &mp->hdr.mnt;
+ }
+ return 0;
+}
+
+int
+mntclose(void* handle)
+{
+ register Handle_t* mp = (Handle_t*)handle;
+
+ if (!mp)
+ return -1;
+ free(mp);
+ return 0;
+}
+
+#else
+
+#if !_lib_setmntent
+#undef _lib_getmntent
+#if !_SCO_COFF && !_SCO_ELF && !_UTS
+#undef _hdr_mnttab
+#endif
+#endif
+
+#if _lib_getmntent && ( _hdr_mntent || _sys_mntent && !_sys_mnttab )
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide endmntent getmntent
+#else
+#define endmntent ______endmntent
+#define getmntent ______getmntent
+#endif
+
+#include <stdio.h>
+#if _hdr_mntent
+#include <mntent.h>
+#else
+#include <sys/mntent.h>
+#endif
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide endmntent getmntent
+#else
+#undef endmntent
+#undef getmntent
+#endif
+
+extern int endmntent(FILE*);
+extern struct mntent* getmntent(FILE*);
+
+#else
+
+#undef _lib_getmntent
+
+#if _hdr_mnttab
+#include <mnttab.h>
+#else
+#if _sys_mnttab
+#include <sys/mnttab.h>
+#endif
+#endif
+
+#endif
+
+#ifndef MOUNTED
+#ifdef MNT_MNTTAB
+#define MOUNTED MNT_MNTTAB
+#else
+#if _hdr_mnttab || _sys_mnttab
+#define MOUNTED "/etc/mnttab"
+#else
+#define MOUNTED "/etc/mtab"
+#endif
+#endif
+#endif
+
+#ifdef __Lynx__
+#undef MOUNTED
+#define MOUNTED "/etc/fstab"
+#define SEP ':'
+#endif
+
+#if _lib_getmntent
+
+typedef struct
+#if _mem_mnt_opts_mntent
+#define OPTIONS(p) ((p)->mnt_opts)
+#else
+#define OPTIONS(p) NiL
+#endif
+
+{
+ Header_t hdr;
+ FILE* fp;
+} Handle_t;
+
+void*
+mntopen(const char* path, const char* mode)
+{
+ register Handle_t* mp;
+
+ FIXARGS(path, mode, MOUNTED);
+ if (!(mp = newof(0, Handle_t, 1, 0)))
+ return 0;
+ if (!(mp->fp = setmntent(path, mode)))
+ {
+ free(mp);
+ return 0;
+ }
+ return (void*)mp;
+}
+
+Mnt_t*
+mntread(void* handle)
+{
+ register Handle_t* mp = (Handle_t*)handle;
+ register struct mntent* mnt;
+
+ if (mnt = getmntent(mp->fp))
+ {
+ set(&mp->hdr, mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, OPTIONS(mnt));
+ return &mp->hdr.mnt;
+ }
+ return 0;
+}
+
+int
+mntclose(void* handle)
+{
+ register Handle_t* mp = (Handle_t*)handle;
+
+ if (!mp)
+ return -1;
+ endmntent(mp->fp);
+ free(mp);
+ return 0;
+}
+
+#else
+
+#if _sys_mntent && _lib_w_getmntent
+
+#include <sys/mntent.h>
+
+#define mntent w_mntent
+
+#define mnt_dir mnt_mountpoint
+#define mnt_type mnt_fstname
+
+#define MNTBUFSIZE (sizeof(struct w_mnth)+16*sizeof(struct w_mntent))
+
+#if _mem_mnt_opts_w_mntent
+#define OPTIONS(p) ((p)->mnt_opts)
+#else
+#define OPTIONS(p) NiL
+#endif
+
+#else
+
+#undef _lib_w_getmntent
+
+#define MNTBUFSIZE sizeof(struct mntent)
+
+#if !_mem_mt_dev_mnttab || !_mem_mt_filsys_mnttab
+#undef _hdr_mnttab
+#endif
+
+#if _hdr_mnttab
+
+#define mntent mnttab
+
+#define mnt_fsname mt_dev
+#define mnt_dir mt_filsys
+#if _mem_mt_fstyp_mnttab
+#define mnt_type mt_fstyp
+#endif
+
+#if _mem_mnt_opts_mnttab
+#define OPTIONS(p) ((p)->mnt_opts)
+#else
+#define OPTIONS(p) NiL
+#endif
+
+#else
+
+struct mntent
+{
+ char mnt_fsname[256];
+ char mnt_dir[256];
+ char mnt_type[32];
+ char mnt_opts[64];
+};
+
+#define OPTIONS(p) ((p)->mnt_opts)
+
+#endif
+
+#endif
+
+typedef struct
+{
+ Header_t hdr;
+ Sfio_t* fp;
+ struct mntent* mnt;
+#if _lib_w_getmntent
+ int count;
+#endif
+ char buf[MNTBUFSIZE];
+} Handle_t;
+
+void*
+mntopen(const char* path, const char* mode)
+{
+ register Handle_t* mp;
+
+ FIXARGS(path, mode, MOUNTED);
+ if (!(mp = newof(0, Handle_t, 1, 0)))
+ return 0;
+#if _lib_w_getmntent
+ if ((mp->count = w_getmntent(mp->buf, sizeof(mp->buf))) > 0)
+ mp->mnt = (struct mntent*)(((struct w_mnth*)mp->buf) + 1);
+ else
+#else
+ mp->mnt = (struct mntent*)mp->buf;
+ if (!(mp->fp = sfopen(NiL, path, mode)))
+#endif
+ {
+ free(mp);
+ return 0;
+ }
+ return (void*)mp;
+}
+
+Mnt_t*
+mntread(void* handle)
+{
+ register Handle_t* mp = (Handle_t*)handle;
+
+#if _lib_w_getmntent
+
+ if (mp->count-- <= 0)
+ {
+ if ((mp->count = w_getmntent(mp->buf, sizeof(mp->buf))) <= 0)
+ return 0;
+ mp->count--;
+ mp->mnt = (struct mntent*)(((struct w_mnth*)mp->buf) + 1);
+ }
+ set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, mp->mnt->mnt_type, OPTIONS(mp->mnt));
+ mp->mnt++;
+ return &mp->hdr.mnt;
+
+#else
+
+#if _hdr_mnttab
+
+ while (sfread(mp->fp, &mp->buf, sizeof(mp->buf)) == sizeof(mp->buf))
+ if (*mp->mnt->mnt_fsname && *mp->mnt->mnt_dir)
+ {
+#ifndef mnt_type
+ struct stat st;
+
+ static char typ[32];
+
+ set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, stat(mp->mnt->mnt_dir, &st) ? FS_default : strlcpy(typ, fmtfs(&st), sizeof(typ)), OPTIONS(mp->mnt));
+#else
+ set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, mp->mnt->mnt_type, OPTIONS(mp->mnt));
+#endif
+ return &mp->hdr.mnt;
+ }
+ return 0;
+
+#else
+
+ register int c;
+ register char* s;
+ register char* m;
+ register char* b;
+ register int q;
+ register int x;
+
+ again:
+ q = 0;
+ x = 0;
+ b = s = mp->mnt->mnt_fsname;
+ m = s + sizeof(mp->mnt->mnt_fsname) - 1;
+ for (;;) switch (c = sfgetc(mp->fp))
+ {
+ case EOF:
+ return 0;
+ case '"':
+ case '\'':
+ if (q == c)
+ q = 0;
+ else if (!q)
+ q = c;
+ break;
+#ifdef SEP
+ case SEP:
+#else
+ case ' ':
+ case '\t':
+#endif
+ if (s != b && !q) switch (++x)
+ {
+ case 1:
+ *s = 0;
+ b = s = mp->mnt->mnt_dir;
+ m = s + sizeof(mp->mnt->mnt_dir) - 1;
+ break;
+ case 2:
+ *s = 0;
+ b = s = mp->mnt->mnt_type;
+ m = s + sizeof(mp->mnt->mnt_type) - 1;
+ break;
+ case 3:
+ *s = 0;
+ b = s = mp->mnt->mnt_opts;
+ m = s + sizeof(mp->mnt->mnt_opts) - 1;
+ break;
+ case 4:
+ *s = 0;
+ b = s = m = 0;
+ break;
+ }
+ break;
+ case '\n':
+ if (x >= 3)
+ {
+ set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, mp->mnt->mnt_type, OPTIONS(mp->mnt));
+ return &mp->hdr.mnt;
+ }
+ goto again;
+ default:
+ if (s < m)
+ *s++ = c;
+ break;
+ }
+
+#endif
+
+#endif
+
+}
+
+int
+mntclose(void* handle)
+{
+ register Handle_t* mp = (Handle_t*)handle;
+
+ if (!mp)
+ return -1;
+ sfclose(mp->fp);
+ free(mp);
+ return 0;
+}
+
+#endif
+
+#endif
+
+#endif
+
+/*
+ * currently no write
+ */
+
+int
+mntwrite(void* handle, const Mnt_t* mnt)
+{
+ NoP(handle);
+ NoP(mnt);
+ return -1;
+}
+
+#endif
diff --git a/src/lib/libast/port/touch.c b/src/lib/libast/port/touch.c
new file mode 100644
index 0000000..c921181
--- /dev/null
+++ b/src/lib/libast/port/touch.c
@@ -0,0 +1,74 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * touch file access and modify times of file
+ * if flags&PATH_TOUCH_CREATE then file will be created if it doesn't exist
+ * if flags&PATH_TOUCH_VERBATIM then times are taken verbatim
+ * times have one second granularity
+ *
+ * (time_t)(-1) retain old time
+ * 0 use current time
+ *
+ * the old interface flag values were:
+ * 1 PATH_TOUCH_CREATE
+ * -1 PATH_TOUCH_CREATE|PATH_TOUCH_VERBATIM
+ * PATH_TOUCH_VERBATIM -- not supported
+ */
+
+#include <ast.h>
+#include <times.h>
+#include <tv.h>
+
+int
+touch(const char* path, time_t at, time_t mt, int flags)
+{
+ Tv_t av;
+ Tv_t mv;
+ Tv_t* ap;
+ Tv_t* mp;
+
+ if (at == (time_t)(-1) && !(flags & PATH_TOUCH_VERBATIM))
+ ap = TV_TOUCH_RETAIN;
+ else if (!at && !(flags & PATH_TOUCH_VERBATIM))
+ ap = 0;
+ else
+ {
+ av.tv_sec = at;
+ av.tv_nsec = 0;
+ ap = &av;
+ }
+ if (mt == (time_t)(-1) && !(flags & PATH_TOUCH_VERBATIM))
+ mp = TV_TOUCH_RETAIN;
+ else if (!mt && !(flags & PATH_TOUCH_VERBATIM))
+ mp = 0;
+ else
+ {
+ mv.tv_sec = mt;
+ mv.tv_nsec = 0;
+ mp = &mv;
+ }
+ return tvtouch(path, ap, mp, NiL, flags & 1);
+}
diff --git a/src/lib/libast/preroot/getpreroot.c b/src/lib/libast/preroot/getpreroot.c
new file mode 100644
index 0000000..3747d19
--- /dev/null
+++ b/src/lib/libast/preroot/getpreroot.c
@@ -0,0 +1,165 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Bell Laboratories
+ * return the real absolute pathname of the preroot dir for cmd
+ * if cmd==0 then current preroot path returned
+ */
+
+#include <ast.h>
+#include <preroot.h>
+
+#if FS_PREROOT
+
+#include <ast_dir.h>
+#include <ls.h>
+#include <error.h>
+#include <stdio.h>
+
+#ifndef ERANGE
+#define ERANGE E2BIG
+#endif
+
+#define ERROR(e) {errno=e;goto error;}
+
+char*
+getpreroot(char* path, const char* cmd)
+{
+ register int c;
+ register FILE* fp;
+ register char* p;
+ char buf[PATH_MAX];
+
+ if (!path) path = buf;
+ if (cmd)
+ {
+ sfsprintf(buf, sizeof(buf), "set x `%s= %s - </dev/null 2>&1`\nwhile :\ndo\nshift\ncase $# in\n[012]) break ;;\nesac\ncase \"$1 $2\" in\n\"+ %s\") echo $3; exit ;;\nesac\ndone\necho\n", PR_SILENT, cmd, PR_COMMAND);
+ if (!(fp = popen(buf, "rug"))) return(0);
+ for (p = path; (c = getc(fp)) != EOF && c != '\n'; *p++ = c);
+ *p = 0;
+ pclose(fp);
+ if (path == p) return(0);
+ return(path == buf ? strdup(path) : path);
+ }
+ else
+ {
+ char* d;
+ DIR* dirp = 0;
+ int namlen;
+ int euid;
+ int ruid;
+ struct dirent* entry;
+ struct stat* cur;
+ struct stat* par;
+ struct stat* tmp;
+ struct stat curst;
+ struct stat parst;
+ struct stat tstst;
+ char dots[PATH_MAX];
+
+ cur = &curst;
+ par = &parst;
+ if ((ruid = getuid()) != (euid = geteuid())) setuid(ruid);
+ if (stat(PR_REAL, cur) || stat("/", par) || cur->st_dev == par->st_dev && cur->st_ino == par->st_ino) ERROR(ENOTDIR);
+
+ /*
+ * like getcwd() but starting at the preroot
+ */
+
+ d = dots;
+ *d++ = '/';
+ p = path + PATH_MAX - 1;
+ *p = 0;
+ for (;;)
+ {
+ tmp = cur;
+ cur = par;
+ par = tmp;
+ if ((d - dots) > (PATH_MAX - 4)) ERROR(ERANGE);
+ *d++ = '.';
+ *d++ = '.';
+ *d = 0;
+ if (!(dirp = opendir(dots))) ERROR(errno);
+#if !_dir_ok || _mem_dd_fd_DIR
+ if (fstat(dirp->dd_fd, par)) ERROR(errno);
+#else
+ if (stat(dots, par)) ERROR(errno);
+#endif
+ *d++ = '/';
+ if (par->st_dev == cur->st_dev)
+ {
+ if (par->st_ino == cur->st_ino)
+ {
+ closedir(dirp);
+ *--p = '/';
+ if (ruid != euid) setuid(euid);
+ if (path == buf) return(strdup(p));
+ if (path != p)
+ {
+ d = path;
+ while (*d++ = *p++);
+ }
+ return(path);
+ }
+#ifdef D_FILENO
+ while (entry = readdir(dirp))
+ if (D_FILENO(entry) == cur->st_ino)
+ {
+ namlen = D_NAMLEN(entry);
+ goto found;
+ }
+#endif
+
+ /*
+ * this fallthrough handles logical naming
+ */
+
+ rewinddir(dirp);
+ }
+ do
+ {
+ if (!(entry = readdir(dirp))) ERROR(ENOENT);
+ namlen = D_NAMLEN(entry);
+ if ((d - dots) > (PATH_MAX - 1 - namlen)) ERROR(ERANGE);
+ memcpy(d, entry->d_name, namlen + 1);
+ if (stat(dots, &tstst)) ERROR(errno);
+ } while (tstst.st_ino != cur->st_ino || tstst.st_dev != cur->st_dev);
+ found:
+ if (*p) *--p = '/';
+ if ((p -= namlen) <= (path + 1)) ERROR(ERANGE);
+ memcpy(p, entry->d_name, namlen);
+ closedir(dirp);
+ dirp = 0;
+ }
+ error:
+ if (dirp) closedir(dirp);
+ if (ruid != euid) setuid(euid);
+ }
+ return(0);
+}
+
+#else
+
+NoN(getpreroot)
+
+#endif
diff --git a/src/lib/libast/preroot/ispreroot.c b/src/lib/libast/preroot/ispreroot.c
new file mode 100644
index 0000000..36bf62c
--- /dev/null
+++ b/src/lib/libast/preroot/ispreroot.c
@@ -0,0 +1,71 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Bell Laboratories
+ * return 1 if dir [any dir] is the preroot
+ */
+
+#include <ast.h>
+#include <preroot.h>
+
+#if FS_PREROOT
+
+#include <ls.h>
+
+/*
+ * return 1 if files a and b are the same under preroot
+ *
+ * NOTE: the kernel disables preroot for set-uid processes
+ */
+
+static int
+same(const char* a, const char* b)
+{
+ int i;
+ int euid;
+ int ruid;
+
+ struct stat ast;
+ struct stat bst;
+
+ if ((ruid = getuid()) != (euid = geteuid())) setuid(ruid);
+ i = !stat(a, &ast) && !stat(b, &bst) && ast.st_dev == bst.st_dev && ast.st_ino == bst.st_ino;
+ if (ruid != euid) setuid(euid);
+ return(i);
+}
+
+int
+ispreroot(const char* dir)
+{
+ static int prerooted = -1;
+
+ if (dir) return(same("/", dir));
+ if (prerooted < 0) prerooted = !same("/", PR_REAL);
+ return(prerooted);
+}
+
+#else
+
+NoN(ispreroot)
+
+#endif
diff --git a/src/lib/libast/preroot/realopen.c b/src/lib/libast/preroot/realopen.c
new file mode 100644
index 0000000..387559b
--- /dev/null
+++ b/src/lib/libast/preroot/realopen.c
@@ -0,0 +1,47 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Bell Laboratories
+ * disable preroot and open path relative to the real root
+ */
+
+#include <ast.h>
+#include <preroot.h>
+
+#if FS_PREROOT
+
+int
+realopen(const char* path, int mode, int perm)
+{
+ char buf[PATH_MAX + 8];
+
+ if (*path != '/' || !ispreroot(NiL)) return(-1);
+ strcopy(strcopy(buf, PR_REAL), path);
+ return(open(buf, mode, perm));
+}
+
+#else
+
+NoN(realopen)
+
+#endif
diff --git a/src/lib/libast/preroot/setpreroot.c b/src/lib/libast/preroot/setpreroot.c
new file mode 100644
index 0000000..1e8b6c1
--- /dev/null
+++ b/src/lib/libast/preroot/setpreroot.c
@@ -0,0 +1,75 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * AT&T Bell Laboratories
+ * force current command to run under dir preroot
+ */
+
+#include <ast.h>
+#include <preroot.h>
+
+#if FS_PREROOT
+
+#include <option.h>
+
+void
+setpreroot(register char** argv, const char* dir)
+{
+ register char* s;
+ register char** ap;
+ int argc;
+ char* cmd;
+ char** av;
+ char buf[PATH_MAX];
+
+ if ((argv || (argv = opt_info.argv)) && (dir || (dir = getenv(PR_BASE)) && *dir) && !ispreroot(dir) && (*(cmd = *argv++) == '/' || (cmd = pathpath(cmd, NiL, PATH_ABSOLUTE|PATH_REGULAR|PATH_EXECUTE, buf, sizeof(buf)))))
+ {
+ argc = 3;
+ for (ap = argv; *ap++; argc++);
+ if (av = newof(0, char*, argc, 0))
+ {
+ ap = av;
+ *ap++ = PR_COMMAND;
+ *ap++ = (char*)dir;
+ *ap++ = cmd;
+ while (*ap++ = *argv++);
+ if (!(s = getenv(PR_SILENT)) || !*s)
+ {
+ sfprintf(sfstderr, "+");
+ ap = av;
+ while (s = *ap++)
+ sfprintf(sfstderr, " %s", s);
+ sfprintf(sfstderr, "\n");
+ sfsync(sfstderr);
+ }
+ execv(*av, av);
+ free(av);
+ }
+ }
+}
+
+#else
+
+NoN(setpreroot)
+
+#endif
diff --git a/src/lib/libast/regex/regalloc.c b/src/lib/libast/regex/regalloc.c
new file mode 100644
index 0000000..03807a4
--- /dev/null
+++ b/src/lib/libast/regex/regalloc.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * posix regex alloc control
+ */
+
+#include "reglib.h"
+
+void
+regalloc(void* handle, void*(*resize)(void*,void*,size_t), regflags_t flags)
+{
+ state.disc.re_flags = flags;
+ state.disc.re_resizef = resize;
+ state.disc.re_resizehandle = handle;
+}
diff --git a/src/lib/libast/regex/regcache.c b/src/lib/libast/regex/regcache.c
new file mode 100644
index 0000000..a45f0e3
--- /dev/null
+++ b/src/lib/libast/regex/regcache.c
@@ -0,0 +1,198 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * regcomp() regex_t cache
+ * at&t research
+ */
+
+#include <ast.h>
+#include <regex.h>
+
+#define CACHE 8 /* default # cached re's */
+#define ROUND 64 /* pattern buffer size round */
+
+typedef unsigned long Key_t;
+
+typedef struct Cache_s
+{
+ char* pattern;
+ regex_t re;
+ unsigned long serial;
+ regflags_t reflags;
+ int keep;
+ int size;
+} Cache_t;
+
+typedef struct State_s
+{
+ unsigned int size;
+ unsigned long serial;
+ char* locale;
+ Cache_t** cache;
+} State_t;
+
+static State_t matchstate;
+
+/*
+ * flush the cache
+ */
+
+static void
+flushcache(void)
+{
+ register int i;
+
+ for (i = matchstate.size; i--;)
+ if (matchstate.cache[i] && matchstate.cache[i]->keep)
+ {
+ matchstate.cache[i]->keep = 0;
+ regfree(&matchstate.cache[i]->re);
+ }
+}
+
+/*
+ * return regcomp() compiled re for pattern and reflags
+ */
+
+regex_t*
+regcache(const char* pattern, regflags_t reflags, int* status)
+{
+ register Cache_t* cp;
+ register int i;
+ char* s;
+ int empty;
+ int unused;
+ int old;
+ Key_t key;
+
+ /*
+ * 0 pattern flushes the cache and reflags>0 extends cache
+ */
+
+ if (!pattern)
+ {
+ flushcache();
+ i = 0;
+ if (reflags > matchstate.size)
+ {
+ if (matchstate.cache = newof(matchstate.cache, Cache_t*, reflags, 0))
+ matchstate.size = reflags;
+ else
+ {
+ matchstate.size = 0;
+ i = 1;
+ }
+ }
+ if (status)
+ *status = i;
+ return 0;
+ }
+ if (!matchstate.cache)
+ {
+ if (!(matchstate.cache = newof(0, Cache_t*, CACHE, 0)))
+ return 0;
+ matchstate.size = CACHE;
+ }
+
+ /*
+ * flush the cache if the locale changed
+ * the ast setlocale() intercept maintains
+ * persistent setlocale() return values
+ */
+
+ if ((s = setlocale(LC_CTYPE, NiL)) != matchstate.locale)
+ {
+ matchstate.locale = s;
+ flushcache();
+ }
+
+ /*
+ * check if the pattern is in the cache
+ */
+
+ for (i = 0; i < sizeof(key) && pattern[i]; i++)
+ ((char*)&key)[i] = pattern[i];
+ for (; i < sizeof(key); i++)
+ ((char*)&key)[i] = 0;
+ empty = unused = -1;
+ old = 0;
+ for (i = matchstate.size; i--;)
+ if (!matchstate.cache[i])
+ empty = i;
+ else if (!matchstate.cache[i]->keep)
+ unused = i;
+ else if (*(Key_t*)matchstate.cache[i]->pattern == key && !strcmp(matchstate.cache[i]->pattern, pattern) && matchstate.cache[i]->reflags == reflags)
+ break;
+ else if (!matchstate.cache[old] || matchstate.cache[old]->serial > matchstate.cache[i]->serial)
+ old = i;
+ if (i < 0)
+ {
+ if (unused < 0)
+ {
+ if (empty < 0)
+ unused = old;
+ else
+ unused = empty;
+ }
+ if (!(cp = matchstate.cache[unused]) && !(cp = matchstate.cache[unused] = newof(0, Cache_t, 1, 0)))
+ {
+ if (status)
+ *status = REG_ESPACE;
+ return 0;
+ }
+ if (cp->keep)
+ {
+ cp->keep = 0;
+ regfree(&cp->re);
+ }
+ if ((i = strlen(pattern) + 1) > cp->size)
+ {
+ cp->size = roundof(i, ROUND);
+ if (!(cp->pattern = newof(cp->pattern, char, cp->size, 0)))
+ {
+ if (status)
+ *status = REG_ESPACE;
+ return 0;
+ }
+ }
+ strcpy(cp->pattern, pattern);
+ while (++i < sizeof(Key_t))
+ cp->pattern[i] = 0;
+ pattern = (const char*)cp->pattern;
+ if (i = regcomp(&cp->re, pattern, reflags))
+ {
+ if (status)
+ *status = i;
+ return 0;
+ }
+ cp->keep = 1;
+ cp->reflags = reflags;
+ }
+ else
+ cp = matchstate.cache[i];
+ cp->serial = ++matchstate.serial;
+ if (status)
+ *status = 0;
+ return &cp->re;
+}
diff --git a/src/lib/libast/regex/regclass.c b/src/lib/libast/regex/regclass.c
new file mode 100644
index 0000000..87ada74
--- /dev/null
+++ b/src/lib/libast/regex/regclass.c
@@ -0,0 +1,298 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * RE character class support
+ */
+
+#include "reglib.h"
+
+struct Ctype_s; typedef struct Ctype_s Ctype_t;
+
+struct Ctype_s
+{
+ const char* name;
+ size_t size;
+ regclass_t ctype;
+ Ctype_t* next;
+#if _lib_wctype
+ wctype_t wtype;
+#endif
+};
+
+static Ctype_t* ctypes;
+
+/*
+ * this stuff gets around posix failure to define isblank,
+ * and the fact that ctype functions are macros
+ * and any local extensions that may not even have functions or macros
+ */
+
+#if _need_iswblank
+
+int
+_reg_iswblank(wint_t wc)
+{
+ static int initialized;
+ static wctype_t wt;
+
+ if (!initialized)
+ {
+ initialized = 1;
+ wt = wctype("blank");
+ }
+ return iswctype(wc, wt);
+}
+
+#endif
+
+static int Isalnum(int c) { return iswalnum(c); }
+static int Isalpha(int c) { return iswalpha(c); }
+static int Isblank(int c) { return iswblank(c); }
+static int Iscntrl(int c) { return iswcntrl(c); }
+static int Isdigit(int c) { return iswdigit(c); }
+static int Notdigit(int c) { return !iswdigit(c); }
+static int Isgraph(int c) { return iswgraph(c); }
+static int Islower(int c) { return iswlower(c); }
+static int Isprint(int c) { return iswprint(c); }
+static int Ispunct(int c) { return iswpunct(c); }
+static int Isspace(int c) { return iswspace(c); }
+static int Notspace(int c) { return !iswspace(c); }
+static int Isupper(int c) { return iswupper(c); }
+static int Isword(int c) { return iswalnum(c) || c == '_'; }
+static int Notword(int c) { return !iswalnum(c) && c != '_'; }
+static int Isxdigit(int c) { return iswxdigit(c);}
+
+#if _lib_wctype
+
+static int Is_wc_1(int);
+static int Is_wc_2(int);
+static int Is_wc_3(int);
+static int Is_wc_4(int);
+static int Is_wc_5(int);
+static int Is_wc_6(int);
+static int Is_wc_7(int);
+static int Is_wc_8(int);
+static int Is_wc_9(int);
+static int Is_wc_10(int);
+static int Is_wc_11(int);
+static int Is_wc_12(int);
+static int Is_wc_13(int);
+static int Is_wc_14(int);
+static int Is_wc_15(int);
+static int Is_wc_16(int);
+
+#endif
+
+#define SZ(s) s,(sizeof(s)-1)
+
+static Ctype_t ctype[] =
+{
+ { SZ("alnum"), Isalnum },
+ { SZ("alpha"), Isalpha },
+ { SZ("blank"), Isblank },
+ { SZ("cntrl"), Iscntrl },
+ { SZ("digit"), Isdigit },
+ { SZ("graph"), Isgraph },
+ { SZ("lower"), Islower },
+ { SZ("print"), Isprint },
+ { SZ("punct"), Ispunct },
+ { SZ("space"), Isspace },
+ { SZ("upper"), Isupper },
+ { SZ("word"), Isword },
+ { SZ("xdigit"),Isxdigit},
+
+#define CTYPES 13
+
+#if _lib_wctype
+ { 0, 0, Is_wc_1 },
+ { 0, 0, Is_wc_2 },
+ { 0, 0, Is_wc_3 },
+ { 0, 0, Is_wc_4 },
+ { 0, 0, Is_wc_5 },
+ { 0, 0, Is_wc_6 },
+ { 0, 0, Is_wc_7 },
+ { 0, 0, Is_wc_8 },
+ { 0, 0, Is_wc_9 },
+ { 0, 0, Is_wc_10 },
+ { 0, 0, Is_wc_11 },
+ { 0, 0, Is_wc_12 },
+ { 0, 0, Is_wc_13 },
+ { 0, 0, Is_wc_14 },
+ { 0, 0, Is_wc_15 },
+ { 0, 0, Is_wc_16 },
+
+#define WTYPES 16
+
+#else
+
+#define WTYPES 0
+
+#endif
+};
+
+#if _lib_wctype
+
+static int Is_wc_1(int c) { return iswctype(c, ctype[CTYPES+0].wtype); }
+static int Is_wc_2(int c) { return iswctype(c, ctype[CTYPES+1].wtype); }
+static int Is_wc_3(int c) { return iswctype(c, ctype[CTYPES+2].wtype); }
+static int Is_wc_4(int c) { return iswctype(c, ctype[CTYPES+3].wtype); }
+static int Is_wc_5(int c) { return iswctype(c, ctype[CTYPES+4].wtype); }
+static int Is_wc_6(int c) { return iswctype(c, ctype[CTYPES+5].wtype); }
+static int Is_wc_7(int c) { return iswctype(c, ctype[CTYPES+6].wtype); }
+static int Is_wc_8(int c) { return iswctype(c, ctype[CTYPES+7].wtype); }
+static int Is_wc_9(int c) { return iswctype(c, ctype[CTYPES+8].wtype); }
+static int Is_wc_10(int c) { return iswctype(c, ctype[CTYPES+9].wtype); }
+static int Is_wc_11(int c) { return iswctype(c, ctype[CTYPES+10].wtype); }
+static int Is_wc_12(int c) { return iswctype(c, ctype[CTYPES+11].wtype); }
+static int Is_wc_13(int c) { return iswctype(c, ctype[CTYPES+12].wtype); }
+static int Is_wc_14(int c) { return iswctype(c, ctype[CTYPES+13].wtype); }
+static int Is_wc_15(int c) { return iswctype(c, ctype[CTYPES+14].wtype); }
+static int Is_wc_16(int c) { return iswctype(c, ctype[CTYPES+15].wtype); }
+
+#endif
+
+/*
+ * return pointer to ctype function for :class:] in s
+ * s points to the first char after the initial [
+ * dynamic wctype classes are locale-specific
+ * dynamic entry locale is punned in Ctype_t.next
+ * the search does a lazy (one entry at a time) flush on locale mismatch
+ * if e!=0 it points to next char in s
+ * 0 returned on error
+ */
+
+regclass_t
+regclass(const char* s, char** e)
+{
+ register Ctype_t* cp;
+ register int c;
+ register size_t n;
+ register const char* t;
+ Ctype_t* lc;
+ Ctype_t* xp;
+ Ctype_t* zp;
+
+ if (!(c = *s++))
+ return 0;
+ for (t = s; *t && (*t != c || *(t + 1) != ']'); t++);
+ if (*t != c || !(n = t - s))
+ return 0;
+ for (cp = ctypes; cp; cp = cp->next)
+ if (n == cp->size && strneq(s, cp->name, n))
+ goto found;
+ xp = zp = 0;
+ lc = (Ctype_t*)setlocale(LC_CTYPE, NiL);
+ for (cp = ctype; cp < &ctype[elementsof(ctype)]; cp++)
+ {
+#if _lib_wctype
+ if (!zp)
+ {
+ if (!cp->size)
+ zp = cp;
+ else if (!xp && cp->next && cp->next != lc)
+ xp = cp;
+ }
+#endif
+ if (n == cp->size && strneq(s, cp->name, n) && (!cp->next || cp->next == lc))
+ goto found;
+ }
+#if _lib_wctype
+ if (!(cp = zp))
+ {
+ if (!(cp = xp))
+ return 0;
+ cp->size = 0;
+ if (!streq(cp->name, s))
+ {
+ free((char*)cp->name);
+ cp->name = 0;
+ }
+ }
+ if (!cp->name)
+ {
+ if (!(cp->name = (const char*)memdup(s, n + 1)))
+ return 0;
+ *((char*)cp->name + n) = 0;
+ }
+ /* mvs.390 needs the (char*) cast -- barf */
+ if (!(cp->wtype = wctype((char*)cp->name)))
+ {
+ free((char*)cp->name);
+ cp->name = 0;
+ return 0;
+ }
+ cp->size = n;
+ cp->next = lc;
+#endif
+ found:
+ if (e)
+ *e = (char*)t + 2;
+ return cp->ctype;
+}
+
+/*
+ * associate the ctype function fun with name
+ */
+
+int
+regaddclass(const char* name, regclass_t fun)
+{
+ register Ctype_t* cp;
+ register Ctype_t* np;
+ register size_t n;
+
+ n = strlen(name);
+ for (cp = ctypes; cp; cp = cp->next)
+ if (cp->size == n && strneq(name, cp->name, n))
+ {
+ cp->ctype = fun;
+ return 0;
+ }
+ if (!(np = newof(0, Ctype_t, 1, n + 1)))
+ return REG_ESPACE;
+ np->size = n;
+ np->name = strcpy((char*)(np + 1), name);
+ np->ctype = fun;
+ np->next = ctypes;
+ ctypes = np;
+ return 0;
+}
+
+/*
+ * return pointer to ctype function for token
+ */
+
+regclass_t
+classfun(int type)
+{
+ switch (type)
+ {
+ case T_ALNUM: return Isword;
+ case T_ALNUM_NOT: return Notword;
+ case T_DIGIT: return Isdigit;
+ case T_DIGIT_NOT: return Notdigit;
+ case T_SPACE: return Isspace;
+ case T_SPACE_NOT: return Notspace;
+ }
+ return 0;
+}
diff --git a/src/lib/libast/regex/regcoll.c b/src/lib/libast/regex/regcoll.c
new file mode 100644
index 0000000..64dc7a8
--- /dev/null
+++ b/src/lib/libast/regex/regcoll.c
@@ -0,0 +1,120 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * regex collation symbol support
+ */
+
+#include "reglib.h"
+
+/*
+ * return the collating symbol delimited by [c c], where c is either '=' or '.'
+ * s points to the first char after the initial [
+ * if e!=0 it is set to point to the next char in s on return
+ *
+ * the collating symbol is converted to multibyte in <buf,size>
+ * the return value is:
+ * -1 syntax error / invalid collating element
+ * >=0 size with 0-terminated mb character (*wc != 0)
+ * or collating element (*wc == 0) in buf
+ */
+
+int
+regcollate(register const char* s, char** e, char* buf, size_t size, wchar_t* wc)
+{
+ register int c;
+ register char* b;
+ register char* x;
+ const char* t;
+ int i;
+ int r;
+ int term;
+ wchar_t w;
+ char xfm[256];
+ char tmp[sizeof(xfm)];
+
+ if (size < 2 || (term = *s) != '.' && term != '=' || !*++s || *s == term && *(s + 1) == ']')
+ goto nope;
+ t = s;
+ w = mbchar(s);
+ if ((r = (s - t)) > 1)
+ {
+ if (*s++ != term || *s++ != ']')
+ goto oops;
+ goto done;
+ }
+ if (*s == term && *(s + 1) == ']')
+ {
+ s += 2;
+ goto done;
+ }
+ b = buf;
+ x = buf + size - 2;
+ s = t;
+ for (;;)
+ {
+ if (!(c = *s++))
+ goto oops;
+ if (c == term)
+ {
+ if (!(c = *s++))
+ goto oops;
+ if (c != term)
+ {
+ if (c != ']')
+ goto oops;
+ break;
+ }
+ }
+ if (b < x)
+ *b++ = c;
+ }
+ r = s - t - 2;
+ w = 0;
+ if (b >= x)
+ goto done;
+ *b = 0;
+ for (i = 0; i < r && i < sizeof(tmp) - 1; i++)
+ tmp[i] = '0';
+ tmp[i] = 0;
+ if (mbxfrm(xfm, buf, sizeof(xfm)) >= mbxfrm(xfm, tmp, sizeof(xfm)))
+ goto nope;
+ t = (const char*)buf;
+ done:
+ if (r <= size)
+ {
+ memcpy(buf, t, r);
+ if (r < size)
+ buf[r] = 0;
+ }
+ if (wc)
+ *wc = w;
+ if (e)
+ *e = (char*)s;
+ return r;
+ oops:
+ s--;
+ nope:
+ if (e)
+ *e = (char*)s;
+ return -1;
+}
diff --git a/src/lib/libast/regex/regcomp.c b/src/lib/libast/regex/regcomp.c
new file mode 100644
index 0000000..416d453
--- /dev/null
+++ b/src/lib/libast/regex/regcomp.c
@@ -0,0 +1,3544 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * posix regex compiler
+ */
+
+#include "reglib.h"
+
+#if _PACKAGE_ast
+#include "lclib.h"
+#endif
+
+#define serialize re_serialize /* hp.ia64 <unistd.h>! */
+
+#define C_ESC (-1)
+#define C_MB (-2)
+
+#if _AST_REGEX_DEBUG
+
+#define DEBUG_TEST(f,y,n) ((debug&(debug_flag=f))?(y):(n))
+#define DEBUG_CODE(f,y,n) do if(debug&(f)){y}else{n} while(0)
+#define DEBUG_INIT() do { char* t; if (!debug) { debug = 0x80000000; if (t = getenv("_AST_regex_comp_debug")) debug |= strtoul(t, NiL, 0); } } while (0)
+
+static unsigned long debug;
+static unsigned long debug_flag;
+
+#else
+
+#define DEBUG_INIT()
+#define DEBUG_TEST(f,y,n) (n)
+#define DEBUG_CODE(f,y,n) do {n} while(0)
+
+#endif
+
+#if _PACKAGE_ast
+
+typedef struct Cchr_s
+{
+ Dtlink_t lnk;
+ unsigned char nam[2];
+ Ckey_t key;
+} Cchr_t;
+
+#endif
+
+#define eat(p) do{if ((p)->token.push)(p)->token.push=0;else (p)->cursor+=(p)->token.len;}while (0)
+
+/*
+ * determine whether greedy matching will work, i.e. produce
+ * the best match first. such expressions are "easy", and
+ * need no backtracking once a complete match is found.
+ * if an expression has backreferences or alts it's hard
+ * else if it has only one closure it's easy
+ * else if all closures are simple (i.e. one-character) it's easy
+ * else it's hard.
+ */
+
+typedef struct Stats_s
+{
+ unsigned long l; /* min length to left of x */
+ unsigned long k; /* min length to left of y */
+ unsigned long m; /* min length */
+ unsigned long n; /* max length */
+ unsigned short a; /* number of alternations */
+ unsigned short b; /* number of backrefs */
+ unsigned short c; /* number of closures */
+ unsigned short e; /* $ */
+ unsigned short i; /* number of negations */
+ unsigned short p; /* number of named subexpressions */
+ unsigned short s; /* number of simple closures */
+ unsigned short t; /* number of tries */
+ unsigned short u; /* number of unnamed subexpressions */
+ Rex_t* x; /* max length REX_STRING */
+ Rex_t* y; /* max length REX_TRIE */
+} Stats_t;
+
+typedef struct Token_s
+{
+ unsigned long min;
+ unsigned long max;
+ short lex;
+ short len;
+ short esc;
+ short att;
+ short push;
+} Token_t;
+
+typedef struct Cenv_s
+{
+ int delimiter; /* pattern delimiter */
+ int error; /* last error */
+ int explicit; /* explicit match on this char */
+ int mappeddot; /* inverse mapped '.' */
+ int mappednewline; /* inverse mapped '\n' */
+ int mappedslash; /* inverse mapped '/' */
+ regflags_t flags; /* flags arg to regcomp */
+ int type; /* BRE,ERE,ARE,SRE,KRE */
+ unsigned char* cursor; /* curent point in re */
+ unsigned char* pattern; /* the original pattern */
+ unsigned char* literal; /* literal restart pattern */
+ int parno; /* number of last open paren */
+ int parnest; /* paren nest count */
+ int posixkludge; /* to make * nonspecial */
+ int regexp; /* <regexp.h> compatibility */
+ Token_t token; /* token lookahead */
+ Stats_t stats; /* RE statistics */
+ int terminator; /* pattern terminator */
+ Rex_t* paren[2*(BACK_REF_MAX+2)];
+ /* paren[i]!=0 if \i defined */
+ regex_t* regex; /* user handle */
+ regdisc_t* disc; /* user discipline */
+ unsigned char* map; /* external to native ccode map */
+ unsigned char* MAP; /* fold and/or map */
+} Cenv_t;
+
+/*
+ * allocate a new Rex_t node
+ */
+
+#if _BLD_DEBUG
+#define node(a,b,c,d,e) node(a,b,c,d,e, const char* file, unsigned int line)
+#endif
+
+static Rex_t*
+node(Cenv_t* env, int type, int lo, int hi, size_t extra)
+{
+ register Rex_t* e;
+
+ DEBUG_TEST(0x0800,(sfprintf(sfstdout, "%s:%d node(%d,%d,%d,%u)\n", file, line, type, lo, hi, sizeof(Rex_t) + extra)),(0));
+ if (e = (Rex_t*)alloc(env->disc, 0, sizeof(Rex_t) + extra))
+ {
+ memset(e, 0, sizeof(Rex_t) + extra);
+ e->type = type;
+ e->marked = 0;
+ e->lo = lo;
+ e->hi = hi;
+ e->flags = env->flags;
+ e->map = (e->flags & REG_ICASE) ? env->MAP : env->map;
+ e->explicit = env->explicit;
+ if (extra)
+ e->re.data = (char*)e + sizeof(Rex_t);
+ }
+ return e;
+}
+
+#if _BLD_DEBUG
+#undef node
+#define node(a,b,c,d,e) node(a,b,c,d,e,__FILE__,__LINE__)
+#endif
+
+/*
+ * free a Trie_node_t node
+ */
+
+static void
+triedrop(regdisc_t* disc, Trie_node_t* e)
+{
+ if (e)
+ {
+ triedrop(disc, e->son);
+ triedrop(disc, e->sib);
+ alloc(disc, e, 0);
+ }
+}
+
+/*
+ * free a Rex_t node
+ */
+
+void
+drop(regdisc_t* disc, Rex_t* e)
+{
+ int i;
+ Rex_t* x;
+
+ if (e && !(disc->re_flags & REG_NOFREE))
+ do
+ {
+ switch (e->type)
+ {
+ case REX_ALT:
+ case REX_CONJ:
+ drop(disc, e->re.group.expr.binary.left);
+ drop(disc, e->re.group.expr.binary.right);
+ break;
+ case REX_GROUP:
+ case REX_GROUP_AHEAD:
+ case REX_GROUP_AHEAD_NOT:
+ case REX_GROUP_BEHIND:
+ case REX_GROUP_BEHIND_NOT:
+ case REX_GROUP_CUT:
+ case REX_NEG:
+ case REX_REP:
+ drop(disc, e->re.group.expr.rex);
+ break;
+ case REX_TRIE:
+ for (i = 0; i <= UCHAR_MAX; i++)
+ triedrop(disc, e->re.trie.root[i]);
+ break;
+ }
+ x = e->next;
+ alloc(disc, e, 0);
+ } while (e = x);
+}
+
+/*
+ * mark e and descendants minimal
+ */
+
+static void
+mark(register Rex_t* e, int set)
+{
+ if (e && !e->marked)
+ do
+ {
+ e->marked = 1;
+ if (set)
+ e->flags |= REG_MINIMAL;
+ else
+ e->flags &= ~REG_MINIMAL;
+ switch (e->type)
+ {
+ case REX_ALT:
+ case REX_CONJ:
+ case REX_GROUP_COND:
+ if (e->re.group.expr.binary.left)
+ mark(e->re.group.expr.binary.left, set);
+ if (e->re.group.expr.binary.right)
+ mark(e->re.group.expr.binary.right, set);
+ break;
+ case REX_GROUP:
+ case REX_GROUP_AHEAD:
+ case REX_GROUP_AHEAD_NOT:
+ case REX_GROUP_BEHIND:
+ case REX_GROUP_BEHIND_NOT:
+ case REX_GROUP_CUT:
+ case REX_NEG:
+ case REX_REP:
+ case REX_TRIE:
+ mark(e->re.group.expr.rex, set);
+ break;
+ }
+ } while (e = e->next);
+}
+
+/*
+ * assign subexpression numbers by a preorder tree walk
+ */
+
+static int
+serialize(Cenv_t* env, Rex_t* e, int n)
+{
+ do
+ {
+ e->serial = n++;
+ switch (e->type)
+ {
+ case REX_ALT:
+ case REX_GROUP_COND:
+ if (e->re.group.expr.binary.left)
+ n = serialize(env, e->re.group.expr.binary.left, n);
+ e->re.group.expr.binary.serial = n++;
+ if (e->re.group.expr.binary.right)
+ n = serialize(env, e->re.group.expr.binary.right, n);
+ break;
+ case REX_CONJ:
+ n = serialize(env, e->re.group.expr.binary.left, n);
+ n = serialize(env, e->re.group.expr.binary.right, n);
+ break;
+ case REX_GROUP:
+ case REX_GROUP_AHEAD:
+ case REX_GROUP_AHEAD_NOT:
+ case REX_GROUP_BEHIND:
+ case REX_GROUP_BEHIND_NOT:
+ case REX_GROUP_CUT:
+ case REX_NEG:
+ case REX_REP:
+ n = serialize(env, e->re.group.expr.rex, n);
+ break;
+ }
+ } while (e = e->next);
+ return n;
+}
+
+/*
+ * catenate e and f into a sequence, collapsing them if possible
+ */
+
+static Rex_t*
+cat(Cenv_t* env, Rex_t* e, Rex_t* f)
+{
+ Rex_t* g;
+
+ if (!f)
+ {
+ drop(env->disc, e);
+ return 0;
+ }
+ if (e->type == REX_NULL)
+ {
+ drop(env->disc, e);
+ return f;
+ }
+ if (f->type == REX_NULL)
+ {
+ g = f->next;
+ f->next = 0;
+ drop(env->disc, f);
+ f = g;
+ }
+ else if (e->type == REX_DOT && f->type == REX_DOT)
+ {
+ unsigned int m = e->lo + f->lo;
+ unsigned int n = e->hi + f->hi;
+
+ if (m <= RE_DUP_MAX)
+ {
+ if (e->hi > RE_DUP_MAX || f->hi > RE_DUP_MAX)
+ {
+ n = RE_DUP_INF;
+ goto combine;
+ }
+ else if (n <= RE_DUP_MAX)
+ {
+ combine:
+ e->lo = m;
+ e->hi = n;
+ g = f->next;
+ f->next = 0;
+ drop(env->disc, f);
+ f = g;
+ }
+ }
+ }
+ e->next = f;
+ return e;
+}
+
+/*
+ * collect re statistics
+ */
+
+static int
+stats(register Cenv_t* env, register Rex_t* e)
+{
+ register unsigned long n;
+ register unsigned long m;
+ unsigned long cm;
+ unsigned long nm;
+ unsigned long cn;
+ unsigned long nn;
+ unsigned long l;
+ unsigned long k;
+ unsigned long t;
+ Rex_t* q;
+ Rex_t* x;
+ Rex_t* y;
+ unsigned char c;
+ unsigned char b;
+
+ do
+ {
+ switch (e->type)
+ {
+ case REX_ALT:
+ x = env->stats.x;
+ l = env->stats.l;
+ y = env->stats.y;
+ k = env->stats.k;
+ t = env->stats.t;
+ if (++env->stats.a <= 0)
+ return 1;
+ cm = env->stats.m;
+ env->stats.m = 0;
+ cn = env->stats.n;
+ env->stats.n = 0;
+ if (stats(env, e->re.group.expr.binary.left))
+ return 1;
+ m = env->stats.m;
+ env->stats.m = 0;
+ n = env->stats.n;
+ env->stats.n = 0;
+ if (e->re.group.expr.binary.right && stats(env, e->re.group.expr.binary.right))
+ return 1;
+ if (env->stats.m > m)
+ env->stats.m = m;
+ else
+ m = env->stats.m;
+ if ((env->stats.m += cm) < m)
+ return 1;
+ if (env->stats.n < n)
+ env->stats.n = n;
+ else
+ n = env->stats.n;
+ if ((env->stats.n += cn) < n)
+ return 1;
+ env->stats.x = x;
+ env->stats.l = l;
+ env->stats.y = y;
+ env->stats.k = k;
+ env->stats.t = t;
+ break;
+ case REX_BACK:
+ if (++env->stats.b <= 0)
+ return 1;
+ break;
+ case REX_CLASS:
+ case REX_COLL_CLASS:
+ case REX_DOT:
+ case REX_ONECHAR:
+ n = env->stats.m;
+ if ((env->stats.m += e->lo) < n)
+ return 1;
+ if (e->hi != RE_DUP_INF)
+ {
+ n = env->stats.n;
+ if ((env->stats.n += e->hi) < n)
+ return 1;
+ }
+ if (e->lo != e->hi)
+ {
+ if (++env->stats.c <= 0)
+ return 1;
+ if (++env->stats.s <= 0)
+ return 1;
+ }
+ break;
+ case REX_CONJ:
+ cm = env->stats.m;
+ env->stats.m = 0;
+ cn = env->stats.n;
+ env->stats.n = 0;
+ if (stats(env, e->re.group.expr.binary.left))
+ return 1;
+ nm = env->stats.m;
+ env->stats.m = 0;
+ nn = env->stats.n;
+ env->stats.n = 0;
+ if (stats(env, e->re.group.expr.binary.right))
+ return 1;
+ if (env->stats.m < nm)
+ env->stats.m = nm;
+ else
+ nm = env->stats.m;
+ if ((env->stats.m += cm) < nm)
+ return 1;
+ if (env->stats.n < nn)
+ env->stats.n = nn;
+ else
+ nn = env->stats.n;
+ if ((env->stats.n += cn) < nn)
+ return 1;
+ break;
+ case REX_END:
+ env->stats.e = 1;
+ break;
+ case REX_GROUP:
+ if (e->re.group.number && ++env->stats.p <= 0 || !e->re.group.number && ++env->stats.u <= 0)
+ return 1;
+ if (stats(env, e->re.group.expr.rex))
+ return 1;
+ break;
+ case REX_GROUP_AHEAD:
+ case REX_GROUP_AHEAD_NOT:
+ case REX_GROUP_BEHIND:
+ case REX_GROUP_BEHIND_NOT:
+ m = env->stats.m;
+ n = env->stats.n;
+ x = env->stats.x;
+ y = env->stats.y;
+ if (stats(env, e->re.group.expr.rex))
+ return 1;
+ env->stats.m = m;
+ env->stats.n = n;
+ env->stats.x = x;
+ env->stats.y = y;
+ switch (e->type)
+ {
+ case REX_GROUP_AHEAD:
+ case REX_GROUP_BEHIND:
+ if (++env->stats.u <= 0)
+ return 1;
+ break;
+ }
+ break;
+ case REX_GROUP_COND:
+ if (++env->stats.u <= 0)
+ return 1;
+ m = env->stats.m;
+ n = env->stats.n;
+ x = env->stats.x;
+ y = env->stats.y;
+ if (e->re.group.size > 0 && ++env->stats.b <= 0)
+ return 1;
+ if (e->re.group.expr.binary.left && stats(env, e->re.group.expr.binary.left))
+ return 1;
+ if (q = e->re.group.expr.binary.right)
+ {
+ if (q->re.group.expr.binary.left && stats(env, q->re.group.expr.binary.left))
+ return 1;
+ if (q->re.group.expr.binary.right && stats(env, q->re.group.expr.binary.right))
+ return 1;
+ }
+ env->stats.m = m;
+ env->stats.n = n;
+ env->stats.x = x;
+ env->stats.y = y;
+ break;
+ case REX_GROUP_CUT:
+ if (++env->stats.u <= 0)
+ return 1;
+ m = env->stats.m;
+ n = env->stats.n;
+ x = env->stats.x;
+ y = env->stats.y;
+ if (stats(env, e->re.group.expr.rex))
+ return 1;
+ env->stats.m = m;
+ env->stats.n = n;
+ env->stats.x = x;
+ env->stats.y = y;
+ break;
+ case REX_NEG:
+ env->stats.i++;
+ x = env->stats.x;
+ l = env->stats.l;
+ y = env->stats.y;
+ k = env->stats.k;
+ t = env->stats.t;
+ cm = env->stats.m;
+ env->stats.m = 0;
+ if (stats(env, e->re.group.expr.rex))
+ return 1;
+ env->stats.m = !env->stats.m;
+ if ((env->stats.m += cm) < cm)
+ return 1;
+ env->stats.x = x;
+ env->stats.l = l;
+ env->stats.y = y;
+ env->stats.k = k;
+ env->stats.t = t;
+ break;
+ case REX_REP:
+ x = env->stats.x;
+ l = env->stats.l;
+ y = env->stats.y;
+ k = env->stats.k;
+ t = env->stats.t;
+ if (++env->stats.c <= 0)
+ return 1;
+ b = env->stats.b;
+ c = env->stats.c;
+ cm = env->stats.m;
+ env->stats.m = 0;
+ if (stats(env, e->re.group.expr.rex))
+ return 1;
+ if (env->stats.m == 1 && b == env->stats.b && c == env->stats.c && ++env->stats.s <= 0)
+ return 1;
+ if (e->lo < 1)
+ {
+ env->stats.x = x;
+ env->stats.l = l;
+ env->stats.y = y;
+ env->stats.k = k;
+ env->stats.t = t;
+ env->stats.m = cm;
+ }
+ else
+ {
+ m = env->stats.m;
+ if ((env->stats.m *= e->lo) > 0 && env->stats.m < m)
+ return 1;
+ m = env->stats.m;
+ if ((env->stats.m += cm) < m)
+ return 1;
+ if (env->stats.x != x)
+ env->stats.l = cm;
+ if (env->stats.y != y)
+ env->stats.k = cm;
+ }
+ break;
+ case REX_STRING:
+ if (!e->map)
+ {
+ cm = env->stats.m;
+ if ((env->stats.m += e->re.string.size) < cm)
+ return 1;
+ cn = env->stats.n;
+ if ((env->stats.n += e->re.string.size) < cn)
+ return 1;
+ if (!env->stats.x || env->stats.x->re.string.size < e->re.string.size)
+ {
+ env->stats.x = e;
+ env->stats.l = cm;
+ }
+ }
+ break;
+ case REX_TRIE:
+ if (++env->stats.s <= 0)
+ return 1;
+ cm = env->stats.m;
+ if ((env->stats.m += e->re.trie.min) < cm)
+ return 1;
+ cn = env->stats.n;
+ if ((env->stats.n += e->re.trie.max) < cn)
+ return 1;
+ env->stats.t++;
+ if (!env->stats.y || env->stats.y->re.trie.min < e->re.trie.min)
+ {
+ env->stats.y = e;
+ env->stats.k = cm;
+ }
+ break;
+ }
+ } while (e = e->next);
+ return 0;
+}
+
+static int token(Cenv_t*);
+
+static int
+magic(register Cenv_t* env, register int c, int escaped)
+{
+ register char* sp;
+ register int n;
+ int o = c;
+ int e = env->error;
+ int l = env->token.len;
+ short* mp;
+ char* ep;
+
+ if (mp = state.magic[c])
+ {
+ c = mp[env->type+escaped];
+ if (c >= T_META)
+ {
+ sp = (char*)env->cursor + env->token.len;
+ switch (c)
+ {
+ case T_LEFT:
+ n = 0;
+ ep = sp;
+ while (*sp >= '0' && *sp <= '9')
+ {
+ if (n > (INT_MAX / 10))
+ {
+ env->error = REG_BADBR;
+ goto bad;
+ }
+ n = n * 10 + *sp++ - '0';
+ }
+ if (sp == ep)
+ {
+ if (env->type < SRE || *sp != ',')
+ {
+ env->error = *sp ? REG_BADBR : REG_EBRACE;
+ goto bad;
+ }
+ }
+ else if (n > RE_DUP_MAX)
+ {
+ env->error = REG_BADBR;
+ goto bad;
+ }
+ env->token.min = n;
+ if (*sp == ',')
+ {
+ n = 0;
+ ep = ++sp;
+ while (*sp >= '0' && *sp <= '9')
+ {
+ if (n > (INT_MAX / 10))
+ {
+ env->error = REG_BADBR;
+ goto bad;
+ }
+ n = n * 10 + *sp++ - '0';
+ }
+ if (sp == ep)
+ n = RE_DUP_INF;
+ else if (n < env->token.min)
+ {
+ env->error = REG_BADBR;
+ goto bad;
+ }
+ }
+ env->token.max = n;
+ switch (*sp)
+ {
+ case 0:
+ env->error = REG_EBRACE;
+ goto bad;
+ case '\\':
+ if (!escaped)
+ {
+ env->error = REG_BADBR;
+ goto bad;
+ }
+ sp++;
+ break;
+ default:
+ if (escaped)
+ {
+ env->error = REG_BADBR;
+ goto bad;
+ }
+ break;
+ }
+ switch (*sp++)
+ {
+ case 0:
+ env->error = REG_EBRACE;
+ goto bad;
+ case '}':
+ break;
+ default:
+ env->error = REG_BADBR;
+ goto bad;
+ }
+ env->token.len = sp - (char*)env->cursor;
+ break;
+ case T_RIGHT:
+ env->error = REG_EBRACE;
+ goto bad;
+ case T_OPEN:
+ if (env->type < SRE && *sp == '?')
+ {
+ env->token.len++;
+ env->token.lex = 0;
+ goto group;
+ }
+ break;
+ case T_ESCAPE:
+ c = chresc(sp - 2, &ep);
+ if (ep < sp)
+ goto bad;
+ env->token.len += ep - sp;
+ if (c >= T_META)
+ {
+ env->token.lex = c;
+ c = C_ESC;
+ }
+ return c;
+ case T_BACK+0:
+ case T_BACK+1:
+ case T_BACK+2:
+ case T_BACK+3:
+ case T_BACK+4:
+ case T_BACK+5:
+ case T_BACK+6:
+ case T_BACK+7:
+ n = chresc(sp - 2, &ep);
+ if (ep > sp + 1)
+ {
+ env->token.len += ep - sp;
+ return n;
+ }
+ /*FALLTHROUGH*/
+ case T_BACK+8:
+ case T_BACK+9:
+ if (env->type == SRE || c == T_BACK && !(env->flags & REG_LENIENT))
+ {
+ env->error = REG_BADESC;
+ goto bad;
+ }
+ if ((env->flags & REG_MULTIREF) && isdigit(*sp))
+ {
+ c = (c - T_BACK) * 10 + (*sp - '0');
+ if (c > 0 && c <= env->parno && env->paren[c])
+ c += T_BACK;
+ else
+ c = chresc(sp - 2, &ep);
+ env->token.len++;
+ }
+ if (c == T_BACK)
+ c = 0;
+ break;
+ case T_BAD:
+ if (escaped == 1 && (env->flags & REG_LENIENT) && (c = mp[env->type+escaped+2]) >= T_META)
+ return c;
+ goto bad;
+ }
+ if (env->type >= SRE)
+ {
+ if (c == T_DOT)
+ c = '.';
+ else if (c < T_OPEN)
+ {
+ if (env->type == KRE && *(env->cursor + env->token.len) == '-' && *(env->cursor + env->token.len + 1) == '(')
+ {
+ env->token.len++;
+ env->token.att = 1;
+ }
+ if (env->type == KRE && *(env->cursor + env->token.len) == '(')
+ {
+ env->token.len++;
+ switch (c)
+ {
+ case T_AT:
+ break;
+ case T_PERCENT:
+ env->token.lex = c;
+ goto group;
+ case T_TILDE:
+ env->token.lex = 0;
+ goto group;
+ default:
+ env->token.lex = c;
+ break;
+ }
+ c = T_OPEN;
+ }
+ else if (c == T_STAR)
+ c = T_DOTSTAR;
+ else if (c == T_QUES)
+ c = T_DOT;
+ else
+ {
+ c = o;
+ env->token.len = l;
+ }
+ }
+ else if (c > T_BACK)
+ {
+ c = (c - T_BACK) * 2 - 1;
+ c = (c > env->parno || !env->paren[c]) ? o : T_BACK + c;
+ }
+ else if (env->type == KRE && !env->parnest && (env->flags & REG_SHELL_GROUP))
+ {
+ if (c == T_AND)
+ c = '&';
+ else if (c == T_BAR)
+ c = '|';
+ else if (c == T_OPEN)
+ c = '(';
+ }
+ }
+ }
+ }
+ else if (escaped == 2)
+ {
+ if (env->type >= SRE && !(env->flags & REG_SHELL_ESCAPED) || (env->flags & REG_ESCAPE) && (c == '[' || c == '-' || c == ']' || env->delimiter && c == env->delimiter))
+ /*ok*/;
+ else
+ {
+ env->error = REG_BADESC;
+ goto bad;
+ }
+ }
+ else if (escaped && !(env->flags & REG_LENIENT) && c != ']')
+ {
+ env->error = REG_BADESC;
+ goto bad;
+ }
+ return c;
+ group:
+ sp = (char*)env->cursor + env->token.len;
+ switch (*sp++)
+ {
+ case ')':
+ break;
+ case '#':
+ for (;;)
+ {
+ switch (*sp++)
+ {
+ case 0:
+ env->error = REG_EPAREN;
+ return T_BAD;
+ case ')':
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+ break;
+ default:
+ return T_GROUP;
+ }
+ env->cursor = (unsigned char*)sp;
+ return token(env);
+ bad:
+ if (escaped == 2)
+ env->error = e;
+ else if (env->flags & REG_LENIENT)
+ return o;
+ else if (escaped == 1 && !env->error)
+ {
+ if (mp || o == ']')
+ return o;
+ env->error = REG_BADESC;
+ }
+ return T_BAD;
+}
+
+static int
+token(register Cenv_t* env)
+{
+ int c;
+ int posixkludge;
+
+ if (env->token.push)
+ return env->token.lex;
+ env->token.att = env->token.esc = 0;
+ if ((env->token.len = MBSIZE(env->cursor)) > 1)
+ return env->token.lex = C_MB;
+ env->token.lex = 0;
+ for (;;)
+ {
+ c = *env->cursor;
+ if (c == 0 || c == env->delimiter || c == env->terminator)
+ return T_END;
+ if (!(env->flags & REG_COMMENT))
+ break;
+ if (c == '#')
+ {
+ do
+ {
+ c = *++env->cursor;
+ if (c == 0 || c == env->delimiter)
+ return T_END;
+ } while (c != '\n');
+ }
+ else if (!isspace(c))
+ break;
+ env->cursor++;
+ }
+ if (c == '\n' && (env->flags & REG_MULTIPLE) && !env->delimiter)
+ {
+ if (env->parnest)
+ {
+ env->error = REG_EPAREN;
+ return T_BAD;
+ }
+ env->parno = 0;
+ env->pattern = env->cursor + 1;
+ return T_BAR;
+ }
+ if (env->flags & REG_LITERAL)
+ return c;
+ if (posixkludge = env->posixkludge)
+ {
+ env->posixkludge = 0;
+ if (c == '*')
+ return c;
+ }
+ if (c == '\\')
+ {
+ if (env->flags & REG_SHELL_ESCAPED)
+ return c;
+ if (!(c = *(env->cursor + 1)) || c == env->terminator)
+ {
+ if (env->flags & REG_LENIENT)
+ {
+ if (c)
+ {
+ env->token.esc = env->token.len;
+ env->token.len += MBSIZE(env->cursor + 1);
+ return c;
+ }
+ return '\\';
+ }
+ env->error = REG_EESCAPE;
+ return T_BAD;
+ }
+ env->token.esc = env->token.len;
+ env->token.len += MBSIZE(env->cursor + 1);
+ if (env->delimiter && c == 'n')
+ return '\n';
+ else if (c == env->delimiter)
+ return magic(env, c, 0);
+ else if (c == '(' && env->type == BRE)
+ env->posixkludge = 1;
+ else if (c == ')' && env->type == BRE && env->parnest <= 0)
+ {
+ env->error = REG_EPAREN;
+ return T_BAD;
+ }
+ else if (isspace(c) && (env->flags & REG_COMMENT))
+ return c;
+ return magic(env, c, 1);
+ }
+ else if (c == '$')
+ {
+ if (env->type == BRE && (*(env->cursor + 1) == 0 || *(env->cursor + 1) == env->delimiter || *(env->cursor + 1) == env->terminator || *(env->cursor + 1) == '\\' && *(env->cursor + 2) == ')') || (env->flags & REG_MULTIPLE) && *(env->cursor + 1) == '\n')
+ return T_DOLL;
+ }
+ else if (c == '^')
+ {
+ if (env->type == BRE && (env->cursor == env->pattern || posixkludge == 1))
+ {
+ env->posixkludge = 2;
+ return T_CFLX;
+ }
+ }
+ else if (c == ')')
+ {
+ if (env->type != BRE && env->parnest <= 0)
+ return c;
+ }
+ else if (c == '/' && env->explicit == env->mappedslash)
+ {
+ while (*(env->cursor + env->token.len) == c)
+ env->token.len++;
+ return T_SLASHPLUS;
+ }
+ return magic(env, c, 0);
+}
+
+static Celt_t*
+col(Celt_t* ce, int ic, unsigned char* bp, int bw, int bc, unsigned char* ep, int ew, int ec)
+{
+ register char* s;
+ register unsigned char* k;
+ register unsigned char* e;
+ register int c;
+ register int cc;
+ int bt;
+ int et;
+ Ckey_t key;
+
+ cc = 0;
+ for (;;)
+ {
+ k = key;
+ if (bw == 1)
+ {
+ c = bc;
+ if (ic)
+ {
+ if (isupper(c))
+ {
+ c = tolower(c);
+ cc = -1;
+ }
+ else if (islower(c))
+ {
+ c = toupper(c);
+ cc = -1;
+ }
+ }
+ *k++ = c;
+ }
+ else if (bw < COLL_KEY_MAX)
+ {
+ s = (char*)bp;
+ if (ic)
+ {
+ c = mbchar(s);
+ if (iswupper(c))
+ {
+ c = towlower(c);
+ cc = 1;
+ }
+ else if (iswlower(c))
+ {
+ c = towupper(c);
+ cc = 1;
+ }
+ }
+ if (cc > 0)
+ {
+ cc = -1;
+ k += mbconv((char*)k, c);
+ }
+ else
+ for (e = k + bw; k < e; *k++ = *s++);
+ }
+ *k = 0;
+ mbxfrm(ce->beg, key, COLL_KEY_MAX);
+ if (ep)
+ {
+ k = key;
+ c = mbchar(k);
+ if (iswupper(c))
+ bt = COLL_range_uc;
+ else if (iswlower(c))
+ bt = COLL_range_lc;
+ else
+ bt = COLL_range;
+ k = key;
+ if (ew == 1)
+ {
+ c = ec;
+ if (ic)
+ {
+ if (isupper(c))
+ {
+ c = tolower(c);
+ cc = -1;
+ }
+ else if (islower(c))
+ {
+ c = toupper(c);
+ cc = -1;
+ }
+ }
+ *k++ = c;
+ }
+ else if (ew < COLL_KEY_MAX)
+ {
+ s = (char*)ep;
+ if (ic)
+ {
+ c = mbchar(s);
+ if (iswupper(c))
+ {
+ c = towlower(c);
+ cc = 1;
+ }
+ else if (iswlower(c))
+ {
+ c = towupper(c);
+ cc = 1;
+ }
+ }
+ if (cc > 0)
+ {
+ cc = -1;
+ k += mbconv((char*)k, c);
+ }
+ else
+ for (e = k + ew; k < e; *k++ = *s++);
+ }
+ *k = 0;
+ mbxfrm(ce->end, key, COLL_KEY_MAX);
+ k = key;
+ c = mbchar(k);
+ if (iswupper(c))
+ et = COLL_range_uc;
+ else if (iswlower(c))
+ et = COLL_range_lc;
+ else
+ et = COLL_range;
+ ce->typ = bt == et ? bt : COLL_range;
+ }
+ else
+ ce->typ = COLL_char;
+ ce++;
+ if (!ic || !cc)
+ break;
+ ic = 0;
+ }
+ return ce;
+}
+
+static Rex_t*
+bra(Cenv_t* env)
+{
+ Rex_t* e;
+ int c;
+ int i;
+ int w;
+ int neg;
+ int last;
+ int inrange;
+ int complicated;
+ int collate;
+ int elements;
+ unsigned char* first;
+ unsigned char* start;
+ unsigned char* begin;
+ unsigned char* s;
+ regclass_t f;
+ unsigned char buf[4 * (COLL_KEY_MAX + 1)];
+#if _PACKAGE_ast
+ int ic;
+ char mbc[COLL_KEY_MAX + 1];
+#endif
+
+ if (!(e = node(env, REX_CLASS, 1, 1, sizeof(Set_t))))
+ return 0;
+ collate = complicated = elements = 0;
+ if (*env->cursor == '^' || env->type >= SRE && *env->cursor == '!')
+ {
+ env->cursor++;
+ neg = 1;
+ }
+ else
+ neg = 0;
+ first = env->cursor;
+ start = first + MBSIZE(first);
+ if (*env->cursor == 0 || *(env->cursor + 1) == 0 || *env->cursor == env->terminator || *(env->cursor + 1) == env->terminator || (env->flags & REG_ESCAPE) && (*env->cursor == env->delimiter || *env->cursor != '\\' && *(env->cursor + 1) == env->delimiter))
+ goto error;
+ begin = env->cursor + MBSIZE(env->cursor);
+
+ /*
+ * inrange: 0=no, 1=possibly, 2=definitely
+ */
+
+ inrange = 0;
+ for (;;)
+ {
+ if (!(c = *env->cursor) || c == env->terminator || c == env->delimiter && (env->flags & REG_ESCAPE))
+ goto error;
+ env->cursor += (w = MBSIZE(env->cursor));
+ if (c == '\\' && ((env->flags & REG_CLASS_ESCAPE) || *env->cursor == env->delimiter && (env->flags & REG_ESCAPE)))
+ {
+ if (*env->cursor)
+ {
+ if (*env->cursor == 'n')
+ {
+ env->cursor++;
+ c = '\n';
+ }
+ else if (env->type < SRE || !(env->flags & REG_SHELL_ESCAPED))
+ {
+ env->token.len = 1;
+ w = magic(env, *env->cursor, 2);
+ if (env->token.len > 1 || w != T_BAD)
+ {
+ if (env->token.len == 1 && (f = classfun(w)))
+ {
+ if (inrange > 1)
+ {
+ if (env->type < SRE && !(env->flags & REG_LENIENT))
+ goto erange;
+ inrange = 0;
+ }
+ env->cursor++;
+ for (c = 0; c <= UCHAR_MAX; c++)
+ if ((*f)(c))
+ setadd(e->re.charclass, c);
+ complicated++;
+ elements++;
+ continue;
+ }
+ if (env->token.len > 1 || w >= 0 && w < T_META)
+ {
+ c = w;
+ if (c > UCHAR_MAX)
+ {
+ if (env->type < SRE && !(env->flags & REG_LENIENT) && !mbwide())
+ goto erange;
+ c = UCHAR_MAX;
+ }
+ env->cursor += env->token.len;
+ }
+ }
+ }
+ }
+ }
+ else if (c == ']')
+ {
+ if (env->cursor == begin)
+ {
+ last = c;
+ inrange = 1;
+ continue;
+ }
+ if (inrange != 0)
+ {
+ setadd(e->re.charclass, last);
+ elements++;
+ if (inrange == 2)
+ {
+ setadd(e->re.charclass, '-');
+ elements++;
+ }
+ }
+ break;
+ }
+ else if (c == '-')
+ {
+ if (!inrange && env->cursor != begin && *env->cursor != ']')
+ {
+ if (env->type < SRE && !(env->flags & REG_LENIENT))
+ goto erange;
+ continue;
+ }
+ else if (inrange == 1)
+ {
+ inrange = 2;
+ complicated++;
+ continue;
+ }
+ }
+ else if (c == '[')
+ {
+ switch (*env->cursor)
+ {
+ case 0:
+ goto error;
+ case ':':
+ if (env->regexp)
+ goto normal;
+ if (inrange == 1)
+ {
+ setadd(e->re.charclass, last);
+ elements++;
+ }
+ if (!(f = regclass((char*)env->cursor, (char**)&env->cursor)))
+ {
+ if (env->cursor == start && (c = *(env->cursor + 1)))
+ {
+ s = start = env->cursor + 1;
+ while (*++s && *s != ':');
+ if (*s == ':' && *(s + 1) == ']' && *(s + 2) == ']')
+ {
+ if ((i = (s - start)) == 1)
+ {
+ switch (c)
+ {
+ case '<':
+ i = REX_WBEG;
+ break;
+ case '>':
+ i = REX_WEND;
+ break;
+ default:
+ i = 0;
+ break;
+ }
+ if (i)
+ {
+ env->cursor = s + 3;
+ drop(env->disc, e);
+ return node(env, i, 0, 0, 0);
+ }
+ }
+ }
+ }
+ env->error = REG_ECTYPE;
+ goto error;
+ }
+ for (c = 0; c <= UCHAR_MAX; c++)
+ if ((*f)(c))
+ setadd(e->re.charclass, c);
+ inrange = 0;
+ complicated++;
+ elements++;
+ continue;
+ case '=':
+ if (env->regexp)
+ goto normal;
+ if (inrange == 2)
+ goto erange;
+ if (inrange == 1)
+ {
+ setadd(e->re.charclass, last);
+ elements++;
+ }
+ if ((c = regcollate((char*)env->cursor, (char**)&env->cursor, (char*)buf, sizeof(buf), NiL)) < 0)
+ goto ecollate;
+ if (c > 1)
+ collate++;
+ else
+ setadd(e->re.charclass, buf[0]);
+ c = buf[0];
+ inrange = 0;
+ complicated++;
+ elements++;
+ continue;
+ case '.':
+ if (env->regexp)
+ goto normal;
+ if ((c = regcollate((char*)env->cursor, (char**)&env->cursor, (char*)buf, sizeof(buf), NiL)) < 0)
+ goto ecollate;
+ if (c > 1)
+ collate++;
+ c = buf[0];
+ complicated++;
+ break;
+ default:
+ normal:
+ if (*env->cursor == env->terminator || *env->cursor == env->delimiter && (env->flags & REG_ESCAPE))
+ goto error;
+ break;
+ }
+ }
+ else if (w > 1)
+ complicated++;
+ if (inrange == 2)
+ {
+ if (last <= c)
+ {
+ for (i = last; i <= c; i++)
+ setadd(e->re.charclass, i);
+ inrange = env->type >= SRE || (env->flags & REG_LENIENT);
+ elements += 2;
+ }
+ else if (env->type >= SRE)
+ {
+ setadd(e->re.charclass, last);
+ setadd(e->re.charclass, c);
+ elements += 2;
+ inrange = 1;
+ }
+ else if (!(env->flags & REG_LENIENT))
+ goto erange;
+ else
+ inrange = 0;
+ }
+ else if (inrange == 1)
+ {
+ setadd(e->re.charclass, last);
+ elements++;
+ }
+ else
+ inrange = 1;
+ last = c;
+ }
+#if _PACKAGE_ast
+ if (complicated && mbcoll())
+ {
+ Dt_t* dt;
+ Cchr_t* cc;
+ Cchr_t* tc;
+ Cchr_t* xc;
+ Celt_t* ce;
+ Cchr_t key;
+ int rw;
+ int rc;
+ wchar_t wc;
+ unsigned char* rp;
+ unsigned char* pp;
+ char* wp;
+ char cb[2][COLL_KEY_MAX+1];
+
+ static Dtdisc_t disc;
+
+ static const char primary[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+ if (!(dt = (Dt_t*)LCINFO(AST_LC_COLLATE)->data))
+ {
+ disc.key = offsetof(Cchr_t, key);
+ if ((cc = newof(0, Cchr_t, elementsof(primary), 0)) && (dt = dtopen(&disc, Dtoset)))
+ {
+ for (i = 0; i < elementsof(primary) - 1; i++, cc++)
+ {
+ cc->nam[0] = primary[i];
+ mbxfrm(cc->key, cc->nam, COLL_KEY_MAX);
+ dtinsert(dt, cc);
+ }
+ for (i = 0; i < elementsof(cc->key); i++)
+ cc->key[i] = ~0;
+ dtinsert(dt, cc);
+ LCINFO(AST_LC_COLLATE)->data = (void*)dt;
+ }
+ else
+ {
+ if (cc)
+ free(cc);
+ drop(env->disc, e);
+ return 0;
+ }
+ }
+ if (dt)
+ {
+ drop(env->disc, e);
+ if (ic = env->flags & REG_ICASE)
+ elements *= 2;
+ if (!(e = node(env, REX_COLL_CLASS, 1, 1, (elements + 3) * sizeof(Celt_t))))
+ return 0;
+ ce = (Celt_t*)e->re.data;
+ e->re.collate.invert = neg;
+ e->re.collate.elements = ce;
+ env->cursor = first;
+ inrange = 0;
+ for (;;)
+ {
+ if ((c = *env->cursor) == 0 || c == env->terminator || (env->flags & REG_ESCAPE) && c == env->delimiter)
+ goto error;
+ pp = env->cursor;
+ env->cursor += (w = MBSIZE(env->cursor));
+ if (c == '\\' && ((env->flags & REG_CLASS_ESCAPE) || *env->cursor == env->delimiter && (env->flags & REG_ESCAPE)))
+ {
+ if (*env->cursor)
+ {
+ if (*env->cursor == 'n')
+ {
+ pp = env->cursor++;
+ c = '\n';
+ }
+ else if (env->type < SRE || !(env->flags & REG_SHELL_ESCAPED))
+ {
+ env->token.len = 1;
+ w = magic(env, *env->cursor, 2);
+ if (env->token.len > 1 || w != T_BAD)
+ {
+ if (env->token.len == 1 && (f = classfun(w)))
+ {
+ if (inrange > 1)
+ {
+ if (env->type < SRE && !(env->flags & REG_LENIENT))
+ goto erange;
+ inrange = 0;
+ }
+ env->cursor++;
+ ce->fun = f;
+ ce->typ = COLL_call;
+ ce++;
+ continue;
+ }
+ if (env->token.len > 1 || w >= 0 && w < T_META)
+ {
+ c = w;
+ w = mbconv(mbc, c);
+ pp = (unsigned char*)mbc;
+ env->cursor += env->token.len;
+ }
+ }
+ }
+ }
+ }
+ else if (c == ']')
+ {
+ if (env->cursor == begin)
+ {
+ rp = pp;
+ rw = w;
+ inrange = 1;
+ continue;
+ }
+ if (inrange != 0)
+ {
+ ce = col(ce, ic, rp, rw, rc, NiL, 0, 0);
+ if (inrange == 2)
+ ce = col(ce, ic, NiL, 1, '-', NiL, 0, 0);
+ }
+ break;
+ }
+ else if (c == '-')
+ {
+ if (!inrange && env->cursor != begin && *env->cursor != ']')
+ {
+ if (env->type < SRE && !(env->flags & REG_LENIENT))
+ goto erange;
+ continue;
+ }
+ else if (inrange == 1)
+ {
+ inrange = 2;
+ continue;
+ }
+ }
+ else if (c == '[')
+ {
+ switch (*env->cursor)
+ {
+ case 0:
+ goto error;
+ case ':':
+ if (env->regexp)
+ goto complicated_normal;
+ if (inrange == 1)
+ ce = col(ce, ic, rp, rw, rc, NiL, 0, 0);
+ if (!(f = regclass((char*)env->cursor, (char**)&env->cursor)))
+ {
+ if (env->cursor == start && (c = *(env->cursor + 1)) && *(env->cursor + 2) == ':' && *(env->cursor + 3) == ']' && *(env->cursor + 4) == ']')
+ {
+ switch (c)
+ {
+ case '<':
+ i = REX_WBEG;
+ break;
+ case '>':
+ i = REX_WEND;
+ break;
+ default:
+ i = 0;
+ break;
+ }
+ if (i)
+ {
+ env->cursor += 5;
+ drop(env->disc, e);
+ return node(env, i, 0, 0, 0);
+ }
+ }
+ env->error = REG_ECTYPE;
+ goto error;
+ }
+ ce->fun = f;
+ ce->typ = COLL_call;
+ ce++;
+ inrange = 0;
+ continue;
+ case '=':
+ if (env->regexp)
+ goto complicated_normal;
+ if (inrange == 2)
+ goto erange;
+ if (inrange == 1)
+ ce = col(ce, ic, rp, rw, rc, NiL, 0, 0);
+ pp = (unsigned char*)cb[inrange];
+ rp = env->cursor + 1;
+ if ((rw = regcollate((char*)env->cursor, (char**)&env->cursor, (char*)pp, COLL_KEY_MAX, &wc)) < 0)
+ goto ecollate;
+ c = 0;
+ if (ic)
+ {
+ if (iswupper(wc))
+ {
+ wc = towlower(wc);
+ rw = mbconv((char*)pp, wc);
+ c = 'u';
+ }
+ else if (iswlower(wc))
+ c = 'l';
+ }
+ i = 1;
+ for (;;)
+ {
+ mbxfrm(key.key, (char*)pp, COLL_KEY_MAX);
+ if (!(cc = (Cchr_t*)dtsearch(dt, &key)) && !(cc = (Cchr_t*)dtprev(dt, &key)))
+ {
+ if (i)
+ {
+ c = *pp;
+ goto singleton;
+ }
+ goto ecollate;
+ }
+ xc = (tc = (Cchr_t*)dtprev(dt, cc)) && !strcasecmp((char*)tc->nam, (char*)cc->nam) ? tc : cc;
+ if (c == 'l' || c == 'L' && !(c = 0))
+ ce->typ = COLL_range_lc;
+ else if (c == 'u' || c == 'U' && !(c = 0))
+ ce->typ = COLL_range_uc;
+ else
+ ce->typ = COLL_range;
+ strcpy((char*)ce->beg, (char*)xc->key);
+ if (!(cc = (Cchr_t*)dtnext(dt, cc)))
+ {
+ if (i)
+ {
+ c = *pp;
+ goto singleton;
+ }
+ goto ecollate;
+ }
+ if (!strcasecmp((char*)xc->nam, (char*)cc->nam) && (tc = (Cchr_t*)dtnext(dt, cc)))
+ cc = tc;
+ strcpy((char*)ce->end, (char*)cc->key);
+ ce->max = -1;
+ ce++;
+ if (!c)
+ break;
+ if (c == 'u')
+ {
+ wc = towlower(wc);
+ c = 'L';
+ }
+ else
+ {
+ wc = towupper(wc);
+ c = 'U';
+ }
+ rw = mbconv((char*)pp, wc);
+ i = 0;
+ }
+ inrange = 0;
+ c = *pp;
+ continue;
+ case '.':
+ if (env->regexp)
+ goto complicated_normal;
+ pp = (unsigned char*)cb[inrange];
+ if ((w = regcollate((char*)env->cursor, (char**)&env->cursor, (char*)pp, COLL_KEY_MAX, NiL)) < 0)
+ goto ecollate;
+ c = *pp;
+ break;
+ default:
+ complicated_normal:
+ if (*env->cursor == env->terminator || *env->cursor == env->delimiter && (env->flags & REG_ESCAPE))
+ goto error;
+ break;
+ }
+ }
+ singleton:
+ if (inrange == 2)
+ {
+ ce = col(ce, ic, rp, rw, rc, pp, w, c);
+ if (strcmp((char*)ce->beg, (char*)ce->end) > 0)
+ {
+ if (env->type < SRE && !(env->flags & REG_LENIENT))
+ goto erange;
+ (ce-1)->typ = COLL_char;
+ strcpy((char*)ce->beg, (char*)(ce-1)->end);
+ ce->typ = COLL_char;
+ ce++;
+ }
+ inrange = env->type >= SRE || (env->flags & REG_LENIENT);
+ }
+ else if (inrange == 1)
+ ce = col(ce, ic, rp, rw, rc, NiL, 0, 0);
+ else
+ inrange = 1;
+ rp = pp;
+ rw = w;
+ rc = c;
+ }
+ ce->typ = COLL_end;
+ return e;
+ }
+ }
+#endif
+ if (collate)
+ goto ecollate;
+ if (env->flags & REG_ICASE)
+ for (i = 0; i <= UCHAR_MAX; i++)
+ if (settst(e->re.charclass, i))
+ {
+ if (isupper(i))
+ c = tolower(i);
+ else if (islower(i))
+ c = toupper(i);
+ else
+ continue;
+ setadd(e->re.charclass, c);
+ }
+ if (neg)
+ {
+ for (i = 0; i < elementsof(e->re.charclass->bits); i++)
+ e->re.charclass->bits[i] ^= ~0;
+ if (env->explicit >= 0)
+ setclr(e->re.charclass, env->explicit);
+ }
+ return e;
+ ecollate:
+ env->error = REG_ECOLLATE;
+ goto error;
+ erange:
+ env->error = REG_ERANGE;
+ error:
+ drop(env->disc, e);
+ if (!env->error)
+ env->error = REG_EBRACK;
+ return 0;
+}
+
+static Rex_t*
+ccl(Cenv_t* env, int type)
+{
+ int i;
+ Rex_t* e;
+ Celt_t* ce;
+ regclass_t f;
+
+ if (!(f = classfun(type)))
+ {
+ env->error = REG_BADESC;
+ return 0;
+ }
+ if (!mbcoll())
+ {
+ if (!(e = node(env, REX_CLASS, 1, 1, sizeof(Set_t))))
+ return 0;
+ for (i = 0; i <= UCHAR_MAX; i++)
+ if ((*f)(i))
+ setadd(e->re.charclass, i);
+ if (env->explicit >= 0)
+ setclr(e->re.charclass, env->explicit);
+ }
+ else
+ {
+ if (!(e = node(env, REX_COLL_CLASS, 1, 1, 2 * sizeof(Celt_t))))
+ return 0;
+ ce = (Celt_t*)e->re.data;
+ e->re.collate.invert = 0;
+ e->re.collate.elements = ce;
+ ce->fun = f;
+ ce->typ = COLL_call;
+ ce++;
+ ce->typ = COLL_end;
+ }
+ return e;
+}
+
+static Rex_t*
+rep(Cenv_t* env, Rex_t* e, int number, int last)
+{
+ Rex_t* f;
+ unsigned long m = 0;
+ unsigned long n = RE_DUP_INF;
+ int minimal = -1;
+
+ if (!e)
+ return 0;
+ switch (token(env))
+ {
+ case T_BANG:
+ eat(env);
+ if (!(f = node(env, REX_NEG, m, n, 0)))
+ {
+ drop(env->disc, e);
+ return 0;
+ }
+ f->re.group.expr.rex = e;
+ return f;
+ case T_QUES:
+ eat(env);
+ n = 1;
+ break;
+ case T_STAR:
+ eat(env);
+ break;
+ case T_PLUS:
+ eat(env);
+ m = 1;
+ break;
+ case T_LEFT:
+ eat(env);
+ m = env->token.min;
+ n = env->token.max;
+ break;
+ default:
+ return e;
+ }
+ if (env->token.att)
+ minimal = 1;
+ else if (env->type < SRE)
+ switch (token(env))
+ {
+ case T_QUES:
+ eat(env);
+ minimal = !(env->flags & REG_MINIMAL);
+ break;
+ case T_STAR: /*AST*/
+ eat(env);
+ minimal = !!(env->flags & REG_MINIMAL);
+ break;
+ }
+ switch (e->type)
+ {
+ case REX_DOT:
+ case REX_CLASS:
+ case REX_COLL_CLASS:
+ case REX_ONECHAR:
+ e->lo = m;
+ e->hi = n;
+ if (minimal >= 0)
+ mark(e, minimal);
+ return e;
+#if HUH_2002_08_07
+ case REX_BEG:
+#endif
+ case REX_BEG_STR:
+ case REX_END_STR:
+ case REX_FIN_STR:
+ case REX_WBEG:
+ case REX_WEND:
+ case REX_WORD:
+ case REX_WORD_NOT:
+ env->error = REG_BADRPT;
+ drop(env->disc, e);
+ return 0;
+ }
+ if (m == 1 && n == 1)
+ {
+ if (minimal >= 0)
+ mark(e, minimal);
+ return e;
+ }
+ if (!(f = node(env, REX_REP, m, n, 0)))
+ {
+ drop(env->disc, e);
+ return 0;
+ }
+ f->re.group.expr.rex = e;
+ f->re.group.number = number;
+ f->re.group.last = last;
+ if (minimal >= 0)
+ mark(f, minimal);
+ if (m <= n && n)
+ {
+ for (; e && e->type >= REX_GROUP && e->type <= REX_GROUP_CUT; e = e->re.group.expr.rex);
+ if (e && e->type == REX_NEG)
+ f->type = REX_GROUP;
+ }
+ return f;
+}
+
+static int
+isstring(Rex_t* e)
+{
+ switch (e->type)
+ {
+ case REX_ONECHAR:
+ return e->lo == 1 && e->hi == 1;
+ case REX_STRING:
+ return 1;
+ }
+ return 0;
+}
+
+static Trie_node_t*
+trienode(Cenv_t* env, int c)
+{
+ Trie_node_t* t;
+
+ if (t = (Trie_node_t*)alloc(env->disc, 0, sizeof(Trie_node_t)))
+ {
+ memset(t, 0, sizeof(Trie_node_t));
+ t->c = c;
+ }
+ return t;
+}
+
+static int
+insert(Cenv_t* env, Rex_t* f, Rex_t* g)
+{
+ unsigned char* s;
+ unsigned char* e;
+ Trie_node_t* t;
+ int len;
+ unsigned char tmp[2];
+
+ switch (f->type)
+ {
+ case REX_ONECHAR:
+ *(s = tmp) = f->re.onechar;
+ e = s + 1;
+ break;
+ case REX_STRING:
+ s = f->re.string.base;
+ e = s + f->re.string.size;
+ break;
+ default:
+ return 1;
+ }
+ if (!(t = g->re.trie.root[*s]) && !(t = g->re.trie.root[*s] = trienode(env, *s)))
+ return 1;
+ for (len = 1;;)
+ {
+ if (t->c == *s)
+ {
+ if (++s >= e)
+ break;
+ if (!t->son && !(t->son = trienode(env, *s)))
+ return 1;
+ t = t->son;
+ len++;
+ }
+ else
+ {
+ if (!t->sib && !(t->sib = trienode(env, *s)))
+ return 1;
+ t = t->sib;
+ }
+ }
+ if (g->re.trie.min > len)
+ g->re.trie.min = len;
+ if (g->re.trie.max < len)
+ g->re.trie.max = len;
+ t->end = 1;
+ return 0;
+}
+
+/*
+ * trie() tries to combine nontrivial e and f into a REX_TRIE
+ * unless 0 is returned, e and f are deleted as far as possible
+ * also called by regcomb
+ */
+
+static Rex_t*
+trie(Cenv_t* env, Rex_t* e, Rex_t* f)
+{
+ Rex_t* g;
+
+ if (e->next || f->next || !isstring(e) || e->flags != f->flags)
+ return 0;
+ if (isstring(f))
+ {
+ if (!(g = node(env, REX_TRIE, 0, 0, (UCHAR_MAX + 1) * sizeof(Trie_node_t*))))
+ return 0;
+ g->re.trie.min = INT_MAX;
+ if (insert(env, f, g))
+ goto nospace;
+ drop(env->disc, f);
+ }
+ else if (f->type != REX_TRIE)
+ return 0;
+ else
+ g = f;
+ if (insert(env, e, g))
+ goto nospace;
+ drop(env->disc, e);
+ return g;
+ nospace:
+ if (g != f)
+ drop(env->disc, g);
+ return 0;
+}
+
+static Rex_t* alt(Cenv_t*, int, int);
+
+static int
+chr(register Cenv_t* env, int* escaped)
+{
+ unsigned char* p;
+ int c;
+
+ *escaped = 0;
+ if (!(c = *env->cursor))
+ return -1;
+ env->cursor++;
+ if (c == '\\')
+ {
+ if (env->flags & REG_SHELL_ESCAPED)
+ return c;
+ if (!(c = *(env->cursor + 1)) || c == env->terminator)
+ {
+ if (env->flags & REG_LENIENT)
+ return c ? c : '\\';
+ env->error = REG_EESCAPE;
+ return -1;
+ }
+ p = env->cursor;
+ c = chresc((char*)env->cursor - 1, (char**)&env->cursor);
+ *escaped = env->cursor - p;
+ }
+ return c;
+}
+
+/*
+ * open the perly gates
+ */
+
+static Rex_t*
+grp(Cenv_t* env, int parno)
+{
+ Rex_t* e;
+ Rex_t* f;
+ int c;
+ int i;
+ int n;
+ int x;
+ int esc;
+ int typ;
+ int beg;
+ unsigned char* p;
+
+ beg = env->pattern == env->cursor - env->token.len;
+ if (!(c = env->token.lex) && (c = *env->cursor))
+ env->cursor++;
+ env->token.len = 0;
+ env->parnest++;
+ typ = -1;
+ switch (c)
+ {
+ case '-':
+ case '+':
+ case 'a':
+ case 'g':
+ case 'i':
+ case 'l':
+ case 'm':
+ case 'p':
+ case 'r':
+ case 's':
+ case 'x':
+ case 'A':
+ case 'B':
+ case 'E':
+ case 'F':
+ case 'G':
+ case 'I':
+ case 'K':
+ case 'L':
+ case 'M': /* glob(3) */
+ case 'N': /* glob(3) */
+ case 'O': /* glob(3) */
+ case 'P':
+ case 'R': /* pcre */
+ case 'S':
+ case 'U': /* pcre */
+ case 'X': /* pcre */
+ x = REX_GROUP;
+ i = 1;
+ env->token.push = 1;
+ for (;;)
+ {
+ switch (c)
+ {
+ case ')':
+ if (!(env->flags & REG_LITERAL))
+ {
+ env->error = REG_BADRPT;
+ return 0;
+ }
+ /*FALLTHROUGH*/
+ case 0:
+ case T_CLOSE:
+ x = 0;
+ goto done;
+ case ':':
+ eat(env);
+ if (token(env) == T_CLOSE)
+ x = 0;
+ goto done;
+ case '-':
+ i = 0;
+ break;
+ case '+':
+ i = 1;
+ break;
+ case 'a':
+ if (i)
+ env->flags |= (REG_LEFT|REG_RIGHT);
+ else
+ env->flags &= ~(REG_LEFT|REG_RIGHT);
+ break;
+ case 'g':
+ if (i)
+ env->flags &= ~REG_MINIMAL;
+ else
+ env->flags |= REG_MINIMAL;
+ break;
+ case 'i':
+ if (i)
+ env->flags |= REG_ICASE;
+ else
+ env->flags &= ~REG_ICASE;
+ break;
+ case 'l':
+ if (i)
+ env->flags |= REG_LEFT;
+ else
+ env->flags &= ~REG_LEFT;
+ break;
+ case 'm':
+ if (i)
+ env->flags |= REG_NEWLINE;
+ else
+ env->flags &= ~REG_NEWLINE;
+ env->explicit = (env->flags & (REG_NEWLINE|REG_SPAN)) == REG_NEWLINE ? env->mappednewline : -1;
+ break;
+ case 'p':
+ if (i)
+ env->flags &= ~REG_LENIENT;
+ else
+ env->flags |= REG_LENIENT;
+ break;
+ case 'r':
+ if (i)
+ env->flags |= REG_RIGHT;
+ else
+ env->flags &= ~REG_RIGHT;
+ break;
+ case 's':
+ if (i)
+ env->flags |= REG_SPAN;
+ else
+ env->flags &= ~REG_SPAN;
+ env->explicit = (env->flags & (REG_NEWLINE|REG_SPAN)) == REG_NEWLINE ? env->mappednewline : -1;
+ break;
+ case 'x':
+ if (i)
+ env->flags |= REG_COMMENT;
+ else
+ env->flags &= ~REG_COMMENT;
+ break;
+ case 'X':
+ if (typ >= 0 || env->type == ERE && (env->flags & REG_CLASS_ESCAPE))
+ break; /* PCRE_EXTRA */
+ /*FALLTHROUGH*/
+ case 'A':
+ env->flags &= ~(REG_AUGMENTED|REG_EXTENDED|REG_LITERAL|REG_SHELL|REG_LEFT|REG_RIGHT);
+ env->flags |= REG_AUGMENTED|REG_EXTENDED;
+ typ = ARE;
+ break;
+ case 'B':
+ case 'G':
+ env->flags &= ~(REG_AUGMENTED|REG_EXTENDED|REG_LITERAL|REG_SHELL|REG_LEFT|REG_RIGHT);
+ typ = BRE;
+ break;
+ case 'E':
+ env->flags &= ~(REG_AUGMENTED|REG_EXTENDED|REG_LITERAL|REG_SHELL|REG_LEFT|REG_RIGHT);
+ env->flags |= REG_EXTENDED;
+ typ = ERE;
+ break;
+ case 'F':
+ case 'L':
+ env->flags &= ~(REG_AUGMENTED|REG_EXTENDED|REG_LITERAL|REG_SHELL|REG_LEFT|REG_RIGHT);
+ env->flags |= REG_LITERAL;
+ typ = ERE;
+ break;
+ case 'K':
+ env->flags &= ~(REG_AUGMENTED|REG_EXTENDED|REG_LITERAL|REG_SHELL|REG_LEFT|REG_RIGHT);
+ env->flags |= REG_AUGMENTED|REG_SHELL|REG_LEFT|REG_RIGHT;
+ typ = KRE;
+ break;
+ case 'M':
+ /* used by caller to disable glob(3) GLOB_BRACE */
+ break;
+ case 'N':
+ /* used by caller to disable glob(3) GLOB_NOCHECK */
+ break;
+ case 'O':
+ /* used by caller to disable glob(3) GLOB_STARSTAR */
+ break;
+ case 'P':
+ env->flags &= ~(REG_AUGMENTED|REG_EXTENDED|REG_LITERAL|REG_SHELL|REG_LEFT|REG_RIGHT);
+ env->flags |= REG_EXTENDED|REG_CLASS_ESCAPE;
+ typ = ERE;
+ break;
+ case 'S':
+ env->flags &= ~(REG_AUGMENTED|REG_EXTENDED|REG_LITERAL|REG_SHELL|REG_LEFT|REG_RIGHT);
+ env->flags |= REG_SHELL|REG_LEFT|REG_RIGHT;
+ typ = SRE;
+ break;
+ case 'U': /* PCRE_UNGREEDY */
+ if (typ >= 0 || env->type == ERE && (env->flags & REG_CLASS_ESCAPE))
+ {
+ if (i)
+ env->flags |= REG_MINIMAL;
+ else
+ env->flags &= ~REG_MINIMAL;
+ }
+ break;
+ default:
+ env->error = REG_BADRPT;
+ return 0;
+ }
+ eat(env);
+ c = token(env);
+ }
+ done:
+ break;
+ case ':':
+ x = REX_GROUP;
+ break;
+ case '=':
+ x = REX_GROUP_AHEAD;
+ break;
+ case '!':
+ x = REX_GROUP_AHEAD_NOT;
+ break;
+ case '<':
+ switch (token(env))
+ {
+ case '=':
+ x = REX_GROUP_BEHIND;
+ break;
+ case '!':
+ case T_BANG:
+ x = REX_GROUP_BEHIND_NOT;
+ break;
+ default:
+ env->error = REG_BADRPT;
+ return 0;
+ }
+ eat(env);
+ break;
+ case '>':
+ x = REX_GROUP_CUT;
+ break;
+ case '%':
+ case T_PERCENT:
+ e = node(env, REX_NEST, 0, 0, (UCHAR_MAX + 1) * sizeof(unsigned short));
+ e->re.nest.primary = isalnum(*env->cursor) ? -1 : *env->cursor;
+ n = 1;
+ for (;;)
+ {
+ switch (i = chr(env, &esc))
+ {
+ case -1:
+ case 0:
+ invalid:
+ env->cursor -= esc + 1;
+ env->error = REG_EPAREN;
+ return 0;
+ case 'D':
+ x = REX_NEST_delimiter;
+ /*FALLTHROUGH*/
+ delimiter:
+ if ((i = chr(env, &esc)) < 0)
+ goto invalid;
+ if (e->re.nest.type[i] & ~x)
+ goto invalid;
+ e->re.nest.type[i] = x;
+ continue;
+ case 'E':
+ x = REX_NEST_escape;
+ goto delimiter;
+ case 'L':
+ x = REX_NEST_literal;
+ goto quote;
+ case 'O':
+ switch (i = chr(env, &esc))
+ {
+ case 'T':
+ e->re.nest.type[UCHAR_MAX+1] |= REX_NEST_terminator;
+ break;
+ default:
+ goto invalid;
+ }
+ continue;
+ case 'Q':
+ x = REX_NEST_quote;
+ /*FALLTHROUGH*/
+ quote:
+ if ((i = chr(env, &esc)) < 0)
+ goto invalid;
+ if (e->re.nest.type[i] & ~x)
+ goto invalid;
+ e->re.nest.type[i] = x|REX_NEST_open|REX_NEST_close|(i<<REX_NEST_SHIFT);
+ continue;
+ case 'S':
+ x = REX_NEST_separator;
+ goto delimiter;
+ case 'T':
+ x = REX_NEST_terminator;
+ goto delimiter;
+ case '|':
+ case '&':
+ if (!esc)
+ goto invalid;
+ goto nesting;
+ case '(':
+ if (!esc)
+ n++;
+ goto nesting;
+ case ')':
+ if (!esc && !--n)
+ break;
+ goto nesting;
+ default:
+ nesting:
+ if (isalnum(i) || (e->re.nest.type[i] & (REX_NEST_close|REX_NEST_escape|REX_NEST_literal|REX_NEST_quote|REX_NEST_delimiter|REX_NEST_separator|REX_NEST_terminator)))
+ goto invalid;
+ e->re.nest.type[i] = REX_NEST_open;
+ if ((x = chr(env, &esc)) < 0 || (e->re.nest.type[x] & (REX_NEST_close|REX_NEST_escape|REX_NEST_delimiter|REX_NEST_separator|REX_NEST_terminator)))
+ goto invalid;
+ if (!esc)
+ {
+ if (x == ')' && !--n)
+ goto invalid;
+ else if (x == '(')
+ n++;
+ }
+ e->re.nest.type[x] |= REX_NEST_close;
+ e->re.nest.type[i] |= x << REX_NEST_SHIFT;
+ continue;
+ }
+ break;
+ }
+ env->parnest--;
+ if (c == T_PERCENT)
+ for (n = 0; n < 2; n++)
+ {
+ parno = ++env->parno;
+ if (!(f = node(env, REX_GROUP, 0, 0, 0)))
+ {
+ drop(env->disc, e);
+ return 0;
+ }
+ if (parno < elementsof(env->paren))
+ env->paren[parno] = f;
+ f->re.group.back = 0;
+ f->re.group.number = parno;
+ f->re.group.expr.rex = e;
+ e = f;
+ }
+ return e;
+ case '(':
+ c = 0;
+ if (isdigit(*env->cursor))
+ {
+ f = 0;
+ do
+ {
+ if (c > (INT_MAX / 10))
+ {
+ env->error = REG_BADRPT;
+ return 0;
+ }
+ c = c * 10 + (*env->cursor++ - '0');
+ } while (isdigit(*env->cursor));
+ if (*env->cursor++ != ')')
+ {
+ env->error = REG_BADRPT;
+ return 0;
+ }
+ if (c && env->type >= SRE)
+ c = c * 2 - 1;
+ if (!c || c > env->parno || !env->paren[c])
+ {
+ if (!(env->flags & REG_LENIENT))
+ {
+ env->error = REG_ESUBREG;
+ return 0;
+ }
+ if (c)
+ c = -1;
+ }
+ }
+ else
+ {
+ if (env->type < SRE && *env->cursor++ != '?')
+ {
+ env->error = REG_BADRPT;
+ return 0;
+ }
+ if (!(f = grp(env, parno + 1)) && env->error)
+ return 0;
+ }
+ if (!(e = node(env, REX_GROUP_COND, 0, 0, 0)))
+ {
+ drop(env->disc, f);
+ return 0;
+ }
+ e->re.group.size = c;
+ e->re.group.expr.binary.left = f;
+ if (!(e->re.group.expr.binary.right = alt(env, parno, 1)))
+ {
+ drop(env->disc, e);
+ return 0;
+ }
+ if (token(env) != T_CLOSE)
+ {
+ env->error = REG_EPAREN;
+ return 0;
+ }
+ eat(env);
+ env->parnest--;
+ return rep(env, e, parno, parno);
+ case '{':
+ p = env->cursor;
+ n = 1;
+ while (c = *env->cursor)
+ {
+ if (c == '\\' && *(env->cursor + 1))
+ env->cursor++;
+ else if (c == '{')
+ n++;
+ else if (c == '}' && !--n)
+ break;
+ else if (c == env->delimiter || c == env->terminator)
+ break;
+ env->cursor++;
+ }
+ if (c != '}')
+ {
+ env->error = REG_EBRACE;
+ return 0;
+ }
+ if (*++env->cursor != ')')
+ {
+ env->error = REG_EPAREN;
+ return 0;
+ }
+ env->cursor++;
+ env->parnest--;
+ if (env->disc->re_version < REG_VERSION_EXEC)
+ {
+ env->error = REG_BADRPT;
+ return 0;
+ }
+ if (!env->disc->re_execf)
+ return 0;
+ if (!(e = node(env, REX_EXEC, 0, 0, 0)))
+ return 0;
+ e->re.exec.text = (const char*)p;
+ e->re.exec.size = env->cursor - p - 2;
+ if (!env->disc->re_compf)
+ e->re.exec.data = 0;
+ else
+ e->re.exec.data = (*env->disc->re_compf)(env->regex, e->re.exec.text, e->re.exec.size, env->disc);
+ return e;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ c -= '0';
+ while (isdigit(*env->cursor))
+ {
+ if (c > (INT_MAX / 10))
+ {
+ env->error = REG_ESUBREG;
+ return 0;
+ }
+ c = c * 10 + *env->cursor++ - '0';
+ }
+ if (*env->cursor == ')')
+ {
+ env->cursor++;
+ env->parnest--;
+ env->token.len = 1;
+ if (c > env->parno || !env->paren[c])
+ {
+ env->error = REG_ESUBREG;
+ return 0;
+ }
+ env->paren[c]->re.group.back = 1;
+ return rep(env, node(env, REX_BACK, c, 0, 0), 0, 0);
+ }
+ /*FALLTHROUGH*/
+ default:
+ env->error = REG_BADRPT;
+ return 0;
+ }
+ if (x && !(e = alt(env, parno, 0)))
+ return 0;
+ c = token(env);
+ env->parnest--;
+ if (c != T_CLOSE && (!(env->flags & REG_LITERAL) || c != ')'))
+ {
+ env->error = REG_EPAREN;
+ return 0;
+ }
+ eat(env);
+ if (typ >= 0)
+ {
+ if (beg)
+ env->pattern = env->cursor;
+ env->type = typ;
+ }
+ if (!x)
+ return 0;
+ if (!(f = node(env, x, 0, 0, 0)))
+ {
+ drop(env->disc, e);
+ return 0;
+ }
+ f->re.group.expr.rex = e;
+ if (x == REX_GROUP_BEHIND || x == REX_GROUP_BEHIND_NOT)
+ {
+ if (stats(env, e))
+ {
+ drop(env->disc, f);
+ if (!env->error)
+ env->error = REG_ECOUNT;
+ return 0;
+ }
+ f->re.group.size = env->stats.m;
+ memset(&env->stats, 0, sizeof(env->stats));
+ }
+ switch (x)
+ {
+ case REX_GROUP:
+ case REX_GROUP_CUT:
+ f = rep(env, f, parno, env->parno);
+ break;
+ }
+ return f;
+}
+
+static Rex_t*
+seq(Cenv_t* env)
+{
+ Rex_t* e;
+ Rex_t* f;
+ Token_t tok;
+ int c;
+ int i;
+ int n;
+ int x;
+ int parno;
+ int type;
+ regflags_t flags;
+ unsigned char* s;
+ unsigned char* p;
+ unsigned char* t;
+ unsigned char* u;
+ unsigned char buf[256];
+
+ for (;;)
+ {
+ s = buf;
+ while ((c = token(env)) < T_META && s < &buf[sizeof(buf) - env->token.len])
+ {
+ x = c;
+ p = env->cursor;
+ if (c >= 0)
+ {
+ n = 1;
+ *s++ = (env->flags & REG_ICASE) ? toupper(c) : c;
+ }
+ else if (c == C_ESC || (env->flags & REG_ICASE))
+ {
+ c = (c == C_ESC) ? env->token.lex : mbchar(p);
+ if (env->flags & REG_ICASE)
+ c = towupper(c);
+ if ((&buf[sizeof(buf)] - s) < MB_CUR_MAX)
+ break;
+ if ((n = mbconv((char*)s, c)) < 0)
+ *s++ = c;
+ else if (n)
+ s += n;
+ else
+ {
+ n = 1;
+ *s++ = 0;
+ }
+ }
+ else
+ {
+ n = env->token.len - env->token.esc;
+ for (t = p, u = s + n; s < u; *s++ = *t++);
+ }
+ eat(env);
+ }
+ if (c == T_BAD)
+ return 0;
+ if (s > buf)
+ switch (c)
+ {
+ case T_STAR:
+ case T_PLUS:
+ case T_LEFT:
+ case T_QUES:
+ case T_BANG:
+ if ((s -= n) == buf)
+ e = 0;
+ else
+ {
+ i = s - buf;
+ if (!(e = node(env, REX_STRING, 0, 0, i)))
+ return 0;
+ memcpy((char*)(e->re.string.base = (unsigned char*)e->re.data), (char*)buf, i);
+ e->re.string.size = i;
+ }
+ if (x >= 0)
+ {
+ if (!(f = node(env, REX_ONECHAR, 1, 1, 0)))
+ {
+ drop(env->disc, e);
+ return 0;
+ }
+ f->re.onechar = (env->flags & REG_ICASE) ? toupper(x) : x;
+ }
+ else
+ {
+ if (!(f = node(env, REX_STRING, 0, 0, n)))
+ return 0;
+ memcpy((char*)(f->re.string.base = (unsigned char*)f->re.data), (char*)p, n);
+ f->re.string.size = n;
+ }
+ if (!(f = rep(env, f, 0, 0)) || !(f = cat(env, f, seq(env))))
+ {
+ drop(env->disc, e);
+ return 0;
+ }
+ if (e)
+ f = cat(env, e, f);
+ return f;
+ default:
+ c = s - buf;
+ if (!(e = node(env, REX_STRING, 0, 0, c)))
+ return 0;
+ memcpy((char*)(e->re.string.base = (unsigned char*)e->re.data), (char*)buf, c);
+ e->re.string.size = c;
+ return cat(env, e, seq(env));
+ }
+ else if (c > T_BACK)
+ {
+ eat(env);
+ c -= T_BACK;
+ if (c > env->parno || !env->paren[c])
+ {
+ env->error = REG_ESUBREG;
+ return 0;
+ }
+ env->paren[c]->re.group.back = 1;
+ e = rep(env, node(env, REX_BACK, c, 0, 0), 0, 0);
+ }
+ else
+ switch (c)
+ {
+ case T_AND:
+ case T_CLOSE:
+ case T_BAR:
+ case T_END:
+ return node(env, REX_NULL, 0, 0, 0);
+ case T_DOLL:
+ eat(env);
+ e = rep(env, node(env, REX_END, 0, 0, 0), 0, 0);
+ break;
+ case T_CFLX:
+ eat(env);
+ if ((e = node(env, REX_BEG, 0, 0, 0)) && (env->flags & REG_EXTENDED))
+ e = rep(env, e, 0, 0);
+ break;
+ case T_OPEN:
+ tok = env->token;
+ eat(env);
+ flags = env->flags;
+ type = env->type;
+ if (env->token.att)
+ env->flags |= REG_MINIMAL;
+ env->parnest++;
+ if (env->type == KRE)
+ ++env->parno;
+ parno = ++env->parno;
+ if (!(e = alt(env, parno + 1, 0)))
+ break;
+ if (e->type == REX_NULL && env->type == ERE && !(env->flags & REG_NULL))
+ {
+ drop(env->disc, e);
+ env->error = (*env->cursor == 0 || *env->cursor == env->delimiter || *env->cursor == env->terminator) ? REG_EPAREN : REG_ENULL;
+ return 0;
+ }
+ if (token(env) != T_CLOSE)
+ {
+ drop(env->disc, e);
+ env->error = REG_EPAREN;
+ return 0;
+ }
+ env->parnest--;
+ eat(env);
+ if (!(f = node(env, REX_GROUP, 0, 0, 0)))
+ {
+ drop(env->disc, e);
+ return 0;
+ }
+ if (parno < elementsof(env->paren))
+ env->paren[parno] = f;
+ f->re.group.back = 0;
+ f->re.group.number = parno;
+ f->re.group.expr.rex = e;
+ if (tok.lex)
+ {
+ tok.push = 1;
+ env->token = tok;
+ }
+ if (!(e = rep(env, f, parno, env->parno)))
+ return 0;
+ if (env->type == KRE)
+ {
+ if (!(f = node(env, REX_GROUP, 0, 0, 0)))
+ {
+ drop(env->disc, e);
+ return 0;
+ }
+ if (--parno < elementsof(env->paren))
+ env->paren[parno] = f;
+ f->re.group.back = 0;
+ f->re.group.number = parno;
+ f->re.group.expr.rex = e;
+ e = f;
+ }
+ env->flags = flags;
+ env->type = type;
+ break;
+ case T_GROUP:
+ p = env->cursor;
+ eat(env);
+ flags = env->flags;
+ type = env->type;
+ if (!(e = grp(env, env->parno + 1)))
+ {
+ if (env->error)
+ return 0;
+ if (env->literal == env->pattern && env->literal == p)
+ env->literal = env->cursor;
+ continue;
+ }
+ env->flags = flags;
+ env->type = type;
+ break;
+ case T_BRA:
+ eat(env);
+ if (e = bra(env))
+ e = rep(env, e, 0, 0);
+ break;
+ case T_ALNUM:
+ case T_ALNUM_NOT:
+ case T_DIGIT:
+ case T_DIGIT_NOT:
+ case T_SPACE:
+ case T_SPACE_NOT:
+ eat(env);
+ if (e = ccl(env, c))
+ e = rep(env, e, 0, 0);
+ break;
+ case T_LT:
+ eat(env);
+ e = rep(env, node(env, REX_WBEG, 0, 0, 0), 0, 0);
+ break;
+ case T_GT:
+ eat(env);
+ e = rep(env, node(env, REX_WEND, 0, 0, 0), 0, 0);
+ break;
+ case T_DOT:
+ eat(env);
+ e = rep(env, node(env, REX_DOT, 1, 1, 0), 0, 0);
+ break;
+ case T_DOTSTAR:
+ eat(env);
+ env->token.lex = T_STAR;
+ env->token.push = 1;
+ e = rep(env, node(env, REX_DOT, 1, 1, 0), 0, 0);
+ break;
+ case T_SLASHPLUS:
+ eat(env);
+ env->token.lex = T_PLUS;
+ env->token.push = 1;
+ if (e = node(env, REX_ONECHAR, 1, 1, 0))
+ {
+ e->re.onechar = '/';
+ e = rep(env, e, 0, 0);
+ }
+ break;
+ case T_WORD:
+ eat(env);
+ e = rep(env, node(env, REX_WORD, 0, 0, 0), 0, 0);
+ break;
+ case T_WORD_NOT:
+ eat(env);
+ e = rep(env, node(env, REX_WORD_NOT, 0, 0, 0), 0, 0);
+ break;
+ case T_BEG_STR:
+ eat(env);
+ e = rep(env, node(env, REX_BEG_STR, 0, 0, 0), 0, 0);
+ break;
+ case T_END_STR:
+ eat(env);
+ e = rep(env, node(env, REX_END_STR, 0, 0, 0), 0, 0);
+ break;
+ case T_FIN_STR:
+ eat(env);
+ e = rep(env, node(env, REX_FIN_STR, 0, 0, 0), 0, 0);
+ break;
+ default:
+ env->error = REG_BADRPT;
+ return 0;
+ }
+ if (e && *env->cursor != 0 && *env->cursor != env->delimiter && *env->cursor != env->terminator)
+ e = cat(env, e, seq(env));
+ return e;
+ }
+}
+
+static Rex_t*
+con(Cenv_t* env)
+{
+ Rex_t* e;
+ Rex_t* f;
+ Rex_t* g;
+
+ if (!(e = seq(env)) || !(env->flags & REG_AUGMENTED) || token(env) != T_AND)
+ return e;
+ eat(env);
+ if (!(f = con(env)))
+ {
+ drop(env->disc, e);
+ return 0;
+ }
+ if (!(g = node(env, REX_CONJ, 0, 0, 0)))
+ {
+ drop(env->disc, e);
+ drop(env->disc, f);
+ return 0;
+ }
+ g->re.group.expr.binary.left = e;
+ g->re.group.expr.binary.right = f;
+ return g;
+}
+
+static Rex_t*
+alt(Cenv_t* env, int number, int cond)
+{
+ Rex_t* e;
+ Rex_t* f;
+ Rex_t* g;
+
+ if (!(e = con(env)))
+ return 0;
+ else if (token(env) != T_BAR)
+ {
+ if (!cond)
+ return e;
+ f = 0;
+ if (e->type == REX_NULL)
+ goto bad;
+ }
+ else
+ {
+ eat(env);
+ if (!(f = alt(env, number, 0)))
+ {
+ drop(env->disc, e);
+ return 0;
+ }
+ if ((e->type == REX_NULL || f->type == REX_NULL) && !(env->flags & REG_NULL))
+ goto bad;
+ if (!cond && (g = trie(env, e, f)))
+ return g;
+ }
+ if (!(g = node(env, REX_ALT, 0, 0, 0)))
+ {
+ env->error = REG_ESPACE;
+ goto bad;
+ }
+ g->re.group.number = number;
+ g->re.group.last = env->parno;
+ g->re.group.expr.binary.left = e;
+ g->re.group.expr.binary.right = f;
+ return g;
+ bad:
+ drop(env->disc, e);
+ drop(env->disc, f);
+ if (!env->error)
+ env->error = REG_ENULL;
+ return 0;
+}
+
+/*
+ * add v to REX_BM tables
+ */
+
+static void
+bmstr(Cenv_t* env, register Rex_t* a, unsigned char* v, int n, Bm_mask_t b)
+{
+ int c;
+ int m;
+ size_t z;
+
+ for (m = 0; m < n; m++)
+ {
+ if (!(z = n - m - 1))
+ z = HIT;
+ c = v[m];
+ a->re.bm.mask[m][c] |= b;
+ if (z == HIT || !a->re.bm.skip[c] || a->re.bm.skip[c] > z && a->re.bm.skip[c] < HIT)
+ a->re.bm.skip[c] = z;
+ if (a->flags & REG_ICASE)
+ {
+ if (isupper(c))
+ c = tolower(c);
+ else if (islower(c))
+ c = toupper(c);
+ else
+ continue;
+ a->re.bm.mask[m][c] |= b;
+ if (z == HIT || !a->re.bm.skip[c] || a->re.bm.skip[c] > z && a->re.bm.skip[c] < HIT)
+ a->re.bm.skip[c] = z;
+ }
+ }
+}
+
+/*
+ * set up BM table from trie
+ */
+
+static int
+bmtrie(Cenv_t* env, Rex_t* a, unsigned char* v, Trie_node_t* x, int n, int m, Bm_mask_t b)
+{
+ do
+ {
+ v[m] = x->c;
+ if (m >= (n - 1))
+ {
+ bmstr(env, a, v, n, b);
+ if (!(b <<= 1))
+ {
+ b = 1;
+ a->re.bm.complete = 0;
+ }
+ else if (x->son)
+ a->re.bm.complete = 0;
+ }
+ else if (x->son)
+ b = bmtrie(env, a, v, x->son, n, m + 1, b);
+ } while (x = x->sib);
+ return b;
+}
+
+/*
+ * rewrite the expression tree for some special cases
+ * 1. it is a null expression - illegal
+ * 2. max length fixed string found -- use BM algorithm
+ * 3. it begins with an unanchored string - use KMP algorithm
+ * 0 returned on success
+ */
+
+static int
+special(Cenv_t* env, regex_t* p)
+{
+ Rex_t* a;
+ Rex_t* e;
+ Rex_t* t;
+ Rex_t* x;
+ Rex_t* y;
+ unsigned char* s;
+ int* f;
+ int n;
+ int m;
+ int k;
+
+ DEBUG_INIT();
+ if (e = p->env->rex)
+ {
+ if ((x = env->stats.x) && x->re.string.size < 3)
+ x = 0;
+ if ((t = env->stats.y) && t->re.trie.min < 3)
+ t = 0;
+ if (x && t)
+ {
+ if (x->re.string.size >= t->re.trie.min)
+ t = 0;
+ else
+ x = 0;
+ }
+ if (x || t)
+ {
+ Bm_mask_t** mask;
+ Bm_mask_t* h;
+ unsigned char* v;
+ size_t* q;
+ unsigned long l;
+ int i;
+ int j;
+
+ if (x)
+ {
+ y = x;
+ n = m = x->re.string.size;
+ l = env->stats.l;
+ }
+ else
+ {
+ y = t;
+ n = t->re.trie.min;
+ m = t->re.trie.max;
+ l = env->stats.k;
+ }
+ if (!(q = (size_t*)alloc(env->disc, 0, (n + 1) * sizeof(size_t))))
+ return 1;
+ if (!(a = node(env, REX_BM, 0, 0, n * (sizeof(Bm_mask_t*) + (UCHAR_MAX + 1) * sizeof(Bm_mask_t)) + (UCHAR_MAX + n + 2) * sizeof(size_t))))
+ {
+ alloc(env->disc, q, 0);
+ return 1;
+ }
+ a->flags = y->flags;
+ a->map = y->map;
+ a->re.bm.size = n;
+ a->re.bm.back = (y == e || y == e->re.group.expr.rex) ? (m - n) : -1;
+ a->re.bm.left = l - 1;
+ a->re.bm.right = env->stats.m - l - n;
+ a->re.bm.complete = (env->stats.e || y != e && (e->type != REX_GROUP || y != e->re.group.expr.rex) || e->next || ((a->re.bm.left + a->re.bm.right) >= 0)) ? 0 : n;
+ h = (Bm_mask_t*)&a->re.bm.mask[n];
+ a->re.bm.skip = (size_t*)(h + n * (UCHAR_MAX + 1));
+ a->re.bm.fail = &a->re.bm.skip[UCHAR_MAX + 1];
+ for (m = 0; m <= UCHAR_MAX; m++)
+ a->re.bm.skip[m] = n;
+ a->re.bm.skip[0] = a->re.bm.skip[env->mappednewline] = (y->next && y->next->type == REX_END) ? HIT : (n + a->re.bm.left);
+ for (i = 1; i <= n; i++)
+ a->re.bm.fail[i] = 2 * n - i;
+ mask = a->re.bm.mask;
+ for (m = 0; m < n; m++)
+ {
+ mask[m] = h;
+ h += UCHAR_MAX + 1;
+ }
+ if (x)
+ bmstr(env, a, x->re.string.base, n, 1);
+ else
+ {
+ v = (unsigned char*)q;
+ memset(v, 0, n);
+ m = 1;
+ for (i = 0; i <= UCHAR_MAX; i++)
+ if (t->re.trie.root[i])
+ m = bmtrie(env, a, v, t->re.trie.root[i], n, 0, m);
+ }
+ mask--;
+ memset(q, 0, n * sizeof(*q));
+ for (k = (j = n) + 1; j > 0; j--, k--)
+ {
+ DEBUG_TEST(0x0010,(sfprintf(sfstderr, "BM#0: k=%d j=%d\n", k, j)),(0));
+ for (q[j] = k; k <= n; k = q[k])
+ {
+ for (m = 0; m <= UCHAR_MAX; m++)
+ if (mask[k][m] == mask[j][m])
+ {
+ DEBUG_TEST(0x0010,sfprintf(sfstderr, "CUT1: mask[%d][%c]=mask[%d][%c]\n", k, m, j, m), (0));
+ goto cut;
+ }
+ DEBUG_TEST(0x0010,sfprintf(sfstderr, "BM#2: fail[%d]=%d => %d\n", k, a->re.bm.fail[k], (a->re.bm.fail[k] > n - j) ? (n - j) : a->re.bm.fail[k]), (0));
+ if (a->re.bm.fail[k] > n - j)
+ a->re.bm.fail[k] = n - j;
+ }
+ cut: ;
+ }
+ for (i = 1; i <= n; i++)
+ if (a->re.bm.fail[i] > n + k - i)
+ {
+ DEBUG_TEST(0x0010,sfprintf(sfstderr, "BM#4: fail[%d]=%d => %d\n", i, a->re.bm.fail[i], n + k - i), (0));
+ a->re.bm.fail[i] = n + k - i;
+ }
+#if _AST_REGEX_DEBUG
+ if (DEBUG_TEST(0x0020,(1),(0)))
+ {
+ sfprintf(sfstderr, "STAT: complete=%d n=%d k=%d l=%d r=%d y=%d:%d e=%d:%d\n", a->re.bm.complete, n, k, a->re.bm.left, a->re.bm.right, y->type, y->next ? y->next->type : 0, e->type, e->next ? e->next->type : 0);
+ for (m = 0; m < n; m++)
+ for (i = 1; i <= UCHAR_MAX; i++)
+ if (a->re.bm.mask[m][i])
+ sfprintf(sfstderr, "MASK: [%d]['%c'] = %032..2u\n", m, i, a->re.bm.mask[m][i]);
+ for (i = ' '; i <= UCHAR_MAX; i++)
+ if (a->re.bm.skip[i] >= HIT)
+ sfprintf(sfstderr, "SKIP: ['%c'] = *\n", i);
+ else if (a->re.bm.skip[i] > 0 && a->re.bm.skip[i] < n)
+ sfprintf(sfstderr, "SKIP: ['%c'] = %3d\n", i, a->re.bm.skip[i]);
+ for (j = 31; j >= 0; j--)
+ {
+ sfprintf(sfstderr, " ");
+ next:
+ for (m = 0; m < n; m++)
+ {
+ for (i = 0040; i < 0177; i++)
+ if (a->re.bm.mask[m][i] & (1 << j))
+ {
+ sfprintf(sfstderr, " %c", i);
+ break;
+ }
+ if (i >= 0177)
+ {
+ if (j > 0)
+ {
+ j--;
+ goto next;
+ }
+ sfprintf(sfstderr, " ?");
+ }
+ }
+ sfprintf(sfstderr, "\n");
+ }
+ sfprintf(sfstderr, "FAIL: ");
+ for (m = 1; m <= n; m++)
+ sfprintf(sfstderr, "%3d", a->re.bm.fail[m]);
+ sfprintf(sfstderr, "\n");
+ }
+#endif
+ alloc(env->disc, q, 0);
+ a->next = e;
+ p->env->rex = a;
+ return 0;
+ }
+ switch (e->type)
+ {
+ case REX_BEG:
+ if (env->flags & REG_NEWLINE)
+ return 0;
+ break;
+ case REX_GROUP:
+ if (env->stats.b)
+ return 0;
+ e = e->re.group.expr.rex;
+ if (e->type != REX_DOT)
+ return 0;
+ /*FALLTHROUGH*/
+ case REX_DOT:
+ if (e->lo == 0 && e->hi == RE_DUP_INF)
+ break;
+ return 0;
+ case REX_NULL:
+ if (env->flags & REG_NULL)
+ break;
+ env->error = REG_ENULL;
+ return 1;
+ case REX_STRING:
+ if ((env->flags & (REG_LEFT|REG_LITERAL|REG_RIGHT)) || e->map)
+ return 0;
+ s = e->re.string.base;
+ n = e->re.string.size;
+ if (!(a = node(env, REX_KMP, 0, 0, n * (sizeof(int*) + 1))))
+ return 1;
+ a->flags = e->flags;
+ a->map = e->map;
+ f = a->re.string.fail;
+ memcpy((char*)(a->re.string.base = (unsigned char*)&f[n]), (char*)s, n);
+ s = a->re.string.base;
+ a->re.string.size = n;
+ f[0] = m = -1;
+ for (k = 1; k < n; k++)
+ {
+ while (m >= 0 && s[m+1] != s[k])
+ m = f[m];
+ if (s[m+1] == s[k])
+ m++;
+ f[k] = m;
+ }
+ a->next = e->next;
+ p->env->rex = a;
+ e->next = 0;
+ drop(env->disc, e);
+ break;
+ default:
+ return 0;
+ }
+ }
+ p->env->once = 1;
+ return 0;
+}
+
+int
+regcomp(regex_t* p, const char* pattern, regflags_t flags)
+{
+ Rex_t* e;
+ Rex_t* f;
+ regdisc_t* disc;
+ unsigned char* fold;
+ int i;
+ Cenv_t env;
+
+ if (!p)
+ return REG_BADPAT;
+ if (flags & REG_DISCIPLINE)
+ {
+ flags &= ~REG_DISCIPLINE;
+ disc = p->re_disc;
+ }
+ else
+ disc = &state.disc;
+ if (!disc->re_errorlevel)
+ disc->re_errorlevel = 2;
+ p->env = 0;
+ if (!pattern)
+ return fatal(disc, REG_BADPAT, pattern);
+ if (!state.initialized)
+ {
+ state.initialized = 1;
+ for (i = 0; i < elementsof(state.escape); i++)
+ state.magic[state.escape[i].key] = state.escape[i].val;
+ }
+ if (!(fold = (unsigned char*)LCINFO(AST_LC_CTYPE)->data))
+ {
+ if (!(fold = newof(0, unsigned char, UCHAR_MAX, 1)))
+ return fatal(disc, REG_ESPACE, pattern);
+ for (i = 0; i <= UCHAR_MAX; i++)
+ fold[i] = toupper(i);
+ LCINFO(AST_LC_CTYPE)->data = (void*)fold;
+ }
+ again:
+ if (!(p->env = (Env_t*)alloc(disc, 0, sizeof(Env_t))))
+ return fatal(disc, REG_ESPACE, pattern);
+ memset(p->env, 0, sizeof(*p->env));
+ memset(&env, 0, sizeof(env));
+ env.regex = p;
+ env.flags = flags;
+ env.disc = p->env->disc = disc;
+ if (env.flags & REG_AUGMENTED)
+ env.flags |= REG_EXTENDED;
+ env.mappeddot = '.';
+ env.mappednewline = '\n';
+ env.mappedslash = '/';
+ if (disc->re_version >= REG_VERSION_MAP && disc->re_map)
+ {
+ env.map = disc->re_map;
+ env.MAP = p->env->fold;
+ for (i = 0; i <= UCHAR_MAX; i++)
+ {
+ env.MAP[i] = fold[env.map[i]];
+ if (env.map[i] == '.')
+ env.mappeddot = i;
+ if (env.map[i] == '\n')
+ env.mappednewline = i;
+ if (env.map[i] == '/')
+ env.mappedslash = i;
+ }
+ }
+ else
+ env.MAP = fold;
+ env.type = (env.flags & REG_AUGMENTED) ? ARE : (env.flags & REG_EXTENDED) ? ERE : BRE;
+ env.explicit = -1;
+ if (env.flags & REG_SHELL)
+ {
+ if (env.flags & REG_SHELL_PATH)
+ env.explicit = env.mappedslash;
+ if (!(env.flags & REG_SHELL_ESCAPED))
+ env.flags |= REG_CLASS_ESCAPE;
+ env.flags |= REG_LENIENT|REG_NULL;
+ env.type = env.type == BRE ? SRE : KRE;
+ }
+ else
+ env.flags &= ~(REG_SHELL_DOT|REG_SHELL_ESCAPED|REG_SHELL_GROUP|REG_SHELL_PATH);
+ if ((env.flags & (REG_NEWLINE|REG_SPAN)) == REG_NEWLINE)
+ env.explicit = env.mappednewline;
+ p->env->leading = (env.flags & REG_SHELL_DOT) ? env.mappeddot : -1;
+ env.posixkludge = !(env.flags & (REG_EXTENDED|REG_SHELL));
+ env.regexp = !!(env.flags & REG_REGEXP);
+ env.token.lex = 0;
+ env.token.push = 0;
+ if (env.flags & REG_DELIMITED)
+ {
+ switch (env.delimiter = *pattern++)
+ {
+ case 0:
+ case '\\':
+ case '\n':
+ case '\r':
+ env.error = REG_EDELIM;
+ goto bad;
+ }
+ env.terminator = '\n';
+ }
+ env.literal = env.pattern = env.cursor = (unsigned char*)pattern;
+ if (!(p->env->rex = alt(&env, 1, 0)))
+ goto bad;
+ if (env.parnest)
+ {
+ env.error = REG_EPAREN;
+ goto bad;
+ }
+ if ((env.flags & REG_LEFT) && p->env->rex->type != REX_BEG)
+ {
+ if (p->env->rex->type == REX_ALT)
+ env.flags &= ~REG_FIRST;
+ if (!(e = node(&env, REX_BEG, 0, 0, 0)))
+ {
+ regfree(p);
+ return fatal(disc, REG_ESPACE, pattern);
+ }
+ e->next = p->env->rex;
+ p->env->rex = e;
+ p->env->once = 1;
+ }
+ for (e = p->env->rex; e->next; e = e->next);
+ p->env->done.type = REX_DONE;
+ p->env->done.flags = e->flags;
+ if ((env.flags & REG_RIGHT) && e->type != REX_END)
+ {
+ if (p->env->rex->type == REX_ALT)
+ env.flags &= ~REG_FIRST;
+ if (!(f = node(&env, REX_END, 0, 0, 0)))
+ {
+ regfree(p);
+ return fatal(disc, REG_ESPACE, pattern);
+ }
+ f->flags = e->flags;
+ f->map = e->map;
+ e->next = f;
+ }
+ if (stats(&env, p->env->rex))
+ {
+ if (!env.error)
+ env.error = REG_ECOUNT;
+ goto bad;
+ }
+ if (env.stats.b)
+ p->env->hard = p->env->separate = 1;
+ else if (!(env.flags & REG_FIRST) && (env.stats.a || env.stats.c > 1 && env.stats.c != env.stats.s || env.stats.t && (env.stats.t > 1 || env.stats.a || env.stats.c)))
+ p->env->hard = 1;
+ if (p->env->hard || env.stats.c || env.stats.i)
+ p->env->stats.re_min = p->env->stats.re_max = -1;
+ else
+ {
+ if (!(p->env->stats.re_min = env.stats.m))
+ p->env->stats.re_min = -1;
+ if (!(p->env->stats.re_max = env.stats.n))
+ p->env->stats.re_max = -1;
+ }
+ if (special(&env, p))
+ goto bad;
+ serialize(&env, p->env->rex, 1);
+ p->re_nsub = env.stats.p;
+ if (env.type == KRE)
+ p->re_nsub /= 2;
+ if (env.flags & REG_DELIMITED)
+ {
+ p->re_npat = env.cursor - env.pattern + 1;
+ if (*env.cursor == env.delimiter)
+ p->re_npat++;
+ else if (env.flags & REG_MUSTDELIM)
+ {
+ env.error = REG_EDELIM;
+ goto bad;
+ }
+ else
+ env.flags &= ~REG_DELIMITED;
+ }
+ p->env->explicit = env.explicit;
+ p->env->flags = env.flags & REG_COMP;
+ p->env->min = env.stats.m;
+ p->env->nsub = env.stats.p + env.stats.u;
+ p->env->refs = 1;
+ return 0;
+ bad:
+ regfree(p);
+ if (!env.error)
+ env.error = REG_ESPACE;
+ if (env.type >= SRE && env.error != REG_ESPACE && !(flags & REG_LITERAL))
+ {
+ flags |= REG_LITERAL;
+ pattern = (const char*)env.literal;
+ goto again;
+ }
+ return fatal(disc, env.error, pattern);
+}
+
+/*
+ * regcomp() on sized pattern
+ * the lazy way around adding and checking env.end
+ */
+
+int
+regncomp(regex_t* p, const char* pattern, size_t size, regflags_t flags)
+{
+ char* s;
+ int r;
+
+ if (!(s = malloc(size + 1)))
+ return fatal((flags & REG_DISCIPLINE) ? p->re_disc : &state.disc, REG_ESPACE, pattern);
+ memcpy(s, pattern, size);
+ s[size] = 0;
+ r = regcomp(p, s, flags);
+ free(s);
+ return r;
+}
+
+/*
+ * combine two compiled regular expressions if possible,
+ * replacing first with the combination and freeing second.
+ * return 0 on success.
+ * the only combinations handled are building a Trie
+ * from String|Kmp|Trie and String|Kmp
+ */
+
+int
+regcomb(regex_t* p, regex_t* q)
+{
+ Rex_t* e = p->env->rex;
+ Rex_t* f = q->env->rex;
+ Rex_t* g;
+ Rex_t* h;
+ Cenv_t env;
+
+ if (!e || !f)
+ return fatal(p->env->disc, REG_BADPAT, NiL);
+ if (p->env->separate || q->env->separate)
+ return REG_ESUBREG;
+ memset(&env, 0, sizeof(env));
+ env.disc = p->env->disc;
+ if (e->type == REX_BM)
+ {
+ p->env->rex = e->next;
+ e->next = 0;
+ drop(env.disc, e);
+ e = p->env->rex;
+ }
+ if (f->type == REX_BM)
+ {
+ q->env->rex = f->next;
+ f->next = 0;
+ drop(env.disc, f);
+ f = q->env->rex;
+ }
+ if (e->type == REX_BEG && f->type == REX_BEG)
+ {
+ p->env->flags |= REG_LEFT;
+ p->env->rex = e->next;
+ e->next = 0;
+ drop(env.disc, e);
+ e = p->env->rex;
+ q->env->rex = f->next;
+ f->next = 0;
+ drop(env.disc, f);
+ f = q->env->rex;
+ }
+ for (g = e; g->next; g = g->next);
+ for (h = f; h->next; h = h->next);
+ if (g->next && g->next->type == REX_END && h->next && h->next->type == REX_END)
+ {
+ p->env->flags |= REG_RIGHT;
+ drop(env.disc, g->next);
+ g->next = 0;
+ drop(env.disc, h->next);
+ h->next = 0;
+ }
+ if (!(g = trie(&env, f, e)))
+ return fatal(p->env->disc, REG_BADPAT, NiL);
+ p->env->rex = g;
+ if (!q->env->once)
+ p->env->once = 0;
+ q->env->rex = 0;
+ if (p->env->flags & REG_LEFT)
+ {
+ if (!(e = node(&env, REX_BEG, 0, 0, 0)))
+ {
+ regfree(p);
+ return fatal(p->env->disc, REG_ESPACE, NiL);
+ }
+ e->next = p->env->rex;
+ p->env->rex = e;
+ p->env->once = 1;
+ }
+ if (p->env->flags & REG_RIGHT)
+ {
+ for (f = p->env->rex; f->next; f = f->next);
+ if (f->type != REX_END)
+ {
+ if (!(e = node(&env, REX_END, 0, 0, 0)))
+ {
+ regfree(p);
+ return fatal(p->env->disc, REG_ESPACE, NiL);
+ }
+ f->next = e;
+ }
+ }
+ env.explicit = p->env->explicit;
+ env.flags = p->env->flags;
+ env.disc = p->env->disc;
+ if (stats(&env, p->env->rex))
+ {
+ regfree(p);
+ return fatal(p->env->disc, env.error ? env.error : REG_ECOUNT, NiL);
+ }
+ if (special(&env, p))
+ {
+ regfree(p);
+ return fatal(p->env->disc, env.error ? env.error : REG_ESPACE, NiL);
+ }
+ p->env->min = g->re.trie.min;
+ return 0;
+}
+
+/*
+ * copy a reference of p into q
+ * p and q may then have separate regsubcomp() instantiations
+ */
+
+int
+regdup(regex_t* p, regex_t* q)
+{
+ if (!p || !q)
+ return REG_BADPAT;
+ *q = *p;
+ p->env->refs++;
+ q->re_sub = 0;
+ return 0;
+}
diff --git a/src/lib/libast/regex/regdecomp.c b/src/lib/libast/regex/regdecomp.c
new file mode 100644
index 0000000..a9fe6f3
--- /dev/null
+++ b/src/lib/libast/regex/regdecomp.c
@@ -0,0 +1,448 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * posix regex decompiler
+ */
+
+#include "reglib.h"
+
+#undef ismeta
+#define ismeta(c,t,e,d) (state.magic[c] && state.magic[c][(t)+(e)] >= T_META || (c) == (d))
+#define meta(f,c,t,e,d) do { if (ismeta(c,t,e,d)) sfputc(f, '\\'); sfputc(f, c); } while (0)
+
+static void
+detrie(Trie_node_t* x, Sfio_t* sp, char* b, char* p, char* e, int delimiter)
+{
+ register Trie_node_t* y;
+ char* o;
+ int k;
+
+ o = p;
+ k = 1;
+ do
+ {
+ if (k)
+ {
+ o = p;
+ if (p < e)
+ *p++ = x->c;
+ }
+ sfputc(sp, x->c);
+ for (y = x->sib; y; y = y->sib)
+ {
+ sfputc(sp, '|');
+ sfputc(sp, '<');
+ sfwrite(sp, b, p - b);
+ sfputc(sp, '>');
+ detrie(y, sp, b, p, e, delimiter);
+ }
+ if (x->end && x->son)
+ {
+ sfputc(sp, '|');
+ sfputc(sp, '{');
+ sfwrite(sp, b, p - b);
+ sfputc(sp, '}');
+ p = o;
+ }
+ } while (x = x->son);
+}
+
+static int
+decomp(register Rex_t* e, Sfio_t* sp, int type, int delimiter, regflags_t flags)
+{
+ Rex_t* q;
+ unsigned char* s;
+ unsigned char* t;
+ int c;
+ int m;
+ int cb;
+ int cd;
+ int cr;
+ int ib;
+ int ie;
+ int nb;
+ int ne;
+ unsigned char ic[2*UCHAR_MAX];
+ unsigned char nc[2*UCHAR_MAX];
+
+ do
+ {
+ switch (e->type)
+ {
+ case REX_ALT:
+ if (decomp(e->re.group.expr.binary.left, sp, type, delimiter, flags))
+ return 1;
+ sfputc(sp, '|');
+ if (e->re.group.expr.binary.right && decomp(e->re.group.expr.binary.right, sp, type, delimiter, flags))
+ return 1;
+ break;
+ case REX_BACK:
+ sfprintf(sp, "\\%d", e->lo);
+ break;
+ case REX_BEG:
+ if (type < SRE)
+ sfputc(sp, '^');
+ break;
+ case REX_END:
+ if (type < SRE)
+ sfputc(sp, '$');
+ break;
+ case REX_WBEG:
+ meta(sp, '<', type, 1, delimiter);
+ break;
+ case REX_WEND:
+ meta(sp, '<', type, 1, delimiter);
+ break;
+ case REX_WORD:
+ sfprintf(sp, "\\w");
+ break;
+ case REX_CLASS:
+ case REX_COLL_CLASS:
+ case REX_ONECHAR:
+ case REX_DOT:
+ case REX_REP:
+ if (type >= SRE)
+ {
+ c = ')';
+ if (e->hi == RE_DUP_INF)
+ {
+ if (!e->lo)
+ sfputc(sp, '*');
+ else if (e->lo == 1)
+ sfputc(sp, '+');
+ else
+ sfprintf(sp, "{%d,}", e->lo);
+ }
+ else if (e->hi != 1)
+ sfprintf(sp, "{%d,%d}", e->lo, e->hi);
+ else if (e->lo == 0)
+ sfputc(sp, '?');
+ else
+ c = 0;
+ }
+ switch (e->type)
+ {
+ case REX_REP:
+ if (decomp(e->re.group.expr.rex, sp, type, delimiter, flags))
+ return 1;
+ break;
+ case REX_CLASS:
+ sfputc(sp, '[');
+ nb = ne = ib = ie = -2;
+ cb = cd = cr = 0;
+ s = nc;
+ t = ic;
+ for (m = 0; m <= UCHAR_MAX; m++)
+ if (settst(e->re.charclass, m))
+ {
+ if (m == ']')
+ cb = 1;
+ else if (m == '-')
+ cr = 1;
+ else if (m == delimiter)
+ cd = 1;
+ else if (nb < 0)
+ ne = nb = m;
+ else if (ne == (m - 1))
+ ne = m;
+ else
+ {
+ if (ne == nb)
+ *s++ = ne;
+ else
+ {
+ *s++ = nb;
+ *s++ = '-';
+ *s++ = ne;
+ }
+ ne = nb = m;
+ }
+ }
+ else
+ {
+ if (m == ']')
+ cb = -1;
+ else if (m == '-')
+ cr = -1;
+ else if (m == delimiter)
+ cd = -1;
+ else if (ib < 0)
+ ie = ib = m;
+ else if (ie == (m - 1))
+ ie = m;
+ else
+ {
+ if (ie == ib)
+ *t++ = ie;
+ else
+ {
+ *t++ = ib;
+ *t++ = '-';
+ *t++ = ie;
+ }
+ ie = ib = m;
+ }
+ }
+ if (nb >= 0)
+ {
+ *s++ = nb;
+ if (ne != nb)
+ {
+ *s++ = '-';
+ *s++ = ne;
+ }
+ }
+ if (ib >= 0)
+ {
+ *t++ = ib;
+ if (ie != ib)
+ {
+ *t++ = '-';
+ *t++ = ie;
+ }
+ }
+ if ((t - ic + 1) < (s - nc + (nc[0] == '^')))
+ {
+ sfputc(sp, '^');
+ if (cb < 0)
+ sfputc(sp, ']');
+ if (cr < 0)
+ sfputc(sp, '-');
+ if (cd < 0 && delimiter > 0)
+ {
+ if (flags & REG_ESCAPE)
+ sfputc(sp, '\\');
+ sfputc(sp, delimiter);
+ }
+ sfwrite(sp, ic, t - ic);
+ }
+ else
+ {
+ if (cb > 0)
+ sfputc(sp, ']');
+ if (cr > 0)
+ sfputc(sp, '-');
+ if (cd > 0 && delimiter > 0)
+ {
+ if (flags & REG_ESCAPE)
+ sfputc(sp, '\\');
+ sfputc(sp, delimiter);
+ }
+ if (nc[0] == '^')
+ {
+ sfwrite(sp, nc + 1, s - nc - 1);
+ sfputc(sp, '^');
+ }
+ else
+ sfwrite(sp, nc, s - nc);
+ }
+ sfputc(sp, ']');
+ break;
+ case REX_COLL_CLASS:
+ break;
+ case REX_ONECHAR:
+ meta(sp, e->re.onechar, type, 0, delimiter);
+ break;
+ case REX_DOT:
+ sfputc(sp, '.');
+ break;
+ }
+ if (type < SRE)
+ {
+ if (e->hi == RE_DUP_INF)
+ {
+ if (!e->lo)
+ sfputc(sp, '*');
+ else if (e->lo == 1 && ismeta('+', type, 0, delimiter))
+ meta(sp, '+', type, 1, delimiter);
+ else
+ {
+ meta(sp, '{', type, 1, delimiter);
+ sfprintf(sp, "%d,", e->lo);
+ meta(sp, '}', type, 1, delimiter);
+ }
+ }
+ else if (e->hi != 1 || e->lo == 0 && !ismeta('?', type, 0, delimiter))
+ {
+ meta(sp, '{', type, 1, delimiter);
+ sfprintf(sp, "%d,%d", e->lo, e->hi);
+ meta(sp, '}', type, 1, delimiter);
+ }
+ else if (e->lo == 0)
+ meta(sp, '?', type, 1, delimiter);
+ }
+ else if (c)
+ sfputc(sp, c);
+ break;
+ case REX_STRING:
+ case REX_KMP:
+ t = (s = e->re.string.base) + e->re.string.size;
+ while (s < t)
+ {
+ c = *s++;
+ meta(sp, c, type, 0, delimiter);
+ }
+ break;
+ case REX_TRIE:
+ ib = 0;
+ for (c = 0; c <= UCHAR_MAX; c++)
+ if (e->re.trie.root[c])
+ {
+ char pfx[1024];
+
+ if (ib)
+ sfputc(sp, '|');
+ else
+ ib = 1;
+ detrie(e->re.trie.root[c], sp, pfx, pfx, &pfx[sizeof(pfx)], delimiter);
+ }
+ break;
+ case REX_NEG:
+ if (type >= SRE)
+ sfprintf(sp, "!(");
+ if (decomp(e->re.group.expr.rex, sp, type, delimiter, flags))
+ return 1;
+ if (type >= SRE)
+ sfputc(sp, ')');
+ else
+ sfputc(sp, '!');
+ break;
+ case REX_CONJ:
+ if (decomp(e->re.group.expr.binary.left, sp, type, delimiter, flags))
+ return 1;
+ sfputc(sp, '&');
+ if (decomp(e->re.group.expr.binary.right, sp, type, delimiter, flags))
+ return 1;
+ break;
+ case REX_GROUP:
+ if (type >= SRE)
+ sfputc(sp, '@');
+ meta(sp, '(', type, 1, delimiter);
+ if (decomp(e->re.group.expr.rex, sp, type, delimiter, flags))
+ return 1;
+ meta(sp, ')', type, 1, delimiter);
+ break;
+ case REX_GROUP_AHEAD:
+ case REX_GROUP_AHEAD_NOT:
+ case REX_GROUP_BEHIND:
+ case REX_GROUP_BEHIND_NOT:
+ meta(sp, '(', type, 1, delimiter);
+ sfputc(sp, '?');
+ if (decomp(e->re.group.expr.rex, sp, type, delimiter, flags))
+ return 1;
+ meta(sp, ')', type, 1, delimiter);
+ break;
+ case REX_GROUP_COND:
+ meta(sp, '(', type, 1, delimiter);
+ sfputc(sp, '?');
+ if (e->re.group.expr.binary.left && decomp(e->re.group.expr.binary.left, sp, type, delimiter, flags))
+ return 1;
+ if (q = e->re.group.expr.binary.right)
+ {
+ sfputc(sp, ':');
+ if (q->re.group.expr.binary.left && decomp(q->re.group.expr.binary.left, sp, type, delimiter, flags))
+ return 1;
+ sfputc(sp, ':');
+ if (q->re.group.expr.binary.right && decomp(q->re.group.expr.binary.right, sp, type, delimiter, flags))
+ return 1;
+ }
+ meta(sp, ')', type, 1, delimiter);
+ break;
+ case REX_GROUP_CUT:
+ meta(sp, '(', type, 1, delimiter);
+ sfputc(sp, '?');
+ if (decomp(e->re.group.expr.rex, sp, type, delimiter, flags))
+ return 1;
+ meta(sp, ')', type, 1, delimiter);
+ break;
+ case REX_BM:
+ break;
+ default:
+ sfprintf(sp, "<ERROR:REX_%d>", e->type);
+ break;
+ }
+ } while (e = e->next);
+ return 0;
+}
+
+/*
+ * reconstruct pattern from compiled re p into sp
+ */
+
+size_t
+regdecomp(regex_t* p, regflags_t flags, char* buf, size_t n)
+{
+ Sfio_t* sp;
+ char* s;
+ int type;
+ int delimiter;
+ size_t r;
+
+ if (!(sp = sfstropen()))
+ return 0;
+ if (flags == (regflags_t)~0)
+ flags = p->env->flags;
+ switch (flags & (REG_AUGMENTED|REG_EXTENDED|REG_SHELL))
+ {
+ case 0:
+ type = BRE;
+ break;
+ case REG_AUGMENTED:
+ case REG_AUGMENTED|REG_EXTENDED:
+ type = ARE;
+ break;
+ case REG_EXTENDED:
+ type = ERE;
+ break;
+ case REG_SHELL:
+ type = SRE;
+ break;
+ default:
+ type = KRE;
+ break;
+ }
+ if (flags & REG_DELIMITED)
+ {
+ delimiter = '/';
+ sfputc(sp, delimiter);
+ }
+ else
+ delimiter = -1;
+ if (decomp(p->env->rex, sp, type, delimiter, flags))
+ r = 0;
+ else
+ {
+ if (delimiter > 0)
+ sfputc(sp, delimiter);
+ if ((r = sfstrtell(sp) + 1) <= n)
+ {
+ if (!(s = sfstruse(sp)))
+ r = 0;
+ else
+ memcpy(buf, s, r);
+ }
+ }
+ sfstrclose(sp);
+ return r;
+}
diff --git a/src/lib/libast/regex/regerror.c b/src/lib/libast/regex/regerror.c
new file mode 100644
index 0000000..3d0e40d
--- /dev/null
+++ b/src/lib/libast/regex/regerror.c
@@ -0,0 +1,95 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * posix regex error message handler
+ */
+
+static const char id[] = "\n@(#)$Id: regex (AT&T Research) 2010-09-22 $\0\n";
+
+#include "reglib.h"
+
+static const char* reg_error[] =
+{
+ /* REG_ENOSYS */ "not supported",
+ /* REG_SUCCESS */ "success",
+ /* REG_NOMATCH */ "no match",
+ /* REG_BADPAT */ "invalid regular expression",
+ /* REG_ECOLLATE */ "invalid collation element",
+ /* REG_ECTYPE */ "invalid character class",
+ /* REG_EESCAPE */ "trailing \\ in pattern",
+ /* REG_ESUBREG */ "invalid \\digit backreference",
+ /* REG_EBRACK */ "[...] imbalance",
+ /* REG_EPAREN */ "\\(...\\) or (...) imbalance",
+ /* REG_EBRACE */ "\\{...\\} or {...} imbalance",
+ /* REG_BADBR */ "invalid {...} digits",
+ /* REG_ERANGE */ "invalid [...] range endpoint",
+ /* REG_ESPACE */ "out of space",
+ /* REG_BADRPT */ "unary op not preceded by re",
+ /* REG_ENULL */ "empty subexpr in pattern",
+ /* REG_ECOUNT */ "re component count overflow",
+ /* REG_BADESC */ "invalid \\char escape",
+ /* REG_VERSIONID*/ &id[10],
+ /* REG_EFLAGS */ "conflicting flags",
+ /* REG_EDELIM */ "invalid or omitted delimiter",
+ /* REG_PANIC */ "unrecoverable internal error",
+};
+
+size_t
+regerror(int code, const regex_t* p, char* buf, size_t size)
+{
+ const char* s;
+
+ NoP(p);
+ if (code++ == REG_VERSIONID)
+ s = (const char*)fmtident(&id[1]);
+ else if (code >= 0 && code < elementsof(reg_error))
+ s = reg_error[code];
+ else
+ s = (const char*)"unknown error";
+ if (size)
+ {
+ strlcpy(buf, s, size);
+ buf[size - 1] = 0;
+ }
+ else
+ buf = (char*)s;
+ return strlen(buf) + 1;
+}
+
+/*
+ * discipline error intercept
+ */
+
+int
+fatal(regdisc_t* disc, int code, const char* pattern)
+{
+ if (disc->re_errorf)
+ {
+ if (pattern)
+ (*disc->re_errorf)(NiL, disc, disc->re_errorlevel, "regular expression: %s: %s", pattern, reg_error[code+1]);
+ else
+ (*disc->re_errorf)(NiL, disc, disc->re_errorlevel, "regular expression: %s", reg_error[code+1]);
+ }
+ return code;
+}
diff --git a/src/lib/libast/regex/regexec.c b/src/lib/libast/regex/regexec.c
new file mode 100644
index 0000000..fb8f428
--- /dev/null
+++ b/src/lib/libast/regex/regexec.c
@@ -0,0 +1,54 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * posix regex executor
+ * single unsized-string interface
+ */
+
+#include "reglib.h"
+
+/*
+ * standard wrapper for the sized-record interface
+ */
+
+int
+regexec(const regex_t* p, const char* s, size_t nmatch, regmatch_t* match, regflags_t flags)
+{
+ if (flags & REG_STARTEND)
+ {
+ int r;
+ int m = match->rm_so;
+ regmatch_t* e;
+
+ if (!(r = regnexec(p, s + m, match->rm_eo - m, nmatch, match, flags)) && m > 0)
+ for (e = match + nmatch; match < e; match++)
+ if (match->rm_so >= 0)
+ {
+ match->rm_so += m;
+ match->rm_eo += m;
+ }
+ return r;
+ }
+ return regnexec(p, s, s ? strlen(s) : 0, nmatch, match, flags);
+}
diff --git a/src/lib/libast/regex/regfatal.c b/src/lib/libast/regex/regfatal.c
new file mode 100644
index 0000000..09e8689
--- /dev/null
+++ b/src/lib/libast/regex/regfatal.c
@@ -0,0 +1,49 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * posix regex fatal error interface to error()
+ */
+
+#include "reglib.h"
+
+#include <error.h>
+
+void
+regfatalpat(regex_t* p, int level, int code, const char* pat)
+{
+ char buf[128];
+
+ regerror(code, p, buf, sizeof(buf));
+ regfree(p);
+ if (pat)
+ error(level, "regular expression: %s: %s", pat, buf);
+ else
+ error(level, "regular expression: %s", buf);
+}
+
+void
+regfatal(regex_t* p, int level, int code)
+{
+ regfatalpat(p, level, code, NiL);
+}
diff --git a/src/lib/libast/regex/reginit.c b/src/lib/libast/regex/reginit.c
new file mode 100644
index 0000000..e4719b4
--- /dev/null
+++ b/src/lib/libast/regex/reginit.c
@@ -0,0 +1,412 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * posix regex state and alloc
+ */
+
+#include "reglib.h"
+
+#if _PACKAGE_ast
+
+#include <ccode.h>
+
+#else
+
+#define CC_bel '\a'
+#define CC_esc '\033'
+#define CC_vt '\v'
+
+#endif
+
+/*
+ * state shared by all threads
+ */
+
+State_t state =
+{
+ { -1, -1 },
+
+ /*
+ * escape code table
+ * the "funny" things get special treatment at ends of BRE
+ *
+ * BRE 0:normal 1:escaped 2:escaped-char-class
+ * ERE 3:normal 4:escaped 5:escaped-char-class
+ * ARE 6:normal 7:escaped 8:escaped-char-class
+ * SRE 9:normal 10:escaped 11:escaped-char-class
+ * KRE 12:normal 13:escaped 14:escaped-char-class
+ */
+
+ '\\',
+ '\\', '\\', '\\',
+ '\\', '\\', '\\',
+ '\\', '\\', '\\',
+ '\\', '\\', '\\',
+ '\\', '\\', '\\',
+ '^', /* funny */
+ '^', '^', '^',
+ T_CFLX, '^', '^',
+ T_CFLX, '^', '^',
+ '^', '^', '^',
+ '^', '^', '^',
+ '.',
+ T_DOT, '.', T_BAD,
+ T_DOT, '.', T_BAD,
+ T_DOT, '.', T_BAD,
+ '.', '.', T_BAD,
+ '.', '.', T_BAD,
+ '$', /* funny */
+ '$', '$', T_BAD,
+ T_DOLL, '$', T_BAD,
+ T_DOLL, '$', T_BAD,
+ '$', '$', T_BAD,
+ '$', '$', T_BAD,
+ '*',
+ T_STAR, '*', T_BAD,
+ T_STAR, '*', T_BAD,
+ T_STAR, '*', T_BAD,
+ T_STAR, '*', '*',
+ T_STAR, '*', '*',
+ '[',
+ T_BRA, '[', '[',
+ T_BRA, '[', '[',
+ T_BRA, '[', '[',
+ T_BRA, '[', '[',
+ T_BRA, '[', '[',
+ '|',
+ '|', T_BAD, T_BAD,
+ T_BAR, '|', T_BAD,
+ T_BAR, '|', T_BAD,
+ '|', '|', T_BAD,
+ T_BAR, '|', T_BAD,
+ '+',
+ '+', T_BAD, T_BAD,
+ T_PLUS, '+', T_BAD,
+ T_PLUS, '+', T_BAD,
+ '+', '+', T_BAD,
+ T_PLUS, '+', T_BAD,
+ '?',
+ '?', T_BAD, T_BAD,
+ T_QUES, '?', T_BAD,
+ T_QUES, '?', T_BAD,
+ T_QUES, '?', '?',
+ T_QUES, '?', '?',
+ '(',
+ '(', T_OPEN, T_BAD,
+ T_OPEN, '(', T_BAD,
+ T_OPEN, '(', T_BAD,
+ '(', '(', '(',
+ T_OPEN, '(', '(',
+ ')',
+ ')', T_CLOSE, T_BAD,
+ T_CLOSE, ')', T_BAD,
+ T_CLOSE, ')', T_BAD,
+ ')', ')', ')',
+ T_CLOSE, ')', ')',
+ '{',
+ '{', T_LEFT, T_BAD,
+ T_LEFT, '{', T_BAD,
+ T_LEFT, '{', T_BAD,
+ '{', '{', '{',
+ T_LEFT, '{', '{',
+ '}',
+ '}', T_RIGHT, T_BAD,
+ '}', T_BAD, T_BAD,
+ '}', T_BAD, T_BAD,
+ '}', '}', '}',
+ '}', '}', '}',
+ '&',
+ '&', T_BAD, T_BAD,
+ '&', T_AND, T_BAD,
+ T_AND, '&', T_BAD,
+ '&', '&', T_BAD,
+ T_AND, '&', T_BAD,
+ '!',
+ '!', T_BAD, T_BAD,
+ '!', T_BANG, T_BAD,
+ T_BANG, '!', T_BAD,
+ '!', '!', T_BAD,
+ T_BANG, '!', T_BAD,
+ '@',
+ '@', T_BAD, T_BAD,
+ '@', T_BAD, T_BAD,
+ '@', T_BAD, T_BAD,
+ '@', '@', T_BAD,
+ T_AT, '@', T_BAD,
+ '~',
+ '~', T_BAD, T_BAD,
+ '~', T_BAD, T_BAD,
+ '~', T_BAD, T_BAD,
+ '~', '~', T_BAD,
+ T_TILDE, '~', T_BAD,
+ '%',
+ '%', T_BAD, T_BAD,
+ '%', T_BAD, T_BAD,
+ '%', T_BAD, T_BAD,
+ '%', '%', T_BAD,
+ T_PERCENT, '%', T_BAD,
+ '<',
+ '<', T_LT, T_BAD,
+ '<', T_LT, T_BAD,
+ T_LT, '<', T_BAD,
+ '<', '<', T_BAD,
+ '<', '<', T_BAD,
+ '>',
+ '>', T_GT, T_BAD,
+ '>', T_GT, T_BAD,
+ T_GT, '>', T_BAD,
+ '>', '>', T_BAD,
+ '>', '>', T_BAD,
+
+ /* backrefs */
+
+ '0',
+ '0', T_BACK+0, T_ESCAPE,
+ '0', T_BACK+0, T_ESCAPE,
+ '0', T_BACK+0, T_ESCAPE,
+ '0', T_BACK+0, T_ESCAPE,
+ '0', T_BACK+0, T_ESCAPE,
+ '1',
+ '1', T_BACK+1, T_ESCAPE,
+ '1', T_BACK+1, T_ESCAPE,
+ '1', T_BACK+1, T_ESCAPE,
+ '1', T_BACK+1, T_ESCAPE,
+ '1', T_BACK+1, T_ESCAPE,
+ '2',
+ '2', T_BACK+2, T_ESCAPE,
+ '2', T_BACK+2, T_ESCAPE,
+ '2', T_BACK+2, T_ESCAPE,
+ '2', T_BACK+2, T_ESCAPE,
+ '2', T_BACK+2, T_ESCAPE,
+ '3',
+ '3', T_BACK+3, T_ESCAPE,
+ '3', T_BACK+3, T_ESCAPE,
+ '3', T_BACK+3, T_ESCAPE,
+ '3', T_BACK+3, T_ESCAPE,
+ '3', T_BACK+3, T_ESCAPE,
+ '4',
+ '4', T_BACK+4, T_ESCAPE,
+ '4', T_BACK+4, T_ESCAPE,
+ '4', T_BACK+4, T_ESCAPE,
+ '4', T_BACK+4, T_ESCAPE,
+ '4', T_BACK+4, T_ESCAPE,
+ '5',
+ '5', T_BACK+5, T_ESCAPE,
+ '5', T_BACK+5, T_ESCAPE,
+ '5', T_BACK+5, T_ESCAPE,
+ '5', T_BACK+5, T_ESCAPE,
+ '5', T_BACK+5, T_ESCAPE,
+ '6',
+ '6', T_BACK+6, T_ESCAPE,
+ '6', T_BACK+6, T_ESCAPE,
+ '6', T_BACK+6, T_ESCAPE,
+ '6', T_BACK+6, T_ESCAPE,
+ '6', T_BACK+6, T_ESCAPE,
+ '7',
+ '7', T_BACK+7, T_ESCAPE,
+ '7', T_BACK+7, T_ESCAPE,
+ '7', T_BACK+7, T_ESCAPE,
+ '7', T_BACK+7, T_ESCAPE,
+ '7', T_BACK+7, T_ESCAPE,
+ '8',
+ '8', T_BACK+8, T_ESCAPE,
+ '8', T_BACK+8, T_ESCAPE,
+ '8', T_BACK+8, T_ESCAPE,
+ '8', '8', T_ESCAPE,
+ '8', T_BACK+8, T_ESCAPE,
+ '9',
+ '9', T_BACK+9, T_ESCAPE,
+ '9', T_BACK+9, T_ESCAPE,
+ '9', T_BACK+9, T_ESCAPE,
+ '9', '9', T_ESCAPE,
+ '9', T_BACK+9, T_ESCAPE,
+
+ /* perl */
+
+ 'A',
+ 'A', T_BEG_STR, T_BAD,
+ 'A', T_BEG_STR, T_BAD,
+ 'A', T_BEG_STR, T_BAD,
+ 'A', T_BEG_STR, T_BAD,
+ 'A', T_BEG_STR, T_BAD,
+ 'b',
+ 'b', T_WORD, '\b',
+ 'b', T_WORD, '\b',
+ 'b', T_WORD, '\b',
+ 'b', T_WORD, '\b',
+ 'b', T_WORD, '\b',
+ 'B',
+ 'B', T_WORD_NOT, T_BAD,
+ 'B', T_WORD_NOT, T_BAD,
+ 'B', T_WORD_NOT, T_BAD,
+ 'B', T_WORD_NOT, T_BAD,
+ 'B', T_WORD_NOT, T_BAD,
+ 'd',
+ 'd', T_DIGIT, T_DIGIT,
+ 'd', T_DIGIT, T_DIGIT,
+ 'd', T_DIGIT, T_DIGIT,
+ 'd', T_DIGIT, T_DIGIT,
+ 'd', T_DIGIT, T_DIGIT,
+ 'D',
+ 'D', T_DIGIT_NOT, T_DIGIT_NOT,
+ 'D', T_DIGIT_NOT, T_DIGIT_NOT,
+ 'D', T_DIGIT_NOT, T_DIGIT_NOT,
+ 'D', T_DIGIT_NOT, T_DIGIT_NOT,
+ 'D', T_DIGIT_NOT, T_DIGIT_NOT,
+ 's',
+ 's', T_SPACE, T_SPACE,
+ 's', T_SPACE, T_SPACE,
+ 's', T_SPACE, T_SPACE,
+ 's', T_SPACE, T_SPACE,
+ 's', T_SPACE, T_SPACE,
+ 'S',
+ 'S', T_SPACE_NOT, T_SPACE_NOT,
+ 'S', T_SPACE_NOT, T_SPACE_NOT,
+ 'S', T_SPACE_NOT, T_SPACE_NOT,
+ 'S', T_SPACE_NOT, T_SPACE_NOT,
+ 'S', T_SPACE_NOT, T_SPACE_NOT,
+ 'w',
+ 'w', T_ALNUM, T_ALNUM,
+ 'w', T_ALNUM, T_ALNUM,
+ 'w', T_ALNUM, T_ALNUM,
+ 'w', T_ALNUM, T_ALNUM,
+ 'w', T_ALNUM, T_ALNUM,
+ 'W',
+ 'W', T_ALNUM_NOT, T_ALNUM_NOT,
+ 'W', T_ALNUM_NOT, T_ALNUM_NOT,
+ 'W', T_ALNUM_NOT, T_ALNUM_NOT,
+ 'W', T_ALNUM_NOT, T_ALNUM_NOT,
+ 'W', T_ALNUM_NOT, T_ALNUM_NOT,
+ 'z',
+ 'z', T_FIN_STR, T_BAD,
+ 'z', T_FIN_STR, T_BAD,
+ 'z', T_FIN_STR, T_BAD,
+ 'z', T_FIN_STR, T_BAD,
+ 'z', T_FIN_STR, T_BAD,
+ 'Z',
+ 'Z', T_END_STR, T_BAD,
+ 'Z', T_END_STR, T_BAD,
+ 'Z', T_END_STR, T_BAD,
+ 'Z', T_END_STR, T_BAD,
+ 'Z', T_END_STR, T_BAD,
+
+ /* C escapes */
+
+ 'a',
+ 'a', CC_bel, CC_bel,
+ 'a', CC_bel, CC_bel,
+ 'a', CC_bel, CC_bel,
+ 'a', CC_bel, CC_bel,
+ 'a', CC_bel, CC_bel,
+ 'c',
+ 'c', T_ESCAPE, T_ESCAPE,
+ 'c', T_ESCAPE, T_ESCAPE,
+ 'c', T_ESCAPE, T_ESCAPE,
+ 'c', T_ESCAPE, T_ESCAPE,
+ 'c', T_ESCAPE, T_ESCAPE,
+ 'C',
+ 'C', T_ESCAPE, T_ESCAPE,
+ 'C', T_ESCAPE, T_ESCAPE,
+ 'C', T_ESCAPE, T_ESCAPE,
+ 'C', T_ESCAPE, T_ESCAPE,
+ 'C', T_ESCAPE, T_ESCAPE,
+ 'e',
+ 'e', CC_esc, CC_esc,
+ 'e', CC_esc, CC_esc,
+ 'e', CC_esc, CC_esc,
+ 'e', CC_esc, CC_esc,
+ 'e', CC_esc, CC_esc,
+ 'E',
+ 'E', CC_esc, CC_esc,
+ 'E', CC_esc, CC_esc,
+ 'E', CC_esc, CC_esc,
+ 'E', CC_esc, CC_esc,
+ 'E', CC_esc, CC_esc,
+ 'f',
+ 'f', '\f', '\f',
+ 'f', '\f', '\f',
+ 'f', '\f', '\f',
+ 'f', '\f', '\f',
+ 'f', '\f', '\f',
+ 'n',
+ 'n', '\n', '\n',
+ 'n', '\n', '\n',
+ 'n', '\n', '\n',
+ 'n', '\n', '\n',
+ 'n', '\n', '\n',
+ 'r',
+ 'r', '\r', '\r',
+ 'r', '\r', '\r',
+ 'r', '\r', '\r',
+ 'r', '\r', '\r',
+ 'r', '\r', '\r',
+ 't',
+ 't', '\t', '\t',
+ 't', '\t', '\t',
+ 't', '\t', '\t',
+ 't', '\t', '\t',
+ 't', '\t', '\t',
+ 'v',
+ 'v', CC_vt, CC_vt,
+ 'v', CC_vt, CC_vt,
+ 'v', CC_vt, CC_vt,
+ 'v', CC_vt, CC_vt,
+ 'v', CC_vt, CC_vt,
+ 'x',
+ 'x', T_ESCAPE, T_ESCAPE,
+ 'x', T_ESCAPE, T_ESCAPE,
+ 'x', T_ESCAPE, T_ESCAPE,
+ 'x', T_ESCAPE, T_ESCAPE,
+ 'x', T_ESCAPE, T_ESCAPE,
+};
+
+/*
+ * all allocation/free done here
+ * interface compatible with vmresize()
+ *
+ * malloc(n) alloc(0,n)
+ * realloc(p,n) alloc(p,n)
+ * free(p) alloc(p,0)
+ */
+
+void*
+alloc(register regdisc_t* disc, void* p, size_t n)
+{
+ if (disc->re_resizef)
+ {
+ if (!n && (disc->re_flags & REG_NOFREE))
+ return 0;
+ return (*disc->re_resizef)(disc->re_resizehandle, p, n);
+ }
+ else if (!n)
+ {
+ if (!(disc->re_flags & REG_NOFREE))
+ free(p);
+ return 0;
+ }
+ else if (p)
+ return realloc(p, n);
+ else
+ return malloc(n);
+}
diff --git a/src/lib/libast/regex/reglib.h b/src/lib/libast/regex/reglib.h
new file mode 100644
index 0000000..6b84e5d
--- /dev/null
+++ b/src/lib/libast/regex/reglib.h
@@ -0,0 +1,582 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * posix regex implementation
+ *
+ * based on Doug McIlroy's C++ implementation
+ * Knuth-Morris-Pratt adapted from Corman-Leiserson-Rivest
+ * Boyer-Moore from conversations with David Korn, Phong Vo, Andrew Hume
+ */
+
+#ifndef _REGLIB_H
+#define _REGLIB_H
+
+#define REG_VERSION_EXEC 20020509L
+#define REG_VERSION_MAP 20030916L /* regdisc_t.re_map */
+
+#define re_info env
+
+#define alloc _reg_alloc
+#define classfun _reg_classfun
+#define drop _reg_drop
+#define fatal _reg_fatal
+#define state _reg_state
+
+typedef struct regsubop_s
+{
+ int op; /* REG_SUB_LOWER,REG_SUB_UPPER */
+ int off; /* re_rhs or match[] offset */
+ int len; /* re_rhs len or len==0 match[] */
+} regsubop_t;
+
+#define _REG_SUB_PRIVATE_ \
+ char* re_cur; /* re_buf cursor */ \
+ char* re_end; /* re_buf end */ \
+ regsubop_t* re_ops; /* rhs ops */ \
+ char re_rhs[1]; /* substitution rhs */
+
+#include <ast.h>
+#include <cdt.h>
+#include <stk.h>
+
+#include "regex.h"
+
+#include <ctype.h>
+#include <errno.h>
+
+#if _BLD_DEBUG && !defined(_AST_REGEX_DEBUG)
+#define _AST_REGEX_DEBUG 1
+#endif
+
+#define MBSIZE(p) ((ast.tmp_int=mbsize(p))>0?ast.tmp_int:1)
+
+#undef RE_DUP_MAX /* posix puts this in limits.h! */
+#define RE_DUP_MAX (INT_MAX/2-1) /* 2*RE_DUP_MAX won't overflow */
+#define RE_DUP_INF (RE_DUP_MAX+1) /* infinity, for * */
+#define BACK_REF_MAX 9
+
+#define REG_COMP (~REG_EXEC)
+#define REG_EXEC (REG_ADVANCE|REG_INVERT|REG_NOTBOL|REG_NOTEOL|REG_STARTEND)
+
+#define REX_NULL 0 /* null string (internal) */
+#define REX_ALT 1 /* a|b */
+#define REX_ALT_CATCH 2 /* REX_ALT catcher */
+#define REX_BACK 3 /* \1, \2, etc */
+#define REX_BEG 4 /* initial ^ */
+#define REX_BEG_STR 5 /* initial ^ w/ no newline */
+#define REX_BM 6 /* Boyer-Moore */
+#define REX_CAT 7 /* catenation catcher */
+#define REX_CLASS 8 /* [...] */
+#define REX_COLL_CLASS 9 /* collation order [...] */
+#define REX_CONJ 10 /* a&b */
+#define REX_CONJ_LEFT 11 /* REX_CONJ left catcher */
+#define REX_CONJ_RIGHT 12 /* REX_CONJ right catcher */
+#define REX_DONE 13 /* completed match (internal) */
+#define REX_DOT 14 /* . */
+#define REX_END 15 /* final $ */
+#define REX_END_STR 16 /* final $ before tail newline */
+#define REX_EXEC 17 /* call re.re_exec() */
+#define REX_FIN_STR 18 /* final $ w/ no newline */
+#define REX_GROUP 19 /* \(...\) */
+#define REX_GROUP_CATCH 20 /* REX_GROUP catcher */
+#define REX_GROUP_AHEAD 21 /* 0-width lookahead */
+#define REX_GROUP_AHEAD_CATCH 22 /* REX_GROUP_AHEAD catcher */
+#define REX_GROUP_AHEAD_NOT 23 /* inverted 0-width lookahead */
+#define REX_GROUP_BEHIND 24 /* 0-width lookbehind */
+#define REX_GROUP_BEHIND_CATCH 25 /* REX_GROUP_BEHIND catcher */
+#define REX_GROUP_BEHIND_NOT 26 /* inverted 0-width lookbehind */
+#define REX_GROUP_BEHIND_NOT_CATCH 27 /* REX_GROUP_BEHIND_NOT catcher */
+#define REX_GROUP_COND 28 /* conditional group */
+#define REX_GROUP_COND_CATCH 29 /* conditional group catcher */
+#define REX_GROUP_CUT 30 /* don't backtrack over this */
+#define REX_GROUP_CUT_CATCH 31 /* REX_GROUP_CUT catcher */
+#define REX_KMP 32 /* Knuth-Morris-Pratt */
+#define REX_NEG 33 /* negation */
+#define REX_NEG_CATCH 34 /* REX_NEG catcher */
+#define REX_NEST 35 /* nested match */
+#define REX_ONECHAR 36 /* a single-character literal */
+#define REX_REP 37 /* Kleene closure */
+#define REX_REP_CATCH 38 /* REX_REP catcher */
+#define REX_STRING 39 /* some chars */
+#define REX_TRIE 40 /* alternation of strings */
+#define REX_WBEG 41 /* \< */
+#define REX_WEND 42 /* \> */
+#define REX_WORD 43 /* word boundary */
+#define REX_WORD_NOT 44 /* not word boundary */
+
+#define T_META ((int)UCHAR_MAX+1)
+#define T_STAR (T_META+0)
+#define T_PLUS (T_META+1)
+#define T_QUES (T_META+2)
+#define T_BANG (T_META+3)
+#define T_AT (T_META+4)
+#define T_TILDE (T_META+5)
+#define T_PERCENT (T_META+6)
+#define T_LEFT (T_META+7)
+#define T_OPEN (T_META+8)
+#define T_CLOSE (T_OPEN+1)
+#define T_RIGHT (T_OPEN+2)
+#define T_CFLX (T_OPEN+3)
+#define T_DOT (T_OPEN+4)
+#define T_DOTSTAR (T_OPEN+5)
+#define T_END (T_OPEN+6)
+#define T_BAD (T_OPEN+7)
+#define T_DOLL (T_OPEN+8)
+#define T_BRA (T_OPEN+9)
+#define T_BAR (T_OPEN+10)
+#define T_AND (T_OPEN+11)
+#define T_LT (T_OPEN+12)
+#define T_GT (T_OPEN+13)
+#define T_SLASHPLUS (T_OPEN+14)
+#define T_GROUP (T_OPEN+15)
+#define T_WORD (T_OPEN+16)
+#define T_WORD_NOT (T_WORD+1)
+#define T_BEG_STR (T_WORD+2)
+#define T_END_STR (T_WORD+3)
+#define T_FIN_STR (T_WORD+4)
+#define T_ESCAPE (T_WORD+5)
+#define T_ALNUM (T_WORD+6)
+#define T_ALNUM_NOT (T_ALNUM+1)
+#define T_DIGIT (T_ALNUM+2)
+#define T_DIGIT_NOT (T_ALNUM+3)
+#define T_SPACE (T_ALNUM+4)
+#define T_SPACE_NOT (T_ALNUM+5)
+#define T_BACK (T_ALNUM+6)
+
+#define BRE 0
+#define ERE 3
+#define ARE 6
+#define SRE 9
+#define KRE 12
+
+#define HIT SSIZE_MAX
+
+#define bitclr(p,c) ((p)[((c)>>3)&037]&=(~(1<<((c)&07))))
+#define bitset(p,c) ((p)[((c)>>3)&037]|=(1<<((c)&07)))
+#define bittst(p,c) ((p)[((c)>>3)&037]&(1<<((c)&07)))
+
+#define setadd(p,c) bitset((p)->bits,c)
+#define setclr(p,c) bitclr((p)->bits,c)
+#define settst(p,c) bittst((p)->bits,c)
+
+#if _hdr_wchar && _lib_wctype && _lib_iswctype
+
+#include <stdio.h> /* because <wchar.h> includes it and we generate it */
+#include <wchar.h>
+#if _hdr_wctype
+#include <wctype.h>
+#endif
+
+#if !defined(iswblank) && !_lib_iswblank
+#define _need_iswblank 1
+#define iswblank(x) _reg_iswblank(x)
+extern int _reg_iswblank(wint_t);
+#endif
+
+#if !defined(towupper) && !_lib_towupper
+#define towupper(x) toupper(x)
+#endif
+
+#if !defined(towlower) && !_lib_towlower
+#define towlower(x) tolower(x)
+#endif
+
+#else
+
+#undef _lib_wctype
+
+#ifndef iswalnum
+#define iswalnum(x) isalnum(x)
+#endif
+#ifndef iswalpha
+#define iswalpha(x) isalpha(x)
+#endif
+#ifndef iswcntrl
+#define iswcntrl(x) iscntrl(x)
+#endif
+#ifndef iswdigit
+#define iswdigit(x) isdigit(x)
+#endif
+#ifndef iswgraph
+#define iswgraph(x) isgraph(x)
+#endif
+#ifndef iswlower
+#define iswlower(x) islower(x)
+#endif
+#ifndef iswprint
+#define iswprint(x) isprint(x)
+#endif
+#ifndef iswpunct
+#define iswpunct(x) ispunct(x)
+#endif
+#ifndef iswspace
+#define iswspace(x) isspace(x)
+#endif
+#ifndef iswupper
+#define iswupper(x) isupper(x)
+#endif
+#ifndef iswxdigit
+#define iswxdigit(x) isxdigit(x)
+#endif
+
+#ifndef towlower
+#define towlower(x) tolower(x)
+#endif
+#ifndef towupper
+#define towupper(x) toupper(x)
+#endif
+
+#endif
+
+#ifndef iswblank
+#define iswblank(x) ((x)==' '||(x)=='\t')
+#endif
+
+#ifndef iswgraph
+#define iswgraph(x) (iswprint(x)&&!iswblank(x))
+#endif
+
+#define isword(x) (isalnum(x)||(x)=='_')
+
+/*
+ * collation element support
+ */
+
+#define COLL_KEY_MAX 32
+
+#if COLL_KEY_MAX < MB_LEN_MAX
+#undef COLL_KEY_MAX
+#define COLL_KEY_MAX MB_LEN_MAX
+#endif
+
+typedef unsigned char Ckey_t[COLL_KEY_MAX+1];
+
+#define COLL_end 0
+#define COLL_call 1
+#define COLL_char 2
+#define COLL_range 3
+#define COLL_range_lc 4
+#define COLL_range_uc 5
+
+typedef struct Celt_s
+{
+ short typ;
+ short min;
+ short max;
+ regclass_t fun;
+ Ckey_t beg;
+ Ckey_t end;
+} Celt_t;
+
+/*
+ * private stuff hanging off regex_t
+ */
+
+typedef struct Stk_pos_s
+{
+ off_t offset;
+ char* base;
+} Stk_pos_t;
+
+typedef struct Vector_s
+{
+ Stk_t* stk; /* stack pointer */
+ char* vec; /* the data */
+ int inc; /* growth increment */
+ int siz; /* element size */
+ int max; /* max index */
+ int cur; /* current index -- user domain */
+} Vector_t;
+
+/*
+ * Rex_t subtypes
+ */
+
+typedef struct Cond_s
+{
+ unsigned char* beg; /* beginning of next match */
+ struct Rex_s* next[2]; /* 0:no 1:yes next pattern */
+ struct Rex_s* cont; /* right catcher */
+ int yes; /* yes condition hit */
+} Cond_t;
+
+typedef struct Conj_left_s
+{
+ unsigned char* beg; /* beginning of left match */
+ struct Rex_s* right; /* right pattern */
+ struct Rex_s* cont; /* right catcher */
+} Conj_left_t;
+
+typedef struct Conj_right_s
+{
+ unsigned char* end; /* end of left match */
+ struct Rex_s* cont; /* ambient continuation */
+} Conj_right_t;
+
+typedef unsigned int Bm_mask_t;
+
+typedef struct Bm_s
+{
+ Bm_mask_t** mask;
+ size_t* skip;
+ size_t* fail;
+ size_t size;
+ ssize_t back;
+ ssize_t left;
+ ssize_t right;
+ size_t complete;
+} Bm_t;
+
+typedef struct String_s
+{
+ int* fail;
+ unsigned char* base;
+ size_t size;
+} String_t;
+
+typedef struct Set_s
+{
+ unsigned char bits[(UCHAR_MAX+1)/CHAR_BIT];
+} Set_t;
+
+typedef struct Collate_s
+{
+ int invert;
+ Celt_t* elements;
+} Collate_t;
+
+typedef struct Binary_s
+{
+ struct Rex_s* left;
+ struct Rex_s* right;
+ int serial;
+} Binary_t;
+
+typedef struct Group_s
+{
+ int number; /* group number */
+ int last; /* last contained group number */
+ int size; /* lookbehind size */
+ int back; /* backreferenced */
+ regflags_t flags; /* group flags */
+ union
+ {
+ Binary_t binary;
+ struct Rex_s* rex;
+ } expr;
+} Group_t;
+
+typedef struct Exec_s
+{
+ void* data;
+ const char* text;
+ size_t size;
+} Exec_t;
+
+#define REX_NEST_open 0x01
+#define REX_NEST_close 0x02
+#define REX_NEST_escape 0x04
+#define REX_NEST_quote 0x08
+#define REX_NEST_literal 0x10
+#define REX_NEST_delimiter 0x20
+#define REX_NEST_terminator 0x40
+#define REX_NEST_separator 0x80
+
+#define REX_NEST_SHIFT 8
+
+typedef struct Nest_s
+{
+ int primary;
+ unsigned short none; /* for Nest_t.type[-1] */
+ unsigned short type[1];
+} Nest_t;
+
+/*
+ * REX_ALT catcher, solely to get control at the end of an
+ * alternative to keep records for comparing matches.
+ */
+
+typedef struct Alt_catch_s
+{
+ struct Rex_s* cont;
+} Alt_catch_t;
+
+typedef struct Group_catch_s
+{
+ struct Rex_s* cont;
+ regoff_t* eo;
+} Group_catch_t;
+
+typedef struct Behind_catch_s
+{
+ struct Rex_s* cont;
+ unsigned char* beg;
+ unsigned char* end;
+} Behind_catch_t;
+
+/*
+ * REX_NEG catcher determines what string lengths can be matched,
+ * then Neg investigates continuations of other lengths.
+ * This is inefficient. For !POSITIONS expressions, we can do better:
+ * since matches to rex will be enumerated in decreasing order,
+ * we can investigate continuations whenever a length is skipped.
+ */
+
+typedef struct Neg_catch_s
+{
+ unsigned char* beg;
+ unsigned char* index;
+} Neg_catch_t;
+
+/*
+ * REX_REP catcher. One is created on the stack for
+ * each iteration of a complex repetition.
+ */
+
+typedef struct Rep_catch_s
+{
+ struct Rex_s* cont;
+ struct Rex_s* ref;
+ unsigned char* beg;
+ int n;
+} Rep_catch_t;
+
+/*
+ * data structure for an alternation of pure strings
+ * son points to a subtree of all strings with a common
+ * prefix ending in character c. sib links alternate
+ * letters in the same position of a word. end=1 if
+ * some word ends with c. the order of strings is
+ * irrelevant, except long words must be investigated
+ * before short ones.
+ */
+
+typedef struct Trie_node_s
+{
+ unsigned char c;
+ unsigned char end;
+ struct Trie_node_s* son;
+ struct Trie_node_s* sib;
+} Trie_node_t;
+
+typedef struct Trie_s
+{
+ Trie_node_t** root;
+ int min;
+ int max;
+} Trie_t;
+
+/*
+ * Rex_t is a node in a regular expression
+ */
+
+typedef struct Rex_s
+{
+ unsigned char type; /* node type */
+ unsigned char marked; /* already marked */
+ short serial; /* subpattern number */
+ regflags_t flags; /* scoped flags */
+ int explicit; /* scoped explicit match*/
+ struct Rex_s* next; /* remaining parts */
+ int lo; /* lo dup count */
+ int hi; /* hi dup count */
+ unsigned char* map; /* fold and/or ccode map*/
+ union
+ {
+ Alt_catch_t alt_catch; /* alt catcher */
+ Bm_t bm; /* bm */
+ Behind_catch_t behind_catch; /* behind catcher */
+ Set_t* charclass; /* char class */
+ Collate_t collate; /* collation class */
+ Cond_t cond_catch; /* cond catcher */
+ Conj_left_t conj_left; /* conj left catcher */
+ Conj_right_t conj_right; /* conj right catcher */
+ void* data; /* data after Rex_t */
+ Exec_t exec; /* re.re_exec() args */
+ Group_t group; /* a|b or rep */
+ Group_catch_t group_catch; /* group catcher */
+ Neg_catch_t neg_catch; /* neg catcher */
+ Nest_t nest; /* nested match */
+ unsigned char onechar; /* single char */
+ Rep_catch_t rep_catch; /* rep catcher */
+ String_t string; /* string/kmp */
+ Trie_t trie; /* trie */
+ } re;
+} Rex_t;
+
+typedef struct reglib_s /* library private regex_t info */
+{
+ struct Rex_s* rex; /* compiled expression */
+ regdisc_t* disc; /* REG_DISCIPLINE discipline */
+ const regex_t* regex; /* from regexec */
+ unsigned char* beg; /* beginning of string */
+ unsigned char* end; /* end of string */
+ Vector_t* pos; /* posns of certain subpatterns */
+ Vector_t* bestpos; /* ditto for best match */
+ regmatch_t* match; /* subexrs in current match */
+ regmatch_t* best; /* ditto in best match yet */
+ Stk_pos_t stk; /* exec stack pos */
+ size_t min; /* minimum match length */
+ size_t nsub; /* internal re_nsub */
+ regflags_t flags; /* flags from regcomp() */
+ int error; /* last error */
+ int explicit; /* explicit match on this char */
+ int leading; /* leading match on this char */
+ int refs; /* regcomp()+regdup() references*/
+ Rex_t done; /* the last continuation */
+ regstat_t stats; /* for regstat() */
+ unsigned char fold[UCHAR_MAX+1]; /* REG_ICASE map */
+ unsigned char hard; /* hard comp */
+ unsigned char once; /* if 1st parse fails, quit */
+ unsigned char separate; /* cannot combine */
+ unsigned char stack; /* hard comp or exec */
+ unsigned char sub; /* re_sub is valid */
+ unsigned char test; /* debug/test bitmask */
+} Env_t;
+
+typedef struct State_s /* shared state */
+{
+ regmatch_t nomatch;
+ struct
+ {
+ unsigned char key;
+ short val[15];
+ } escape[52];
+ short* magic[UCHAR_MAX+1];
+ regdisc_t disc;
+ int fatal;
+ int initialized;
+ Dt_t* attrs;
+ Dt_t* names;
+ Dtdisc_t dtdisc;
+} State_t;
+
+extern State_t state;
+
+extern void* alloc(regdisc_t*, void*, size_t);
+extern regclass_t classfun(int);
+extern void drop(regdisc_t*, Rex_t*);
+extern int fatal(regdisc_t*, int, const char*);
+
+#endif
diff --git a/src/lib/libast/regex/regnexec.c b/src/lib/libast/regex/regnexec.c
new file mode 100644
index 0000000..0c3a0aa
--- /dev/null
+++ b/src/lib/libast/regex/regnexec.c
@@ -0,0 +1,2045 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * posix regex executor
+ * single sized-record interface
+ */
+
+#include "reglib.h"
+
+#if _AST_REGEX_DEBUG
+
+#define DEBUG_TEST(f,y,n) ((debug&(debug_flag=f))?(y):(n))
+#define DEBUG_CODE(f,y,n) do if(debug&(f)){y}else{n} while(0)
+#define DEBUG_INIT() do { char* t; if (!debug) { debug = 0x80000000; if (t = getenv("_AST_regex_exec_debug")) debug |= strtoul(t, NiL, 0); } } while (0)
+
+static unsigned long debug;
+static unsigned long debug_flag;
+
+static const char* rexnames[] =
+{
+ "REX_NULL",
+ "REX_ALT",
+ "REX_ALT_CATCH",
+ "REX_BACK",
+ "REX_BEG",
+ "REX_BEG_STR",
+ "REX_BM",
+ "REX_CAT",
+ "REX_CLASS",
+ "REX_COLL_CLASS",
+ "REX_CONJ",
+ "REX_CONJ_LEFT",
+ "REX_CONJ_RIGHT",
+ "REX_DONE",
+ "REX_DOT",
+ "REX_END",
+ "REX_END_STR",
+ "REX_EXEC",
+ "REX_FIN_STR",
+ "REX_GROUP",
+ "REX_GROUP_CATCH",
+ "REX_GROUP_AHEAD",
+ "REX_GROUP_AHEAD_CATCH",
+ "REX_GROUP_AHEAD_NOT",
+ "REX_GROUP_BEHIND",
+ "REX_GROUP_BEHIND_CATCH",
+ "REX_GROUP_BEHIND_NOT",
+ "REX_GROUP_BEHIND_NOT_CATCH",
+ "REX_GROUP_COND",
+ "REX_GROUP_COND_CATCH",
+ "REX_GROUP_CUT",
+ "REX_GROUP_CUT_CATCH",
+ "REX_KMP",
+ "REX_NEG",
+ "REX_NEG_CATCH",
+ "REX_NEST",
+ "REX_ONECHAR",
+ "REX_REP",
+ "REX_REP_CATCH",
+ "REX_STRING",
+ "REX_TRIE",
+ "REX_WBEG",
+ "REX_WEND",
+ "REX_WORD",
+ "REX_WORD_NOT"
+};
+
+static const char* rexname(Rex_t* rex)
+{
+ if (!rex)
+ return "NIL";
+ if (rex->type >= elementsof(rexnames))
+ return "ERROR";
+ return rexnames[rex->type];
+}
+
+#else
+
+#define DEBUG_INIT()
+#define DEBUG_TEST(f,y,n) (n)
+#define DEBUG_CODE(f,y,n) do {n} while(0)
+
+#endif
+
+#define BEG_ALT 1 /* beginning of an alt */
+#define BEG_ONE 2 /* beginning of one iteration of a rep */
+#define BEG_REP 3 /* beginning of a repetition */
+#define BEG_SUB 4 /* beginning of a subexpression */
+#define END_ANY 5 /* end of any of above */
+
+/*
+ * returns from parse()
+ */
+
+#define NONE 0 /* no parse found */
+#define GOOD 1 /* some parse was found */
+#define CUT 2 /* no match and no backtrack */
+#define BEST 3 /* an unbeatable parse was found */
+#define BAD 4 /* error ocurred */
+
+/*
+ * REG_SHELL_DOT test
+ */
+
+#define LEADING(e,r,s) (*(s)==(e)->leading&&((s)==(e)->beg||*((s)-1)==(r)->explicit))
+
+/*
+ * Pos_t is for comparing parses. An entry is made in the
+ * array at the beginning and at the end of each Group_t,
+ * each iteration in a Group_t, and each Binary_t.
+ */
+
+typedef struct
+{
+ unsigned char* p; /* where in string */
+ size_t length; /* length in string */
+ short serial; /* preorder subpattern number */
+ short be; /* which end of pair */
+} Pos_t;
+
+/* ===== begin library support ===== */
+
+#define vector(t,v,i) (((i)<(v)->max)?(t*)((v)->vec+(i)*(v)->siz):(t*)vecseek(&(v),i))
+
+static Vector_t*
+vecopen(int inc, int siz)
+{
+ Vector_t* v;
+ Stk_t* sp;
+
+ if (inc <= 0)
+ inc = 16;
+ if (!(sp = stkopen(STK_SMALL|STK_NULL)))
+ return 0;
+ if (!(v = (Vector_t*)stkseek(sp, sizeof(Vector_t) + inc * siz)))
+ {
+ stkclose(sp);
+ return 0;
+ }
+ v->stk = sp;
+ v->vec = (char*)v + sizeof(Vector_t);
+ v->max = v->inc = inc;
+ v->siz = siz;
+ v->cur = 0;
+ return v;
+}
+
+static void*
+vecseek(Vector_t** p, int index)
+{
+ Vector_t* v = *p;
+
+ if (index >= v->max)
+ {
+ while ((v->max += v->inc) <= index);
+ if (!(v = (Vector_t*)stkseek(v->stk, sizeof(Vector_t) + v->max * v->siz)))
+ return 0;
+ *p = v;
+ v->vec = (char*)v + sizeof(Vector_t);
+ }
+ return v->vec + index * v->siz;
+}
+
+static void
+vecclose(Vector_t* v)
+{
+ if (v)
+ stkclose(v->stk);
+}
+
+typedef struct
+{
+ Stk_pos_t pos;
+ char data[1];
+} Stk_frame_t;
+
+#define stknew(s,p) ((p)->offset=stktell(s),(p)->base=stkfreeze(s,0))
+#define stkold(s,p) stkset(s,(p)->base,(p)->offset)
+
+#define stkframe(s) (*((Stk_frame_t**)stktop(s)-1))
+#define stkdata(s,t) ((t*)stkframe(s)->data)
+#define stkpop(s) stkold(s,&(stkframe(s)->pos))
+
+static void*
+stkpush(Stk_t* sp, size_t size)
+{
+ Stk_frame_t* f;
+ Stk_pos_t p;
+
+ stknew(sp, &p);
+ size = sizeof(Stk_frame_t) + sizeof(size_t) + size - 1;
+ if (!(f = (Stk_frame_t*)stkalloc(sp, sizeof(Stk_frame_t) + sizeof(Stk_frame_t*) + size - 1)))
+ return 0;
+ f->pos = p;
+ stkframe(sp) = f;
+ return f->data;
+}
+
+/* ===== end library support ===== */
+
+/*
+ * Match_frame_t is for saving and restoring match records
+ * around alternate attempts, so that fossils will not be
+ * left in the match array. These are the only entries in
+ * the match array that are not otherwise guaranteed to
+ * have current data in them when they get used.
+ */
+
+typedef struct
+{
+ size_t size;
+ regmatch_t* match;
+ regmatch_t save[1];
+} Match_frame_t;
+
+#define matchpush(e,x) ((x)->re.group.number?_matchpush(e,x):0)
+#define matchcopy(e,x) do if ((x)->re.group.number) { Match_frame_t* fp = (void*)stkframe(stkstd)->data; memcpy(fp->match, fp->save, fp->size); } while (0)
+#define matchpop(e,x) do if ((x)->re.group.number) { Match_frame_t* fp = (void*)stkframe(stkstd)->data; memcpy(fp->match, fp->save, fp->size); stkpop(stkstd); } while (0)
+
+#define pospop(e) (--(e)->pos->cur)
+
+/*
+ * allocate a frame and push a match onto the stack
+ */
+
+static int
+_matchpush(Env_t* env, Rex_t* rex)
+{
+ Match_frame_t* f;
+ regmatch_t* m;
+ regmatch_t* e;
+ regmatch_t* s;
+ int num;
+
+ if (rex->re.group.number <= 0 || (num = rex->re.group.last - rex->re.group.number + 1) <= 0)
+ num = 0;
+ if (!(f = (Match_frame_t*)stkpush(stkstd, sizeof(Match_frame_t) + (num - 1) * sizeof(regmatch_t))))
+ {
+ env->error = REG_ESPACE;
+ return 1;
+ }
+ f->size = num * sizeof(regmatch_t);
+ f->match = m = env->match + rex->re.group.number;
+ e = m + num;
+ s = f->save;
+ while (m < e)
+ {
+ *s++ = *m;
+ *m++ = state.nomatch;
+ }
+ return 0;
+}
+
+/*
+ * allocate a frame and push a pos onto the stack
+ */
+
+static int
+pospush(Env_t* env, Rex_t* rex, unsigned char* p, int be)
+{
+ Pos_t* pos;
+
+ if (!(pos = vector(Pos_t, env->pos, env->pos->cur)))
+ {
+ env->error = REG_ESPACE;
+ return 1;
+ }
+ pos->serial = rex->serial;
+ pos->p = p;
+ pos->be = be;
+ env->pos->cur++;
+ return 0;
+}
+
+/*
+ * two matches are known to have the same length
+ * os is start of old pos array, ns is start of new,
+ * oend and nend are end+1 pointers to ends of arrays.
+ * oe and ne are ends (not end+1) of subarrays.
+ * returns 1 if new is better, -1 if old, else 0.
+ */
+
+static int
+better(Env_t* env, Pos_t* os, Pos_t* ns, Pos_t* oend, Pos_t* nend, int level)
+{
+ Pos_t* oe;
+ Pos_t* ne;
+ int k;
+ int n;
+
+ if (env->error)
+ return -1;
+ for (;;)
+ {
+ DEBUG_CODE(0x0080,{sfprintf(sfstdout, " %-*.*sold ", (level + 3) * 4, (level + 3) * 4, "");for (oe = os; oe < oend; oe++)sfprintf(sfstdout, "<%d,%d,%d>", oe->p - env->beg, oe->serial, oe->be);sfprintf(sfstdout, "\n %-*.*snew ", (level + 3) * 4, (level + 3) * 4, "");for (oe = ns; oe < nend; oe++)sfprintf(sfstdout, "<%d,%d,%d>", oe->p - env->beg, oe->serial, oe->be);sfprintf(sfstdout, "\n");},{0;});
+ if (ns >= nend)
+ return DEBUG_TEST(0x8000,(os < oend),(0));
+ if (os >= oend)
+ return DEBUG_TEST(0x8000,(-1),(1));
+ n = os->serial;
+ if (ns->serial > n)
+ return -1;
+ if (n > ns->serial)
+ {
+ env->error = REG_PANIC;
+ return -1;
+ }
+ if (ns->p > os->p)
+ return 1;
+ if (os->p > ns->p)
+ return -1;
+ oe = os;
+ k = 0;
+ for (;;)
+ if ((++oe)->serial == n)
+ {
+ if (oe->be != END_ANY)
+ k++;
+ else if (k-- <= 0)
+ break;
+ }
+ ne = ns;
+ k = 0;
+ for (;;)
+ if ((++ne)->serial == n)
+ {
+ if (ne->be != END_ANY)
+ k++;
+ else if (k-- <= 0)
+ break;
+ }
+ if (ne->p > oe->p)
+ return 1;
+ if (oe->p > ne->p)
+ return -1;
+ if (k = better(env, os + 1, ns + 1, oe, ne, level + 1))
+ return k;
+ os = oe + 1;
+ ns = ne + 1;
+ }
+}
+
+#if _AST_REGEX_DEBUG
+
+static void
+showmatch(regmatch_t* p)
+{
+ sfputc(sfstdout, '(');
+ if (p->rm_so < 0)
+ sfputc(sfstdout, '?');
+ else
+ sfprintf(sfstdout, "%d", p->rm_so);
+ sfputc(sfstdout, ',');
+ if (p->rm_eo < 0)
+ sfputc(sfstdout, '?');
+ else
+ sfprintf(sfstdout, "%d", p->rm_eo);
+ sfputc(sfstdout, ')');
+}
+
+static int
+_better(Env_t* env, Pos_t* os, Pos_t* ns, Pos_t* oend, Pos_t* nend, int level)
+{
+ int i;
+
+ DEBUG_CODE(0x0040,{sfprintf(sfstdout, "AHA better old ");for (i = 0; i <= env->nsub; i++)showmatch(&env->best[i]);sfprintf(sfstdout, "\n new ");for (i = 0; i <= env->nsub; i++)showmatch(&env->match[i]);sfprintf(sfstdout, "\n");},{0;});
+ i = better(env, os, ns, oend, nend, 0);
+ DEBUG_TEST(0x0040,(sfprintf(sfstdout, " %s\n", i <= 0 ? "OLD" : "NEW")),(0));
+ return i;
+}
+
+#define better _better
+
+#endif
+
+#define follow(e,r,c,s) ((r)->next?parse(e,(r)->next,c,s):(c)?parse(e,c,0,s):BEST)
+
+static int parse(Env_t*, Rex_t*, Rex_t*, unsigned char*);
+
+static int
+parserep(Env_t* env, Rex_t* rex, Rex_t* cont, unsigned char* s, int n)
+{
+ int i;
+ int r = NONE;
+ Rex_t catcher;
+
+ DEBUG_TEST(0x0010,(sfprintf(sfstdout, "AHA#%04d 0x%04x parserep %s %d %d %d %d `%-.*s'\n", __LINE__, debug_flag, rexname(rex->re.group.expr.rex), rex->re.group.number, rex->lo, n, rex->hi, env->end - s, s)),(0));
+ if ((rex->flags & REG_MINIMAL) && n >= rex->lo && n < rex->hi)
+ {
+ if (env->stack && pospush(env, rex, s, END_ANY))
+ return BAD;
+ i = follow(env, rex, cont, s);
+ if (env->stack)
+ pospop(env);
+ switch (i)
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ case GOOD:
+ return BEST;
+ }
+ }
+ if (n < rex->hi)
+ {
+ catcher.type = REX_REP_CATCH;
+ catcher.serial = rex->serial;
+ catcher.re.rep_catch.ref = rex;
+ catcher.re.rep_catch.cont = cont;
+ catcher.re.rep_catch.beg = s;
+ catcher.re.rep_catch.n = n + 1;
+ catcher.next = rex->next;
+ if (n == 0)
+ rex->re.rep_catch.beg = s;
+ if (env->stack)
+ {
+ if (matchpush(env, rex))
+ return BAD;
+ if (pospush(env, rex, s, BEG_ONE))
+ return BAD;
+DEBUG_TEST(0x0004,(sfprintf(sfstdout,"AHA#%04d 0x%04x PUSH %d (%d,%d)(%d,%d)(%d,%d) (%d,%d)(%d,%d)(%d,%d)\n", __LINE__, debug_flag, rex->re.group.number, env->best[0].rm_so, env->best[0].rm_eo, env->best[1].rm_so, env->best[1].rm_eo, env->best[2].rm_so, env->best[2].rm_eo, env->match[0].rm_so, env->match[0].rm_eo, env->match[1].rm_so, env->match[1].rm_eo, env->match[2].rm_so, env->match[2].rm_eo)),(0));
+ }
+ r = parse(env, rex->re.group.expr.rex, &catcher, s);
+ DEBUG_TEST(0x0010,(sfprintf(sfstdout, "AHA#%04d 0x%04x parserep parse %d %d `%-.*s'\n", __LINE__, debug_flag, rex->re.group.number, r, env->end - s, s)),(0));
+ if (env->stack)
+ {
+ pospop(env);
+ matchpop(env, rex);
+DEBUG_TEST(0x0004,(sfprintf(sfstdout,"AHA#%04d 0x%04x POP %d %d (%d,%d)(%d,%d)(%d,%d) (%d,%d)(%d,%d)(%d,%d)\n", __LINE__, debug_flag, rex->re.group.number, r, env->best[0].rm_so, env->best[0].rm_eo, env->best[1].rm_so, env->best[1].rm_eo, env->best[2].rm_so, env->best[2].rm_eo, env->match[0].rm_so, env->match[0].rm_eo, env->match[1].rm_so, env->match[1].rm_eo, env->match[2].rm_so, env->match[2].rm_eo)),(0));
+ }
+ switch (r)
+ {
+ case BAD:
+ return BAD;
+ case BEST:
+ return BEST;
+ case CUT:
+ r = NONE;
+ break;
+ case GOOD:
+ if (rex->flags & REG_MINIMAL)
+ return BEST;
+ r = GOOD;
+ break;
+ }
+ }
+ if (n < rex->lo)
+ return r;
+ if (!(rex->flags & REG_MINIMAL) || n >= rex->hi)
+ {
+ if (env->stack && pospush(env, rex, s, END_ANY))
+ return BAD;
+ i = follow(env, rex, cont, s);
+ if (env->stack)
+ pospop(env);
+ switch (i)
+ {
+ case BAD:
+ r = BAD;
+ break;
+ case CUT:
+ r = CUT;
+ break;
+ case BEST:
+ r = BEST;
+ break;
+ case GOOD:
+ r = (rex->flags & REG_MINIMAL) ? BEST : GOOD;
+ break;
+ }
+ }
+ return r;
+}
+
+static int
+parsetrie(Env_t* env, Trie_node_t* x, Rex_t* rex, Rex_t* cont, unsigned char* s)
+{
+ unsigned char* p;
+ int r;
+
+ if (p = rex->map)
+ {
+ for (;;)
+ {
+ if (s >= env->end)
+ return NONE;
+ while (x->c != p[*s])
+ if (!(x = x->sib))
+ return NONE;
+ if (x->end)
+ break;
+ x = x->son;
+ s++;
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ if (s >= env->end)
+ return NONE;
+ while (x->c != *s)
+ if (!(x = x->sib))
+ return NONE;
+ if (x->end)
+ break;
+ x = x->son;
+ s++;
+ }
+ }
+ s++;
+ if (rex->flags & REG_MINIMAL)
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ case GOOD:
+ return BEST;
+ }
+ if (x->son)
+ switch (parsetrie(env, x->son, rex, cont, s))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ return BEST;
+ case GOOD:
+ if (rex->flags & REG_MINIMAL)
+ return BEST;
+ r = GOOD;
+ break;
+ default:
+ r = NONE;
+ break;
+ }
+ else
+ r = NONE;
+ if (!(rex->flags & REG_MINIMAL))
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ return BEST;
+ case GOOD:
+ return GOOD;
+ }
+ return r;
+}
+
+static int
+collelt(register Celt_t* ce, char* key, int c, int x)
+{
+ Ckey_t elt;
+
+ mbxfrm(elt, key, COLL_KEY_MAX);
+ for (;; ce++)
+ {
+ switch (ce->typ)
+ {
+ case COLL_call:
+ if (!x && (*ce->fun)(c))
+ return 1;
+ continue;
+ case COLL_char:
+ if (!strcmp((char*)ce->beg, (char*)elt))
+ return 1;
+ continue;
+ case COLL_range:
+ if (strcmp((char*)ce->beg, (char*)elt) <= ce->min && strcmp((char*)elt, (char*)ce->end) <= ce->max)
+ return 1;
+ continue;
+ case COLL_range_lc:
+ if (strcmp((char*)ce->beg, (char*)elt) <= ce->min && strcmp((char*)elt, (char*)ce->end) <= ce->max && (iswlower(c) || !iswupper(c)))
+ return 1;
+ continue;
+ case COLL_range_uc:
+ if (strcmp((char*)ce->beg, (char*)elt) <= ce->min && strcmp((char*)elt, (char*)ce->end) <= ce->max && (iswupper(c) || !iswlower(c)))
+ return 1;
+ continue;
+ }
+ break;
+ }
+ return 0;
+}
+
+static int
+collic(register Celt_t* ce, char* key, register char* nxt, int c, int x)
+{
+ if (!x)
+ {
+ if (collelt(ce, key, c, x))
+ return 1;
+ if (iswlower(c))
+ c = towupper(c);
+ else if (iswupper(c))
+ c = towlower(c);
+ else
+ return 0;
+ x = mbconv(key, c);
+ key[x] = 0;
+ return collelt(ce, key, c, 0);
+ }
+ while (*nxt)
+ {
+ if (collic(ce, key, nxt + 1, c, x))
+ return 1;
+ if (islower(*nxt))
+ *nxt = toupper(*nxt);
+ else if (isupper(*nxt))
+ *nxt = tolower(*nxt);
+ else
+ return 0;
+ nxt++;
+ }
+ return collelt(ce, key, c, x);
+}
+
+static int
+collmatch(Rex_t* rex, unsigned char* s, unsigned char* e, unsigned char** p)
+{
+ unsigned char* t;
+ wchar_t c;
+ int w;
+ int r;
+ int x;
+ int ic;
+ Ckey_t key;
+ Ckey_t elt;
+
+ ic = (rex->flags & REG_ICASE);
+ if ((w = MBSIZE(s)) > 1)
+ {
+ memcpy((char*)key, (char*)s, w);
+ key[w] = 0;
+ t = s;
+ c = mbchar(t);
+#if !_lib_wctype
+ c &= 0xff;
+#endif
+ x = 0;
+ }
+ else
+ {
+ c = s[0];
+ if (ic && isupper(c))
+ c = tolower(c);
+ key[0] = c;
+ key[1] = 0;
+ if (isalpha(c))
+ {
+ x = e - s;
+ if (x > COLL_KEY_MAX)
+ x = COLL_KEY_MAX;
+ while (w < x)
+ {
+ c = s[w];
+ if (!isalpha(c))
+ break;
+ r = mbxfrm(elt, key, COLL_KEY_MAX);
+ if (ic && isupper(c))
+ c = tolower(c);
+ key[w] = c;
+ key[w + 1] = 0;
+ if (mbxfrm(elt, key, COLL_KEY_MAX) != r)
+ break;
+ w++;
+ }
+ }
+ key[w] = 0;
+ c = key[0];
+ x = w - 1;
+ }
+ r = 1;
+ for (;;)
+ {
+ if (ic ? collic(rex->re.collate.elements, (char*)key, (char*)key, c, x) : collelt(rex->re.collate.elements, (char*)key, c, x))
+ break;
+ if (!x)
+ {
+ r = 0;
+ break;
+ }
+ w = x--;
+ key[w] = 0;
+ }
+ *p = s + w;
+ return rex->re.collate.invert ? !r : r;
+}
+
+static unsigned char*
+nestmatch(register unsigned char* s, register unsigned char* e, const unsigned short* type, register int co)
+{
+ register int c;
+ register int cc;
+ unsigned int n;
+ int oc;
+
+ if (type[co] & (REX_NEST_literal|REX_NEST_quote))
+ {
+ n = (type[co] & REX_NEST_literal) ? REX_NEST_terminator : (REX_NEST_escape|REX_NEST_terminator);
+ while (s < e)
+ {
+ c = *s++;
+ if (c == co)
+ return s;
+ else if (type[c] & n)
+ {
+ if (s >= e || (type[c] & REX_NEST_terminator))
+ break;
+ s++;
+ }
+ }
+ }
+ else
+ {
+ cc = type[co] >> REX_NEST_SHIFT;
+ oc = type[co] & (REX_NEST_open|REX_NEST_close);
+ n = 1;
+ while (s < e)
+ {
+ c = *s++;
+ switch (type[c] & (REX_NEST_escape|REX_NEST_open|REX_NEST_close|REX_NEST_delimiter|REX_NEST_separator|REX_NEST_terminator))
+ {
+ case REX_NEST_delimiter:
+ case REX_NEST_terminator:
+ return oc ? 0 : s;
+ case REX_NEST_separator:
+ if (!oc)
+ return s;
+ break;
+ case REX_NEST_escape:
+ if (s >= e)
+ return 0;
+ s++;
+ break;
+ case REX_NEST_open|REX_NEST_close:
+ if (c == cc)
+ {
+ if (!--n)
+ return s;
+ }
+ /*FALLTHROUGH*/
+ case REX_NEST_open:
+ if (c == co)
+ {
+ if (!++n)
+ return 0;
+ }
+ else if (!(s = nestmatch(s, e, type, c)))
+ return 0;
+ break;
+ case REX_NEST_close:
+ if (c != cc)
+ return 0;
+ if (!--n)
+ return s;
+ break;
+ }
+ }
+ return (oc || !(type[UCHAR_MAX+1] & REX_NEST_terminator)) ? 0 : s;
+ }
+ return 0;
+}
+
+static int
+parse(Env_t* env, Rex_t* rex, Rex_t* cont, unsigned char* s)
+{
+ int c;
+ int d;
+ int i;
+ int m;
+ int n;
+ int r;
+ int* f;
+ unsigned char* p;
+ unsigned char* t;
+ unsigned char* b;
+ unsigned char* e;
+ char* u;
+ regmatch_t* o;
+ Trie_node_t* x;
+ Rex_t* q;
+ Rex_t catcher;
+ Rex_t next;
+
+ for (;;)
+ {
+DEBUG_TEST(0x0008,(sfprintf(sfstdout, "AHA#%04d 0x%04x parse %s `%-.*s'\n", __LINE__, debug_flag, rexname(rex), env->end - s, s)),(0));
+ switch (rex->type)
+ {
+ case REX_ALT:
+ if (env->stack)
+ {
+ if (matchpush(env, rex))
+ return BAD;
+ if (pospush(env, rex, s, BEG_ALT))
+ return BAD;
+ catcher.type = REX_ALT_CATCH;
+ catcher.serial = rex->serial;
+ catcher.re.alt_catch.cont = cont;
+ catcher.next = rex->next;
+ r = parse(env, rex->re.group.expr.binary.left, &catcher, s);
+ if (r < BEST || (rex->flags & REG_MINIMAL))
+ {
+ matchcopy(env, rex);
+ ((Pos_t*)env->pos->vec + env->pos->cur - 1)->serial = catcher.serial = rex->re.group.expr.binary.serial;
+ n = parse(env, rex->re.group.expr.binary.right, &catcher, s);
+ if (n != NONE)
+ r = n;
+ }
+ pospop(env);
+ matchpop(env, rex);
+ }
+ else
+ {
+ if ((r = parse(env, rex->re.group.expr.binary.left, cont, s)) == NONE)
+ r = parse(env, rex->re.group.expr.binary.right, cont, s);
+ if (r == GOOD)
+ r = BEST;
+ }
+ return r;
+ case REX_ALT_CATCH:
+ if (pospush(env, rex, s, END_ANY))
+ return BAD;
+ r = follow(env, rex, rex->re.alt_catch.cont, s);
+ pospop(env);
+ return r;
+ case REX_BACK:
+ o = &env->match[rex->lo];
+ if (o->rm_so < 0)
+ return NONE;
+ i = o->rm_eo - o->rm_so;
+ e = s + i;
+ if (e > env->end)
+ return NONE;
+ t = env->beg + o->rm_so;
+ if (!(p = rex->map))
+ {
+ while (s < e)
+ if (*s++ != *t++)
+ return NONE;
+ }
+ else if (!mbwide())
+ {
+ while (s < e)
+ if (p[*s++] != p[*t++])
+ return NONE;
+ }
+ else
+ {
+ while (s < e)
+ {
+ c = mbchar(s);
+ d = mbchar(t);
+ if (towupper(c) != towupper(d))
+ return NONE;
+ }
+ }
+ break;
+ case REX_BEG:
+ if ((!(rex->flags & REG_NEWLINE) || s <= env->beg || *(s - 1) != '\n') && ((env->flags & REG_NOTBOL) || s != env->beg))
+ return NONE;
+ break;
+ case REX_CLASS:
+ if (LEADING(env, rex, s))
+ return NONE;
+ n = rex->hi;
+ if (n > env->end - s)
+ n = env->end - s;
+ m = rex->lo;
+ if (m > n)
+ return NONE;
+ r = NONE;
+ if (!(rex->flags & REG_MINIMAL))
+ {
+ for (i = 0; i < n; i++)
+ if (!settst(rex->re.charclass, s[i]))
+ {
+ n = i;
+ break;
+ }
+ for (s += n; n-- >= m; s--)
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ return BEST;
+ case GOOD:
+ r = GOOD;
+ break;
+ }
+ }
+ else
+ {
+ for (e = s + m; s < e; s++)
+ if (!settst(rex->re.charclass, *s))
+ return r;
+ e += n - m;
+ for (;;)
+ {
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ case GOOD:
+ return BEST;
+ }
+ if (s >= e || !settst(rex->re.charclass, *s))
+ break;
+ s++;
+ }
+ }
+ return r;
+ case REX_COLL_CLASS:
+ if (LEADING(env, rex, s))
+ return NONE;
+ n = rex->hi;
+ if (n > env->end - s)
+ n = env->end - s;
+ m = rex->lo;
+ if (m > n)
+ return NONE;
+ r = NONE;
+ e = env->end;
+ if (!(rex->flags & REG_MINIMAL))
+ {
+ if (!(b = (unsigned char*)stkpush(stkstd, n)))
+ {
+ env->error = REG_ESPACE;
+ return BAD;
+ }
+ for (i = 0; s < e && i < n && collmatch(rex, s, e, &t); i++)
+ {
+ b[i] = t - s;
+ s = t;
+ }
+ for (; i-- >= rex->lo; s -= b[i])
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ stkpop(stkstd);
+ return BAD;
+ case CUT:
+ stkpop(stkstd);
+ return CUT;
+ case BEST:
+ stkpop(stkstd);
+ return BEST;
+ case GOOD:
+ r = GOOD;
+ break;
+ }
+ stkpop(stkstd);
+ }
+ else
+ {
+ for (i = 0; i < m && s < e; i++, s = t)
+ if (!collmatch(rex, s, e, &t))
+ return r;
+ while (i++ <= n)
+ {
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ case GOOD:
+ return BEST;
+ }
+ if (s >= e || !collmatch(rex, s, e, &s))
+ break;
+ }
+ }
+ return r;
+ case REX_CONJ:
+ next.type = REX_CONJ_RIGHT;
+ next.re.conj_right.cont = cont;
+ next.next = rex->next;
+ catcher.type = REX_CONJ_LEFT;
+ catcher.re.conj_left.right = rex->re.group.expr.binary.right;
+ catcher.re.conj_left.cont = &next;
+ catcher.re.conj_left.beg = s;
+ catcher.next = 0;
+ return parse(env, rex->re.group.expr.binary.left, &catcher, s);
+ case REX_CONJ_LEFT:
+ rex->re.conj_left.cont->re.conj_right.end = s;
+ cont = rex->re.conj_left.cont;
+ s = rex->re.conj_left.beg;
+ rex = rex->re.conj_left.right;
+ continue;
+ case REX_CONJ_RIGHT:
+ if (rex->re.conj_right.end != s)
+ return NONE;
+ cont = rex->re.conj_right.cont;
+ break;
+ case REX_DONE:
+ if (!env->stack)
+ return BEST;
+ n = s - env->beg;
+ r = env->nsub;
+ DEBUG_TEST(0x0100,(sfprintf(sfstdout,"AHA#%04d 0x%04x %s (%d,%d)(%d,%d)(%d,%d)(%d,%d) (%d,%d)(%d,%d)\n", __LINE__, debug_flag, rexname(rex), env->best[0].rm_so, env->best[0].rm_eo, env->best[1].rm_so, env->best[1].rm_eo, env->best[2].rm_so, env->best[2].rm_eo, env->best[3].rm_so, env->best[3].rm_eo, env->match[0].rm_so, env->match[0].rm_eo, env->match[1].rm_so, env->match[1].rm_eo)),(0));
+ if ((i = env->best[0].rm_eo) >= 0)
+ {
+ if (rex->flags & REG_MINIMAL)
+ {
+ if (n > i)
+ return GOOD;
+ }
+ else
+ {
+ if (n < i)
+ return GOOD;
+ }
+ if (n == i && better(env,
+ (Pos_t*)env->bestpos->vec,
+ (Pos_t*)env->pos->vec,
+ (Pos_t*)env->bestpos->vec+env->bestpos->cur,
+ (Pos_t*)env->pos->vec+env->pos->cur,
+ 0) <= 0)
+ return GOOD;
+ }
+ env->best[0].rm_eo = n;
+ memcpy(&env->best[1], &env->match[1], r * sizeof(regmatch_t));
+ n = env->pos->cur;
+ if (!vector(Pos_t, env->bestpos, n))
+ {
+ env->error = REG_ESPACE;
+ return BAD;
+ }
+ env->bestpos->cur = n;
+ memcpy(env->bestpos->vec, env->pos->vec, n * sizeof(Pos_t));
+ DEBUG_TEST(0x0100,(sfprintf(sfstdout,"AHA#%04d 0x%04x %s (%d,%d)(%d,%d)(%d,%d)(%d,%d) (%d,%d)(%d,%d)\n", __LINE__, debug_flag, rexname(rex), env->best[0].rm_so, env->best[0].rm_eo, env->best[1].rm_so, env->best[1].rm_eo, env->best[2].rm_so, env->best[2].rm_eo, env->best[3].rm_so, env->best[3].rm_eo, env->match[0].rm_so, env->match[0].rm_eo, env->match[1].rm_so, env->match[1].rm_eo)),(0));
+ return GOOD;
+ case REX_DOT:
+ if (LEADING(env, rex, s))
+ return NONE;
+ n = rex->hi;
+ if (n > env->end - s)
+ n = env->end - s;
+ m = rex->lo;
+ if (m > n)
+ return NONE;
+ if ((c = rex->explicit) >= 0 && !mbwide())
+ for (i = 0; i < n; i++)
+ if (s[i] == c)
+ {
+ n = i;
+ break;
+ }
+ r = NONE;
+ if (!(rex->flags & REG_MINIMAL))
+ {
+ if (!mbwide())
+ {
+ for (s += n; n-- >= m; s--)
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ return BEST;
+ case GOOD:
+ r = GOOD;
+ break;
+ }
+ }
+ else
+ {
+ if (!(b = (unsigned char*)stkpush(stkstd, n)))
+ {
+ env->error = REG_ESPACE;
+ return BAD;
+ }
+ e = env->end;
+ for (i = 0; s < e && i < n && *s != c; i++)
+ s += b[i] = MBSIZE(s);
+ for (; i-- >= m; s -= b[i])
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ stkpop(stkstd);
+ return BAD;
+ case CUT:
+ stkpop(stkstd);
+ return CUT;
+ case BEST:
+ stkpop(stkstd);
+ return BEST;
+ case GOOD:
+ r = GOOD;
+ break;
+ }
+ stkpop(stkstd);
+ }
+ }
+ else
+ {
+ if (!mbwide())
+ {
+ e = s + n;
+ for (s += m; s <= e; s++)
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ case GOOD:
+ return BEST;
+ }
+ }
+ else
+ {
+ e = env->end;
+ for (i = 0; s < e && i < m && *s != c; i++)
+ s += MBSIZE(s);
+ if (i >= m)
+ for (; s <= e && i <= n; s += MBSIZE(s), i++)
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ case GOOD:
+ return BEST;
+ }
+ }
+ }
+ return r;
+ case REX_END:
+ if ((!(rex->flags & REG_NEWLINE) || *s != '\n') && ((env->flags & REG_NOTEOL) || s < env->end))
+ return NONE;
+ break;
+ case REX_GROUP:
+DEBUG_TEST(0x0200,(sfprintf(sfstdout,"AHA#%04d 0x%04x parse %s `%-.*s'\n", __LINE__, debug_flag, rexname(rex), env->end - s, s)),(0));
+ if (env->stack)
+ {
+ if (rex->re.group.number)
+ env->match[rex->re.group.number].rm_so = s - env->beg;
+ if (pospush(env, rex, s, BEG_SUB))
+ return BAD;
+ catcher.re.group_catch.eo = rex->re.group.number ? &env->match[rex->re.group.number].rm_eo : (regoff_t*)0;
+ }
+ catcher.type = REX_GROUP_CATCH;
+ catcher.serial = rex->serial;
+ catcher.re.group_catch.cont = cont;
+ catcher.next = rex->next;
+ r = parse(env, rex->re.group.expr.rex, &catcher, s);
+ if (env->stack)
+ {
+ pospop(env);
+ if (rex->re.group.number)
+ env->match[rex->re.group.number].rm_so = -1;
+ }
+ return r;
+ case REX_GROUP_CATCH:
+DEBUG_TEST(0x0200,(sfprintf(sfstdout,"AHA#%04d 0x%04x parse %s=>%s `%-.*s'\n", __LINE__, debug_flag, rexname(rex), rexname(rex->re.group_catch.cont), env->end - s, s)),(0));
+ if (env->stack)
+ {
+ if (rex->re.group_catch.eo)
+ *rex->re.group_catch.eo = s - env->beg;
+ if (pospush(env, rex, s, END_ANY))
+ return BAD;
+ }
+ r = follow(env, rex, rex->re.group_catch.cont, s);
+ if (env->stack)
+ {
+ pospop(env);
+ if (rex->re.group_catch.eo)
+ *rex->re.group_catch.eo = -1;
+ }
+ return r;
+ case REX_GROUP_AHEAD:
+ catcher.type = REX_GROUP_AHEAD_CATCH;
+ catcher.flags = rex->flags;
+ catcher.serial = rex->serial;
+ catcher.re.rep_catch.beg = s;
+ catcher.re.rep_catch.cont = cont;
+ catcher.next = rex->next;
+ return parse(env, rex->re.group.expr.rex, &catcher, s);
+ case REX_GROUP_AHEAD_CATCH:
+ return follow(env, rex, rex->re.rep_catch.cont, rex->re.rep_catch.beg);
+ case REX_GROUP_AHEAD_NOT:
+ r = parse(env, rex->re.group.expr.rex, NiL, s);
+ if (r == NONE)
+ r = follow(env, rex, cont, s);
+ else if (r != BAD)
+ r = NONE;
+ return r;
+ case REX_GROUP_BEHIND:
+ if ((s - env->beg) < rex->re.group.size)
+ return NONE;
+ catcher.type = REX_GROUP_BEHIND_CATCH;
+ catcher.flags = rex->flags;
+ catcher.serial = rex->serial;
+ catcher.re.behind_catch.beg = s;
+ catcher.re.behind_catch.end = e = env->end;
+ catcher.re.behind_catch.cont = cont;
+ catcher.next = rex->next;
+ for (t = s - rex->re.group.size; t >= env->beg; t--)
+ {
+ env->end = s;
+ r = parse(env, rex->re.group.expr.rex, &catcher, t);
+ env->end = e;
+ if (r != NONE)
+ return r;
+ }
+ return NONE;
+ case REX_GROUP_BEHIND_CATCH:
+ if (s != rex->re.behind_catch.beg)
+ return NONE;
+ env->end = rex->re.behind_catch.end;
+ return follow(env, rex, rex->re.behind_catch.cont, rex->re.behind_catch.beg);
+ case REX_GROUP_BEHIND_NOT:
+ if ((s - env->beg) < rex->re.group.size)
+ r = NONE;
+ else
+ {
+ catcher.type = REX_GROUP_BEHIND_NOT_CATCH;
+ catcher.re.neg_catch.beg = s;
+ catcher.next = 0;
+ e = env->end;
+ env->end = s;
+ for (t = s - rex->re.group.size; t >= env->beg; t--)
+ {
+ r = parse(env, rex->re.group.expr.rex, &catcher, t);
+ if (r != NONE)
+ break;
+ }
+ env->end = e;
+ }
+ if (r == NONE)
+ r = follow(env, rex, cont, s);
+ else if (r != BAD)
+ r = NONE;
+ return r;
+ case REX_GROUP_BEHIND_NOT_CATCH:
+ return s == rex->re.neg_catch.beg ? GOOD : NONE;
+ case REX_GROUP_COND:
+ if (q = rex->re.group.expr.binary.right)
+ {
+ catcher.re.cond_catch.next[0] = q->re.group.expr.binary.right;
+ catcher.re.cond_catch.next[1] = q->re.group.expr.binary.left;
+ }
+ else
+ catcher.re.cond_catch.next[0] = catcher.re.cond_catch.next[1] = 0;
+ if (q = rex->re.group.expr.binary.left)
+ {
+ catcher.type = REX_GROUP_COND_CATCH;
+ catcher.flags = rex->flags;
+ catcher.serial = rex->serial;
+ catcher.re.cond_catch.yes = 0;
+ catcher.re.cond_catch.beg = s;
+ catcher.re.cond_catch.cont = cont;
+ catcher.next = rex->next;
+ r = parse(env, q, &catcher, s);
+ if (r == BAD || catcher.re.cond_catch.yes)
+ return r;
+ }
+ else if (!rex->re.group.size || rex->re.group.size > 0 && env->match[rex->re.group.size].rm_so >= 0)
+ r = GOOD;
+ else
+ r = NONE;
+ if (q = catcher.re.cond_catch.next[r != NONE])
+ {
+ catcher.type = REX_CAT;
+ catcher.flags = q->flags;
+ catcher.serial = q->serial;
+ catcher.re.group_catch.cont = cont;
+ catcher.next = rex->next;
+ return parse(env, q, &catcher, s);
+ }
+ return follow(env, rex, cont, s);
+ case REX_GROUP_COND_CATCH:
+ rex->re.cond_catch.yes = 1;
+ catcher.type = REX_CAT;
+ catcher.flags = rex->flags;
+ catcher.serial = rex->serial;
+ catcher.re.group_catch.cont = rex->re.cond_catch.cont;
+ catcher.next = rex->next;
+ return parse(env, rex->re.cond_catch.next[1], &catcher, rex->re.cond_catch.beg);
+ case REX_CAT:
+ return follow(env, rex, rex->re.group_catch.cont, s);
+ case REX_GROUP_CUT:
+ catcher.type = REX_GROUP_CUT_CATCH;
+ catcher.flags = rex->flags;
+ catcher.serial = rex->serial;
+ catcher.re.group_catch.cont = cont;
+ catcher.next = rex->next;
+ return parse(env, rex->re.group.expr.rex, &catcher, s);
+ case REX_GROUP_CUT_CATCH:
+ switch (r = follow(env, rex, rex->re.group_catch.cont, s))
+ {
+ case GOOD:
+ r = BEST;
+ break;
+ case NONE:
+ r = CUT;
+ break;
+ }
+ return r;
+ case REX_KMP:
+ f = rex->re.string.fail;
+ b = rex->re.string.base;
+ n = rex->re.string.size;
+ t = s;
+ e = env->end;
+ if (p = rex->map)
+ {
+ while (t + n <= e)
+ {
+ for (i = -1; t < e; t++)
+ {
+ while (i >= 0 && b[i+1] != p[*t])
+ i = f[i];
+ if (b[i+1] == p[*t])
+ i++;
+ if (i + 1 == n)
+ {
+ t++;
+ if (env->stack)
+ env->best[0].rm_so = t - s - n;
+ switch (follow(env, rex, cont, t))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ case GOOD:
+ return BEST;
+ }
+ t -= n - 1;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ while (t + n <= e)
+ {
+ for (i = -1; t < e; t++)
+ {
+ while (i >= 0 && b[i+1] != *t)
+ i = f[i];
+ if (b[i+1] == *t)
+ i++;
+ if (i + 1 == n)
+ {
+ t++;
+ if (env->stack)
+ env->best[0].rm_so = t - s - n;
+ switch (follow(env, rex, cont, t))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ case GOOD:
+ return BEST;
+ }
+ t -= n - 1;
+ break;
+ }
+ }
+ }
+ }
+ return NONE;
+ case REX_NEG:
+ if (LEADING(env, rex, s))
+ return NONE;
+ i = env->end - s;
+ n = ((i + 7) >> 3) + 1;
+ catcher.type = REX_NEG_CATCH;
+ catcher.re.neg_catch.beg = s;
+ if (!(p = (unsigned char*)stkpush(stkstd, n)))
+ return BAD;
+ memset(catcher.re.neg_catch.index = p, 0, n);
+ catcher.next = rex->next;
+ if (parse(env, rex->re.group.expr.rex, &catcher, s) == BAD)
+ r = BAD;
+ else
+ {
+ r = NONE;
+ for (; i >= 0; i--)
+ if (!bittst(p, i))
+ {
+ switch (follow(env, rex, cont, s + i))
+ {
+ case BAD:
+ r = BAD;
+ break;
+ case BEST:
+ r = BEST;
+ break;
+ case CUT:
+ r = CUT;
+ break;
+ case GOOD:
+ r = GOOD;
+ /*FALLTHROUGH*/
+ default:
+ continue;
+ }
+ break;
+ }
+ }
+ stkpop(stkstd);
+ return r;
+ case REX_NEG_CATCH:
+ bitset(rex->re.neg_catch.index, s - rex->re.neg_catch.beg);
+ return NONE;
+ case REX_NEST:
+ if (s >= env->end)
+ return NONE;
+ do
+ {
+ if ((c = *s++) == rex->re.nest.primary)
+ {
+ if (s >= env->end || !(s = nestmatch(s, env->end, rex->re.nest.type, c)))
+ return NONE;
+ break;
+ }
+ if (rex->re.nest.primary >= 0)
+ return NONE;
+ if (rex->re.nest.type[c] & (REX_NEST_delimiter|REX_NEST_separator|REX_NEST_terminator))
+ break;
+ if (!(s = nestmatch(s, env->end, rex->re.nest.type, c)))
+ return NONE;
+ } while (s < env->end && !(rex->re.nest.type[*(s-1)] & (REX_NEST_delimiter|REX_NEST_separator|REX_NEST_terminator)));
+ break;
+ case REX_NULL:
+ break;
+ case REX_ONECHAR:
+ n = rex->hi;
+ if (n > env->end - s)
+ n = env->end - s;
+ m = rex->lo;
+ if (m > n)
+ return NONE;
+ r = NONE;
+ c = rex->re.onechar;
+ if (!(rex->flags & REG_MINIMAL))
+ {
+ if (!mbwide())
+ {
+ if (p = rex->map)
+ {
+ for (i = 0; i < n; i++, s++)
+ if (p[*s] != c)
+ break;
+ }
+ else
+ {
+ for (i = 0; i < n; i++, s++)
+ if (*s != c)
+ break;
+ }
+ for (; i-- >= m; s--)
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ return BAD;
+ case BEST:
+ return BEST;
+ case CUT:
+ return CUT;
+ case GOOD:
+ r = GOOD;
+ break;
+ }
+ }
+ else
+ {
+ if (!(b = (unsigned char*)stkpush(stkstd, n)))
+ {
+ env->error = REG_ESPACE;
+ return BAD;
+ }
+ e = env->end;
+ if (!(rex->flags & REG_ICASE))
+ {
+ for (i = 0; s < e && i < n; i++, s = t)
+ {
+ t = s;
+ if (mbchar(t) != c)
+ break;
+ b[i] = t - s;
+ }
+ }
+ else
+ {
+ for (i = 0; s < e && i < n; i++, s = t)
+ {
+ t = s;
+ if (towupper(mbchar(t)) != c)
+ break;
+ b[i] = t - s;
+ }
+ }
+ for (; i-- >= m; s -= b[i])
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ stkpop(stkstd);
+ return BAD;
+ case BEST:
+ stkpop(stkstd);
+ return BEST;
+ case CUT:
+ stkpop(stkstd);
+ return CUT;
+ case GOOD:
+ r = GOOD;
+ break;
+ }
+ stkpop(stkstd);
+ }
+ }
+ else
+ {
+ if (!mbwide())
+ {
+ e = s + m;
+ if (p = rex->map)
+ {
+ for (; s < e; s++)
+ if (p[*s] != c)
+ return r;
+ e += n - m;
+ for (;;)
+ {
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ case GOOD:
+ return BEST;
+ }
+ if (s >= e || p[*s++] != c)
+ break;
+ }
+ }
+ else
+ {
+ for (; s < e; s++)
+ if (*s != c)
+ return r;
+ e += n - m;
+ for (;;)
+ {
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ case GOOD:
+ return BEST;
+ }
+ if (s >= e || *s++ != c)
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (!(rex->flags & REG_ICASE))
+ {
+ for (i = 0; i < m && s < e; i++, s = t)
+ {
+ t = s;
+ if (mbchar(t) != c)
+ return r;
+ }
+ while (i++ <= n)
+ {
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ case GOOD:
+ return BEST;
+ }
+ if (s >= e || mbchar(s) != c)
+ break;
+ }
+ }
+ else
+ {
+ for (i = 0; i < m && s < e; i++, s = t)
+ {
+ t = s;
+ if (towupper(mbchar(t)) != c)
+ return r;
+ }
+ while (i++ <= n)
+ {
+ switch (follow(env, rex, cont, s))
+ {
+ case BAD:
+ return BAD;
+ case CUT:
+ return CUT;
+ case BEST:
+ case GOOD:
+ return BEST;
+ }
+ if (s >= e || towupper(mbchar(s)) != c)
+ break;
+ }
+ }
+ }
+ }
+ return r;
+ case REX_REP:
+ if (env->stack && pospush(env, rex, s, BEG_REP))
+ return BAD;
+ r = parserep(env, rex, cont, s, 0);
+ if (env->stack)
+ pospop(env);
+ return r;
+ case REX_REP_CATCH:
+ DEBUG_TEST(0x0020,(sfprintf(sfstdout, "AHA#%04d 0x%04x %s n %d len %d s `%-.*s'\n", __LINE__, debug_flag, rexname(rex), rex->re.rep_catch.n, s - rex->re.rep_catch.beg, env->end - s, s)),(0));
+ if (env->stack && pospush(env, rex, s, END_ANY))
+ return BAD;
+ if (s == rex->re.rep_catch.beg && rex->re.rep_catch.n > rex->re.rep_catch.ref->lo)
+ {
+ /*
+ * optional empty iteration
+ */
+
+DEBUG_TEST(0x0002,(sfprintf(sfstdout, "AHA#%04d %p re.group.back=%d re.group.expr.rex=%s\n", __LINE__, rex->re.rep_catch.ref->re.group.expr.rex, rex->re.rep_catch.ref->re.group.expr.rex->re.group.back, rexname(rex->re.rep_catch.ref->re.group.expr.rex))),(0));
+ if (!env->stack || s != rex->re.rep_catch.ref->re.rep_catch.beg && !rex->re.rep_catch.ref->re.group.expr.rex->re.group.back)
+ r = NONE;
+ else if (pospush(env, rex, s, END_ANY))
+ r = BAD;
+ else
+ {
+ r = follow(env, rex, rex->re.rep_catch.cont, s);
+ pospop(env);
+ }
+ }
+ else
+ r = parserep(env, rex->re.rep_catch.ref, rex->re.rep_catch.cont, s, rex->re.rep_catch.n);
+ if (env->stack)
+ pospop(env);
+ return r;
+ case REX_STRING:
+DEBUG_TEST(0x0200,(sfprintf(sfstdout,"AHA#%04d 0x%04x parse %s \"%-.*s\" `%-.*s'\n", __LINE__, debug_flag, rexname(rex), rex->re.string.size, rex->re.string.base, env->end - s, s)),(0));
+ if (rex->re.string.size > (env->end - s))
+ return NONE;
+ t = rex->re.string.base;
+ e = t + rex->re.string.size;
+ if (!(p = rex->map))
+ {
+ while (t < e)
+ if (*s++ != *t++)
+ return NONE;
+ }
+ else if (!mbwide())
+ {
+ while (t < e)
+ if (p[*s++] != *t++)
+ return NONE;
+ }
+ else
+ {
+ while (t < e)
+ {
+ c = mbchar(s);
+ d = mbchar(t);
+ if (towupper(c) != d)
+ return NONE;
+ }
+ }
+ break;
+ case REX_TRIE:
+ if (((s + rex->re.trie.min) > env->end) || !(x = rex->re.trie.root[rex->map ? rex->map[*s] : *s]))
+ return NONE;
+ return parsetrie(env, x, rex, cont, s);
+ case REX_EXEC:
+ u = 0;
+ r = (*env->disc->re_execf)(env->regex, rex->re.exec.data, rex->re.exec.text, rex->re.exec.size, (const char*)s, env->end - s, &u, env->disc);
+ e = (unsigned char*)u;
+ if (e >= s && e <= env->end)
+ s = e;
+ switch (r)
+ {
+ case 0:
+ break;
+ case REG_NOMATCH:
+ return NONE;
+ default:
+ env->error = r;
+ return BAD;
+ }
+ break;
+ case REX_WBEG:
+ if (!isword(*s) || s > env->beg && isword(*(s - 1)))
+ return NONE;
+ break;
+ case REX_WEND:
+ if (isword(*s) || s > env->beg && !isword(*(s - 1)))
+ return NONE;
+ break;
+ case REX_WORD:
+ if (s > env->beg && isword(*(s - 1)) == isword(*s))
+ return NONE;
+ break;
+ case REX_WORD_NOT:
+ if (s == env->beg || isword(*(s - 1)) != isword(*s))
+ return NONE;
+ break;
+ case REX_BEG_STR:
+ if (s != env->beg)
+ return NONE;
+ break;
+ case REX_END_STR:
+ for (t = s; t < env->end && *t == '\n'; t++);
+ if (t < env->end)
+ return NONE;
+ break;
+ case REX_FIN_STR:
+ if (s < env->end)
+ return NONE;
+ break;
+ }
+ if (!(rex = rex->next))
+ {
+ if (!(rex = cont))
+ break;
+ cont = 0;
+ }
+ }
+ return GOOD;
+}
+
+#if _AST_REGEX_DEBUG
+
+static void
+listnode(Rex_t* e, int level)
+{
+ int i;
+
+ if (e)
+ {
+ do
+ {
+ for (i = 0; i < level; i++)
+ sfprintf(sfstderr, " ");
+ sfprintf(sfstderr, "%s\n", rexname(e));
+ switch (e->type)
+ {
+ case REX_ALT:
+ case REX_CONJ:
+ listnode(e->re.group.expr.binary.left, level + 1);
+ listnode(e->re.group.expr.binary.right, level + 1);
+ break;
+ case REX_GROUP:
+ case REX_GROUP_AHEAD:
+ case REX_GROUP_AHEAD_NOT:
+ case REX_GROUP_BEHIND:
+ case REX_GROUP_BEHIND_NOT:
+ case REX_GROUP_CUT:
+ case REX_NEG:
+ case REX_REP:
+ listnode(e->re.group.expr.rex, level + 1);
+ break;
+ }
+ } while (e = e->next);
+ }
+}
+
+static int
+list(Env_t* env, Rex_t* rex)
+{
+ sfprintf(sfstderr, "AHA regex hard=%d stack=%p\n", env->hard, env->stack);
+ if (rex)
+ listnode(rex, 1);
+ return 0;
+}
+
+#endif
+
+/*
+ * returning REG_BADPAT or REG_ESPACE is not explicitly
+ * countenanced by the standard
+ */
+
+int
+regnexec(const regex_t* p, const char* s, size_t len, size_t nmatch, regmatch_t* match, regflags_t flags)
+{
+ register int n;
+ register int i;
+ int j;
+ int k;
+ int m;
+ int advance;
+ Env_t* env;
+ Rex_t* e;
+
+ DEBUG_INIT();
+ DEBUG_TEST(0x0001,(sfprintf(sfstdout, "AHA#%04d 0x%04x regnexec %d 0x%08x `%-.*s'\n", __LINE__, debug_flag, nmatch, flags, len, s)),(0));
+ if (!p || !(env = p->env))
+ return REG_BADPAT;
+ if (!s)
+ return fatal(env->disc, REG_BADPAT, NiL);
+ if (len < env->min)
+ {
+ DEBUG_TEST(0x0080,(sfprintf(sfstdout, "AHA#%04d REG_NOMATCH %d %d\n", __LINE__, len, env->min)),(0));
+ return REG_NOMATCH;
+ }
+ env->regex = p;
+ env->beg = (unsigned char*)s;
+ env->end = env->beg + len;
+ stknew(stkstd, &env->stk);
+ env->flags &= ~REG_EXEC;
+ env->flags |= (flags & REG_EXEC);
+ advance = 0;
+ if (env->stack = env->hard || !(env->flags & REG_NOSUB) && nmatch)
+ {
+ n = env->nsub;
+ if (!(env->match = (regmatch_t*)stkpush(stkstd, 2 * (n + 1) * sizeof(regmatch_t))) ||
+ !env->pos && !(env->pos = vecopen(16, sizeof(Pos_t))) ||
+ !env->bestpos && !(env->bestpos = vecopen(16, sizeof(Pos_t))))
+ {
+ k = REG_ESPACE;
+ goto done;
+ }
+ env->pos->cur = env->bestpos->cur = 0;
+ env->best = &env->match[n + 1];
+ env->best[0].rm_so = 0;
+ env->best[0].rm_eo = -1;
+ for (i = 0; i <= n; i++)
+ env->match[i] = state.nomatch;
+ if (flags & REG_ADVANCE)
+ advance = 1;
+ }
+ DEBUG_TEST(0x1000,(list(env,env->rex)),(0));
+ k = REG_NOMATCH;
+ if ((e = env->rex)->type == REX_BM)
+ {
+ DEBUG_TEST(0x0080,(sfprintf(sfstdout, "AHA#%04d REX_BM\n", __LINE__)),(0));
+ if (len < e->re.bm.right)
+ {
+ DEBUG_TEST(0x0080,(sfprintf(sfstdout, "AHA#%04d REG_NOMATCH %d %d\n", __LINE__, len, e->re.bm.right)),(0));
+ goto done;
+ }
+ else if (!(flags & REG_LEFT))
+ {
+ register unsigned char* buf = (unsigned char*)s;
+ register size_t index = e->re.bm.left + e->re.bm.size;
+ register size_t mid = len - e->re.bm.right;
+ register size_t* skip = e->re.bm.skip;
+ register size_t* fail = e->re.bm.fail;
+ register Bm_mask_t** mask = e->re.bm.mask;
+ Bm_mask_t m;
+ size_t x;
+
+ DEBUG_TEST(0x0080,(sfprintf(sfstdout, "AHA#%04d REX_BM len=%d right=%d left=%d size=%d %d %d\n", __LINE__, len, e->re.bm.right, e->re.bm.left, e->re.bm.size, index, mid)),(0));
+ for (;;)
+ {
+ while ((index += skip[buf[index]]) < mid);
+ if (index < HIT)
+ {
+ DEBUG_TEST(0x0080,(sfprintf(sfstdout, "AHA#%04d REG_NOMATCH %d %d\n", __LINE__, index, HIT)),(0));
+ goto done;
+ }
+ index -= HIT;
+ m = mask[n = e->re.bm.size - 1][buf[index]];
+ do
+ {
+ if (!n--)
+ {
+ if (e->re.bm.back < 0)
+ goto possible;
+ if (advance)
+ {
+ i = index - e->re.bm.back;
+ s += i;
+ if (env->stack)
+ env->best[0].rm_so += i;
+ goto possible;
+ }
+ x = index;
+ if (index < e->re.bm.back)
+ index = 0;
+ else
+ index -= e->re.bm.back;
+ while (index <= x)
+ {
+ if ((i = parse(env, e->next, &env->done, buf + index)) != NONE)
+ {
+ if (env->stack)
+ env->best[0].rm_so = index;
+ n = env->nsub;
+ goto hit;
+ }
+ index++;
+ }
+ index += e->re.bm.size;
+ break;
+ }
+ } while (m &= mask[n][buf[--index]]);
+ if ((index += fail[n + 1]) >= len)
+ goto done;
+ }
+ }
+ possible:
+ n = env->nsub;
+ e = e->next;
+ }
+ j = env->once || (flags & REG_LEFT);
+ DEBUG_TEST(0x0080,(sfprintf(sfstdout, "AHA#%04d parse once=%d\n", __LINE__, j)),(0));
+ while ((i = parse(env, e, &env->done, (unsigned char*)s)) == NONE || advance && !env->best[0].rm_eo && !(advance = 0))
+ {
+ if (j)
+ goto done;
+ i = MBSIZE(s);
+ s += i;
+ if ((unsigned char*)s > env->end - env->min)
+ goto done;
+ if (env->stack)
+ env->best[0].rm_so += i;
+ }
+ if ((flags & REG_LEFT) && env->stack && env->best[0].rm_so)
+ goto done;
+ hit:
+ if (k = env->error)
+ goto done;
+ if (i == CUT)
+ {
+ k = env->error = REG_NOMATCH;
+ goto done;
+ }
+ if (!(env->flags & REG_NOSUB))
+ {
+ k = (env->flags & (REG_SHELL|REG_AUGMENTED)) == (REG_SHELL|REG_AUGMENTED);
+ for (i = j = m = 0; j < nmatch; i++)
+ if (!i || !k || (i & 1))
+ {
+ if (i > n)
+ match[j] = state.nomatch;
+ else
+ match[m = j] = env->best[i];
+ j++;
+ }
+ if (k)
+ {
+ while (m > 0 && match[m].rm_so == -1 && match[m].rm_eo == -1)
+ m--;
+ ((regex_t*)p)->re_nsub = m;
+ }
+ }
+ k = 0;
+ done:
+ stkold(stkstd, &env->stk);
+ env->stk.base = 0;
+ if (k > REG_NOMATCH)
+ fatal(p->env->disc, k, NiL);
+ return k;
+}
+
+void
+regfree(regex_t* p)
+{
+ Env_t* env;
+
+ if (p && (env = p->env))
+ {
+#if _REG_subcomp
+ if (env->sub)
+ {
+ regsubfree(p);
+ p->re_sub = 0;
+ }
+#endif
+ p->env = 0;
+ if (--env->refs <= 0 && !(env->disc->re_flags & REG_NOFREE))
+ {
+ drop(env->disc, env->rex);
+ if (env->pos)
+ vecclose(env->pos);
+ if (env->bestpos)
+ vecclose(env->bestpos);
+ if (env->stk.base)
+ stkold(stkstd, &env->stk);
+ alloc(env->disc, env, 0);
+ }
+ }
+}
diff --git a/src/lib/libast/regex/regrecord.c b/src/lib/libast/regex/regrecord.c
new file mode 100644
index 0000000..001d14c
--- /dev/null
+++ b/src/lib/libast/regex/regrecord.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * return 1 if regrexec() can be used
+ */
+
+#include "reglib.h"
+
+int
+regrecord(const regex_t* p)
+{
+ return p && p->env && p->env->rex->type == REX_BM;
+}
diff --git a/src/lib/libast/regex/regrexec.c b/src/lib/libast/regex/regrexec.c
new file mode 100644
index 0000000..6cb1272
--- /dev/null
+++ b/src/lib/libast/regex/regrexec.c
@@ -0,0 +1,145 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * posix regex record executor
+ * multiple record sized-buffer interface
+ */
+
+#include "reglib.h"
+
+/*
+ * call regnexec() on records selected by Boyer-Moore
+ */
+
+int
+regrexec(const regex_t* p, const char* s, size_t len, size_t nmatch, regmatch_t* match, regflags_t flags, int sep, void* handle, regrecord_t record)
+{
+ register unsigned char* buf = (unsigned char*)s;
+ register unsigned char* beg;
+ register unsigned char* l;
+ register unsigned char* r;
+ register unsigned char* x;
+ register size_t* skip;
+ register size_t* fail;
+ register Bm_mask_t** mask;
+ register size_t index;
+ register int n;
+ unsigned char* end;
+ size_t mid;
+ int complete;
+ int exactlen;
+ int leftlen;
+ int rightlen;
+ int inv;
+ Bm_mask_t m;
+ Env_t* env;
+ Rex_t* e;
+
+ if (!s || !p || !(env = p->env) || (e = env->rex)->type != REX_BM)
+ return REG_BADPAT;
+ inv = (flags & REG_INVERT) != 0;
+ buf = beg = (unsigned char*)s;
+ end = buf + len;
+ mid = (len < e->re.bm.right) ? 0 : (len - e->re.bm.right);
+ skip = e->re.bm.skip;
+ fail = e->re.bm.fail;
+ mask = e->re.bm.mask;
+ complete = e->re.bm.complete && !nmatch;
+ exactlen = e->re.bm.size;
+ leftlen = e->re.bm.left + exactlen;
+ rightlen = exactlen + e->re.bm.right;
+ index = leftlen++;
+ for (;;)
+ {
+ while ((index += skip[buf[index]]) < mid);
+ if (index < HIT)
+ goto impossible;
+ index -= HIT;
+ m = mask[n = exactlen - 1][buf[index]];
+ do
+ {
+ if (!n--)
+ goto possible;
+ } while (m &= mask[n][buf[--index]]);
+ if ((index += fail[n + 1]) < len)
+ continue;
+ impossible:
+ if (inv)
+ {
+ l = r = buf + len;
+ goto invert;
+ }
+ n = 0;
+ goto done;
+ possible:
+ r = (l = buf + index) + exactlen;
+ while (l > beg)
+ if (*--l == sep)
+ {
+ l++;
+ break;
+ }
+ if ((r - l) < leftlen)
+ goto spanned;
+ while (r < end && *r != sep)
+ r++;
+ if ((r - (buf + index)) < rightlen)
+ goto spanned;
+ if (complete || (env->rex = ((r - l) > 128) ? e : e->next) && !(n = regnexec(p, (char*)l, r - l, nmatch, match, flags)))
+ {
+ if (inv)
+ {
+ invert:
+ x = beg;
+ while (beg < l)
+ {
+ while (x < l && *x != sep)
+ x++;
+ if (n = (*record)(handle, (char*)beg, x - beg))
+ goto done;
+ beg = ++x;
+ }
+ }
+ else if (n = (*record)(handle, (char*)l, r - l))
+ goto done;
+ if ((index = (r - buf) + leftlen) >= len)
+ {
+ n = (inv && (++r - buf) < len) ? (*record)(handle, (char*)r, (buf + len) - r): 0;
+ goto done;
+ }
+ beg = r + 1;
+ }
+ else if (n != REG_NOMATCH)
+ goto done;
+ else
+ {
+ spanned:
+ if ((index += exactlen) >= mid)
+ goto impossible;
+ }
+ }
+ done:
+ env->rex = e;
+ return n;
+}
diff --git a/src/lib/libast/regex/regstat.c b/src/lib/libast/regex/regstat.c
new file mode 100644
index 0000000..c7f725f
--- /dev/null
+++ b/src/lib/libast/regex/regstat.c
@@ -0,0 +1,53 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * return p stat info
+ */
+
+#include "reglib.h"
+
+regstat_t*
+regstat(const regex_t* p)
+{
+ register Rex_t* e;
+
+ p->env->stats.re_flags = p->env->flags;
+ p->env->stats.re_info = 0;
+ e = p->env->rex;
+ if (e && e->type == REX_BM)
+ {
+ p->env->stats.re_record = p->env->rex->re.bm.size;
+ e = e->next;
+ }
+ else
+ p->env->stats.re_record = 0;
+ if (e && e->type == REX_BEG)
+ e = e->next;
+ if (e && e->type == REX_STRING)
+ e = e->next;
+ if (!e || e->type == REX_END && !e->next)
+ p->env->stats.re_info |= REG_LITERAL;
+ p->env->stats.re_record = (p && p->env && p->env->rex->type == REX_BM) ? p->env->rex->re.bm.size : -1;
+ return &p->env->stats;
+}
diff --git a/src/lib/libast/regex/regsub.c b/src/lib/libast/regex/regsub.c
new file mode 100644
index 0000000..8e89bea
--- /dev/null
+++ b/src/lib/libast/regex/regsub.c
@@ -0,0 +1,269 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * OBSOLETE Sfio_t buffer interface -- use regsubcomp(),regsubexec()
+ */
+
+#include "reglib.h"
+
+/*
+ * do a single substitution
+ */
+
+static int
+subold(register Sfio_t* dp, const char* op, register const char* sp, size_t nmatch, register regmatch_t* match, register regflags_t flags, int sre)
+{
+ register int c;
+ char* s;
+ char* e;
+ const char* b;
+ regflags_t f;
+
+ f = flags &= (REG_SUB_LOWER|REG_SUB_UPPER);
+ for (;;)
+ {
+ switch (c = *sp++)
+ {
+ case 0:
+ return 0;
+ case '~':
+ if (!sre || *sp != '(')
+ {
+ sfputc(dp, c);
+ continue;
+ }
+ b = sp - 1;
+ sp++;
+ break;
+ case '\\':
+ if (sre)
+ {
+ sfputc(dp, chresc(sp - 1, &s));
+ sp = (const char*)s;
+ continue;
+ }
+ if (*sp == '&')
+ {
+ c = *sp++;
+ sfputc(dp, c);
+ continue;
+ }
+ break;
+ case '&':
+ if (sre)
+ {
+ sfputc(dp, c);
+ continue;
+ }
+ sp--;
+ break;
+ default:
+ switch (flags)
+ {
+ case REG_SUB_UPPER:
+ if (islower(c))
+ c = toupper(c);
+ break;
+ case REG_SUB_LOWER:
+ if (isupper(c))
+ c = tolower(c);
+ break;
+ case REG_SUB_UPPER|REG_SUB_LOWER:
+ if (isupper(c))
+ c = tolower(c);
+ else if (islower(c))
+ c = toupper(c);
+ break;
+ }
+ sfputc(dp, c);
+ continue;
+ }
+ switch (c = *sp++)
+ {
+ case 0:
+ sp--;
+ continue;
+ case '&':
+ c = 0;
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ c -= '0';
+ if (sre)
+ while (isdigit(*sp))
+ c = c * 10 + *sp++ - '0';
+ break;
+ case 'l':
+ if (sre && *sp != ')')
+ {
+ c = -1;
+ break;
+ }
+ if (c = *sp)
+ {
+ sp++;
+ if (isupper(c))
+ c = tolower(c);
+ sfputc(dp, c);
+ }
+ continue;
+ case 'u':
+ if (sre)
+ {
+ if (*sp != ')')
+ {
+ c = -1;
+ break;
+ }
+ sp++;
+ }
+ if (c = *sp)
+ {
+ sp++;
+ if (islower(c))
+ c = toupper(c);
+ sfputc(dp, c);
+ }
+ continue;
+ case 'E':
+ if (sre)
+ {
+ if (*sp != ')')
+ {
+ c = -1;
+ break;
+ }
+ sp++;
+ }
+ flags = f;
+ continue;
+ case 'L':
+ if (sre)
+ {
+ if (*sp != ')')
+ {
+ c = -1;
+ break;
+ }
+ sp++;
+ }
+ f = flags;
+ flags = REG_SUB_LOWER;
+ continue;
+ case 'U':
+ if (sre)
+ {
+ if (*sp != ')')
+ {
+ c = -1;
+ break;
+ }
+ sp++;
+ }
+ f = flags;
+ flags = REG_SUB_UPPER;
+ continue;
+ default:
+ if (!sre)
+ {
+ sfputc(dp, chresc(sp - 2, &s));
+ sp = (const char*)s;
+ continue;
+ }
+ sp--;
+ c = -1;
+ break;
+ }
+ if (sre)
+ {
+ if (c < 0 || *sp != ')')
+ {
+ for (; b < sp; b++)
+ sfputc(dp, *b);
+ continue;
+ }
+ sp++;
+ }
+ if (c >= nmatch)
+ return REG_ESUBREG;
+ s = (char*)op + match[c].rm_so;
+ e = (char*)op + match[c].rm_eo;
+ while (s < e)
+ {
+ c = *s++;
+ switch (flags)
+ {
+ case REG_SUB_UPPER:
+ if (islower(c))
+ c = toupper(c);
+ break;
+ case REG_SUB_LOWER:
+ if (isupper(c))
+ c = tolower(c);
+ break;
+ case REG_SUB_UPPER|REG_SUB_LOWER:
+ if (isupper(c))
+ c = tolower(c);
+ else if (islower(c))
+ c = toupper(c);
+ break;
+ }
+ sfputc(dp, c);
+ }
+ }
+}
+
+/*
+ * ed(1) style substitute using matches from last regexec()
+ */
+
+int
+regsub(const regex_t* p, Sfio_t* dp, const char* op, const char* sp, size_t nmatch, regmatch_t* match, regflags_t flags)
+{
+ int m;
+ int r;
+ int sre;
+
+ if ((p->env->flags & REG_NOSUB) || !nmatch)
+ return fatal(p->env->disc, REG_BADPAT, NiL);
+ m = (flags >> 16) & 0x3fff;
+ sre = !!(p->env->flags & REG_SHELL);
+ r = 0;
+ do
+ {
+ if (--m > 0)
+ sfwrite(dp, op, match->rm_eo);
+ else
+ {
+ sfwrite(dp, op, match->rm_so);
+ if (r = subold(dp, op, sp, nmatch, match, flags, sre))
+ return fatal(p->env->disc, r, NiL);
+ }
+ op += match->rm_eo;
+ } while ((m > 0 || (flags & REG_SUB_ALL)) && !(r = regexec(p, op, nmatch, match, p->env->flags|(match->rm_so == match->rm_eo ? REG_ADVANCE : 0))));
+ if (r && r != REG_NOMATCH)
+ return fatal(p->env->disc, r, NiL);
+ sfputr(dp, op, -1);
+ return 0;
+}
diff --git a/src/lib/libast/regex/regsubcomp.c b/src/lib/libast/regex/regsubcomp.c
new file mode 100644
index 0000000..73bde4c
--- /dev/null
+++ b/src/lib/libast/regex/regsubcomp.c
@@ -0,0 +1,377 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * posix regex ed(1) style substitute compile
+ */
+
+#include "reglib.h"
+
+static const regflags_t submap[] =
+{
+ 'g', REG_SUB_ALL,
+ 'l', REG_SUB_LOWER,
+ 'n', REG_SUB_NUMBER,
+ 'p', REG_SUB_PRINT,
+ 's', REG_SUB_STOP,
+ 'u', REG_SUB_UPPER,
+ 'w', REG_SUB_WRITE|REG_SUB_LAST,
+ 0, 0
+};
+
+int
+regsubflags(regex_t* p, register const char* s, char** e, int delim, register const regflags_t* map, int* pm, regflags_t* pf)
+{
+ register int c;
+ register const regflags_t* m;
+ regflags_t flags;
+ int minmatch;
+ regdisc_t* disc;
+
+ flags = pf ? *pf : 0;
+ minmatch = pm ? *pm : 0;
+ if (!map)
+ map = submap;
+ while (!(flags & REG_SUB_LAST))
+ {
+ if (!(c = *s++) || c == delim)
+ {
+ s--;
+ break;
+ }
+ else if (c >= '0' && c <= '9')
+ {
+ if (minmatch)
+ {
+ disc = p->env->disc;
+ regfree(p);
+ return fatal(disc, REG_EFLAGS, s - 1);
+ }
+ minmatch = c - '0';
+ while (*s >= '0' && *s <= '9')
+ minmatch = minmatch * 10 + *s++ - '0';
+ }
+ else
+ {
+ for (m = map; *m; m++)
+ if (*m++ == c)
+ {
+ if (flags & *m)
+ {
+ disc = p->env->disc;
+ regfree(p);
+ return fatal(disc, REG_EFLAGS, s - 1);
+ }
+ flags |= *m--;
+ break;
+ }
+ if (!*m)
+ {
+ s--;
+ break;
+ }
+ }
+ }
+ if (pf)
+ *pf = flags;
+ if (pm)
+ *pm = minmatch;
+ if (e)
+ *e = (char*)s;
+ return 0;
+}
+
+/*
+ * compile substitute rhs and optional flags
+ */
+
+int
+regsubcomp(regex_t* p, register const char* s, const regflags_t* map, int minmatch, regflags_t flags)
+{
+ register regsub_t* sub;
+ register int c;
+ register int d;
+ register char* t;
+ register regsubop_t* op;
+ char* e;
+ const char* r;
+ int sre;
+ int f;
+ int g;
+ int n;
+ int nops;
+ const char* o;
+ regdisc_t* disc;
+
+ disc = p->env->disc;
+ if (p->env->flags & REG_NOSUB)
+ {
+ regfree(p);
+ return fatal(disc, REG_BADPAT, NiL);
+ }
+ if (!(sub = (regsub_t*)alloc(p->env->disc, 0, sizeof(regsub_t) + strlen(s))) || !(sub->re_ops = (regsubop_t*)alloc(p->env->disc, 0, (nops = 8) * sizeof(regsubop_t))))
+ {
+ if (sub)
+ alloc(p->env->disc, sub, 0);
+ regfree(p);
+ return fatal(disc, REG_ESPACE, s);
+ }
+ sub->re_buf = sub->re_end = 0;
+ p->re_sub = sub;
+ p->env->sub = 1;
+ op = sub->re_ops;
+ o = s;
+ if (!(p->env->flags & REG_DELIMITED))
+ d = 0;
+ else
+ switch (d = *(s - 1))
+ {
+ case '\\':
+ case '\n':
+ case '\r':
+ regfree(p);
+ return fatal(disc, REG_EDELIM, s);
+ }
+ sre = p->env->flags & REG_SHELL;
+ t = sub->re_rhs;
+ if (d)
+ {
+ r = s;
+ for (;;)
+ {
+ if (!*s)
+ {
+ if (p->env->flags & REG_MUSTDELIM)
+ {
+ regfree(p);
+ return fatal(disc, REG_EDELIM, r);
+ }
+ break;
+ }
+ else if (*s == d)
+ {
+ flags |= REG_SUB_FULL;
+ s++;
+ break;
+ }
+ else if (*s++ == '\\' && !*s++)
+ {
+ regfree(p);
+ return fatal(disc, REG_EESCAPE, r);
+ }
+ }
+ if (*s)
+ {
+ if (n = regsubflags(p, s, &e, d, map, &minmatch, &flags))
+ return n;
+ s = (const char*)e;
+ }
+ p->re_npat = s - o;
+ s = r;
+ }
+ else
+ p->re_npat = 0;
+ op->op = f = g = flags & (REG_SUB_LOWER|REG_SUB_UPPER);
+ op->off = 0;
+ while ((c = *s++) != d)
+ {
+ again:
+ if (!c)
+ {
+ p->re_npat = s - o - 1;
+ break;
+ }
+ else if (c == '\\')
+ {
+ if (*s == c)
+ {
+ *t++ = *s++;
+ continue;
+ }
+ if ((c = *s++) == d)
+ goto again;
+ if (!c)
+ {
+ regfree(p);
+ return fatal(disc, REG_EESCAPE, s - 2);
+ }
+ if (c == '&')
+ {
+ *t++ = c;
+ continue;
+ }
+ }
+ else if (c == '&')
+ {
+ if (sre)
+ {
+ *t++ = c;
+ continue;
+ }
+ }
+ else
+ {
+ switch (op->op)
+ {
+ case REG_SUB_UPPER:
+ if (islower(c))
+ c = toupper(c);
+ break;
+ case REG_SUB_LOWER:
+ if (isupper(c))
+ c = tolower(c);
+ break;
+ case REG_SUB_UPPER|REG_SUB_LOWER:
+ if (isupper(c))
+ c = tolower(c);
+ else if (islower(c))
+ c = toupper(c);
+ break;
+ }
+ *t++ = c;
+ continue;
+ }
+ switch (c)
+ {
+ case 0:
+ s--;
+ continue;
+ case '&':
+ c = 0;
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ c -= '0';
+ if (isdigit(*s) && (p->env->flags & REG_MULTIREF))
+ c = c * 10 + *s++ - '0';
+ break;
+ case 'l':
+ if (c = *s)
+ {
+ s++;
+ if (isupper(c))
+ c = tolower(c);
+ *t++ = c;
+ }
+ continue;
+ case 'u':
+ if (c = *s)
+ {
+ s++;
+ if (islower(c))
+ c = toupper(c);
+ *t++ = c;
+ }
+ continue;
+ case 'E':
+ f = g;
+ set:
+ if ((op->len = (t - sub->re_rhs) - op->off) && (n = ++op - sub->re_ops) >= nops)
+ {
+ if (!(sub->re_ops = (regsubop_t*)alloc(p->env->disc, sub->re_ops, (nops *= 2) * sizeof(regsubop_t))))
+ {
+ regfree(p);
+ return fatal(disc, REG_ESPACE, NiL);
+ }
+ op = sub->re_ops + n;
+ }
+ op->op = f;
+ op->off = t - sub->re_rhs;
+ continue;
+ case 'L':
+ g = f;
+ f = REG_SUB_LOWER;
+ goto set;
+ case 'U':
+ g = f;
+ f = REG_SUB_UPPER;
+ goto set;
+ default:
+ if (!sre)
+ {
+ *t++ = chresc(s - 2, &e);
+ s = (const char*)e;
+ continue;
+ }
+ s--;
+ c = -1;
+ break;
+ }
+ if (c > p->re_nsub)
+ {
+ regfree(p);
+ return fatal(disc, REG_ESUBREG, s - 1);
+ }
+ if ((n = op - sub->re_ops) >= (nops - 2))
+ {
+ if (!(sub->re_ops = (regsubop_t*)alloc(p->env->disc, sub->re_ops, (nops *= 2) * sizeof(regsubop_t))))
+ {
+ regfree(p);
+ return fatal(disc, REG_ESPACE, NiL);
+ }
+ op = sub->re_ops + n;
+ }
+ if (op->len = (t - sub->re_rhs) - op->off)
+ op++;
+ op->op = f;
+ op->off = c;
+ op->len = 0;
+ op++;
+ op->op = f;
+ op->off = t - sub->re_rhs;
+ }
+ if ((op->len = (t - sub->re_rhs) - op->off) && (n = ++op - sub->re_ops) >= nops)
+ {
+ if (!(sub->re_ops = (regsubop_t*)alloc(p->env->disc, sub->re_ops, (nops *= 2) * sizeof(regsubop_t))))
+ {
+ regfree(p);
+ return fatal(disc, REG_ESPACE, NiL);
+ }
+ op = sub->re_ops + n;
+ }
+ op->len = -1;
+ sub->re_flags = flags;
+ sub->re_min = minmatch;
+ return 0;
+}
+
+void
+regsubfree(regex_t* p)
+{
+ Env_t* env;
+ regsub_t* sub;
+
+ if (p && (env = p->env) && env->sub && (sub = p->re_sub))
+ {
+ env->sub = 0;
+ p->re_sub = 0;
+ if (!(env->disc->re_flags & REG_NOFREE))
+ {
+ if (sub->re_buf)
+ alloc(env->disc, sub->re_buf, 0);
+ if (sub->re_ops)
+ alloc(env->disc, sub->re_ops, 0);
+ alloc(env->disc, sub, 0);
+ }
+ }
+}
diff --git a/src/lib/libast/regex/regsubexec.c b/src/lib/libast/regex/regsubexec.c
new file mode 100644
index 0000000..78caeba
--- /dev/null
+++ b/src/lib/libast/regex/regsubexec.c
@@ -0,0 +1,196 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * posix regex ed(1) style substitute execute
+ */
+
+#include "reglib.h"
+
+#define NEED(p,b,n,r) \
+ do \
+ { \
+ if (((b)->re_end - (b)->re_cur) < (n)) \
+ { \
+ size_t o = (b)->re_cur - (b)->re_buf; \
+ size_t a = ((b)->re_end - (b)->re_buf); \
+ if (a < n) \
+ a = roundof(n, 128); \
+ a *= 2; \
+ if (!((b)->re_buf = alloc(p->env->disc, (b)->re_buf, a))) \
+ { \
+ (b)->re_buf = (b)->re_cur = (b)->re_end = 0; \
+ c = REG_ESPACE; \
+ r; \
+ } \
+ (b)->re_cur = (b)->re_buf + o; \
+ (b)->re_end = (b)->re_buf + a; \
+ } \
+ } while (0)
+
+#define PUTC(p,b,x,r) \
+ do \
+ { \
+ NEED(p, b, 1, r); \
+ *(b)->re_cur++ = (x); \
+ } while (0)
+
+#define PUTS(p,b,x,z,r) \
+ do if (z) \
+ { \
+ NEED(p, b, z, r); \
+ memcpy((b)->re_cur, x, z); \
+ (b)->re_cur += (z); \
+ } while (0)
+
+/*
+ * do a single substitution
+ */
+
+static int
+sub(const regex_t* p, register regsub_t* b, const char* ss, register regsubop_t* op, size_t nmatch, register regmatch_t* match)
+{
+ register char* s;
+ register char* e;
+ register int c;
+
+ for (;; op++)
+ {
+ switch (op->len)
+ {
+ case -1:
+ break;
+ case 0:
+ if (op->off >= nmatch)
+ return REG_ESUBREG;
+ if ((c = match[op->off].rm_so) < 0)
+ continue;
+ s = (char*)ss + c;
+ if ((c = match[op->off].rm_eo) < 0)
+ continue;
+ e = (char*)ss + c;
+ NEED(p, b, e - s, return c);
+ switch (op->op)
+ {
+ case REG_SUB_UPPER:
+ while (s < e)
+ {
+ c = *s++;
+ if (islower(c))
+ c = toupper(c);
+ *b->re_cur++ = c;
+ }
+ break;
+ case REG_SUB_LOWER:
+ while (s < e)
+ {
+ c = *s++;
+ if (isupper(c))
+ c = tolower(c);
+ *b->re_cur++ = c;
+ }
+ break;
+ case REG_SUB_UPPER|REG_SUB_LOWER:
+ while (s < e)
+ {
+ c = *s++;
+ if (isupper(c))
+ c = tolower(c);
+ else if (islower(c))
+ c = toupper(c);
+ *b->re_cur++ = c;
+ }
+ break;
+ default:
+ while (s < e)
+ *b->re_cur++ = *s++;
+ break;
+ }
+ continue;
+ default:
+ NEED(p, b, op->len, return c);
+ s = b->re_rhs + op->off;
+ e = s + op->len;
+ while (s < e)
+ *b->re_cur++ = *s++;
+ continue;
+ }
+ break;
+ }
+ return 0;
+}
+
+/*
+ * ed(1) style substitute using matches from last regexec()
+ */
+
+int
+regsubexec(const regex_t* p, const char* s, size_t nmatch, regmatch_t* match)
+{
+ register int c;
+ register regsub_t* b;
+ const char* e;
+ int m;
+
+ if (!p->env->sub || (p->env->flags & REG_NOSUB) || !nmatch)
+ return fatal(p->env->disc, REG_BADPAT, NiL);
+ b = p->re_sub;
+ m = b->re_min;
+ b->re_cur = b->re_buf;
+ e = (const char*)p->env->end;
+ c = 0;
+ for (;;)
+ {
+ if (--m > 0)
+ PUTS(p, b, s, match->rm_eo, return fatal(p->env->disc, c, NiL));
+ else
+ {
+ PUTS(p, b, s, match->rm_so, return fatal(p->env->disc, c, NiL));
+ if (!c && (c = sub(p, b, s, b->re_ops, nmatch, match)))
+ return fatal(p->env->disc, c, NiL);
+ }
+ s += match->rm_eo;
+ if (m <= 0 && !(b->re_flags & REG_SUB_ALL) || !*s)
+ break;
+ if (c = regnexec(p, s, e - s, nmatch, match, p->env->flags|(match->rm_so == match->rm_eo ? REG_ADVANCE : 0)))
+ {
+ if (c != REG_NOMATCH)
+ return fatal(p->env->disc, c, NiL);
+ break;
+ }
+ if (!match->rm_so && !match->rm_eo && *s && m <= 1)
+ {
+ match->rm_so = match->rm_eo = 1;
+ c = 1;
+ }
+ }
+ while (s < e)
+ {
+ c = *s++;
+ PUTC(p, b, c, return fatal(p->env->disc, c, NiL));
+ }
+ NEED(p, b, 1, return fatal(p->env->disc, c, NiL));
+ *b->re_cur = 0;
+ b->re_len = b->re_cur - b->re_buf;
+ return 0;
+}
diff --git a/src/lib/libast/sfio/_sfclrerr.c b/src/lib/libast/sfio/_sfclrerr.c
new file mode 100644
index 0000000..e00dc1b
--- /dev/null
+++ b/src/lib/libast/sfio/_sfclrerr.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sfclrerr
+
+#if __STD_C
+int sfclrerr(reg Sfio_t* f)
+#else
+int sfclrerr(f)
+reg Sfio_t* f;
+#endif
+{
+ return __sf_clrerr(f);
+}
diff --git a/src/lib/libast/sfio/_sfdlen.c b/src/lib/libast/sfio/_sfdlen.c
new file mode 100644
index 0000000..0b0a9f5
--- /dev/null
+++ b/src/lib/libast/sfio/_sfdlen.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sfdlen
+
+#if __STD_C
+int sfdlen(reg Sfdouble_t v)
+#else
+int sfdlen(v)
+reg Sfdouble_t v;
+#endif
+{
+ return __sf_dlen(v);
+}
diff --git a/src/lib/libast/sfio/_sfeof.c b/src/lib/libast/sfio/_sfeof.c
new file mode 100644
index 0000000..63dc002
--- /dev/null
+++ b/src/lib/libast/sfio/_sfeof.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sfeof
+
+#if __STD_C
+int sfeof(reg Sfio_t* f)
+#else
+int sfeof(f)
+reg Sfio_t* f;
+#endif
+{
+ return __sf_eof(f);
+}
diff --git a/src/lib/libast/sfio/_sferror.c b/src/lib/libast/sfio/_sferror.c
new file mode 100644
index 0000000..43b1a03
--- /dev/null
+++ b/src/lib/libast/sfio/_sferror.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sferror
+
+#if __STD_C
+int sferror(reg Sfio_t* f)
+#else
+int sferror(f)
+reg Sfio_t* f;
+#endif
+{
+ return __sf_error(f);
+}
diff --git a/src/lib/libast/sfio/_sffileno.c b/src/lib/libast/sfio/_sffileno.c
new file mode 100644
index 0000000..f61a830
--- /dev/null
+++ b/src/lib/libast/sfio/_sffileno.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sffileno
+
+#if __STD_C
+int sffileno(reg Sfio_t* f)
+#else
+int sffileno(f)
+reg Sfio_t* f;
+#endif
+{
+ return __sf_fileno(f);
+}
diff --git a/src/lib/libast/sfio/_sfgetc.c b/src/lib/libast/sfio/_sfgetc.c
new file mode 100644
index 0000000..08a51b3
--- /dev/null
+++ b/src/lib/libast/sfio/_sfgetc.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sfgetc
+
+#if __STD_C
+int sfgetc(reg Sfio_t* f)
+#else
+int sfgetc(f)
+reg Sfio_t* f;
+#endif
+{
+ return __sf_getc(f);
+}
diff --git a/src/lib/libast/sfio/_sfgetl.c b/src/lib/libast/sfio/_sfgetl.c
new file mode 100644
index 0000000..cc66462
--- /dev/null
+++ b/src/lib/libast/sfio/_sfgetl.c
@@ -0,0 +1,42 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/*
+ * for backwards compatibility with pre-threaded sfgetl() inline
+ */
+
+#ifdef __EXPORT__
+#define extern __EXPORT__
+#endif
+
+extern
+#if __STD_C
+Sflong_t _sfgetl(reg Sfio_t* f)
+#else
+Sflong_t _sfgetl(f)
+reg Sfio_t* f;
+#endif
+{
+ sfungetc(f, (unsigned char)_SF_(f)->val);
+ return sfgetl(f);
+}
diff --git a/src/lib/libast/sfio/_sfgetl2.c b/src/lib/libast/sfio/_sfgetl2.c
new file mode 100644
index 0000000..a6f9373
--- /dev/null
+++ b/src/lib/libast/sfio/_sfgetl2.c
@@ -0,0 +1,50 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/* OBSOLETE 19961031 -- for shared library compatibility */
+
+#include "sfhdr.h"
+
+#undef _sfgetl2
+
+_BEGIN_EXTERNS_
+#if _BLD_sfio && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern long _sfgetl2 _ARG_((Sfio_t*, long));
+
+#undef extern
+_END_EXTERNS_
+
+#if __STD_C
+long _sfgetl2(reg Sfio_t* f, long v)
+#else
+long _sfgetl2(f, v)
+reg Sfio_t* f;
+long v;
+#endif
+{
+ if (v < 0)
+ return -1;
+ sfungetc(f, v);
+ return sfgetl(f);
+}
diff --git a/src/lib/libast/sfio/_sfgetu.c b/src/lib/libast/sfio/_sfgetu.c
new file mode 100644
index 0000000..183f1a4
--- /dev/null
+++ b/src/lib/libast/sfio/_sfgetu.c
@@ -0,0 +1,42 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/*
+ * for backwards compatibility with pre-threaded sfgetl() inline
+ */
+
+#ifdef __EXPORT__
+#define extern __EXPORT__
+#endif
+
+extern
+#if __STD_C
+Sfulong_t _sfgetu(reg Sfio_t* f)
+#else
+Sfulong_t _sfgetu(f)
+reg Sfio_t* f;
+#endif
+{
+ sfungetc(f, (unsigned char)_SF_(f)->val);
+ return sfgetu(f);
+}
diff --git a/src/lib/libast/sfio/_sfgetu2.c b/src/lib/libast/sfio/_sfgetu2.c
new file mode 100644
index 0000000..27f5661
--- /dev/null
+++ b/src/lib/libast/sfio/_sfgetu2.c
@@ -0,0 +1,50 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/* OBSOLETE 19961031 -- for shared library compatibility */
+
+#include "sfhdr.h"
+
+#undef _sfgetu2
+
+_BEGIN_EXTERNS_
+#if _BLD_sfio && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern long _sfgetu2 _ARG_((Sfio_t*, long));
+
+#undef extern
+_END_EXTERNS_
+
+#if __STD_C
+long _sfgetu2(reg Sfio_t* f, long v)
+#else
+long _sfgetu2(f, v)
+reg Sfio_t* f;
+long v;
+#endif
+{
+ if (v < 0)
+ return -1;
+ sfungetc(f, v);
+ return sfgetu(f);
+}
diff --git a/src/lib/libast/sfio/_sfllen.c b/src/lib/libast/sfio/_sfllen.c
new file mode 100644
index 0000000..2e735e3
--- /dev/null
+++ b/src/lib/libast/sfio/_sfllen.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sfllen
+
+#if __STD_C
+int sfllen(reg Sflong_t v)
+#else
+int sfllen(v)
+reg Sflong_t v;
+#endif
+{
+ return __sf_llen(v);
+}
diff --git a/src/lib/libast/sfio/_sfopen.c b/src/lib/libast/sfio/_sfopen.c
new file mode 100644
index 0000000..9ad93fc
--- /dev/null
+++ b/src/lib/libast/sfio/_sfopen.c
@@ -0,0 +1,219 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Open a file/string for IO.
+** If f is not nil, it is taken as an existing stream that should be
+** closed and its structure reused for the new stream.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if _BLD_sfio && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+extern
+#undef extern
+
+#if __STD_C
+Sfio_t* _sfopen(Sfio_t* f, const char* file, const char* mode)
+#else
+Sfio_t* _sfopen(f,file,mode)
+Sfio_t* f; /* old stream structure */
+char* file; /* file/string to be opened */
+char* mode; /* mode of the stream */
+#endif
+{
+ int fd, oldfd, oflags, sflags;
+ SFMTXDECL(f);
+
+ /* get the control flags */
+ if((sflags = _sftype(mode,&oflags,NIL(int*))) == 0)
+ return NIL(Sfio_t*);
+
+ /* changing the control flags */
+ if(f && !file && !((f->flags|sflags)&SF_STRING) )
+ { SFMTXENTER(f, NIL(Sfio_t*));
+
+ if(f->mode&SF_INIT ) /* stream uninitialized, ok to set flags */
+ { f->flags |= (sflags & (SF_FLAGS & ~SF_RDWR));
+
+ if((sflags &= SF_RDWR) != 0) /* reset read/write modes */
+ { f->flags = (f->flags & ~SF_RDWR) | sflags;
+
+ if((f->flags&SF_RDWR) == SF_RDWR)
+ f->bits |= SF_BOTH;
+ else f->bits &= ~SF_BOTH;
+
+ if(f->flags&SF_READ)
+ f->mode = (f->mode&~SF_WRITE)|SF_READ;
+ else f->mode = (f->mode&~SF_READ)|SF_WRITE;
+ }
+ }
+ else /* make sure there is no buffered data */
+ { if(sfsync(f) < 0)
+ SFMTXRETURN(f,NIL(Sfio_t*));
+ }
+
+ if(f->file >= 0 && (oflags &= (O_TEXT|O_BINARY|O_APPEND)) != 0 )
+ { /* set file access control */
+ int ctl = sysfcntlf(f->file, F_GETFL, 0);
+ ctl = (ctl & ~(O_TEXT|O_BINARY|O_APPEND)) | oflags;
+ sysfcntlf(f->file, F_SETFL, ctl);
+ }
+
+ SFMTXRETURN(f,f);
+ }
+
+ if(sflags&SF_STRING)
+ { f = sfnew(f,(char*)file,
+ file ? (size_t)strlen((char*)file) : (size_t)SF_UNBOUND,
+ -1,sflags);
+ }
+ else
+ { if(!file)
+ return NIL(Sfio_t*);
+
+#if _has_oflags /* open the file */
+ while((fd = sysopenf((char*)file,oflags,SF_CREATMODE)) < 0 && errno == EINTR)
+ errno = 0;
+#else
+ while((fd = sysopenf(file,oflags&O_ACCMODE)) < 0 && errno == EINTR)
+ errno = 0;
+ if(fd >= 0)
+ { if((oflags&(O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL) )
+ { CLOSE(fd); /* error: file already exists */
+ return NIL(Sfio_t*);
+ }
+ if(oflags&O_TRUNC ) /* truncate file */
+ { reg int tf;
+ while((tf = syscreatf(file,SF_CREATMODE)) < 0 &&
+ errno == EINTR)
+ errno = 0;
+ CLOSE(tf);
+ }
+ }
+ else if(oflags&O_CREAT)
+ { while((fd = syscreatf(file,SF_CREATMODE)) < 0 && errno == EINTR)
+ errno = 0;
+ if((oflags&O_ACCMODE) != O_WRONLY)
+ { /* the file now exists, reopen it for read/write */
+ CLOSE(fd);
+ while((fd = sysopenf(file,oflags&O_ACCMODE)) < 0 &&
+ errno == EINTR)
+ errno = 0;
+ }
+ }
+#endif
+ if(fd < 0)
+ return NIL(Sfio_t*);
+
+ /* we may have to reset the file descriptor to its old value */
+ oldfd = f ? f->file : -1;
+ if((f = sfnew(f,NIL(char*),(size_t)SF_UNBOUND,fd,sflags)) && oldfd >= 0)
+ (void)sfsetfd(f,oldfd);
+ }
+
+ return f;
+}
+
+#if __STD_C
+int _sftype(reg const char* mode, int* oflagsp, int* uflagp)
+#else
+int _sftype(mode, oflagsp, uflagp)
+reg char* mode;
+int* oflagsp;
+int* uflagp;
+#endif
+{
+ reg int sflags, oflags, uflag;
+
+ if(!mode)
+ return 0;
+
+ /* construct the open flags */
+ sflags = oflags = uflag = 0;
+ while(1) switch(*mode++)
+ {
+ case 'a' :
+ sflags |= SF_WRITE | SF_APPENDWR;
+ oflags |= O_WRONLY | O_APPEND | O_CREAT;
+ continue;
+ case 'b' :
+ oflags |= O_BINARY;
+ continue;
+ case 'm' :
+ sflags |= SF_MTSAFE;
+ uflag = 0;
+ continue;
+ case 'r' :
+ sflags |= SF_READ;
+ oflags |= O_RDONLY;
+ continue;
+ case 's' :
+ sflags |= SF_STRING;
+ continue;
+ case 't' :
+ oflags |= O_TEXT;
+ continue;
+ case 'u' :
+ sflags &= ~SF_MTSAFE;
+ uflag = 1;
+ continue;
+ case 'w' :
+ sflags |= SF_WRITE;
+ oflags |= O_WRONLY | O_CREAT;
+ if(!(sflags&SF_READ))
+ oflags |= O_TRUNC;
+ continue;
+ case 'x' :
+ oflags |= O_EXCL;
+ continue;
+ case 'F':
+ /* stdio compatibility -- fd >= FOPEN_MAX (or other magic number) ok */
+ continue;
+ case 'W' :
+ sflags |= SF_WCWIDTH;
+ uflag = 0;
+ continue;
+ case '+' :
+ if(sflags)
+ sflags |= SF_READ|SF_WRITE;
+ continue;
+ default :
+ if(!(oflags&O_CREAT) )
+ oflags &= ~O_EXCL;
+#if _WIN32 && !_WINIX
+ if(!(oflags&(O_BINARY|O_TEXT)))
+ oflags |= O_BINARY;
+#endif
+ if((sflags&SF_RDWR) == SF_RDWR)
+ oflags = (oflags&~O_ACCMODE)|O_RDWR;
+ if(oflagsp)
+ *oflagsp = oflags;
+ if(uflagp)
+ *uflagp = uflag;
+ if((sflags&(SF_STRING|SF_RDWR)) == SF_STRING)
+ sflags |= SF_READ;
+ return sflags;
+ }
+}
diff --git a/src/lib/libast/sfio/_sfputc.c b/src/lib/libast/sfio/_sfputc.c
new file mode 100644
index 0000000..8f577e4
--- /dev/null
+++ b/src/lib/libast/sfio/_sfputc.c
@@ -0,0 +1,35 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sfputc
+
+#if __STD_C
+int sfputc(reg Sfio_t* f, reg int c)
+#else
+int sfputc(f,c)
+reg Sfio_t* f;
+reg int c;
+#endif
+{
+ return __sf_putc(f,c);
+}
diff --git a/src/lib/libast/sfio/_sfputd.c b/src/lib/libast/sfio/_sfputd.c
new file mode 100644
index 0000000..733caa6
--- /dev/null
+++ b/src/lib/libast/sfio/_sfputd.c
@@ -0,0 +1,96 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Write out a floating point value in a portable format
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+int _sfputd(Sfio_t* f, Sfdouble_t v)
+#else
+int _sfputd(f,v)
+Sfio_t* f;
+Sfdouble_t v;
+#endif
+{
+#define N_ARRAY (16*sizeof(Sfdouble_t))
+ reg ssize_t n, w;
+ reg uchar *s, *ends;
+ int exp;
+ uchar c[N_ARRAY];
+ Sfdouble_t x;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f,-1);
+
+ if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0)
+ SFMTXRETURN(f, -1);
+ SFLOCK(f,0);
+
+ /* get the sign of v */
+ if(v < 0.)
+ { v = -v;
+ n = 1;
+ }
+ else n = 0;
+
+ /* make the magnitude of v < 1 */
+ if(v != 0.)
+ v = frexpl(v,&exp);
+ else exp = 0;
+
+ /* code the sign of v and exp */
+ if((w = exp) < 0)
+ { n |= 02;
+ w = -w;
+ }
+
+ /* write out the signs and the exp */
+ SFOPEN(f,0);
+ if(sfputc(f,n) < 0 || (w = sfputu(f,w)) < 0)
+ SFMTXRETURN(f, -1);
+ SFLOCK(f,0);
+ w += 1;
+
+ s = (ends = &c[0])+sizeof(c);
+ while(s > ends)
+ { /* get 2^SF_PRECIS precision at a time */
+ n = (int)(x = ldexpl(v,SF_PRECIS));
+ *--s = n|SF_MORE;
+ v = x-n;
+ if(v <= 0.)
+ break;
+ }
+
+ /* last byte is not SF_MORE */
+ ends = &c[0] + sizeof(c) -1;
+ *ends &= ~SF_MORE;
+
+ /* write out coded bytes */
+ n = ends - s + 1;
+ w = SFWRITE(f,(Void_t*)s,n) == n ? w+n : -1;
+
+ SFOPEN(f,0);
+ SFMTXRETURN(f,w);
+}
diff --git a/src/lib/libast/sfio/_sfputl.c b/src/lib/libast/sfio/_sfputl.c
new file mode 100644
index 0000000..df3d9a7
--- /dev/null
+++ b/src/lib/libast/sfio/_sfputl.c
@@ -0,0 +1,82 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Write out a long value in a portable format
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+int _sfputl(Sfio_t* f, Sflong_t v)
+#else
+int _sfputl(f,v)
+Sfio_t* f; /* write a portable long to this stream */
+Sflong_t v; /* the value to be written */
+#endif
+{
+#define N_ARRAY (2*sizeof(Sflong_t))
+ reg uchar *s, *ps;
+ reg ssize_t n, p;
+ uchar c[N_ARRAY];
+ SFMTXDECL(f);
+
+ SFMTXENTER(f,-1);
+ if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0)
+ SFMTXRETURN(f, -1);
+ SFLOCK(f,0);
+
+ s = ps = &(c[N_ARRAY-1]);
+ if(v < 0)
+ { /* add 1 to avoid 2-complement problems with -SF_MAXINT */
+ v = -(v+1);
+ *s = (uchar)(SFSVALUE(v) | SF_SIGN);
+ }
+ else *s = (uchar)(SFSVALUE(v));
+ v = (Sfulong_t)v >> SF_SBITS;
+
+ while(v > 0)
+ { *--s = (uchar)(SFUVALUE(v) | SF_MORE);
+ v = (Sfulong_t)v >> SF_UBITS;
+ }
+ n = (ps-s)+1;
+
+ if(n > 8 || SFWPEEK(f,ps,p) < n)
+ n = SFWRITE(f,(Void_t*)s,n); /* write the hard way */
+ else
+ { switch(n)
+ {
+ case 8 : *ps++ = *s++;
+ case 7 : *ps++ = *s++;
+ case 6 : *ps++ = *s++;
+ case 5 : *ps++ = *s++;
+ case 4 : *ps++ = *s++;
+ case 3 : *ps++ = *s++;
+ case 2 : *ps++ = *s++;
+ case 1 : *ps++ = *s++;
+ }
+ f->next = ps;
+ }
+
+ SFOPEN(f,0);
+ SFMTXRETURN(f, n);
+}
diff --git a/src/lib/libast/sfio/_sfputm.c b/src/lib/libast/sfio/_sfputm.c
new file mode 100644
index 0000000..1fa9d9d
--- /dev/null
+++ b/src/lib/libast/sfio/_sfputm.c
@@ -0,0 +1,78 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Write out an unsigned long value in a portable format.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+int _sfputm(Sfio_t* f, Sfulong_t v, Sfulong_t m)
+#else
+int _sfputm(f,v,m)
+Sfio_t* f; /* write a portable ulong to this stream */
+Sfulong_t v; /* the unsigned value to be written */
+Sfulong_t m; /* the max value of the range */
+#endif
+{
+#define N_ARRAY (2*sizeof(Sfulong_t))
+ reg uchar *s, *ps;
+ reg ssize_t n, p;
+ uchar c[N_ARRAY];
+ SFMTXDECL(f);
+
+ SFMTXENTER(f, -1);
+
+ if(v > m || (f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0) )
+ SFMTXRETURN(f, -1);
+ SFLOCK(f,0);
+
+ /* code v as integers in base SF_UBASE */
+ s = ps = &(c[N_ARRAY-1]);
+ *s = (uchar)SFBVALUE(v);
+ while((m >>= SF_BBITS) > 0 )
+ { v >>= SF_BBITS;
+ *--s = (uchar)SFBVALUE(v);
+ }
+ n = (ps-s)+1;
+
+ if(n > 8 || SFWPEEK(f,ps,p) < n)
+ n = SFWRITE(f,(Void_t*)s,n); /* write the hard way */
+ else
+ { switch(n)
+ {
+ case 8 : *ps++ = *s++;
+ case 7 : *ps++ = *s++;
+ case 6 : *ps++ = *s++;
+ case 5 : *ps++ = *s++;
+ case 4 : *ps++ = *s++;
+ case 3 : *ps++ = *s++;
+ case 2 : *ps++ = *s++;
+ case 1 : *ps++ = *s++;
+ }
+ f->next = ps;
+ }
+
+ SFOPEN(f,0);
+ SFMTXRETURN(f, (int)n);
+}
diff --git a/src/lib/libast/sfio/_sfputu.c b/src/lib/libast/sfio/_sfputu.c
new file mode 100644
index 0000000..e632d9d
--- /dev/null
+++ b/src/lib/libast/sfio/_sfputu.c
@@ -0,0 +1,75 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Write out an unsigned long value in a portable format.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+int _sfputu(Sfio_t* f, Sfulong_t v)
+#else
+int _sfputu(f,v)
+Sfio_t* f; /* write a portable ulong to this stream */
+Sfulong_t v; /* the unsigned value to be written */
+#endif
+{
+#define N_ARRAY (2*sizeof(Sfulong_t))
+ reg uchar *s, *ps;
+ reg ssize_t n, p;
+ uchar c[N_ARRAY];
+ SFMTXDECL(f);
+
+ SFMTXENTER(f, -1);
+
+ if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0)
+ SFMTXRETURN(f, -1);
+ SFLOCK(f,0);
+
+ /* code v as integers in base SF_UBASE */
+ s = ps = &(c[N_ARRAY-1]);
+ *s = (uchar)SFUVALUE(v);
+ while((v >>= SF_UBITS) )
+ *--s = (uchar)(SFUVALUE(v) | SF_MORE);
+ n = (ps-s)+1;
+
+ if(n > 8 || SFWPEEK(f,ps,p) < n)
+ n = SFWRITE(f,(Void_t*)s,n); /* write the hard way */
+ else
+ { switch(n)
+ {
+ case 8 : *ps++ = *s++;
+ case 7 : *ps++ = *s++;
+ case 6 : *ps++ = *s++;
+ case 5 : *ps++ = *s++;
+ case 4 : *ps++ = *s++;
+ case 3 : *ps++ = *s++;
+ case 2 : *ps++ = *s++;
+ case 1 : *ps++ = *s++;
+ }
+ f->next = ps;
+ }
+
+ SFOPEN(f,0);
+ SFMTXRETURN(f, (int)n);
+}
diff --git a/src/lib/libast/sfio/_sfslen.c b/src/lib/libast/sfio/_sfslen.c
new file mode 100644
index 0000000..e34958e
--- /dev/null
+++ b/src/lib/libast/sfio/_sfslen.c
@@ -0,0 +1,33 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sfslen
+
+#if __STD_C
+ssize_t sfslen(void)
+#else
+ssize_t sfslen()
+#endif
+{
+ return __sf_slen();
+}
diff --git a/src/lib/libast/sfio/_sfstacked.c b/src/lib/libast/sfio/_sfstacked.c
new file mode 100644
index 0000000..a785ed5
--- /dev/null
+++ b/src/lib/libast/sfio/_sfstacked.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sfstacked
+
+#if __STD_C
+int sfstacked(reg Sfio_t* f)
+#else
+int sfstacked(f)
+reg Sfio_t* f;
+#endif
+{
+ return __sf_stacked(f);
+}
diff --git a/src/lib/libast/sfio/_sfulen.c b/src/lib/libast/sfio/_sfulen.c
new file mode 100644
index 0000000..71bb258
--- /dev/null
+++ b/src/lib/libast/sfio/_sfulen.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sfulen
+
+#if __STD_C
+int sfulen(reg Sfulong_t v)
+#else
+int sfulen(v)
+reg Sfulong_t v;
+#endif
+{
+ return __sf_ulen(v);
+}
diff --git a/src/lib/libast/sfio/_sfvalue.c b/src/lib/libast/sfio/_sfvalue.c
new file mode 100644
index 0000000..b8dcce7
--- /dev/null
+++ b/src/lib/libast/sfio/_sfvalue.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sfvalue
+
+#if __STD_C
+ssize_t sfvalue(reg Sfio_t* f)
+#else
+ssize_t sfvalue(f)
+reg Sfio_t* f;
+#endif
+{
+ return __sf_value(f);
+}
diff --git a/src/lib/libast/sfio/sfclose.c b/src/lib/libast/sfio/sfclose.c
new file mode 100644
index 0000000..4fb6529
--- /dev/null
+++ b/src/lib/libast/sfio/sfclose.c
@@ -0,0 +1,178 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Close a stream. A file stream is synced before closing.
+**
+** Written by Kiem-Phong Vo
+*/
+
+#if __STD_C
+int sfclose(Sfio_t* f)
+#else
+int sfclose(f)
+Sfio_t* f;
+#endif
+{
+ reg int local, ex, rv;
+ Void_t* data = NIL(Void_t*);
+ SFMTXDECL(f); /* declare a local stream variable for multithreading */
+
+ SFMTXENTER(f, -1);
+
+ GETLOCAL(f,local);
+
+ if(!(f->mode&SF_INIT) &&
+ SFMODE(f,local) != (f->mode&SF_RDWR) &&
+ SFMODE(f,local) != (f->mode&(SF_READ|SF_SYNCED)) &&
+ _sfmode(f,SF_SYNCED,local) < 0)
+ SFMTXRETURN(f,-1);
+
+ /* closing a stack of streams */
+ while(f->push)
+ { reg Sfio_t* pop;
+
+ if(!(pop = (*_Sfstack)(f,NIL(Sfio_t*))) )
+ SFMTXRETURN(f,-1);
+
+ if(sfclose(pop) < 0)
+ { (*_Sfstack)(f,pop);
+ SFMTXRETURN(f,-1);
+ }
+ }
+
+ rv = 0;
+ if(f->disc == _Sfudisc) /* closing the ungetc stream */
+ f->disc = NIL(Sfdisc_t*);
+ else if(f->file >= 0) /* sync file pointer */
+ { f->bits |= SF_ENDING;
+ rv = sfsync(f);
+ }
+
+ SFLOCK(f,0);
+
+ /* raise discipline exceptions */
+ if(f->disc && (ex = SFRAISE(f,local ? SF_NEW : SF_CLOSING,NIL(Void_t*))) != 0)
+ SFMTXRETURN(f,ex);
+
+ if(!local && f->pool)
+ { /* remove from pool */
+ if(f->pool == &_Sfpool)
+ { reg int n;
+
+ POOLMTXLOCK(&_Sfpool);
+ for(n = 0; n < _Sfpool.n_sf; ++n)
+ { if(_Sfpool.sf[n] != f)
+ continue;
+ /* found it */
+ _Sfpool.n_sf -= 1;
+ for(; n < _Sfpool.n_sf; ++n)
+ _Sfpool.sf[n] = _Sfpool.sf[n+1];
+ break;
+ }
+ POOLMTXUNLOCK(&_Sfpool);
+ }
+ else
+ { f->mode &= ~SF_LOCK; /**/ASSERT(_Sfpmove);
+ if((*_Sfpmove)(f,-1) < 0)
+ { SFOPEN(f,0);
+ SFMTXRETURN(f,-1);
+ }
+ f->mode |= SF_LOCK;
+ }
+ f->pool = NIL(Sfpool_t*);
+ }
+
+ if(f->data && (!local || (f->flags&SF_STRING) || (f->bits&SF_MMAP) ) )
+ { /* free buffer */
+#ifdef MAP_TYPE
+ if(f->bits&SF_MMAP)
+ SFMUNMAP(f,f->data,f->endb-f->data);
+ else
+#endif
+ if(f->flags&SF_MALLOC)
+ data = (Void_t*)f->data;
+
+ f->data = NIL(uchar*);
+ f->size = -1;
+ }
+
+ /* zap the file descriptor */
+ if(_Sfnotify)
+ (*_Sfnotify)(f, SF_CLOSING, (void*)((long)f->file));
+ if(f->file >= 0 && !(f->flags&SF_STRING))
+ { while(sysclosef(f->file) < 0 )
+ { if(errno == EINTR)
+ errno = 0;
+ else
+ { rv = -1;
+ break;
+ }
+ }
+ }
+ f->file = -1;
+
+ SFKILL(f);
+ f->flags &= SF_STATIC;
+ f->here = 0;
+ f->extent = -1;
+ f->endb = f->endr = f->endw = f->next = f->data;
+
+ /* zap any associated auxiliary buffer */
+ if(f->rsrv)
+ { free(f->rsrv);
+ f->rsrv = NIL(Sfrsrv_t*);
+ }
+
+ /* delete any associated sfpopen-data */
+ if(f->proc && _sfpclose(f) < 0 )
+ rv = -1;
+
+ /* destroy the mutex */
+ if(f->mutex)
+ { (void)vtmtxclrlock(f->mutex);
+ if(f != sfstdin && f != sfstdout && f != sfstderr)
+ { (void)vtmtxclose(f->mutex);
+ f->mutex = NIL(Vtmutex_t*);
+ }
+ }
+
+ if(!local)
+ { if(f->disc && (ex = SFRAISE(f,SF_FINAL,NIL(Void_t*))) != 0 )
+ { rv = ex;
+ goto done;
+ }
+
+ if(!(f->flags&SF_STATIC) )
+ free(f);
+ else
+ { f->disc = NIL(Sfdisc_t*);
+ f->stdio = NIL(Void_t*);
+ f->mode = SF_AVAIL;
+ }
+ }
+
+done:
+ if(data)
+ free(data);
+ return rv;
+}
diff --git a/src/lib/libast/sfio/sfclrlock.c b/src/lib/libast/sfio/sfclrlock.c
new file mode 100644
index 0000000..711756a
--- /dev/null
+++ b/src/lib/libast/sfio/sfclrlock.c
@@ -0,0 +1,63 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Function to clear a locked stream.
+** This is useful for programs that longjmp from the mid of an sfio function.
+** There is no guarantee on data integrity in such a case.
+**
+** Written by Kiem-Phong Vo
+*/
+#if __STD_C
+int sfclrlock(Sfio_t* f)
+#else
+int sfclrlock(f)
+Sfio_t *f;
+#endif
+{
+ int rv;
+ SFMTXDECL(f); /* declare a local stream variable for multithreading */
+
+ /* already closed */
+ if(f && (f->mode&SF_AVAIL))
+ return 0;
+
+ SFMTXENTER(f,0);
+
+ /* clear error bits */
+ f->flags &= ~(SF_ERROR|SF_EOF);
+
+ /* clear peek locks */
+ if(f->mode&SF_PKRD)
+ { f->here -= f->endb-f->next;
+ f->endb = f->next;
+ }
+
+ SFCLRBITS(f);
+
+ /* throw away all lock bits except for stacking state SF_PUSH */
+ f->mode &= (SF_RDWR|SF_INIT|SF_POOL|SF_PUSH|SF_SYNCED|SF_STDIO);
+
+ rv = (f->mode&SF_PUSH) ? 0 : (f->flags&SF_FLAGS);
+
+ SFMTXRETURN(f, rv);
+}
diff --git a/src/lib/libast/sfio/sfcvt.c b/src/lib/libast/sfio/sfcvt.c
new file mode 100644
index 0000000..ca01f20
--- /dev/null
+++ b/src/lib/libast/sfio/sfcvt.c
@@ -0,0 +1,532 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if __STDC__
+#include "FEATURE/isoc99"
+#endif
+#include "sfhdr.h"
+
+/* Convert a floating point value to ASCII.
+**
+** Written by Kiem-Phong Vo and Glenn Fowler (SFFMT_AFORMAT)
+*/
+
+static char *lc_inf = "inf", *uc_inf = "INF";
+static char *lc_nan = "nan", *uc_nan = "NAN";
+static char *Zero = "0";
+#define SF_INF ((_Sfi = 3), strlcpy(buf, (format & SFFMT_UPPER) ? uc_inf : lc_inf, size), buf)
+#define SF_NAN ((_Sfi = 3), strlcpy(buf, (format & SFFMT_UPPER) ? uc_nan : lc_nan, size), buf)
+#define SF_ZERO ((_Sfi = 1), strlcpy(buf, Zero, size), buf)
+#define SF_INTPART (SF_IDIGITS/2)
+
+#if ! _lib_isnan
+#if _lib_fpclassify
+#define isnan(n) (fpclassify(n)==FP_NAN)
+#define isnanl(n) (fpclassify(n)==FP_NAN)
+#else
+#define isnan(n) (memcmp((void*)&n,(void*)&_Sfdnan,sizeof(n))==0)
+#define isnanl(n) (memcmp((void*)&n,(void*)&_Sflnan,sizeof(n))==0)
+#endif
+#else
+#if ! _lib_isnanl
+#define isnanl(n) isnan(n)
+#endif
+#endif
+
+#if ! _lib_signbit && defined(signbit)
+#undef _lib_signbit
+#define _lib_signbit 1
+#endif
+
+#if ! _lib_signbit
+#if ! _ast_fltmax_double
+static int neg0ld(Sfdouble_t f)
+{
+ Sfdouble_t z = -0.0;
+ return !memcmp(&f, &z, sizeof(f));
+}
+#endif
+static int neg0d(double f)
+{
+ double z = -0.0;
+ return !memcmp(&f, &z, sizeof(f));
+}
+#endif
+
+#if ULONG_DIG && ULONG_DIG < (DBL_DIG-1)
+#define CVT_LDBL_INT long
+#define CVT_LDBL_MAXINT LONG_MAX
+#else
+#if UINT_DIG && UINT_DIG < (DBL_DIG-1)
+#define CVT_LDBL_INT int
+#define CVT_LDBL_MAXINT INT_MAX
+#else
+#define CVT_LDBL_INT long
+#define CVT_LDBL_MAXINT SF_MAXLONG
+#endif
+#endif
+
+#if ULONG_DIG && ULONG_DIG < (DBL_DIG-1)
+#define CVT_DBL_INT long
+#define CVT_DBL_MAXINT LONG_MAX
+#else
+#if UINT_DIG && UINT_DIG < (DBL_DIG-1)
+#define CVT_DBL_INT int
+#define CVT_DBL_MAXINT INT_MAX
+#else
+#define CVT_DBL_INT long
+#define CVT_DBL_MAXINT SF_MAXLONG
+#endif
+#endif
+
+#if __STD_C
+char* _sfcvt(Void_t* vp, char* buf, size_t size, int n_digit,
+ int* decpt, int* sign, int* len, int format)
+#else
+char* _sfcvt(vp,buf,size,n_digit,decpt,sign,len,format)
+Void_t* vp; /* pointer to value to convert */
+char* buf; /* conversion goes here */
+size_t size; /* size of buf */
+int n_digit; /* number of digits wanted */
+int* decpt; /* to return decimal point */
+int* sign; /* to return sign */
+int* len; /* return string length */
+int format; /* conversion format */
+#endif
+{
+ reg char *sp;
+ reg long n, v;
+ reg char *ep, *b, *endsp, *t;
+ int x;
+ _ast_flt_unsigned_max_t m;
+
+ static char lx[] = "0123456789abcdef";
+ static char ux[] = "0123456789ABCDEF";
+
+ *sign = *decpt = 0;
+
+#if !_ast_fltmax_double
+ if(format&SFFMT_LDOUBLE)
+ { Sfdouble_t f = *(Sfdouble_t*)vp;
+
+ if(isnanl(f))
+ {
+#if _lib_signbit
+ if (signbit(f))
+#else
+ if (f < 0)
+#endif
+ *sign = 1;
+ return SF_NAN;
+ }
+#if _lib_isinf
+ if (n = isinf(f))
+ {
+#if _lib_signbit
+ if (signbit(f))
+#else
+ if (n < 0 || f < 0)
+#endif
+ *sign = 1;
+ return SF_INF;
+ }
+#endif
+# if _c99_in_the_wild
+# if _lib_signbit
+ if (signbit(f))
+# else
+# if _lib_copysignl
+ if (copysignl(1.0, f) < 0.0)
+# else
+# if _lib_copysign
+ if (copysign(1.0, (double)f) < 0.0)
+# else
+ if (f < 0.0)
+# endif
+# endif
+# endif
+ { f = -f;
+ *sign = 1;
+ }
+# if _lib_fpclassify
+ switch (fpclassify(f))
+ {
+ case FP_INFINITE:
+ return SF_INF;
+ case FP_NAN:
+ return SF_NAN;
+ case FP_ZERO:
+ return SF_ZERO;
+ }
+# endif
+# else
+# if _lib_signbit
+ if (signbit(f))
+# else
+ if (f < 0.0 || f == 0.0 && neg0ld(f))
+# endif
+ { f = -f;
+ *sign = 1;
+ }
+# endif
+ if(f < LDBL_MIN)
+ return SF_ZERO;
+ if(f > LDBL_MAX)
+ return SF_INF;
+
+ if(format & SFFMT_AFORMAT)
+ { Sfdouble_t g;
+ b = sp = buf;
+ ep = (format & SFFMT_UPPER) ? ux : lx;
+ if(n_digit <= 0 || n_digit >= (size - 9))
+ n_digit = size - 9;
+ endsp = sp + n_digit + 1;
+
+ g = frexpl(f, &x);
+ *decpt = x;
+ f = ldexpl(g, 8 * sizeof(m) - 3);
+
+ for (;;)
+ { m = f;
+ x = 8 * sizeof(m);
+ while ((x -= 4) >= 0)
+ { *sp++ = ep[(m >> x) & 0xf];
+ if (sp >= endsp)
+ goto around;
+ }
+ f -= m;
+ f = ldexpl(f, 8 * sizeof(m));
+ }
+ }
+
+ n = 0;
+ if(f >= (Sfdouble_t)CVT_LDBL_MAXINT)
+ { /* scale to a small enough number to fit an int */
+ v = SF_MAXEXP10-1;
+ do
+ { if(f < _Sfpos10[v])
+ v -= 1;
+ else
+ {
+ f *= _Sfneg10[v];
+ if((n += (1<<v)) >= SF_IDIGITS)
+ return SF_INF;
+ }
+ } while(f >= (Sfdouble_t)CVT_LDBL_MAXINT);
+ }
+ else if(f > 0.0 && f < 0.1)
+ { /* scale to avoid excessive multiply by 10 below */
+ v = SF_MAXEXP10-1;
+ do
+ { if(f <= _Sfneg10[v])
+ { f *= _Sfpos10[v];
+ if((n += (1<<v)) >= SF_IDIGITS)
+ return SF_INF;
+ }
+ else if (--v < 0)
+ break;
+ } while(f < 0.1);
+ n = -n;
+ }
+ *decpt = (int)n;
+
+ b = sp = buf + SF_INTPART;
+ if((v = (CVT_LDBL_INT)f) != 0)
+ { /* translate the integer part */
+ f -= (Sfdouble_t)v;
+
+ sfucvt(v,sp,n,ep,CVT_LDBL_INT,unsigned CVT_LDBL_INT);
+
+ n = b-sp;
+ if((*decpt += (int)n) >= SF_IDIGITS)
+ return SF_INF;
+ b = sp;
+ sp = buf + SF_INTPART;
+ }
+ else n = 0;
+
+ /* remaining number of digits to compute; add 1 for later rounding */
+ n = (((format&SFFMT_EFORMAT) || *decpt <= 0) ? 1 : *decpt+1) - n;
+ if(n_digit > 0)
+ { if(n_digit > LDBL_DIG)
+ n_digit = LDBL_DIG;
+ n += n_digit;
+ }
+
+ if((ep = (sp+n)) > (endsp = buf+(size-2)))
+ ep = endsp;
+ if(sp > ep)
+ sp = ep;
+ else
+ {
+ if((format&SFFMT_EFORMAT) && *decpt == 0 && f > 0.)
+ { Sfdouble_t d;
+ while((long)(d = f*10.) == 0)
+ { f = d;
+ *decpt -= 1;
+ }
+ }
+
+ while(sp < ep)
+ { /* generate fractional digits */
+ if(f <= 0.)
+ { /* fill with 0's */
+ do { *sp++ = '0'; } while(sp < ep);
+ goto done;
+ }
+ else if((n = (long)(f *= 10.)) < 10)
+ { *sp++ = '0' + n;
+ f -= n;
+ }
+ else /* n == 10 */
+ { do { *sp++ = '9'; } while(sp < ep);
+ }
+ }
+ }
+ } else
+#endif
+ { double f = *(double*)vp;
+
+ if(isnan(f))
+ {
+#if _lib_signbit
+ if (signbit(f))
+#else
+ if (f < 0)
+#endif
+ *sign = 1;
+ return SF_NAN;
+ }
+#if _lib_isinf
+ if (n = isinf(f))
+ {
+#if _lib_signbit
+ if (signbit(f))
+#else
+ if (n < 0 || f < 0)
+#endif
+ *sign = 1;
+ return SF_INF;
+ }
+#endif
+#if _c99_in_the_wild
+# if _lib_signbit
+ if (signbit(f))
+# else
+# if _lib_copysign
+ if (copysign(1.0, f) < 0.0)
+# else
+ if (f < 0.0)
+# endif
+# endif
+ { f = -f;
+ *sign = 1;
+ }
+# if _lib_fpclassify
+ switch (fpclassify(f))
+ {
+ case FP_INFINITE:
+ return SF_INF;
+ case FP_NAN:
+ return SF_NAN;
+ case FP_ZERO:
+ return SF_ZERO;
+ }
+# endif
+#else
+# if _lib_signbit
+ if (signbit(f))
+# else
+ if (f < 0.0 || f == 0.0 && neg0d(f))
+# endif
+ { f = -f;
+ *sign = 1;
+ }
+#endif
+ if(f < DBL_MIN)
+ return SF_ZERO;
+ if(f > DBL_MAX)
+ return SF_INF;
+
+ if(format & SFFMT_AFORMAT)
+ { double g;
+ b = sp = buf;
+ ep = (format & SFFMT_UPPER) ? ux : lx;
+ if(n_digit <= 0 || n_digit >= (size - 9))
+ n_digit = size - 9;
+ endsp = sp + n_digit + 1;
+
+ g = frexp(f, &x);
+ *decpt = x;
+ f = ldexp(g, 8 * sizeof(m) - 3);
+
+ for (;;)
+ { m = f;
+ x = 8 * sizeof(m);
+ while ((x -= 4) >= 0)
+ { *sp++ = ep[(m >> x) & 0xf];
+ if (sp >= endsp)
+ goto around;
+ }
+ f -= m;
+ f = ldexp(f, 8 * sizeof(m));
+ }
+ }
+ n = 0;
+ if(f >= (double)CVT_DBL_MAXINT)
+ { /* scale to a small enough number to fit an int */
+ v = SF_MAXEXP10-1;
+ do
+ { if(f < _Sfpos10[v])
+ v -= 1;
+ else
+ { f *= _Sfneg10[v];
+ if((n += (1<<v)) >= SF_IDIGITS)
+ return SF_INF;
+ }
+ } while(f >= (double)CVT_DBL_MAXINT);
+ }
+ else if(f > 0.0 && f < 1e-8)
+ { /* scale to avoid excessive multiply by 10 below */
+ v = SF_MAXEXP10-1;
+ do
+ { if(f <= _Sfneg10[v])
+ { f *= _Sfpos10[v];
+ if((n += (1<<v)) >= SF_IDIGITS)
+ return SF_INF;
+ }
+ else if(--v < 0)
+ break;
+ } while(f < 0.1);
+ n = -n;
+ }
+ *decpt = (int)n;
+
+ b = sp = buf + SF_INTPART;
+ if((v = (CVT_DBL_INT)f) != 0)
+ { /* translate the integer part */
+ f -= (double)v;
+
+ sfucvt(v,sp,n,ep,CVT_DBL_INT,unsigned CVT_DBL_INT);
+
+ n = b-sp;
+ if((*decpt += (int)n) >= SF_IDIGITS)
+ return SF_INF;
+ b = sp;
+ sp = buf + SF_INTPART;
+ }
+ else n = 0;
+
+ /* remaining number of digits to compute; add 1 for later rounding */
+ n = (((format&SFFMT_EFORMAT) || *decpt <= 0) ? 1 : *decpt+1) - n;
+ if(n_digit > 0)
+ { if(n_digit > DBL_DIG)
+ n_digit = DBL_DIG;
+ n += n_digit;
+ }
+
+ if((ep = (sp+n)) > (endsp = buf+(size-2)))
+ ep = endsp;
+ if(sp > ep)
+ sp = ep;
+ else
+ {
+ if((format&SFFMT_EFORMAT) && *decpt == 0 && f > 0.)
+ { reg double d;
+ while((long)(d = f*10.) == 0)
+ { f = d;
+ *decpt -= 1;
+ }
+ }
+
+ while(sp < ep)
+ { /* generate fractional digits */
+ if(f <= 0.)
+ { /* fill with 0's */
+ do { *sp++ = '0'; } while(sp < ep);
+ goto done;
+ }
+ else if((n = (long)(f *= 10.)) < 10)
+ { *sp++ = (char)('0' + n);
+ f -= n;
+ }
+ else /* n == 10 */
+ { do { *sp++ = '9'; } while(sp < ep);
+ break;
+ }
+ }
+ }
+ }
+
+ if(ep <= b)
+ ep = b+1;
+ else if(ep < endsp)
+ { /* round the last digit */
+ *--sp += 5;
+ while(*sp > '9')
+ { *sp = '0';
+ if(sp > b)
+ *--sp += 1;
+ else
+ { /* next power of 10 */
+ *sp = '1';
+ *decpt += 1;
+ if(!(format&SFFMT_EFORMAT))
+ { /* add one more 0 for %f precision */
+ ep[-1] = '0';
+ ep += 1;
+ }
+ }
+ }
+ }
+
+ done:
+ *--ep = '\0';
+ if(len)
+ *len = ep-b;
+ return b;
+ around:
+ if (((m >> x) & 0xf) >= 8)
+ { t = sp - 1;
+ for (;;)
+ { if (--t <= b)
+ { (*decpt)++;
+ break;
+ }
+ switch (*t)
+ {
+ case 'f':
+ case 'F':
+ *t = '0';
+ continue;
+ case '9':
+ *t = ep[10];
+ break;
+ default:
+ (*t)++;
+ break;
+ }
+ break;
+ }
+ }
+ ep = sp + 1;
+ goto done;
+}
diff --git a/src/lib/libast/sfio/sfdisc.c b/src/lib/libast/sfio/sfdisc.c
new file mode 100644
index 0000000..8ffc559
--- /dev/null
+++ b/src/lib/libast/sfio/sfdisc.c
@@ -0,0 +1,271 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Add a new discipline to the discipline stack. Each discipline
+** provides alternative I/O functions that are analogues of the
+** system calls.
+**
+** When the application fills or flushes the stream buffer, data
+** will be processed through discipline functions. A case deserving
+** consideration is stacking a discipline onto a read stream. Each
+** discipline operation implies buffer synchronization so the stream
+** buffer should be empty. However, a read stream representing an
+** unseekable device (eg, a pipe) may not be synchronizable. In that
+** case, any buffered data must then be fed to the new discipline
+** to preserve data processing semantics. This is done by creating
+** a temporary discipline to cache such buffered data and feed
+** them to the new discipline when its readf() asks for new data.
+** Care must then be taken to remove this temporary discipline
+** when it runs out of cached data.
+**
+** Written by Kiem-Phong Vo
+*/
+
+typedef struct _dccache_s
+{ Sfdisc_t disc;
+ uchar* data;
+ uchar* endb;
+} Dccache_t;
+
+#if __STD_C
+static int _dccaexcept(Sfio_t* f, int type, Void_t* val, Sfdisc_t* disc)
+#else
+static int _dccaexcept(f,type,val,disc)
+Sfio_t* f;
+int type;
+Void_t* val;
+Sfdisc_t* disc;
+#endif
+{
+ if(disc && type == SF_FINAL)
+ free(disc);
+ return 0;
+}
+
+#if __STD_C
+static ssize_t _dccaread(Sfio_t* f, Void_t* buf, size_t size, Sfdisc_t* disc)
+#else
+static ssize_t _dccaread(f, buf, size, disc)
+Sfio_t* f;
+Void_t* buf;
+size_t size;
+Sfdisc_t* disc;
+#endif
+{
+ ssize_t sz;
+ Sfdisc_t *prev;
+ Dccache_t *dcca;
+
+ if(!f) /* bad stream */
+ return -1;
+
+ /* make sure that this is on the discipline stack */
+ for(prev = f->disc; prev; prev = prev->disc)
+ if(prev->disc == disc)
+ break;
+ if(!prev)
+ return -1;
+
+ if(size <= 0) /* nothing to do */
+ return size;
+
+ /* read from available data */
+ dcca = (Dccache_t*)disc;
+ if((sz = dcca->endb - dcca->data) > (ssize_t)size)
+ sz = (ssize_t)size;
+ memcpy(buf, dcca->data, sz);
+
+ if((dcca->data += sz) >= dcca->endb) /* free empty cache */
+ { prev->disc = disc->disc;
+ free(disc);
+ }
+
+ return sz;
+}
+
+#if __STD_C
+Sfdisc_t* sfdisc(Sfio_t* f, Sfdisc_t* disc)
+#else
+Sfdisc_t* sfdisc(f,disc)
+Sfio_t* f;
+Sfdisc_t* disc;
+#endif
+{
+ Sfdisc_t *d, *rdisc;
+ Sfread_f oreadf;
+ Sfwrite_f owritef;
+ Sfseek_f oseekf;
+ ssize_t n;
+ Dccache_t *dcca = NIL(Dccache_t*);
+ SFMTXDECL(f); /* declare a local stream variable for multithreading */
+
+ SFMTXENTER(f, NIL(Sfdisc_t*));
+
+ if((Sfio_t*)disc == f) /* special case to get the top discipline */
+ SFMTXRETURN(f,f->disc);
+
+ if((f->flags&SF_READ) && f->proc && (f->mode&SF_WRITE) )
+ { /* make sure in read mode to check for read-ahead data */
+ if(_sfmode(f,SF_READ,0) < 0)
+ SFMTXRETURN(f, NIL(Sfdisc_t*));
+ }
+ else
+ { if((f->mode&SF_RDWR) != f->mode && _sfmode(f,0,0) < 0)
+ SFMTXRETURN(f, NIL(Sfdisc_t*));
+ }
+
+ SFLOCK(f,0);
+ rdisc = NIL(Sfdisc_t*);
+
+ /* disallow popping while there is cached data */
+ if(!disc && f->disc && f->disc->disc && f->disc->disc->readf == _dccaread )
+ goto done;
+
+ /* synchronize before switching to a new discipline */
+ if(!(f->flags&SF_STRING))
+ { (void)SFSYNC(f); /* do a silent buffer synch */
+ if((f->mode&SF_READ) && (f->mode&SF_SYNCED) )
+ { f->mode &= ~SF_SYNCED;
+ f->endb = f->next = f->endr = f->endw = f->data;
+ }
+
+ /* if there is buffered data, ask app before proceeding */
+ if(((f->mode&SF_WRITE) && (n = f->next-f->data) > 0) ||
+ ((f->mode&SF_READ) && (n = f->endb-f->next) > 0) )
+ { int rv = 0;
+ if(rv == 0 && f->disc && f->disc->exceptf) /* ask current discipline */
+ { SFOPEN(f,0);
+ rv = (*f->disc->exceptf)(f, SF_DBUFFER, &n, f->disc);
+ SFLOCK(f,0);
+ }
+ if(rv == 0 && disc && disc->exceptf) /* ask discipline being pushed */
+ { SFOPEN(f,0);
+ rv = (*disc->exceptf)(f, SF_DBUFFER, &n, disc);
+ SFLOCK(f,0);
+ }
+ if(rv < 0)
+ goto done;
+ }
+
+ /* trick the new discipline into processing already buffered data */
+ if((f->mode&SF_READ) && n > 0 && disc && disc->readf )
+ { if(!(dcca = (Dccache_t*)malloc(sizeof(Dccache_t)+n)) )
+ goto done;
+ memclear(dcca, sizeof(Dccache_t));
+
+ dcca->disc.readf = _dccaread;
+ dcca->disc.exceptf = _dccaexcept;
+
+ /* move buffered data into the temp discipline */
+ dcca->data = ((uchar*)dcca) + sizeof(Dccache_t);
+ dcca->endb = dcca->data + n;
+ memcpy(dcca->data, f->next, n);
+ f->endb = f->next = f->endr = f->endw = f->data;
+ }
+ }
+
+ /* save old readf, writef, and seekf to see if stream need reinit */
+#define GETDISCF(func,iof,type) \
+ { for(d = f->disc; d && !d->iof; d = d->disc) ; \
+ func = d ? d->iof : NIL(type); \
+ }
+ GETDISCF(oreadf,readf,Sfread_f);
+ GETDISCF(owritef,writef,Sfwrite_f);
+ GETDISCF(oseekf,seekf,Sfseek_f);
+
+ if(disc == SF_POPDISC)
+ { /* popping, warn the being popped discipline */
+ if(!(d = f->disc) )
+ goto done;
+ disc = d->disc;
+ if(d->exceptf)
+ { SFOPEN(f,0);
+ if((*(d->exceptf))(f,SF_DPOP,(Void_t*)disc,d) < 0 )
+ goto done;
+ SFLOCK(f,0);
+ }
+ f->disc = disc;
+ rdisc = d;
+ }
+ else
+ { /* pushing, warn being pushed discipline */
+ do
+ { /* loop to handle the case where d may pop itself */
+ d = f->disc;
+ if(d && d->exceptf)
+ { SFOPEN(f,0);
+ if( (*(d->exceptf))(f,SF_DPUSH,(Void_t*)disc,d) < 0 )
+ goto done;
+ SFLOCK(f,0);
+ }
+ } while(d != f->disc);
+
+ /* make sure we are not creating an infinite loop */
+ for(; d; d = d->disc)
+ if(d == disc)
+ goto done;
+
+ /* set new disc */
+ if(dcca) /* insert the discipline with cached data */
+ { dcca->disc.disc = f->disc;
+ disc->disc = &dcca->disc;
+ }
+ else disc->disc = f->disc;
+ f->disc = disc;
+ rdisc = disc;
+ }
+
+ if(!(f->flags&SF_STRING) )
+ { /* this stream may have to be reinitialized */
+ reg int reinit = 0;
+#define DISCF(dst,iof,type) (dst ? dst->iof : NIL(type))
+#define REINIT(oiof,iof,type) \
+ if(!reinit) \
+ { for(d = f->disc; d && !d->iof; d = d->disc) ; \
+ if(DISCF(d,iof,type) != oiof) \
+ reinit = 1; \
+ }
+
+ REINIT(oreadf,readf,Sfread_f);
+ REINIT(owritef,writef,Sfwrite_f);
+ REINIT(oseekf,seekf,Sfseek_f);
+
+ if(reinit)
+ { SETLOCAL(f);
+ f->bits &= ~SF_NULL; /* turn off /dev/null handling */
+ if((f->bits&SF_MMAP) || (f->mode&SF_INIT))
+ sfsetbuf(f,NIL(Void_t*),(size_t)SF_UNBOUND);
+ else if(f->data == f->tiny)
+ sfsetbuf(f,NIL(Void_t*),0);
+ else
+ { int flags = f->flags;
+ sfsetbuf(f,(Void_t*)f->data,f->size);
+ f->flags |= (flags&SF_MALLOC);
+ }
+ }
+ }
+
+done :
+ SFOPEN(f,0);
+ SFMTXRETURN(f, rdisc);
+}
diff --git a/src/lib/libast/sfio/sfdlen.c b/src/lib/libast/sfio/sfdlen.c
new file mode 100644
index 0000000..69d6cb4
--- /dev/null
+++ b/src/lib/libast/sfio/sfdlen.c
@@ -0,0 +1,58 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Return the length of a double value if coded in a portable format
+**
+** Written by Kiem-Phong Vo
+*/
+
+#if __STD_C
+int _sfdlen(Sfdouble_t v)
+#else
+int _sfdlen(v)
+Sfdouble_t v;
+#endif
+{
+#define N_ARRAY (16*sizeof(Sfdouble_t))
+ reg int n, w;
+ Sfdouble_t x;
+ int exp;
+
+ if(v < 0)
+ v = -v;
+
+ /* make the magnitude of v < 1 */
+ if(v != 0.)
+ v = frexpl(v,&exp);
+ else exp = 0;
+
+ for(w = 1; w <= N_ARRAY; ++w)
+ { /* get 2^SF_PRECIS precision at a time */
+ n = (int)(x = ldexpl(v,SF_PRECIS));
+ v = x-n;
+ if(v <= 0.)
+ break;
+ }
+
+ return 1 + sfulen(exp) + w;
+}
diff --git a/src/lib/libast/sfio/sfecvt.c b/src/lib/libast/sfio/sfecvt.c
new file mode 100644
index 0000000..35d034b
--- /dev/null
+++ b/src/lib/libast/sfio/sfecvt.c
@@ -0,0 +1,38 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#if __STD_C
+char* sfecvt(double dval, int n_digit, int* decpt, int* sign)
+#else
+char* sfecvt(dval,n_digit,decpt,sign)
+double dval; /* value to convert */
+int n_digit; /* number of digits wanted */
+int* decpt; /* to return decimal point */
+int* sign; /* to return sign */
+#endif
+{
+ int len;
+ static char buf[SF_MAXDIGITS];
+
+ return _sfcvt(&dval,buf,sizeof(buf),n_digit,decpt,sign,&len,SFFMT_EFORMAT);
+}
diff --git a/src/lib/libast/sfio/sfexcept.c b/src/lib/libast/sfio/sfexcept.c
new file mode 100644
index 0000000..fc08d6e
--- /dev/null
+++ b/src/lib/libast/sfio/sfexcept.c
@@ -0,0 +1,133 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Function to handle io exceptions.
+** Written by Kiem-Phong Vo
+*/
+
+#if __STD_C
+int _sfexcept(Sfio_t* f, int type, ssize_t io, Sfdisc_t* disc)
+#else
+int _sfexcept(f,type,io,disc)
+Sfio_t* f; /* stream where the exception happened */
+int type; /* io type that was performed */
+ssize_t io; /* the io return value that indicated exception */
+Sfdisc_t* disc; /* discipline in use */
+#endif
+{
+ reg int ev, local, lock;
+ reg ssize_t size;
+ reg uchar* data;
+ SFMTXDECL(f); /* declare a local stream variable for multithreading */
+
+ SFMTXENTER(f,-1);
+
+ GETLOCAL(f,local);
+ lock = f->mode&SF_LOCK;
+
+ if(local && io <= 0)
+ f->flags |= io < 0 ? SF_ERROR : SF_EOF;
+
+ if(disc && disc->exceptf)
+ { /* let the stream be generally accessible for this duration */
+ if(local && lock)
+ SFOPEN(f,0);
+
+ /* so that exception handler knows what we are asking for */
+ _Sfi = f->val = io;
+ ev = (*(disc->exceptf))(f,type,&io,disc);
+
+ /* relock if necessary */
+ if(local && lock)
+ SFLOCK(f,0);
+
+ if(io > 0 && !(f->flags&SF_STRING) )
+ SFMTXRETURN(f, ev);
+ if(ev < 0)
+ SFMTXRETURN(f, SF_EDONE);
+ if(ev > 0)
+ SFMTXRETURN(f, SF_EDISC);
+ }
+
+ if(f->flags&SF_STRING)
+ { if(type == SF_READ)
+ goto chk_stack;
+ else if(type != SF_WRITE && type != SF_SEEK)
+ SFMTXRETURN(f, SF_EDONE);
+ if(local && io >= 0)
+ { if(f->size >= 0 && !(f->flags&SF_MALLOC))
+ goto chk_stack;
+ /* extend buffer */
+ if((size = f->size) < 0)
+ size = 0;
+ if((io -= size) <= 0)
+ io = SF_GRAIN;
+ size = ((size+io+SF_GRAIN-1)/SF_GRAIN)*SF_GRAIN;
+ if(f->size > 0)
+ data = (uchar*)realloc((char*)f->data,size);
+ else data = (uchar*)malloc(size);
+ if(!data)
+ goto chk_stack;
+ f->endb = data + size;
+ f->next = data + (f->next - f->data);
+ f->endr = f->endw = f->data = data;
+ f->size = size;
+ }
+ SFMTXRETURN(f, SF_EDISC);
+ }
+
+ if(errno == EINTR)
+ { if(_Sfexiting || (f->bits&SF_ENDING) || /* stop being a hero */
+ (f->flags&SF_IOINTR) ) /* application requests to return */
+ SFMTXRETURN(f, SF_EDONE);
+
+ /* a normal interrupt, we can continue */
+ errno = 0;
+ f->flags &= ~(SF_EOF|SF_ERROR);
+ SFMTXRETURN(f, SF_ECONT);
+ }
+
+chk_stack:
+ if(local && f->push &&
+ ((type == SF_READ && f->next >= f->endb) ||
+ (type == SF_WRITE && f->next <= f->data)))
+ { /* pop the stack */
+ reg Sfio_t *pf;
+
+ if(lock)
+ SFOPEN(f,0);
+
+ /* pop and close */
+ pf = (*_Sfstack)(f,NIL(Sfio_t*));
+ if((ev = sfclose(pf)) < 0) /* can't close, restack */
+ (*_Sfstack)(f,pf);
+
+ if(lock)
+ SFLOCK(f,0);
+
+ ev = ev < 0 ? SF_EDONE : SF_ESTACK;
+ }
+ else ev = SF_EDONE;
+
+ SFMTXRETURN(f, ev);
+}
diff --git a/src/lib/libast/sfio/sfextern.c b/src/lib/libast/sfio/sfextern.c
new file mode 100644
index 0000000..e5f2c6e
--- /dev/null
+++ b/src/lib/libast/sfio/sfextern.c
@@ -0,0 +1,99 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* External variables and functions used only by Sfio
+** Written by Kiem-Phong Vo
+*/
+
+/* code to initialize mutexes */
+static Vtmutex_t Sfmutex;
+static Vtonce_t Sfonce = VTONCE_INITDATA;
+static void _sfoncef()
+{ (void)vtmtxopen(_Sfmutex, VT_INIT);
+ (void)vtmtxopen(&_Sfpool.mutex, VT_INIT);
+ (void)vtmtxopen(sfstdin->mutex, VT_INIT);
+ (void)vtmtxopen(sfstdout->mutex, VT_INIT);
+ (void)vtmtxopen(sfstderr->mutex, VT_INIT);
+ _Sfdone = 1;
+}
+
+/* global variables used internally to the package */
+Sfextern_t _Sfextern =
+{ 0, /* _Sfpage */
+ { NIL(Sfpool_t*), 0, 0, 0, NIL(Sfio_t**) }, /* _Sfpool */
+ NIL(int(*)_ARG_((Sfio_t*,int))), /* _Sfpmove */
+ NIL(Sfio_t*(*)_ARG_((Sfio_t*, Sfio_t*))), /* _Sfstack */
+ NIL(void(*)_ARG_((Sfio_t*, int, void*))), /* _Sfnotify */
+ NIL(int(*)_ARG_((Sfio_t*))), /* _Sfstdsync */
+ { NIL(Sfread_f), /* _Sfudisc */
+ NIL(Sfwrite_f),
+ NIL(Sfseek_f),
+ NIL(Sfexcept_f),
+ NIL(Sfdisc_t*)
+ },
+ NIL(void(*)_ARG_((void)) ), /* _Sfcleanup */
+ 0, /* _Sfexiting */
+ 0, /* _Sfdone */
+ &Sfonce, /* _Sfonce */
+ _sfoncef, /* _Sfoncef */
+ &Sfmutex /* _Sfmutex */
+};
+
+ssize_t _Sfi = -1; /* value for a few fast macro functions */
+ssize_t _Sfmaxr = 0; /* default (unlimited) max record size */
+
+#if vt_threaded
+static Vtmutex_t _Sfmtxin, _Sfmtxout, _Sfmtxerr;
+#define SFMTXIN (&_Sfmtxin)
+#define SFMTXOUT (&_Sfmtxout)
+#define SFMTXERR (&_Sfmtxerr)
+#define SF_STDSAFE SF_MTSAFE
+#else
+#define SFMTXIN (0)
+#define SFMTXOUT (0)
+#define SFMTXERR (0)
+#define SF_STDSAFE (0)
+#endif
+
+Sfio_t _Sfstdin = SFNEW(NIL(char*),-1,0,
+ (SF_READ |SF_STATIC|SF_STDSAFE),NIL(Sfdisc_t*),SFMTXIN);
+Sfio_t _Sfstdout = SFNEW(NIL(char*),-1,1,
+ (SF_WRITE|SF_STATIC|SF_STDSAFE),NIL(Sfdisc_t*),SFMTXOUT);
+Sfio_t _Sfstderr = SFNEW(NIL(char*),-1,2,
+ (SF_WRITE|SF_STATIC|SF_STDSAFE),NIL(Sfdisc_t*),SFMTXERR);
+
+#undef sfstdin
+#undef sfstdout
+#undef sfstderr
+
+Sfio_t* sfstdin = &_Sfstdin;
+Sfio_t* sfstdout = &_Sfstdout;
+Sfio_t* sfstderr = &_Sfstderr;
+
+__EXTERN__(ssize_t,_Sfi);
+__EXTERN__(Sfio_t,_Sfstdin);
+__EXTERN__(Sfio_t,_Sfstdout);
+__EXTERN__(Sfio_t,_Sfstderr);
+__EXTERN__(Sfio_t*,sfstdin);
+__EXTERN__(Sfio_t*,sfstdout);
+__EXTERN__(Sfio_t*,sfstderr);
diff --git a/src/lib/libast/sfio/sffcvt.c b/src/lib/libast/sfio/sffcvt.c
new file mode 100644
index 0000000..ade6d5e
--- /dev/null
+++ b/src/lib/libast/sfio/sffcvt.c
@@ -0,0 +1,38 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#if __STD_C
+char *sffcvt(double dval, int n_digit, int* decpt, int* sign)
+#else
+char *sffcvt(dval,n_digit,decpt,sign)
+double dval; /* value to convert */
+int n_digit; /* number of digits wanted */
+int* decpt; /* to return decimal point */
+int* sign; /* to return sign */
+#endif
+{
+ int len;
+ static char buf[SF_MAXDIGITS];
+
+ return _sfcvt(&dval,buf,sizeof(buf),n_digit,decpt,sign,&len,0);
+}
diff --git a/src/lib/libast/sfio/sffilbuf.c b/src/lib/libast/sfio/sffilbuf.c
new file mode 100644
index 0000000..16d5e3a
--- /dev/null
+++ b/src/lib/libast/sfio/sffilbuf.c
@@ -0,0 +1,116 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Fill the buffer of a stream with data.
+** If n < 0, sffilbuf() attempts to fill the buffer if it's empty.
+** If n == 0, if the buffer is not empty, just return the first byte;
+** otherwise fill the buffer and return the first byte.
+** If n > 0, even if the buffer is not empty, try a read to get as
+** close to n as possible. n is reset to -1 if stack pops.
+**
+** Written by Kiem-Phong Vo
+*/
+
+#if __STD_C
+int _sffilbuf(Sfio_t* f, reg int n)
+#else
+int _sffilbuf(f,n)
+Sfio_t* f; /* fill the read buffer of this stream */
+reg int n; /* see above */
+#endif
+{
+ reg ssize_t r;
+ reg int first, local, rcrv, rc, justseek;
+ SFMTXDECL(f); /* declare a local stream variable for multithreading */
+
+ SFMTXENTER(f,-1);
+
+ GETLOCAL(f,local);
+
+ /* any peek data must be preserved across stacked streams */
+ rcrv = f->mode&(SF_RC|SF_RV|SF_LOCK);
+ rc = f->getr;
+
+ justseek = f->bits&SF_JUSTSEEK; f->bits &= ~SF_JUSTSEEK;
+
+ for(first = 1;; first = 0, (f->mode &= ~SF_LOCK) )
+ { /* check mode */
+ if(SFMODE(f,local) != SF_READ && _sfmode(f,SF_READ,local) < 0)
+ SFMTXRETURN(f,-1);
+ SFLOCK(f,local);
+
+ /* current extent of available data */
+ if((r = f->endb-f->next) > 0)
+ { /* on first iteration, n is amount beyond current buffer;
+ afterward, n is the exact amount requested */
+ if((first && n <= 0) || (!first && n <= r) ||
+ (f->flags&SF_STRING))
+ break;
+
+ /* try shifting left to make room for new data */
+ if(!(f->bits&SF_MMAP) && f->next > f->data &&
+ n > (f->size - (f->endb-f->data)) )
+ { ssize_t s = r;
+
+ /* try to maintain block alignment */
+ if(f->blksz > 0 && (f->here%f->blksz) == 0 )
+ { s = ((r + f->blksz-1)/f->blksz)*f->blksz;
+ if(s+n > f->size)
+ s = r;
+ }
+
+ memmove(f->data, f->endb-s, s);
+ f->next = f->data + (s-r);
+ f->endb = f->data + s;
+ }
+ }
+ else if(!(f->flags&SF_STRING) && !(f->bits&SF_MMAP) )
+ f->next = f->endb = f->endr = f->data;
+
+ if(f->bits&SF_MMAP)
+ r = n > 0 ? n : f->size;
+ else if(!(f->flags&SF_STRING) )
+ { r = f->size - (f->endb - f->data); /* available buffer */
+ if(n > 0)
+ { if(r > n && f->extent < 0 && (f->flags&SF_SHARE) )
+ r = n; /* read only as much as requested */
+ else if(justseek && n <= f->iosz && f->iosz <= f->size)
+ r = f->iosz; /* limit buffer filling */
+ }
+ }
+
+ /* SFRD takes care of discipline read and stack popping */
+ f->mode |= rcrv;
+ f->getr = rc;
+ if((r = SFRD(f,f->endb,r,f->disc)) >= 0)
+ { r = f->endb - f->next;
+ break;
+ }
+ }
+
+ SFOPEN(f,local);
+
+ rcrv = (n == 0) ? (r > 0 ? (int)(*f->next++) : EOF) : (int)r;
+
+ SFMTXRETURN(f,rcrv);
+}
diff --git a/src/lib/libast/sfio/sfflsbuf.c b/src/lib/libast/sfio/sfflsbuf.c
new file mode 100644
index 0000000..36d78dc
--- /dev/null
+++ b/src/lib/libast/sfio/sfflsbuf.c
@@ -0,0 +1,126 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Write a buffer out to a file descriptor or
+** extending a buffer for a SF_STRING stream.
+**
+** Written by Kiem-Phong Vo
+*/
+
+#if __STD_C
+int _sfflsbuf(Sfio_t* f, int c)
+#else
+int _sfflsbuf(f,c)
+Sfio_t* f; /* write out the buffered content of this stream */
+int c; /* if c>=0, c is also written out */
+#endif
+{
+ ssize_t n, w, written;
+ uchar* data;
+ uchar outc;
+ int local, isall;
+ int inpc = c;
+ SFMTXDECL(f); /* declare a local stream variable for multithreading */
+
+ SFMTXENTER(f,-1);
+
+ GETLOCAL(f,local);
+
+ for(written = 0;; f->mode &= ~SF_LOCK)
+ { /* check stream mode */
+ if(SFMODE(f,local) != SF_WRITE && _sfmode(f,SF_WRITE,local) < 0)
+ SFMTXRETURN(f, -1);
+ SFLOCK(f,local);
+
+ /* current data extent */
+ n = f->next - (data = f->data);
+
+ if(n == (f->endb-data) && (f->flags&SF_STRING))
+ { /* call sfwr() to extend string buffer and process events */
+ w = ((f->bits&SF_PUTR) && f->val > 0) ? f->val : 1;
+ (void)SFWR(f, data, w, f->disc);
+
+ /* !(f->flags&SF_STRING) is required because exception
+ handlers may turn a string stream to a file stream */
+ if(f->next < f->endb || !(f->flags&SF_STRING) )
+ n = f->next - (data = f->data);
+ else
+ { SFOPEN(f,local);
+ SFMTXRETURN(f, -1);
+ }
+ }
+
+ if(c >= 0)
+ { /* write into buffer */
+ if(n < (f->endb - (data = f->data)))
+ { *f->next++ = c;
+ if(c == '\n' &&
+ (f->flags&SF_LINE) && !(f->flags&SF_STRING))
+ { c = -1;
+ n += 1;
+ }
+ else break;
+ }
+ else if(n == 0)
+ { /* unbuffered io */
+ outc = (uchar)c;
+ data = &outc;
+ c = -1;
+ n = 1;
+ }
+ }
+
+ if(n == 0 || (f->flags&SF_STRING))
+ break;
+
+ isall = SFISALL(f,isall);
+ if((w = SFWR(f,data,n,f->disc)) > 0)
+ { if((n -= w) > 0) /* save unwritten data, then resume */
+ memcpy((char*)f->data,(char*)data+w,n);
+ written += w;
+ f->next = f->data+n;
+ if(c < 0 && (!isall || n == 0))
+ break;
+ }
+ else if(w == 0)
+ { if(written > 0) /* some buffer was cleared */
+ break; /* do normal exit below */
+ else /* nothing was done, returning failure */
+ { SFOPEN(f,local);
+ SFMTXRETURN(f, -1);
+ }
+ }
+ else /* w < 0 means SF_EDISC or SF_ESTACK in sfwr() */
+ { if(c < 0) /* back to the calling write operation */
+ break;
+ else continue; /* try again to write out c */
+ }
+ }
+
+ SFOPEN(f,local);
+
+ if(inpc < 0)
+ inpc = f->endb-f->next;
+
+ SFMTXRETURN(f,inpc);
+}
diff --git a/src/lib/libast/sfio/sfgetd.c b/src/lib/libast/sfio/sfgetd.c
new file mode 100644
index 0000000..8c885c9
--- /dev/null
+++ b/src/lib/libast/sfio/sfgetd.c
@@ -0,0 +1,79 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Read a portably coded double value
+**
+** Written by Kiem-Phong Vo
+*/
+
+#if __STD_C
+Sfdouble_t sfgetd(Sfio_t* f)
+#else
+Sfdouble_t sfgetd(f)
+Sfio_t* f;
+#endif
+{
+ reg uchar *s, *ends, c;
+ reg int p, sign, exp;
+ Sfdouble_t v;
+ SFMTXDECL(f); /* declare a local stream variable for multithreading */
+
+ SFMTXENTER(f,-1.);
+
+ if((sign = sfgetc(f)) < 0 || (exp = (int)sfgetu(f)) < 0)
+ SFMTXRETURN(f, -1.);
+
+ if(f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0)
+ SFMTXRETURN(f, -1.);
+
+ SFLOCK(f,0);
+
+ v = 0.;
+ for(;;)
+ { /* fast read for data */
+ if(SFRPEEK(f,s,p) <= 0)
+ { f->flags |= SF_ERROR;
+ v = -1.;
+ goto done;
+ }
+
+ for(ends = s+p; s < ends; )
+ { c = *s++;
+ v += SFUVALUE(c);
+ v = ldexpl(v,-SF_PRECIS);
+ if(!(c&SF_MORE))
+ { f->next = s;
+ goto done;
+ }
+ }
+ f->next = s;
+ }
+
+done:
+ v = ldexpl(v,(sign&02) ? -exp : exp);
+ if(sign&01)
+ v = -v;
+
+ SFOPEN(f,0);
+ SFMTXRETURN(f, v);
+}
diff --git a/src/lib/libast/sfio/sfgetl.c b/src/lib/libast/sfio/sfgetl.c
new file mode 100644
index 0000000..bc83229
--- /dev/null
+++ b/src/lib/libast/sfio/sfgetl.c
@@ -0,0 +1,70 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Read a long value coded in a portable format.
+**
+** Written by Kiem-Phong Vo
+*/
+
+#if __STD_C
+Sflong_t sfgetl(Sfio_t* f)
+#else
+Sflong_t sfgetl(f)
+Sfio_t* f;
+#endif
+{
+ Sflong_t v;
+ uchar *s, *ends, c;
+ int p;
+ SFMTXDECL(f); /* declare a local stream variable for multithreading */
+
+ SFMTXENTER(f,(Sflong_t)(-1));
+
+ if(f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0)
+ SFMTXRETURN(f, (Sflong_t)(-1));
+ SFLOCK(f,0);
+
+ for(v = 0;;)
+ { if(SFRPEEK(f,s,p) <= 0)
+ { f->flags |= SF_ERROR;
+ v = (Sflong_t)(-1);
+ goto done;
+ }
+ for(ends = s+p; s < ends;)
+ { c = *s++;
+ if(c&SF_MORE)
+ v = ((Sfulong_t)v << SF_UBITS) | SFUVALUE(c);
+ else
+ { /* special translation for this byte */
+ v = ((Sfulong_t)v << SF_SBITS) | SFSVALUE(c);
+ f->next = s;
+ v = (c&SF_SIGN) ? -v-1 : v;
+ goto done;
+ }
+ }
+ f->next = s;
+ }
+done :
+ SFOPEN(f,0);
+ SFMTXRETURN(f, v);
+}
diff --git a/src/lib/libast/sfio/sfgetm.c b/src/lib/libast/sfio/sfgetm.c
new file mode 100644
index 0000000..16598eb
--- /dev/null
+++ b/src/lib/libast/sfio/sfgetm.c
@@ -0,0 +1,68 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Read an unsigned long value coded portably for a given range.
+**
+** Written by Kiem-Phong Vo
+*/
+
+#if __STD_C
+Sfulong_t sfgetm(Sfio_t* f, Sfulong_t m)
+#else
+Sfulong_t sfgetm(f, m)
+Sfio_t* f;
+Sfulong_t m;
+#endif
+{
+ Sfulong_t v;
+ reg uchar *s, *ends, c;
+ reg int p;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f, (Sfulong_t)(-1));
+
+ if(f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0)
+ SFMTXRETURN(f, (Sfulong_t)(-1));
+
+ SFLOCK(f,0);
+
+ for(v = 0;; )
+ { if(SFRPEEK(f,s,p) <= 0)
+ { f->flags |= SF_ERROR;
+ v = (Sfulong_t)(-1);
+ goto done;
+ }
+ for(ends = s+p; s < ends;)
+ { c = *s++;
+ v = (v << SF_BBITS) | SFBVALUE(c);
+ if((m >>= SF_BBITS) <= 0)
+ { f->next = s;
+ goto done;
+ }
+ }
+ f->next = s;
+ }
+done:
+ SFOPEN(f,0);
+ SFMTXRETURN(f, v);
+}
diff --git a/src/lib/libast/sfio/sfgetr.c b/src/lib/libast/sfio/sfgetr.c
new file mode 100644
index 0000000..a3b9d34
--- /dev/null
+++ b/src/lib/libast/sfio/sfgetr.c
@@ -0,0 +1,169 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Read a record delineated by a character.
+** The record length can be accessed via sfvalue(f).
+**
+** Written by Kiem-Phong Vo
+*/
+
+#if __STD_C
+char* sfgetr(Sfio_t *f, int rc, int type)
+#else
+char* sfgetr(f,rc,type)
+Sfio_t* f; /* stream to read from */
+int rc; /* record separator */
+int type;
+#endif
+{
+ ssize_t n, un;
+ uchar *s, *ends, *us;
+ int found;
+ Sfrsrv_t* rsrv;
+ SFMTXDECL(f); /* declare a local stream variable for multithreading */
+
+ SFMTXENTER(f, NIL(char*));
+
+ if(rc < 0 || (f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0) )
+ SFMTXRETURN(f, NIL(char*));
+ SFLOCK(f,0);
+
+ /* buffer to be returned */
+ rsrv = NIL(Sfrsrv_t*);
+ us = NIL(uchar*);
+ un = 0;
+ found = 0;
+
+ /* compatibility mode */
+ type = type < 0 ? SF_LASTR : type == 1 ? SF_STRING : type;
+
+ if(type&SF_LASTR) /* return the broken record */
+ { if((f->flags&SF_STRING) && (un = f->endb - f->next))
+ { us = f->next;
+ f->next = f->endb;
+ found = 1;
+ }
+ else if((rsrv = f->rsrv) && (un = -rsrv->slen) > 0)
+ { us = rsrv->data;
+ found = 1;
+ }
+ goto done;
+ }
+
+ while(!found)
+ { /* fill buffer if necessary */
+ if((n = (ends = f->endb) - (s = f->next)) <= 0)
+ { /* for unseekable devices, peek-read 1 record */
+ f->getr = rc;
+ f->mode |= SF_RC;
+
+ /* fill buffer the conventional way */
+ if(SFRPEEK(f,s,n) <= 0)
+ { us = NIL(uchar*);
+ goto done;
+ }
+ else
+ { ends = s+n;
+ if(f->mode&SF_RC)
+ { s = ends[-1] == rc ? ends-1 : ends;
+ goto do_copy;
+ }
+ }
+ }
+
+#if _lib_memchr
+ if(!(s = (uchar*)memchr((char*)s,rc,n)))
+ s = ends;
+#else
+ while(*s != rc)
+ if((s += 1) == ends)
+ break;
+#endif
+ do_copy:
+ if(s < ends) /* found separator */
+ { s += 1; /* include the separator */
+ found = 1;
+
+ if(!us &&
+ (!(type&SF_STRING) || !(f->flags&SF_STRING) ||
+ ((f->flags&SF_STRING) && (f->bits&SF_BOTH) ) ) )
+ { /* returning data in buffer */
+ us = f->next;
+ un = s - f->next;
+ f->next = s;
+ goto done;
+ }
+ }
+
+ /* amount to be read */
+ n = s - f->next;
+
+ if(!found && (_Sfmaxr > 0 && un+n+1 >= _Sfmaxr || (f->flags&SF_STRING))) /* already exceed limit */
+ { us = NIL(uchar*);
+ goto done;
+ }
+
+ /* get internal buffer */
+ if(!rsrv || rsrv->size < un+n+1)
+ { if(rsrv)
+ rsrv->slen = un;
+ if((rsrv = _sfrsrv(f,un+n+1)) != NIL(Sfrsrv_t*))
+ us = rsrv->data;
+ else
+ { us = NIL(uchar*);
+ goto done;
+ }
+ }
+
+ /* now copy data */
+ s = us+un;
+ un += n;
+ ends = f->next;
+ f->next += n;
+ MEMCPY(s,ends,n);
+ }
+
+done:
+ _Sfi = f->val = un;
+ f->getr = 0;
+ if(found && rc != 0 && (type&SF_STRING) )
+ { us[un-1] = '\0';
+ if(us >= f->data && us < f->endb)
+ { f->getr = rc;
+ f->mode |= SF_GETR;
+ }
+ }
+
+ /* prepare for a call to get the broken record */
+ if(rsrv)
+ rsrv->slen = found ? 0 : -un;
+
+ SFOPEN(f,0);
+
+ if(us && (type&SF_LOCKR) )
+ { f->mode |= SF_PEEK|SF_GETR;
+ f->endr = f->data;
+ }
+
+ SFMTXRETURN(f, (char*)us);
+}
diff --git a/src/lib/libast/sfio/sfgetu.c b/src/lib/libast/sfio/sfgetu.c
new file mode 100644
index 0000000..d0d6b5f
--- /dev/null
+++ b/src/lib/libast/sfio/sfgetu.c
@@ -0,0 +1,67 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Read an unsigned long value coded in a portable format.
+**
+** Written by Kiem-Phong Vo
+*/
+
+#if __STD_C
+Sfulong_t sfgetu(Sfio_t* f)
+#else
+Sfulong_t sfgetu(f)
+Sfio_t* f;
+#endif
+{
+ Sfulong_t v;
+ uchar *s, *ends, c;
+ int p;
+ SFMTXDECL(f); /* declare a local stream variable for multithreading */
+
+ SFMTXENTER(f, (Sfulong_t)(-1));
+
+ if(f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0)
+ SFMTXRETURN(f, (Sfulong_t)(-1));
+
+ SFLOCK(f,0);
+
+ for(v = 0;;)
+ { if(SFRPEEK(f,s,p) <= 0)
+ { f->flags |= SF_ERROR;
+ v = (Sfulong_t)(-1);
+ goto done;
+ }
+ for(ends = s+p; s < ends;)
+ { c = *s++;
+ v = (v << SF_UBITS) | SFUVALUE(c);
+ if(!(c&SF_MORE))
+ { f->next = s;
+ goto done;
+ }
+ }
+ f->next = s;
+ }
+done:
+ SFOPEN(f,0);
+ SFMTXRETURN(f, v);
+}
diff --git a/src/lib/libast/sfio/sfhdr.h b/src/lib/libast/sfio/sfhdr.h
new file mode 100644
index 0000000..d5f15cf
--- /dev/null
+++ b/src/lib/libast/sfio/sfhdr.h
@@ -0,0 +1,1302 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _SFHDR_H
+#define _SFHDR_H 1
+#if !defined(_BLD_sfio) && !defined(_BLD_stdio)
+#define _BLD_sfio 1
+#endif
+
+/* Internal definitions for sfio.
+** Written by Kiem-Phong Vo
+*/
+
+#define _next next
+#define _endw endw
+#define _endr endr
+#define _endb endb
+#define _push push
+#define _flags flags
+#define _file file
+#define _data data
+#define _size size
+#define _val val
+
+#include "FEATURE/sfio"
+#include "FEATURE/mmap"
+
+/* define va_list, etc. before including sfio_t.h (sfio.h) */
+#if !_PACKAGE_ast
+
+/* some systems don't know large files */
+#if defined(_NO_LARGEFILE64_SOURCE) || _mips == 2 /* || __hppa */
+#undef _NO_LARGEFILE64_SOURCE
+#define _NO_LARGEFILE64_SOURCE 1
+#undef _LARGEFILE64_SOURCE
+#undef _LARGEFILE_SOURCE
+#endif
+
+#if !_NO_LARGEFILE64_SOURCE && _typ_off64_t && _lib_lseek64 && _lib_stat64
+#undef _LARGEFILE64_SOURCE
+#undef _LARGEFILE_SOURCE
+#undef _FILE_OFFSET_BITS
+#define _LARGEFILE64_SOURCE 1 /* enabling the *64 stuff */
+#define _LARGEFILE_SOURCE 1
+#endif
+
+#if _hdr_stdarg
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+#include "FEATURE/common"
+#if !__STD_C
+#define const
+#endif
+#endif /* !_PACKAGE_ast */
+
+#include "sfio_t.h"
+
+/* note that the macro vt_threaded has effect on vthread.h */
+#include <vthread.h>
+
+/* file system info */
+#if _PACKAGE_ast
+
+#include <ast.h>
+#include <ast_time.h>
+#include <ast_tty.h>
+#include <ls.h>
+
+/* ast always provides multibyte handling */
+#undef _hdr_wchar
+#undef _lib_mbrtowc
+#undef _lib_wcrtomb
+#define _hdr_wchar 1
+#define _lib_mbrtowc 1
+#define _lib_wcrtomb 1
+
+#if _mem_st_blksize_stat
+#define _stat_blksize 1
+#endif
+
+#if _lib_localeconv && _hdr_locale
+#define _lib_locale 1
+#endif
+
+#define sfoff_t off_t
+#define sfstat_t struct stat
+#define sysclosef close
+#define syscreatf creat
+#define sysdupf dup
+#define sysfcntlf fcntl
+#define sysfstatf fstat
+#define sysftruncatef ftruncate
+#define syslseekf lseek
+#define sysmmapf mmap
+#define sysmunmapf munmap
+#define sysopenf open
+#define syspipef pipe
+#define sysreadf read
+#define sysremovef remove
+#define sysstatf stat
+#define syswritef write
+
+#else /*!_PACKAGE_ast*/
+
+/* when building the binary compatibility package, a number of header files
+ are not needed and they may get in the way so we remove them here.
+*/
+#if _SFBINARY_H
+#undef _hdr_time
+#undef _sys_time
+#undef _sys_stat
+#undef _hdr_stat
+#undef _hdr_filio
+#undef _sys_filio
+#undef _lib_poll
+#undef _stream_peek
+#undef _socket_peek
+#undef _hdr_vfork
+#undef _sys_vfork
+#undef _lib_vfork
+#undef _hdr_values
+#undef _hdr_math
+#undef _sys_mman
+#undef _hdr_mman
+#undef _sys_ioctl
+#endif
+
+#if _hdr_stdlib
+#include <stdlib.h>
+#endif
+
+#if _hdr_string
+#include <string.h>
+#endif
+
+#if _hdr_time
+#include <time.h>
+#endif
+#if _sys_time
+#include <sys/time.h>
+#endif
+
+#if _sys_stat
+#include <sys/stat.h>
+#else
+#if _hdr_stat
+#include <stat.h>
+#ifndef _sys_stat
+#define _sys_stat 1
+#endif
+#endif
+#endif /*_sys_stat*/
+
+#ifndef _sys_stat
+#define _sys_stat 0
+#endif
+
+#include <fcntl.h>
+
+#ifndef F_SETFD
+#ifndef FIOCLEX
+#if _hdr_filio
+#include <filio.h>
+#else
+#if _sys_filio
+#include <sys/filio.h>
+#endif /*_sys_filio*/
+#endif /*_hdr_filio*/
+#endif /*_FIOCLEX*/
+#endif /*F_SETFD*/
+
+#if _hdr_unistd
+#include <unistd.h>
+#endif
+
+#if !_LARGEFILE64_SOURCE /* turn off the *64 stuff */
+#undef _typ_off64_t
+#undef _typ_struct_stat64
+#undef _lib_creat64
+#undef _lib_open64
+#undef _lib_close64
+#undef _lib_stat64
+#undef _lib_fstat64
+#undef _lib_ftruncate64
+#undef _lib_lseek64
+#undef _lib_mmap64
+#undef _lib_munmap64
+#endif /*!_LARGEFILE64_SOURCE */
+
+/* see if we can use memory mapping for io */
+#if _LARGEFILE64_SOURCE && !_lib_mmap64
+#undef _mmap_worthy
+#endif
+#if !_mmap_worthy
+#undef _hdr_mman
+#undef _sys_mman
+#endif
+#if _hdr_mman
+#include <mman.h>
+#endif
+#if _sys_mman
+#include <sys/mman.h>
+#endif
+
+/* standardize system calls and types dealing with files */
+#if _typ_off64_t
+#define sfoff_t off64_t
+#else
+#define sfoff_t off_t
+#endif
+#if _typ_struct_stat64
+#define sfstat_t struct stat64
+#else
+#define sfstat_t struct stat
+#endif
+#if _lib_lseek64
+#define syslseekf lseek64
+#else
+#define syslseekf lseek
+#endif
+#if _lib_stat64
+#define sysstatf stat64
+#else
+#define sysstatf stat
+#endif
+#if _lib_fstat64
+#define sysfstatf fstat64
+#else
+#define sysfstatf fstat
+#endif
+#if _lib_mmap64
+#define sysmmapf mmap64
+#else
+#define sysmmapf mmap
+#endif
+#if _lib_munmap64
+#define sysmunmapf munmap64
+#else
+#define sysmunmapf munmap
+#endif
+#if _lib_open64
+#define sysopenf open64
+#else
+#define sysopenf open
+#endif
+#if _lib_creat64
+#define syscreatf creat64
+#else
+#define syscreatf creat
+#endif
+#if _lib_close64
+#define sysclosef close64
+#else
+#define sysclosef close
+#endif
+#if _lib_ftruncate64
+#undef _lib_ftruncate
+#define _lib_ftruncate 1
+#define sysftruncatef ftruncate64
+#endif
+#if !_lib_ftruncate64 && _lib_ftruncate
+#define sysftruncatef ftruncate
+#endif
+#if _lib_remove
+#define sysremovef remove
+#else
+#define sysremovef unlink
+#endif
+
+#define sysreadf read
+#define syswritef write
+#define syspipef pipe
+#define sysdupf dup
+#define sysfcntlf fcntl
+
+#endif /*_PACKAGE_ast*/
+
+#if !_mmap_worthy
+#undef MAP_TYPE
+#endif
+
+#include "FEATURE/float"
+
+#include <errno.h>
+#include <ctype.h>
+
+/* deal with multi-byte character and string conversions */
+#if _PACKAGE_ast
+
+#include <wchar.h>
+
+#define _has_multibyte 1
+
+#define SFMBMAX mbmax()
+#define SFMBCPY(to,fr) memcpy((to), (fr), sizeof(mbstate_t))
+#define SFMBCLR(mb) memset((mb), 0, sizeof(mbstate_t))
+#define SFMBSET(lhs,v) (lhs = (v))
+#define SFMBLEN(s,mb) mbsize(s)
+#define SFMBDCL(ms) mbstate_t ms;
+
+#else
+
+#if _hdr_wchar && _typ_mbstate_t && _lib_wcrtomb && _lib_mbrtowc
+#define _has_multibyte 1 /* Xopen-compliant */
+#if _typ___va_list && !defined(__va_list)
+#define __va_list va_list
+#endif
+#include <wchar.h>
+#define SFMBCPY(to,fr) memcpy((to), (fr), sizeof(mbstate_t))
+#define SFMBCLR(mb) memset((mb), 0, sizeof(mbstate_t))
+#define SFMBSET(lhs,v) (lhs = (v))
+#define SFMBDCL(mb) mbstate_t mb;
+#define SFMBLEN(s,mb) mbrtowc(NIL(wchar_t*), (s), SFMBMAX, (mb) )
+#endif /*_hdr_wchar && _typ_mbstate_t && _lib_wcrtomb && _lib_mbrtowc*/
+
+#if !_has_multibyte && _hdr_wchar && _lib_mbtowc && _lib_wctomb
+#define _has_multibyte 2 /* no shift states */
+#include <wchar.h>
+#undef mbrtowc
+#define mbrtowc(wp,s,n,mb) mbtowc(wp, s, n)
+#undef wcrtomb
+#define wcrtomb(s,wc,mb) wctomb(s, wc)
+#define SFMBCPY(to,fr)
+#define SFMBCLR(mb)
+#define SFMBSET(lhs,v)
+#define SFMBDCL(mb)
+#define SFMBLEN(s,mb) mbrtowc(NIL(wchar_t*), (s), SFMBMAX, (mb) )
+#endif /*!_has_multibyte && _hdr_wchar && _lib_mbtowc && _lib_wctomb*/
+
+#ifdef MB_CUR_MAX
+#define SFMBMAX MB_CUR_MAX
+#else
+#define SFMBMAX sizeof(Sflong_t)
+#endif
+
+#endif /* _PACKAGE_ast */
+
+#if !_has_multibyte
+#define _has_multibyte 0 /* no multibyte support */
+#define SFMBCPY(to,fr)
+#define SFMBCLR(mb)
+#define SFMBSET(lhs,v)
+#define SFMBLEN(s,mb) (*(s) ? 1 : 0)
+#define SFMBDCL(mb)
+#endif /* _has_multibyte */
+
+/* dealing with streams that might be accessed concurrently */
+#if vt_threaded
+
+#define SFMTXdecl(ff,_mf_) Sfio_t* _mf_ = (ff)
+#define SFMTXbegin(ff,_mf_,rv) \
+ { if((ff)->_flags&SF_MTSAFE) \
+ { (_mf_) = (ff); \
+ if(sfmutex((ff), SFMTX_LOCK) != 0) return(rv); \
+ if(_Sfnotify) \
+ { (*_Sfnotify)((_mf_), SF_MTACCESS, (Void_t*)(&(ff)) ); \
+ if(!(ff)) (ff) = (_mf_); \
+ } \
+ } \
+ }
+#define SFMTXend(ff,_mf_) \
+ { if((ff)->_flags&SF_MTSAFE) \
+ { if(_Sfnotify) \
+ (*_Sfnotify)((_mf_), SF_MTACCESS, NIL(Void_t*) ); \
+ sfmutex((ff), SFMTX_UNLOCK); \
+ (ff) = (_mf_); \
+ } \
+ }
+
+#define SFONCE() (_Sfdone ? 0 : vtonce(_Sfonce,_Sfoncef))
+
+#define SFMTXLOCK(f) (((f)->flags&SF_MTSAFE) ? sfmutex(f,SFMTX_LOCK) : 0)
+#define SFMTXUNLOCK(f) (((f)->flags&SF_MTSAFE) ? sfmutex(f,SFMTX_UNLOCK) : 0)
+
+#define SFMTXDECL(ff) SFMTXdecl((ff), _mtxf1_)
+#define SFMTXBEGIN(ff,v) { SFMTXbegin((ff), _mtxf1_, (v) ); }
+#define SFMTXEND(ff) { SFMTXend(ff, _mtxf1_); }
+#define SFMTXENTER(ff,v) { if(!(ff)) return(v); SFMTXBEGIN((ff), (v)); }
+#define SFMTXRETURN(ff,v) { SFMTXEND(ff); return(v); }
+
+#define SFMTXDECL2(ff) SFMTXdecl((ff), _mtxf2_)
+#define SFMTXBEGIN2(ff,v) { SFMTXbegin((ff), _mtxf2_, (v) ); }
+#define SFMTXEND2(ff) { SFMTXend((ff), _mtxf2_); }
+
+#define POOLMTXLOCK(p) ( vtmtxlock(&(p)->mutex) )
+#define POOLMTXUNLOCK(p) ( vtmtxunlock(&(p)->mutex) )
+#define POOLMTXENTER(p) { POOLMTXLOCK(p); }
+#define POOLMTXRETURN(p,rv) { POOLMTXUNLOCK(p); return(rv); }
+
+#else /*!vt_threaded*/
+
+#undef SF_MTSAFE /* no need to worry about thread-safety */
+#define SF_MTSAFE 0
+
+#define SFONCE() /*(0)*/
+
+#define SFMTXLOCK(f) /*(0)*/
+#define SFMTXUNLOCK(f) /*(0)*/
+
+#define SFMTXDECL(ff) /*(0)*/
+#define SFMTXBEGIN(ff,v) /*(0)*/
+#define SFMTXEND(ff) /*(0)*/
+#define SFMTXENTER(ff,v) { if(!(ff)) return(v); }
+#define SFMTXRETURN(ff,v) { return(v); }
+
+#define SFMTXDECL2(ff) /*(0)*/
+#define SFMTXBEGIN2(ff,v) /*(0)*/
+#define SFMTXEND2(ff) /*(0)*/
+
+#define POOLMTXLOCK(p)
+#define POOLMTXUNLOCK(p)
+#define POOLMTXENTER(p)
+#define POOLMTXRETURN(p,v) { return(v); }
+
+#endif /*vt_threaded*/
+
+
+/* functions for polling readiness of streams */
+#if _lib_select
+#undef _lib_poll
+#else
+#if _lib_poll_fd_1 || _lib_poll_fd_2
+#define _lib_poll 1
+#endif
+#endif /*_lib_select_*/
+
+#if _lib_poll
+#include <poll.h>
+
+#if _lib_poll_fd_1
+#define SFPOLL(pfd,n,tm) poll((pfd),(ulong)(n),(tm))
+#else
+#define SFPOLL(pfd,n,tm) poll((ulong)(n),(pfd),(tm))
+#endif
+#endif /*_lib_poll*/
+
+#if _stream_peek
+#include <stropts.h>
+#endif
+
+#if _socket_peek
+#include <sys/socket.h>
+#endif
+
+/* to test for executable access mode of a file */
+#ifndef X_OK
+#define X_OK 01
+#endif
+
+/* alternative process forking */
+#if _lib_vfork && !defined(fork) && !defined(sparc) && !defined(__sparc)
+#if _hdr_vfork
+#include <vfork.h>
+#endif
+#if _sys_vfork
+#include <sys/vfork.h>
+#endif
+#define fork vfork
+#endif
+
+/* to get rid of pesky compiler warnings */
+#if __STD_C
+#define NOTUSED(x) (void)(x)
+#else
+#define NOTUSED(x) (&x,1)
+#endif
+
+/* Private flags in the "bits" field */
+#define SF_MMAP 00000001 /* in memory mapping mode */
+#define SF_BOTH 00000002 /* both read/write */
+#define SF_HOLE 00000004 /* a hole of zero's was created */
+#define SF_NULL 00000010 /* stream is /dev/null */
+#define SF_SEQUENTIAL 00000020 /* sequential access */
+#define SF_JUSTSEEK 00000040 /* just did a sfseek */
+#define SF_PRIVATE 00000100 /* private stream to Sfio, no mutex */
+#define SF_ENDING 00000200 /* no re-io on interrupts at closing */
+#define SF_WIDE 00000400 /* in wide mode - stdio only */
+#define SF_PUTR 00001000 /* in sfputr() */
+
+/* "bits" flags that must be cleared in sfclrlock */
+#define SF_TMPBITS 00170000
+#define SF_DCDOWN 00010000 /* recurse down the discipline stack */
+
+#define SF_WCFORMAT 00020000 /* wchar_t formatting - stdio only */
+#if _has_multibyte
+#define SFWCSET(f) ((f)->bits |= SF_WCFORMAT)
+#define SFWCGET(f,v) (((v) = (f)->bits & SF_WCFORMAT), ((f)->bits &= ~SF_WCFORMAT) )
+#else
+#define SFWCSET(f)
+#define SFWCGET(f,v)
+#endif
+
+#define SF_MVSIZE 00040000 /* f->size was reset in sfmove() */
+#define SFMVSET(f) (((f)->size *= SF_NMAP), ((f)->bits |= SF_MVSIZE) )
+#define SFMVUNSET(f) (!((f)->bits&SF_MVSIZE) ? 0 : \
+ (((f)->bits &= ~SF_MVSIZE), ((f)->size /= SF_NMAP)) )
+
+#define SFCLRBITS(f) (SFMVUNSET(f), ((f)->bits &= ~SF_TMPBITS) )
+
+
+/* bits for the mode field, SF_INIT defined in sfio_t.h */
+#define SF_RC 00000010 /* peeking for a record */
+#define SF_RV 00000020 /* reserve without read or most write */
+#define SF_LOCK 00000040 /* stream is locked for io op */
+#define SF_PUSH 00000100 /* stream has been pushed */
+#define SF_POOL 00000200 /* stream is in a pool but not current */
+#define SF_PEEK 00000400 /* there is a pending peek */
+#define SF_PKRD 00001000 /* did a peek read */
+#define SF_GETR 00002000 /* did a getr on this stream */
+#define SF_SYNCED 00004000 /* stream was synced */
+#define SF_STDIO 00010000 /* given up the buffer to stdio */
+#define SF_AVAIL 00020000 /* was closed, available for reuse */
+#define SF_LOCAL 00100000 /* sentinel for a local call */
+
+#ifdef DEBUG
+#define ASSERT(p) ((p) ? 0 : (abort(),0) )
+#else
+#define ASSERT(p)
+#endif
+
+/* short-hands */
+#define NIL(t) ((t)0)
+#define reg register
+#ifndef uchar
+#define uchar unsigned char
+#endif
+#ifndef ulong
+#define ulong unsigned long
+#endif
+#ifndef uint
+#define uint unsigned int
+#endif
+#ifndef ushort
+#define ushort unsigned short
+#endif
+
+#define SECOND 1000 /* millisecond units */
+
+/* macros do determine stream types from sfstat_t data */
+#ifndef S_IFDIR
+#define S_IFDIR 0
+#endif
+#ifndef S_IFREG
+#define S_IFREG 0
+#endif
+#ifndef S_IFCHR
+#define S_IFCHR 0
+#endif
+#ifndef S_IFIFO
+#define S_IFIFO 0
+#endif
+#ifndef S_ISOCK
+#define S_ISOCK 0
+#endif
+
+#ifndef S_IFMT
+#define S_IFMT (S_IFDIR|S_IFREG|S_IFCHR|S_IFIFO|S_ISOCK)
+#endif
+
+#ifndef S_ISDIR
+#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
+#endif
+#ifndef S_ISREG
+#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG)
+#endif
+#ifndef S_ISCHR
+#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR)
+#endif
+
+#ifndef S_ISFIFO
+# if S_IFIFO
+# define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO)
+# else
+# define S_ISFIFO(m) (0)
+# endif
+#endif
+
+#ifdef S_IRUSR
+#define SF_CREATMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
+#else
+#define SF_CREATMODE 0666
+#endif
+
+/* set close-on-exec */
+#ifdef F_SETFD
+# ifndef FD_CLOEXEC
+# define FD_CLOEXEC 1
+# endif /*FD_CLOEXEC*/
+# define SETCLOEXEC(fd) ((void)fcntl((fd),F_SETFD,FD_CLOEXEC))
+#else
+# ifdef FIOCLEX
+# define SETCLOEXEC(fd) ((void)ioctl((fd),FIOCLEX,0))
+# else
+# define SETCLOEXEC(fd)
+# endif /*FIOCLEX*/
+#endif /*F_SETFD*/
+
+/* a couple of error number that we use, default values are like Linux */
+#ifndef EINTR
+#define EINTR 4
+#endif
+#ifndef EBADF
+#define EBADF 9
+#endif
+#ifndef EAGAIN
+#define EAGAIN 11
+#endif
+#ifndef ENOMEM
+#define ENOMEM 12
+#endif
+#ifndef EINVAL
+#define EINVAL 22
+#endif
+#ifndef ESPIPE
+#define ESPIPE 29
+#endif
+
+/* function to get the decimal point for local environment */
+#if !defined(SFSETLOCALE) && _PACKAGE_ast
+#include "lclib.h"
+#define SFSETLOCALE(dp,tp) \
+ do if (*(dp) == 0) { \
+ Lc_numeric_t* lv = (Lc_numeric_t*)LCINFO(AST_LC_NUMERIC)->data; \
+ *(dp) = lv->decimal; \
+ if (tp) *(tp) = lv->thousand; \
+ } while (0)
+#endif /*!defined(SFSETLOCALE) && _PACKAGE_ast*/
+
+#if !defined(SFSETLOCALE) && _lib_locale
+#include <locale.h>
+#define SFSETLOCALE(decimal,thousand) \
+ do { struct lconv* lv; \
+ if(*(decimal) == 0) \
+ { *(decimal) = '.'; \
+ if (thousand) *(thousand) = -1; \
+ if((lv = localeconv())) \
+ { if(lv->decimal_point && *lv->decimal_point) \
+ *(decimal) = *(unsigned char*)lv->decimal_point; \
+ if(thousand && lv->thousands_sep && *lv->thousands_sep) \
+ *(thousand) = *(unsigned char*)lv->thousands_sep; \
+ } \
+ } \
+ } while (0)
+#endif /*!defined(SFSETLOCALE) && _lib_locale*/
+
+#if !defined(SFSETLOCALE)
+#define SFSETLOCALE(decimal,thousand) (*(decimal)='.')
+#endif
+
+/* stream pool structure. */
+typedef struct _sfpool_s Sfpool_t;
+struct _sfpool_s
+{ Sfpool_t* next;
+ int mode; /* type of pool */
+ int s_sf; /* size of pool array */
+ int n_sf; /* number currently in pool */
+ Sfio_t** sf; /* array of streams */
+ Sfio_t* array[3]; /* start with 3 */
+ Vtmutex_t mutex; /* mutex lock object */
+};
+
+/* reserve buffer structure */
+typedef struct _sfrsrv_s Sfrsrv_t;
+struct _sfrsrv_s
+{ ssize_t slen; /* last string length */
+ ssize_t size; /* buffer size */
+ uchar data[1]; /* data buffer */
+};
+
+/* co-process structure */
+typedef struct _sfproc_s Sfproc_t;
+struct _sfproc_s
+{ int pid; /* process id */
+ uchar* rdata; /* read data being cached */
+ int ndata; /* size of cached data */
+ int size; /* buffer size */
+ int file; /* saved file descriptor */
+ int sigp; /* sigpipe protection needed */
+};
+
+/* extensions to sfvprintf/sfvscanf */
+#define FP_SET(fp,fn) (fp < 0 ? (fn += 1) : (fn = fp) )
+#define FP_WIDTH 0
+#define FP_PRECIS 1
+#define FP_BASE 2
+#define FP_STR 3
+#define FP_SIZE 4
+#define FP_INDEX 5 /* index size */
+
+typedef struct _fmt_s Fmt_t;
+typedef struct _fmtpos_s Fmtpos_t;
+typedef union
+{ int i, *ip;
+ long l, *lp;
+ short h, *hp;
+ uint ui;
+ ulong ul;
+ ushort uh;
+ Sflong_t ll, *llp;
+ Sfulong_t lu;
+ Sfdouble_t ld;
+ double d;
+ float f;
+#if _has_multibyte
+ wchar_t wc;
+ wchar_t *ws, **wsp;
+#endif
+ char c, *s, **sp;
+ uchar uc, *us, **usp;
+ Void_t *vp;
+ Sffmt_t *ft;
+} Argv_t;
+
+struct _fmt_s
+{ char* form; /* format string */
+ va_list args; /* corresponding arglist */
+ SFMBDCL(mbs) /* multibyte parsing state */
+
+ char* oform; /* original format string */
+ va_list oargs; /* original arg list */
+ int argn; /* number of args already used */
+ Fmtpos_t* fp; /* position list */
+
+ Sffmt_t* ft; /* formatting environment */
+ Sffmtevent_f eventf; /* event function */
+ Fmt_t* next; /* stack frame pointer */
+};
+
+struct _fmtpos_s
+{ Sffmt_t ft; /* environment */
+ Argv_t argv; /* argument value */
+ int fmt; /* original format */
+ int need[FP_INDEX]; /* positions depending on */
+};
+
+#define LEFTP '('
+#define RIGHTP ')'
+#define QUOTE '\''
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+#define FMTSET(ft, frm,ags, fv, sz, flgs, wid,pr,bs, ts,ns) \
+ ((ft->form = (char*)frm), va_copy(ft->args,ags), \
+ (ft->fmt = fv), (ft->size = sz), \
+ (ft->flags = (flgs&SFFMT_SET)), \
+ (ft->width = wid), (ft->precis = pr), (ft->base = bs), \
+ (ft->t_str = ts), (ft->n_str = ns) )
+#define FMTGET(ft, frm,ags, fv, sz, flgs, wid,pr,bs) \
+ ((frm = ft->form), va_copy(ags,ft->args), \
+ (fv = ft->fmt), (sz = ft->size), \
+ (flgs = (flgs&~(SFFMT_SET))|(ft->flags&SFFMT_SET)), \
+ (wid = ft->width), (pr = ft->precis), (bs = ft->base) )
+
+/* format flags&types, must coexist with those in sfio.h */
+#define SFFMT_FORBIDDEN 000077777777 /* for sfio.h only */
+#define SFFMT_EFORMAT 001000000000 /* sfcvt converting %e */
+#define SFFMT_MINUS 002000000000 /* minus sign */
+#define SFFMT_AFORMAT 004000000000 /* sfcvt converting %a */
+#define SFFMT_UPPER 010000000000 /* sfcvt converting upper */
+
+#define SFFMT_TYPES (SFFMT_SHORT|SFFMT_SSHORT | SFFMT_LONG|SFFMT_LLONG|\
+ SFFMT_LDOUBLE | SFFMT_IFLAG|SFFMT_JFLAG| \
+ SFFMT_TFLAG | SFFMT_ZFLAG )
+
+/* type of elements to be converted */
+#define SFFMT_INT 001 /* %d,%i */
+#define SFFMT_UINT 002 /* %u,o,x etc. */
+#define SFFMT_FLOAT 004 /* %f,e,g etc. */
+#define SFFMT_CHAR 010 /* %c,C */
+#define SFFMT_POINTER 020 /* %p,n,s,S */
+#define SFFMT_CLASS 040 /* %[ */
+
+/* local variables used across sf-functions */
+#define _Sfpage (_Sfextern.sf_page)
+#define _Sfpool (_Sfextern.sf_pool)
+#define _Sfpmove (_Sfextern.sf_pmove)
+#define _Sfstack (_Sfextern.sf_stack)
+#define _Sfnotify (_Sfextern.sf_notify)
+#define _Sfstdsync (_Sfextern.sf_stdsync)
+#define _Sfudisc (&(_Sfextern.sf_udisc))
+#define _Sfcleanup (_Sfextern.sf_cleanup)
+#define _Sfexiting (_Sfextern.sf_exiting)
+#define _Sfdone (_Sfextern.sf_done)
+#define _Sfonce (_Sfextern.sf_once)
+#define _Sfoncef (_Sfextern.sf_oncef)
+#define _Sfmutex (_Sfextern.sf_mutex)
+typedef struct _sfextern_s
+{ ssize_t sf_page;
+ struct _sfpool_s sf_pool;
+ int (*sf_pmove)_ARG_((Sfio_t*, int));
+ Sfio_t* (*sf_stack)_ARG_((Sfio_t*, Sfio_t*));
+ void (*sf_notify)_ARG_((Sfio_t*, int, void*));
+ int (*sf_stdsync)_ARG_((Sfio_t*));
+ struct _sfdisc_s sf_udisc;
+ void (*sf_cleanup)_ARG_((void));
+ int sf_exiting;
+ int sf_done;
+ Vtonce_t* sf_once;
+ void (*sf_oncef)_ARG_((void));
+ Vtmutex_t* sf_mutex;
+} Sfextern_t;
+
+/* get the real value of a byte in a coded long or ulong */
+#define SFUVALUE(v) (((ulong)(v))&(SF_MORE-1))
+#define SFSVALUE(v) ((( long)(v))&(SF_SIGN-1))
+#define SFBVALUE(v) (((ulong)(v))&(SF_BYTE-1))
+
+/* pick this many bits in each iteration of double encoding */
+#define SF_PRECIS 7
+
+/* grain size for buffer increment */
+#define SF_GRAIN 1024
+#define SF_PAGE ((ssize_t)(SF_GRAIN*sizeof(int)*2))
+
+/* when the buffer is empty, certain io requests may be better done directly
+ on the given application buffers. The below condition determines when.
+*/
+#define SFDIRECT(f,n) (((ssize_t)(n) >= (f)->size) || \
+ ((n) >= SF_GRAIN && (ssize_t)(n) >= (f)->size/16 ) )
+
+/* number of pages to memory map at a time */
+#if _ptr_bits >= 64
+#define SF_NMAP 1024
+#else
+#define SF_NMAP 32
+#endif
+
+#ifndef MAP_VARIABLE
+#define MAP_VARIABLE 0
+#endif
+#ifndef _mmap_fixed
+#define _mmap_fixed 0
+#endif
+
+/* set/unset sequential states for mmap */
+#if _lib_madvise && defined(MADV_SEQUENTIAL) && defined(MADV_NORMAL)
+#define SFMMSEQON(f,a,s) \
+ do { int oerrno = errno; \
+ (void)madvise((caddr_t)(a),(size_t)(s),MADV_SEQUENTIAL); \
+ errno = oerrno; \
+ } while(0)
+#define SFMMSEQOFF(f,a,s) \
+ do { int oerrno = errno; \
+ (void)madvise((caddr_t)(a),(size_t)(s),MADV_NORMAL); \
+ errno = oerrno; \
+ } while(0)
+#else
+#define SFMMSEQON(f,a,s)
+#define SFMMSEQOFF(f,a,s)
+#endif
+
+#define SFMUNMAP(f,a,s) (sysmunmapf((caddr_t)(a),(size_t)(s)), \
+ ((f)->endb = (f)->endr = (f)->endw = (f)->next = \
+ (f)->data = NIL(uchar*)) )
+
+/* safe closing function */
+#define CLOSE(f) { while(sysclosef(f) < 0 && errno == EINTR) errno = 0; }
+
+/* the bottomless bit bucket */
+#define DEVNULL "/dev/null"
+#define SFSETNULL(f) ((f)->extent = (Sfoff_t)(-1), (f)->bits |= SF_NULL)
+#define SFISNULL(f) ((f)->extent < 0 && ((f)->bits&SF_NULL) )
+
+#define SFKILL(f) ((f)->mode = (SF_AVAIL|SF_LOCK) )
+#define SFKILLED(f) (((f)->mode&(SF_AVAIL|SF_LOCK)) == (SF_AVAIL|SF_LOCK) )
+
+/* exception types */
+#define SF_EDONE 0 /* stop this operation and return */
+#define SF_EDISC 1 /* discipline says it's ok */
+#define SF_ESTACK 2 /* stack was popped */
+#define SF_ECONT 3 /* can continue normally */
+
+#define SETLOCAL(f) ((f)->mode |= SF_LOCAL)
+#define GETLOCAL(f,v) ((v) = ((f)->mode&SF_LOCAL), (f)->mode &= ~SF_LOCAL, (v))
+#define SFWRALL(f) ((f)->mode |= SF_RV)
+#define SFISALL(f,v) ((((v) = (f)->mode&SF_RV) ? ((f)->mode &= ~SF_RV) : 0), \
+ ((v) || ((f)->flags&(SF_SHARE|SF_APPENDWR|SF_WHOLE)) ) )
+#define SFSK(f,a,o,d) (SETLOCAL(f),sfsk(f,(Sfoff_t)a,o,d))
+#define SFRD(f,b,n,d) (SETLOCAL(f),sfrd(f,(Void_t*)b,n,d))
+#define SFWR(f,b,n,d) (SETLOCAL(f),sfwr(f,(Void_t*)b,n,d))
+#define SFSYNC(f) (SETLOCAL(f),sfsync(f))
+#define SFCLOSE(f) (SETLOCAL(f),sfclose(f))
+#define SFFLSBUF(f,n) (SETLOCAL(f),_sfflsbuf(f,n))
+#define SFFILBUF(f,n) (SETLOCAL(f),_sffilbuf(f,n))
+#define SFSETBUF(f,s,n) (SETLOCAL(f),sfsetbuf(f,s,n))
+#define SFWRITE(f,s,n) (SETLOCAL(f),sfwrite(f,s,n))
+#define SFREAD(f,s,n) (SETLOCAL(f),sfread(f,s,n))
+#define SFSEEK(f,p,t) (SETLOCAL(f),sfseek(f,p,t))
+#define SFNPUTC(f,c,n) (SETLOCAL(f),sfnputc(f,c,n))
+#define SFRAISE(f,e,d) (SETLOCAL(f),sfraise(f,e,d))
+
+/* lock/open a stream */
+#define SFMODE(f,l) ((f)->mode & ~(SF_RV|SF_RC|((l) ? SF_LOCK : 0)) )
+#define SFLOCK(f,l) (void)((f)->mode |= SF_LOCK, (f)->endr = (f)->endw = (f)->data)
+#define _SFOPENRD(f) ((f)->endr = ((f)->flags&SF_MTSAFE) ? (f)->data : (f)->endb)
+#define _SFOPENWR(f) ((f)->endw = ((f)->flags&(SF_MTSAFE|SF_LINE)) ? (f)->data : (f)->endb)
+#define _SFOPEN(f) ((f)->mode == SF_READ ? _SFOPENRD(f) : \
+ (f)->mode == SF_WRITE ? _SFOPENWR(f) : \
+ ((f)->endw = (f)->endr = (f)->data) )
+#define SFOPEN(f,l) (void)((l) ? 0 : \
+ ((f)->mode &= ~(SF_LOCK|SF_RC|SF_RV), _SFOPEN(f), 0) )
+
+/* check to see if the stream can be accessed */
+#define SFFROZEN(f) (((f)->mode&(SF_PUSH|SF_LOCK|SF_PEEK)) ? 1 : \
+ !((f)->mode&SF_STDIO) ? 0 : \
+ _Sfstdsync ? (*_Sfstdsync)(f) : (((f)->mode &= ~SF_STDIO),0) )
+
+
+/* set discipline code */
+#define SFDISC(f,dc,iof) \
+ { Sfdisc_t* d; \
+ if(!(dc)) \
+ d = (dc) = (f)->disc; \
+ else d = (f->bits&SF_DCDOWN) ? ((dc) = (dc)->disc) : (dc); \
+ while(d && !(d->iof)) d = d->disc; \
+ if(d) (dc) = d; \
+ }
+#define SFDCRD(f,buf,n,dc,rv) \
+ { int dcdown = f->bits&SF_DCDOWN; f->bits |= SF_DCDOWN; \
+ rv = (*dc->readf)(f,buf,n,dc); \
+ if(!dcdown) f->bits &= ~SF_DCDOWN; \
+ }
+#define SFDCWR(f,buf,n,dc,rv) \
+ { int dcdown = f->bits&SF_DCDOWN; f->bits |= SF_DCDOWN; \
+ rv = (*dc->writef)(f,buf,n,dc); \
+ if(!dcdown) f->bits &= ~SF_DCDOWN; \
+ }
+#define SFDCSK(f,addr,type,dc,rv) \
+ { int dcdown = f->bits&SF_DCDOWN; f->bits |= SF_DCDOWN; \
+ rv = (*dc->seekf)(f,addr,type,dc); \
+ if(!dcdown) f->bits &= ~SF_DCDOWN; \
+ }
+
+/* fast peek of a stream */
+#define _SFAVAIL(f,s,n) ((n) = (f)->endb - ((s) = (f)->next) )
+#define SFRPEEK(f,s,n) (_SFAVAIL(f,s,n) > 0 ? (n) : \
+ ((n) = SFFILBUF(f,-1), (s) = (f)->next, (n)) )
+#define SFWPEEK(f,s,n) (_SFAVAIL(f,s,n) > 0 ? (n) : \
+ ((n) = SFFLSBUF(f,-1), (s) = (f)->next, (n)) )
+
+/* more than this for a line buffer, we might as well flush */
+#define HIFORLINE 128
+
+/* string stream extent */
+#define SFSTRSIZE(f) { Sfoff_t s = (f)->next - (f)->data; \
+ if(s > (f)->here) \
+ { (f)->here = s; if(s > (f)->extent) (f)->extent = s; } \
+ }
+
+/* control flags for open() */
+#ifdef O_CREAT
+#define _has_oflags 1
+#else /* for example, research UNIX */
+#define _has_oflags 0
+#define O_CREAT 004
+#define O_TRUNC 010
+#define O_APPEND 020
+#define O_EXCL 040
+
+#ifndef O_RDONLY
+#define O_RDONLY 000
+#endif
+#ifndef O_WRONLY
+#define O_WRONLY 001
+#endif
+#ifndef O_RDWR
+#define O_RDWR 002
+#endif
+#endif /*O_CREAT*/
+
+#ifndef O_BINARY
+#define O_BINARY 000
+#endif
+#ifndef O_TEXT
+#define O_TEXT 000
+#endif
+#ifndef O_TEMPORARY
+#define O_TEMPORARY 000
+#endif
+
+#define SF_RADIX 64 /* maximum integer conversion base */
+
+#if _PACKAGE_ast
+#define SF_MAXINT INT_MAX
+#define SF_MAXLONG LONG_MAX
+#else
+#define SF_MAXINT ((int)(((uint)~0) >> 1))
+#define SF_MAXLONG ((long)(((ulong)~0L) >> 1))
+#endif
+
+#define SF_MAXCHAR ((uchar)(~0))
+
+/* floating point to ascii conversion */
+#define SF_MAXEXP10 6
+#define SF_MAXPOW10 (1 << SF_MAXEXP10)
+#if !_ast_fltmax_double
+#define SF_FDIGITS 1024 /* max allowed fractional digits */
+#define SF_IDIGITS (8*1024) /* max number of digits in int part */
+#else
+#define SF_FDIGITS 256 /* max allowed fractional digits */
+#define SF_IDIGITS 1024 /* max number of digits in int part */
+#endif
+#define SF_MAXDIGITS (((SF_FDIGITS+SF_IDIGITS)/sizeof(int) + 1)*sizeof(int))
+
+/* tables for numerical translation */
+#define _Sfpos10 (_Sftable.sf_pos10)
+#define _Sfneg10 (_Sftable.sf_neg10)
+#define _Sfdec (_Sftable.sf_dec)
+#define _Sfdigits (_Sftable.sf_digits)
+#define _Sfcvinitf (_Sftable.sf_cvinitf)
+#define _Sfcvinit (_Sftable.sf_cvinit)
+#define _Sffmtposf (_Sftable.sf_fmtposf)
+#define _Sffmtintf (_Sftable.sf_fmtintf)
+#define _Sfcv36 (_Sftable.sf_cv36)
+#define _Sfcv64 (_Sftable.sf_cv64)
+#define _Sftype (_Sftable.sf_type)
+#define _Sfieee (&_Sftable.sf_ieee)
+#define _Sffinf (_Sftable.sf_ieee.fltinf)
+#define _Sfdinf (_Sftable.sf_ieee.dblinf)
+#define _Sflinf (_Sftable.sf_ieee.ldblinf)
+#define _Sffnan (_Sftable.sf_ieee.fltnan)
+#define _Sfdnan (_Sftable.sf_ieee.dblnan)
+#define _Sflnan (_Sftable.sf_ieee.ldblnan)
+#define _Sffpow10 (_Sftable.sf_flt_pow10)
+#define _Sfdpow10 (_Sftable.sf_dbl_pow10)
+#define _Sflpow10 (_Sftable.sf_ldbl_pow10)
+typedef struct _sfieee_s Sfieee_t;
+struct _sfieee_s
+{ float fltnan; /* float NAN */
+ float fltinf; /* float INF */
+ double dblnan; /* double NAN */
+ double dblinf; /* double INF */
+ Sfdouble_t ldblnan; /* Sfdouble_t NAN */
+ Sfdouble_t ldblinf; /* Sfdouble_t INF */
+};
+typedef struct _sftab_
+{ Sfdouble_t sf_pos10[SF_MAXEXP10]; /* positive powers of 10 */
+ Sfdouble_t sf_neg10[SF_MAXEXP10]; /* negative powers of 10 */
+ uchar sf_dec[200]; /* ascii reps of values < 100 */
+ char* sf_digits; /* digits for general bases */
+ int (*sf_cvinitf)(); /* initialization function */
+ int sf_cvinit; /* initialization state */
+ Fmtpos_t* (*sf_fmtposf)_ARG_((Sfio_t*,const char*,va_list,Sffmt_t*,int));
+ char* (*sf_fmtintf)_ARG_((const char*,int*));
+ float* sf_flt_pow10; /* float powers of 10 */
+ double* sf_dbl_pow10; /* double powers of 10 */
+ Sfdouble_t* sf_ldbl_pow10; /* Sfdouble_t powers of 10 */
+ uchar sf_cv36[SF_MAXCHAR+1]; /* conversion for base [2-36] */
+ uchar sf_cv64[SF_MAXCHAR+1]; /* conversion for base [37-64] */
+ uchar sf_type[SF_MAXCHAR+1]; /* conversion formats&types */
+ Sfieee_t sf_ieee; /* IEEE floating point constants*/
+} Sftab_t;
+
+/* thread-safe macro/function to initialize _Sfcv* conversion tables */
+#define SFCVINIT() (_Sfcvinit ? 1 : (_Sfcvinit = (*_Sfcvinitf)()) )
+
+/* sfucvt() converts decimal integers to ASCII */
+#define SFDIGIT(v,scale,digit) \
+ { if(v < 5*scale) \
+ if(v < 2*scale) \
+ if(v < 1*scale) \
+ { digit = '0'; } \
+ else { digit = '1'; v -= 1*scale; } \
+ else if(v < 3*scale) \
+ { digit = '2'; v -= 2*scale; } \
+ else if(v < 4*scale) \
+ { digit = '3'; v -= 3*scale; } \
+ else { digit = '4'; v -= 4*scale; } \
+ else if(v < 7*scale) \
+ if(v < 6*scale) \
+ { digit = '5'; v -= 5*scale; } \
+ else { digit = '6'; v -= 6*scale; } \
+ else if(v < 8*scale) \
+ { digit = '7'; v -= 7*scale; } \
+ else if(v < 9*scale) \
+ { digit = '8'; v -= 8*scale; } \
+ else { digit = '9'; v -= 9*scale; } \
+ }
+#define sfucvt(v,s,n,list,type,utype) \
+ { while((utype)v >= 10000) \
+ { n = v; v = (type)(((utype)v)/10000); \
+ n = (type)((utype)n - ((utype)v)*10000); \
+ s -= 4; SFDIGIT(n,1000,s[0]); SFDIGIT(n,100,s[1]); \
+ s[2] = *(list = (char*)_Sfdec + (n <<= 1)); s[3] = *(list+1); \
+ } \
+ if(v < 100) \
+ { if(v < 10) \
+ { s -= 1; s[0] = (char)('0'+v); \
+ } else \
+ { s -= 2; s[0] = *(list = (char*)_Sfdec + (v <<= 1)); s[1] = *(list+1); \
+ } \
+ } else \
+ { if(v < 1000) \
+ { s -= 3; SFDIGIT(v,100,s[0]); \
+ s[1] = *(list = (char*)_Sfdec + (v <<= 1)); s[2] = *(list+1); \
+ } else \
+ { s -= 4; SFDIGIT(v,1000,s[0]); SFDIGIT(v,100,s[1]); \
+ s[2] = *(list = (char*)_Sfdec + (v <<= 1)); s[3] = *(list+1); \
+ } \
+ } \
+ }
+
+/* handy functions */
+#undef min
+#undef max
+#define min(x,y) ((x) < (y) ? (x) : (y))
+#define max(x,y) ((x) > (y) ? (x) : (y))
+
+/* fast functions for memory copy and memory clear */
+#if _PACKAGE_ast
+#define memclear(s,n) memzero(s,n)
+#else
+#if _lib_bcopy && !_lib_memcpy
+#define memcpy(to,fr,n) bcopy((fr),(to),(n))
+#endif
+#if _lib_bzero && !_lib_memset
+#define memclear(s,n) bzero((s),(n))
+#else
+#define memclear(s,n) memset((s),'\0',(n))
+#endif
+#endif /*_PACKAGE_ast*/
+
+/* note that MEMCPY advances the associated pointers */
+#define MEMCPY(to,fr,n) \
+ switch(n) \
+ { default : memcpy((Void_t*)to,(Void_t*)fr,n); to += n; fr += n; break; \
+ case 7 : *to++ = *fr++; \
+ case 6 : *to++ = *fr++; \
+ case 5 : *to++ = *fr++; \
+ case 4 : *to++ = *fr++; \
+ case 3 : *to++ = *fr++; \
+ case 2 : *to++ = *fr++; \
+ case 1 : *to++ = *fr++; \
+ }
+#define MEMSET(s,c,n) \
+ switch(n) \
+ { default : memset((Void_t*)s,(int)c,n); s += n; break; \
+ case 7 : *s++ = c; \
+ case 6 : *s++ = c; \
+ case 5 : *s++ = c; \
+ case 4 : *s++ = c; \
+ case 3 : *s++ = c; \
+ case 2 : *s++ = c; \
+ case 1 : *s++ = c; \
+ }
+
+_BEGIN_EXTERNS_
+
+extern Sftab_t _Sftable;
+
+extern int _sfpopen _ARG_((Sfio_t*, int, int, int));
+extern int _sfpclose _ARG_((Sfio_t*));
+extern int _sfexcept _ARG_((Sfio_t*, int, ssize_t, Sfdisc_t*));
+extern Sfrsrv_t* _sfrsrv _ARG_((Sfio_t*, ssize_t));
+extern int _sfsetpool _ARG_((Sfio_t*));
+extern char* _sfcvt _ARG_((Void_t*,char*,size_t,int,int*,int*,int*,int));
+extern char** _sfgetpath _ARG_((char*));
+
+#if _BLD_sfio && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+#if !_BLD_sfio && defined(__IMPORT__)
+#define extern extern __IMPORT__
+#endif
+
+extern Sfextern_t _Sfextern;
+
+extern int _sfmode _ARG_((Sfio_t*, int, int));
+extern int _sftype _ARG_((const char*, int*, int*));
+
+#undef extern
+
+#ifndef errno
+extern int errno;
+#endif
+
+/* for portable encoding of double values */
+#ifndef frexpl
+#if _ast_fltmax_double
+#define frexpl frexp
+#endif
+#if !__STDC__
+extern Sfdouble_t frexpl _ARG_((Sfdouble_t, int*));
+#endif
+#endif
+#ifndef ldexpl
+#if _ast_fltmax_double
+#define ldexpl ldexp
+#endif
+#if !__STDC__
+extern Sfdouble_t ldexpl _ARG_((Sfdouble_t, int));
+#endif
+#endif
+
+#if !_PACKAGE_ast
+
+#if !__STDC__ && !_hdr_stdlib
+extern void abort _ARG_((void));
+extern int atexit _ARG_((void(*)(void)));
+extern char* getenv _ARG_((const char*));
+extern void* malloc _ARG_((size_t));
+extern void* realloc _ARG_((void*, size_t));
+extern void free _ARG_((void*));
+extern size_t strlen _ARG_((const char*));
+extern char* strcpy _ARG_((char*, const char*));
+
+extern Void_t* memset _ARG_((void*, int, size_t));
+extern Void_t* memchr _ARG_((const void*, int, size_t));
+extern Void_t* memccpy _ARG_((void*, const void*, int, size_t));
+#ifndef memcpy
+extern Void_t* memcpy _ARG_((void*, const void*, size_t));
+#endif
+#if !defined(strtod)
+extern double strtod _ARG_((const char*, char**));
+#endif
+#if !defined(remove)
+extern int sysremovef _ARG_((const char*));
+#endif
+#endif /* !__STDC__ && !_hdr_stdlib */
+
+#if !_hdr_unistd
+#if _proto_open && __cplusplus
+extern int sysopenf _ARG_((const char*, int, ...));
+#endif
+extern int sysclosef _ARG_((int));
+extern ssize_t sysreadf _ARG_((int, void*, size_t));
+extern ssize_t syswritef _ARG_((int, const void*, size_t));
+extern sfoff_t syslseekf _ARG_((int, sfoff_t, int));
+extern int sysdupf _ARG_((int));
+extern int syspipef _ARG_((int*));
+extern int sysaccessf _ARG_((const char*, int));
+extern int sysremovef _ARG_((const char*));
+extern int sysfstatf _ARG_((int, sfstat_t*));
+extern int sysstatf _ARG_((const char*, sfstat_t*));
+
+extern int isatty _ARG_((int));
+
+extern int wait _ARG_((int*));
+extern uint sleep _ARG_((uint));
+extern int execl _ARG_((const char*, const char*,...));
+extern int execv _ARG_((const char*, char**));
+#if !defined(fork)
+extern int fork _ARG_((void));
+#endif
+#if _lib_unlink
+extern int unlink _ARG_((const char*));
+#endif
+
+#endif /*_hdr_unistd*/
+
+#if _lib_bcopy && !_proto_bcopy
+extern void bcopy _ARG_((const void*, void*, size_t));
+#endif
+#if _lib_bzero && !_proto_bzero
+extern void bzero _ARG_((void*, size_t));
+#endif
+
+extern time_t time _ARG_((time_t*));
+extern int waitpid _ARG_((int,int*,int));
+extern void _exit _ARG_((int));
+typedef int(* Onexit_f)_ARG_((void));
+extern Onexit_f onexit _ARG_((Onexit_f));
+
+#if _lib_vfork && !_hdr_vfork && !_sys_vfork
+extern pid_t vfork _ARG_((void));
+#endif /*_lib_vfork*/
+
+#if _lib_poll
+#if _lib_poll_fd_1
+extern int poll _ARG_((struct pollfd*, ulong, int));
+#else
+extern int poll _ARG_((ulong, struct pollfd*, int));
+#endif
+#endif /*_lib_poll*/
+
+#endif /* _PACKAGE_ast */
+
+_END_EXTERNS_
+
+#endif /*_SFHDR_H*/
diff --git a/src/lib/libast/sfio/sfllen.c b/src/lib/libast/sfio/sfllen.c
new file mode 100644
index 0000000..4dd4879
--- /dev/null
+++ b/src/lib/libast/sfio/sfllen.c
@@ -0,0 +1,39 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Get size of a long value coded in a portable format
+**
+** Written by Kiem-Phong Vo
+*/
+#if __STD_C
+int _sfllen(Sflong_t v)
+#else
+int _sfllen(v)
+Sflong_t v;
+#endif
+{
+ if(v < 0)
+ v = -(v+1);
+ v = (Sfulong_t)v >> SF_SBITS;
+ return 1 + (v > 0 ? sfulen(v) : 0);
+}
diff --git a/src/lib/libast/sfio/sfmode.c b/src/lib/libast/sfio/sfmode.c
new file mode 100644
index 0000000..97182fb
--- /dev/null
+++ b/src/lib/libast/sfio/sfmode.c
@@ -0,0 +1,596 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+static char* Version = "\n@(#)$Id: sfio (AT&T Labs - Research) 2009-09-15 $\0\n";
+
+/* Functions to set a given stream to some desired mode
+**
+** Written by Kiem-Phong Vo.
+**
+** Modifications:
+** 06/27/1990 (first version)
+** 01/06/1991
+** 07/08/1991
+** 06/18/1992
+** 02/02/1993
+** 05/25/1993
+** 02/07/1994
+** 05/21/1996
+** 08/01/1997
+** 08/01/1998 (extended formatting)
+** 09/09/1999 (thread-safe)
+** 02/01/2001 (adaptive buffering)
+** 05/31/2002 (multi-byte handling in sfvprintf/vscanf)
+** 09/06/2002 (SF_IOINTR flag)
+** 11/15/2002 (%#c for sfvprintf)
+** 05/31/2003 (sfsetbuf(f,f,align_size) to set alignment for data)
+** (%I1d is fixed to handle "signed char" correctly)
+** 01/01/2004 Porting issues to various platforms resolved.
+** 06/01/2008 Allowing notify() at entering/exiting thread-safe routines.
+** 09/15/2008 Add sfwalk().
+*/
+
+/* the below is for protecting the application from SIGPIPE */
+#if _PACKAGE_ast
+#include <sig.h>
+#include <wait.h>
+#define Sfsignal_f Sig_handler_t
+#else
+#include <signal.h>
+typedef void(* Sfsignal_f)_ARG_((int));
+#endif
+static int _Sfsigp = 0; /* # of streams needing SIGPIPE protection */
+
+/* done at exiting time */
+#if __STD_C
+static void _sfcleanup(void)
+#else
+static void _sfcleanup()
+#endif
+{
+ reg Sfpool_t* p;
+ reg Sfio_t* f;
+ reg int n;
+ reg int pool;
+
+ f = (Sfio_t*)Version; /* shut compiler warning */
+
+ /* set this so that no more buffering is allowed for write streams */
+ _Sfexiting = 1001;
+
+ sfsync(NIL(Sfio_t*));
+
+ for(p = &_Sfpool; p; p = p->next)
+ { for(n = 0; n < p->n_sf; ++n)
+ { if(!(f = p->sf[n]) || SFFROZEN(f) )
+ continue;
+
+ SFLOCK(f,0);
+ SFMTXLOCK(f);
+
+ /* let application know that we are leaving */
+ (void)SFRAISE(f, SF_ATEXIT, NIL(Void_t*));
+
+ if(f->flags&SF_STRING)
+ continue;
+
+ /* from now on, write streams are unbuffered */
+ pool = f->mode&SF_POOL;
+ f->mode &= ~SF_POOL;
+ if((f->flags&SF_WRITE) && !(f->mode&SF_WRITE))
+ (void)_sfmode(f,SF_WRITE,1);
+ if(f->data &&
+ ((f->bits&SF_MMAP) ||
+ ((f->mode&SF_WRITE) && f->next == f->data) ) )
+ (void)SFSETBUF(f,NIL(Void_t*),0);
+ f->mode |= pool;
+
+ SFMTXUNLOCK(f);
+ SFOPEN(f,0);
+ }
+ }
+}
+
+/* put into discrete pool */
+#if __STD_C
+int _sfsetpool(Sfio_t* f)
+#else
+int _sfsetpool(f)
+Sfio_t* f;
+#endif
+{
+ reg Sfpool_t* p;
+ reg Sfio_t** array;
+ reg int n, rv;
+
+ if(!_Sfcleanup)
+ { _Sfcleanup = _sfcleanup;
+ (void)atexit(_sfcleanup);
+ }
+
+ if(!(p = f->pool) )
+ p = f->pool = &_Sfpool;
+
+ POOLMTXENTER(p);
+
+ rv = -1;
+
+ if(p->n_sf >= p->s_sf)
+ { if(p->s_sf == 0) /* initialize pool array */
+ { p->s_sf = sizeof(p->array)/sizeof(p->array[0]);
+ p->sf = p->array;
+ }
+ else /* allocate a larger array */
+ { n = (p->sf != p->array ? p->s_sf : (p->s_sf/4 + 1)*4) + 4;
+ if(!(array = (Sfio_t**)malloc(n*sizeof(Sfio_t*))) )
+ goto done;
+
+ /* move old array to new one */
+ memcpy((Void_t*)array,(Void_t*)p->sf,p->n_sf*sizeof(Sfio_t*));
+ if(p->sf != p->array)
+ free((Void_t*)p->sf);
+
+ p->sf = array;
+ p->s_sf = n;
+ }
+ }
+
+ /* always add at end of array because if this was done during some sort
+ of walk thru all streams, we'll want the new stream to be seen.
+ */
+ p->sf[p->n_sf++] = f;
+ rv = 0;
+
+done:
+ POOLMTXRETURN(p, rv);
+}
+
+/* create an auxiliary buffer for sfgetr/sfreserve/sfputr */
+#if __STD_C
+Sfrsrv_t* _sfrsrv(reg Sfio_t* f, reg ssize_t size)
+#else
+Sfrsrv_t* _sfrsrv(f,size)
+reg Sfio_t* f;
+reg ssize_t size;
+#endif
+{
+ Sfrsrv_t *rsrv, *rs;
+
+ /* make buffer if nothing yet */
+ size = ((size + SF_GRAIN-1)/SF_GRAIN)*SF_GRAIN;
+ if(!(rsrv = f->rsrv) || size > rsrv->size)
+ { if(!(rs = (Sfrsrv_t*)malloc(size+sizeof(Sfrsrv_t))))
+ size = -1;
+ else
+ { if(rsrv)
+ { if(rsrv->slen > 0)
+ memcpy(rs,rsrv,sizeof(Sfrsrv_t)+rsrv->slen);
+ free(rsrv);
+ }
+ f->rsrv = rsrv = rs;
+ rsrv->size = size;
+ rsrv->slen = 0;
+ }
+ }
+
+ if(rsrv && size > 0)
+ rsrv->slen = 0;
+
+ return size >= 0 ? rsrv : NIL(Sfrsrv_t*);
+}
+
+#ifdef SIGPIPE
+#if __STD_C
+static void ignoresig(int sig)
+#else
+static void ignoresig(sig)
+int sig;
+#endif
+{
+ signal(sig, ignoresig);
+}
+#endif
+
+#if __STD_C
+int _sfpopen(reg Sfio_t* f, int fd, int pid, int stdio)
+#else
+int _sfpopen(f, fd, pid, stdio)
+reg Sfio_t* f;
+int fd;
+int pid;
+int stdio; /* stdio popen() does not reset SIGPIPE handler */
+#endif
+{
+ reg Sfproc_t* p;
+
+ if(f->proc)
+ return 0;
+
+ if(!(p = f->proc = (Sfproc_t*)malloc(sizeof(Sfproc_t))) )
+ return -1;
+
+ p->pid = pid;
+ p->size = p->ndata = 0;
+ p->rdata = NIL(uchar*);
+ p->file = fd;
+ p->sigp = (!stdio && pid >= 0 && (f->flags&SF_WRITE)) ? 1 : 0;
+
+#ifdef SIGPIPE /* protect from broken pipe signal */
+ if(p->sigp)
+ { Sfsignal_f handler;
+
+ (void)vtmtxlock(_Sfmutex);
+ if((handler = signal(SIGPIPE, ignoresig)) != SIG_DFL &&
+ handler != ignoresig)
+ signal(SIGPIPE, handler); /* honor user handler */
+ _Sfsigp += 1;
+ (void)vtmtxunlock(_Sfmutex);
+ }
+#endif
+
+ return 0;
+}
+
+#if __STD_C
+int _sfpclose(reg Sfio_t* f)
+#else
+int _sfpclose(f)
+reg Sfio_t* f; /* stream to close */
+#endif
+{
+ Sfproc_t* p;
+ int pid, status;
+
+ if(!(p = f->proc))
+ return -1;
+ f->proc = NIL(Sfproc_t*);
+
+ if(p->rdata)
+ free(p->rdata);
+
+ if(p->pid < 0)
+ status = 0;
+ else
+ { /* close the associated stream */
+ if(p->file >= 0)
+ CLOSE(p->file);
+
+ /* wait for process termination */
+#if _PACKAGE_ast
+ sigcritical(SIG_REG_EXEC|SIG_REG_PROC);
+#endif
+ while ((pid = waitpid(p->pid,&status,0)) == -1 && errno == EINTR)
+ ;
+ if(pid == -1)
+ status = -1;
+#if _PACKAGE_ast
+ sigcritical(0);
+#endif
+
+#ifdef SIGPIPE
+ (void)vtmtxlock(_Sfmutex);
+ if(p->sigp && (_Sfsigp -= 1) <= 0)
+ { Sfsignal_f handler;
+ if((handler = signal(SIGPIPE,SIG_DFL)) != SIG_DFL &&
+ handler != ignoresig)
+ signal(SIGPIPE,handler); /* honor user handler */
+ _Sfsigp = 0;
+ }
+ (void)vtmtxunlock(_Sfmutex);
+#endif
+ }
+
+ free(p);
+ return status;
+}
+
+#if __STD_C
+static int _sfpmode(Sfio_t* f, int type)
+#else
+static int _sfpmode(f,type)
+Sfio_t* f;
+int type;
+#endif
+{
+ Sfproc_t* p;
+
+ if(!(p = f->proc) )
+ return -1;
+
+ if(type == SF_WRITE)
+ { /* save unread data */
+ p->ndata = f->endb-f->next;
+ if(p->ndata > p->size)
+ { if(p->rdata)
+ free((char*)p->rdata);
+ if((p->rdata = (uchar*)malloc(p->ndata)) )
+ p->size = p->ndata;
+ else
+ { p->size = 0;
+ return -1;
+ }
+ }
+ if(p->ndata > 0)
+ memcpy((Void_t*)p->rdata,(Void_t*)f->next,p->ndata);
+ f->endb = f->data;
+ }
+ else
+ { /* restore read data */
+ if(p->ndata > f->size) /* may lose data!!! */
+ p->ndata = f->size;
+ if(p->ndata > 0)
+ { memcpy((Void_t*)f->data,(Void_t*)p->rdata,p->ndata);
+ f->endb = f->data+p->ndata;
+ p->ndata = 0;
+ }
+ }
+
+ /* switch file descriptor */
+ if(p->pid >= 0)
+ { type = f->file;
+ f->file = p->file;
+ p->file = type;
+ }
+
+ return 0;
+}
+
+#if __STD_C
+int _sfmode(reg Sfio_t* f, reg int wanted, reg int local)
+#else
+int _sfmode(f, wanted, local)
+reg Sfio_t* f; /* change r/w mode and sync file pointer for this stream */
+reg int wanted; /* desired mode */
+reg int local; /* a local call */
+#endif
+{
+ reg int n;
+ Sfoff_t addr;
+ reg int rv = 0;
+
+ SFONCE(); /* initialize mutexes */
+
+ if(wanted&SF_SYNCED) /* for (SF_SYNCED|SF_READ) stream, just junk data */
+ { wanted &= ~SF_SYNCED;
+ if((f->mode&(SF_SYNCED|SF_READ)) == (SF_SYNCED|SF_READ) )
+ { f->next = f->endb = f->endr = f->data;
+ f->mode &= ~SF_SYNCED;
+ }
+ }
+
+ if((!local && SFFROZEN(f)) || (!(f->flags&SF_STRING) && f->file < 0))
+ { if(local || !f->disc || !f->disc->exceptf)
+ { local = 1;
+ goto err_notify;
+ }
+
+ for(;;)
+ { if((rv = (*f->disc->exceptf)(f,SF_LOCKED,0,f->disc)) < 0)
+ return rv;
+ if((!local && SFFROZEN(f)) ||
+ (!(f->flags&SF_STRING) && f->file < 0) )
+ { if(rv == 0)
+ { local = 1;
+ goto err_notify;
+ }
+ else continue;
+ }
+ else break;
+ }
+ }
+
+ if(f->mode&SF_GETR)
+ { f->mode &= ~SF_GETR;
+#ifdef MAP_TYPE
+ if((f->bits&SF_MMAP) && (f->tiny[0] += 1) >= (4*SF_NMAP) )
+ { /* turn off mmap to avoid page faulting */
+ sfsetbuf(f,(Void_t*)f->tiny,(size_t)SF_UNBOUND);
+ f->tiny[0] = 0;
+ }
+ else
+#endif
+ if(f->getr)
+ { f->next[-1] = f->getr;
+ f->getr = 0;
+ }
+ }
+
+ if(f->mode&SF_STDIO) /* synchronizing with stdio pointers */
+ (*_Sfstdsync)(f);
+
+ if(f->disc == _Sfudisc && wanted == SF_WRITE &&
+ sfclose((*_Sfstack)(f,NIL(Sfio_t*))) < 0 )
+ { local = 1;
+ goto err_notify;
+ }
+
+ if(f->mode&SF_POOL)
+ { /* move to head of pool */
+ if(f == f->pool->sf[0] || (*_Sfpmove)(f,0) < 0 )
+ { local = 1;
+ goto err_notify;
+ }
+ f->mode &= ~SF_POOL;
+ }
+
+ SFLOCK(f,local);
+
+ /* buffer initialization */
+ wanted &= SF_RDWR;
+ if(f->mode&SF_INIT)
+ {
+ if(!f->pool && _sfsetpool(f) < 0)
+ { rv = -1;
+ goto done;
+ }
+
+ if(wanted == 0)
+ goto done;
+
+ if(wanted != (int)(f->mode&SF_RDWR) && !(f->flags&wanted) )
+ goto err_notify;
+
+ if((f->flags&SF_STRING) && f->size >= 0 && f->data)
+ { f->mode &= ~SF_INIT;
+ f->extent = ((f->flags&SF_READ) || (f->bits&SF_BOTH)) ?
+ f->size : 0;
+ f->here = 0;
+ f->endb = f->data + f->size;
+ f->next = f->endr = f->endw = f->data;
+ if(f->mode&SF_READ)
+ f->endr = f->endb;
+ else f->endw = f->endb;
+ }
+ else
+ { n = f->flags;
+ (void)SFSETBUF(f,f->data,f->size);
+ f->flags |= (n&SF_MALLOC);
+ }
+ }
+
+ if(wanted == (int)SFMODE(f,1))
+ goto done;
+
+ switch(SFMODE(f,1))
+ {
+ case SF_WRITE: /* switching to SF_READ */
+ if(wanted == 0 || wanted == SF_WRITE)
+ break;
+ if(!(f->flags&SF_READ) )
+ goto err_notify;
+ else if(f->flags&SF_STRING)
+ { SFSTRSIZE(f);
+ f->endb = f->data+f->extent;
+ f->mode = SF_READ;
+ break;
+ }
+
+ /* reset buffer */
+ if(f->next > f->data && SFFLSBUF(f,-1) < 0)
+ goto err_notify;
+
+ if(f->size == 0)
+ { /* unbuffered */
+ f->data = f->tiny;
+ f->size = sizeof(f->tiny);
+ }
+ f->next = f->endr = f->endw = f->endb = f->data;
+ f->mode = SF_READ|SF_LOCK;
+
+ /* restore saved read data for coprocess */
+ if(f->proc && _sfpmode(f,wanted) < 0)
+ goto err_notify;
+
+ break;
+
+ case (SF_READ|SF_SYNCED): /* a previously sync-ed read stream */
+ if(wanted != SF_WRITE)
+ { /* just reset the pointers */
+ f->mode = SF_READ|SF_LOCK;
+
+ /* see if must go with new physical location */
+ if((f->flags&(SF_SHARE|SF_PUBLIC)) == (SF_SHARE|SF_PUBLIC) &&
+ (addr = SFSK(f,0,SEEK_CUR,f->disc)) != f->here)
+ {
+#ifdef MAP_TYPE
+ if((f->bits&SF_MMAP) && f->data)
+ { SFMUNMAP(f,f->data,f->endb-f->data);
+ f->data = NIL(uchar*);
+ }
+#endif
+ f->endb = f->endr = f->endw = f->next = f->data;
+ f->here = addr;
+ }
+ else
+ { addr = f->here + (f->endb - f->next);
+ if(SFSK(f,addr,SEEK_SET,f->disc) < 0)
+ goto err_notify;
+ f->here = addr;
+ }
+
+ break;
+ }
+ /* fall thru */
+
+ case SF_READ: /* switching to SF_WRITE */
+ if(wanted != SF_WRITE)
+ break;
+ else if(!(f->flags&SF_WRITE))
+ goto err_notify;
+ else if(f->flags&SF_STRING)
+ { f->endb = f->data+f->size;
+ f->mode = SF_WRITE|SF_LOCK;
+ break;
+ }
+
+ /* save unread data before switching mode */
+ if(f->proc && _sfpmode(f,wanted) < 0)
+ goto err_notify;
+
+ /* reset buffer and seek pointer */
+ if(!(f->mode&SF_SYNCED) )
+ { n = f->endb - f->next;
+ if(f->extent >= 0 && (n > 0 || (f->data && (f->bits&SF_MMAP))) )
+ { /* reset file pointer */
+ addr = f->here - n;
+ if(SFSK(f,addr,SEEK_SET,f->disc) < 0)
+ goto err_notify;
+ f->here = addr;
+ }
+ }
+
+ f->mode = SF_WRITE|SF_LOCK;
+#ifdef MAP_TYPE
+ if(f->bits&SF_MMAP)
+ { if(f->data)
+ SFMUNMAP(f,f->data,f->endb-f->data);
+ (void)SFSETBUF(f,(Void_t*)f->tiny,(size_t)SF_UNBOUND);
+ }
+#endif
+ if(f->data == f->tiny)
+ { f->endb = f->data = f->next = NIL(uchar*);
+ f->size = 0;
+ }
+ else f->endb = (f->next = f->data) + f->size;
+
+ break;
+
+ default: /* unknown case */
+ err_notify:
+ if((wanted &= SF_RDWR) == 0 && (wanted = f->flags&SF_RDWR) == SF_RDWR)
+ wanted = SF_READ;
+
+ /* set errno for operations that access wrong stream type */
+ if(wanted != (f->mode&SF_RDWR) && f->file >= 0)
+ errno = EBADF;
+
+ if(_Sfnotify) /* notify application of the error */
+ (*_Sfnotify)(f, wanted, (void*)((long)f->file));
+
+ rv = -1;
+ break;
+ }
+
+done:
+ SFOPEN(f,local);
+ return rv;
+}
diff --git a/src/lib/libast/sfio/sfmove.c b/src/lib/libast/sfio/sfmove.c
new file mode 100644
index 0000000..9e39657
--- /dev/null
+++ b/src/lib/libast/sfio/sfmove.c
@@ -0,0 +1,242 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Move data from one stream to another.
+** This code is written so that it'll work even in the presence
+** of stacking streams, pool, and discipline.
+** If you must change it, be gentle.
+**
+** Written by Kiem-Phong Vo.
+*/
+#define MAX_SSIZE ((ssize_t)((~((size_t)0)) >> 1))
+
+#if __STD_C
+Sfoff_t sfmove(Sfio_t* fr, Sfio_t* fw, Sfoff_t n, reg int rc)
+#else
+Sfoff_t sfmove(fr,fw,n,rc)
+Sfio_t* fr; /* moving data from this stream */
+Sfio_t* fw; /* moving data to this stream */
+Sfoff_t n; /* number of bytes/records to move. <0 for unbounded move */
+reg int rc; /* record separator */
+#endif
+{
+ reg uchar *cp, *next;
+ reg ssize_t r, w;
+ reg uchar *endb;
+ reg int direct;
+ Sfoff_t n_move, sk, cur;
+ uchar *rbuf = NIL(uchar*);
+ ssize_t rsize = 0;
+ SFMTXDECL(fr); /* declare a shadow stream variable for from stream */
+ SFMTXDECL2(fw); /* declare a shadow stream variable for to stream */
+
+ SFMTXENTER(fr, (Sfoff_t)0);
+ if(fw)
+ SFMTXBEGIN2(fw, (Sfoff_t)0);
+
+ for(n_move = 0; n != 0; )
+ {
+ if(rc >= 0) /* moving records, let sfgetr() deal with record reading */
+ { if(!(cp = (uchar*)sfgetr(fr,rc,0)) )
+ n = 0;
+ else
+ { r = sfvalue(fr);
+ if(fw && (w = SFWRITE(fw, cp, r)) != r)
+ { if(fr->extent >= 0 )
+ (void)SFSEEK(fr,(Sfoff_t)(-r),SEEK_CUR);
+ if(fw->extent >= 0 && w > 0)
+ (void)SFSEEK(fw,(Sfoff_t)(-w),SEEK_CUR);
+ n = 0;
+ }
+ else
+ { n_move += 1;
+ if(n > 0)
+ n -= 1;
+ }
+ }
+ continue;
+ }
+
+ /* get the streams into the right mode */
+ if(fr->mode != SF_READ && _sfmode(fr,SF_READ,0) < 0)
+ break;
+
+ SFLOCK(fr,0);
+
+ /* flush the write buffer as necessary to make room */
+ if(fw)
+ { if(fw->mode != SF_WRITE && _sfmode(fw,SF_WRITE,0) < 0 )
+ break;
+ SFLOCK(fw,0);
+ if(fw->next >= fw->endb ||
+ (fw->next > fw->data && fr->extent < 0 &&
+ (fw->extent < 0 || (fw->flags&SF_SHARE)) ) )
+ if(SFFLSBUF(fw,-1) < 0 )
+ break;
+ }
+ else if((cur = SFSEEK(fr, (Sfoff_t)0, SEEK_CUR)) >= 0 )
+ { sk = n > 0 ? SFSEEK(fr, n, SEEK_CUR) : SFSEEK(fr, 0, SEEK_END);
+ if(sk > cur) /* safe to skip over data in current stream */
+ { n_move += sk - cur;
+ if(n > 0)
+ n -= sk - cur;
+ continue;
+ }
+ /* else: stream unstacking may happen below */
+ }
+
+ /* about to move all, set map to a large amount */
+ if(n < 0 && (fr->bits&SF_MMAP) && !(fr->bits&SF_MVSIZE) )
+ { SFMVSET(fr);
+ fr->bits |= SF_SEQUENTIAL; /* sequentially access data */
+ }
+
+ /* try reading a block of data */
+ direct = 0;
+ if((r = fr->endb - (next = fr->next)) <= 0)
+ { /* amount of data remained to be read */
+ if((w = n > MAX_SSIZE ? MAX_SSIZE : (ssize_t)n) < 0)
+ { if(fr->extent < 0)
+ w = fr->data == fr->tiny ? SF_GRAIN : fr->size;
+ else if((fr->extent-fr->here) > SF_NMAP*SF_PAGE)
+ w = SF_NMAP*SF_PAGE;
+ else w = (ssize_t)(fr->extent-fr->here);
+ }
+
+ /* use a decent buffer for data transfer but make sure
+ that if we overread, the left over can be retrieved
+ */
+ if(!(fr->flags&SF_STRING) && !(fr->bits&SF_MMAP) &&
+ (n < 0 || fr->extent >= 0) )
+ { reg ssize_t maxw = 4*(_Sfpage > 0 ? _Sfpage : SF_PAGE);
+
+ /* direct transfer to a seekable write stream */
+ if(fw && fw->extent >= 0 && w <= (fw->endb-fw->next) )
+ { w = fw->endb - (next = fw->next);
+ direct = SF_WRITE;
+ }
+ else if(w > fr->size && maxw > fr->size)
+ { /* making our own buffer */
+ if(w >= maxw)
+ w = maxw;
+ else w = ((w+fr->size-1)/fr->size)*fr->size;
+ if(rsize <= 0 && (rbuf = (uchar*)malloc(w)) )
+ rsize = w;
+ if(rbuf)
+ { next = rbuf;
+ w = rsize;
+ direct = SF_STRING;
+ }
+ }
+ }
+
+ if(!direct)
+ { /* make sure we don't read too far ahead */
+ if(n > 0 && fr->extent < 0 && (fr->flags&SF_SHARE) )
+ { if((Sfoff_t)(r = fr->size) > n)
+ r = (ssize_t)n;
+ }
+ else r = -1;
+ if((r = SFFILBUF(fr,r)) <= 0)
+ break;
+ next = fr->next;
+ }
+ else
+ { /* actual amount to be read */
+ if(n > 0 && n < w)
+ w = (ssize_t)n;
+
+ if((r = SFRD(fr,next,w,fr->disc)) > 0)
+ fr->next = fr->endb = fr->endr = fr->data;
+ else if(r == 0)
+ break; /* eof */
+ else goto again; /* popped stack */
+ }
+ }
+
+ /* compute the extent of data to be moved */
+ endb = next+r;
+ if(n > 0)
+ { if(r > n)
+ r = (ssize_t)n;
+ n -= r;
+ }
+ n_move += r;
+ cp = next+r;
+
+ if(!direct)
+ fr->next += r;
+ else if((w = endb-cp) > 0)
+ { /* move left-over to read stream */
+ if(w > fr->size)
+ w = fr->size;
+ memcpy((Void_t*)fr->data,(Void_t*)cp,w);
+ fr->endb = fr->data+w;
+ if((w = endb - (cp+w)) > 0)
+ (void)SFSK(fr,(Sfoff_t)(-w),SEEK_CUR,fr->disc);
+ }
+
+ if(fw)
+ { if(direct == SF_WRITE)
+ fw->next += r;
+ else if(r <= (fw->endb-fw->next) )
+ { memcpy((Void_t*)fw->next,(Void_t*)next,r);
+ fw->next += r;
+ }
+ else if((w = SFWRITE(fw,(Void_t*)next,r)) != r)
+ { /* a write error happened */
+ if(w > 0)
+ { r -= w;
+ n_move -= r;
+ }
+ if(fr->extent >= 0)
+ (void)SFSEEK(fr,(Sfoff_t)(-r),SEEK_CUR);
+ break;
+ }
+ }
+
+ again:
+ SFOPEN(fr,0);
+ if(fw)
+ SFOPEN(fw,0);
+ }
+
+ if(n < 0 && (fr->bits&SF_MMAP) && (fr->bits&SF_MVSIZE))
+ { /* back to normal access mode */
+ SFMVUNSET(fr);
+ if((fr->bits&SF_SEQUENTIAL) && (fr->data))
+ SFMMSEQOFF(fr,fr->data,fr->endb-fr->data);
+ fr->bits &= ~SF_SEQUENTIAL;
+ }
+
+ if(rbuf)
+ free(rbuf);
+
+ if(fw)
+ { SFOPEN(fw,0);
+ SFMTXEND2(fw);
+ }
+
+ SFOPEN(fr,0);
+ SFMTXRETURN(fr, n_move);
+}
diff --git a/src/lib/libast/sfio/sfmutex.c b/src/lib/libast/sfio/sfmutex.c
new file mode 100644
index 0000000..cc3a4b7
--- /dev/null
+++ b/src/lib/libast/sfio/sfmutex.c
@@ -0,0 +1,69 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Obtain/release exclusive use of a stream.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+/* the main locking/unlocking interface */
+#if __STD_C
+int sfmutex(Sfio_t* f, int type)
+#else
+int sfmutex(f, type)
+Sfio_t* f;
+int type;
+#endif
+{
+#if !vt_threaded
+ NOTUSED(f); NOTUSED(type);
+ return 0;
+#else
+
+ SFONCE();
+
+ if(!f)
+ return -1;
+
+ if(!f->mutex)
+ { if(f->bits&SF_PRIVATE)
+ return 0;
+
+ vtmtxlock(_Sfmutex);
+ f->mutex = vtmtxopen(NIL(Vtmutex_t*), VT_INIT);
+ vtmtxunlock(_Sfmutex);
+ if(!f->mutex)
+ return -1;
+ }
+
+ if(type == SFMTX_LOCK)
+ return vtmtxlock(f->mutex);
+ else if(type == SFMTX_TRYLOCK)
+ return vtmtxtrylock(f->mutex);
+ else if(type == SFMTX_UNLOCK)
+ return vtmtxunlock(f->mutex);
+ else if(type == SFMTX_CLRLOCK)
+ return vtmtxclrlock(f->mutex);
+ else return -1;
+#endif /*vt_threaded*/
+}
diff --git a/src/lib/libast/sfio/sfnew.c b/src/lib/libast/sfio/sfnew.c
new file mode 100644
index 0000000..a6feddc
--- /dev/null
+++ b/src/lib/libast/sfio/sfnew.c
@@ -0,0 +1,129 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Fundamental function to create a new stream.
+** The argument flags defines the type of stream and the scheme
+** of buffering.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+Sfio_t* sfnew(Sfio_t* oldf, Void_t* buf, size_t size, int file, int flags)
+#else
+Sfio_t* sfnew(oldf,buf,size,file,flags)
+Sfio_t* oldf; /* old stream to be reused */
+Void_t* buf; /* a buffer to read/write, if NULL, will be allocated */
+size_t size; /* buffer size if buf is given or desired buffer size */
+int file; /* file descriptor to read/write from */
+int flags; /* type of file stream */
+#endif
+{
+ reg Sfio_t* f;
+ reg int sflags;
+
+ SFONCE(); /* initialize mutexes */
+
+ if(!(flags&SF_RDWR))
+ return NIL(Sfio_t*);
+
+ sflags = 0;
+ if((f = oldf) )
+ { if(flags&SF_EOF)
+ { if(f != sfstdin && f != sfstdout && f != sfstderr)
+ f->mutex = NIL(Vtmutex_t*);
+ SFCLEAR(f, f->mutex);
+ oldf = NIL(Sfio_t*);
+ }
+ else if(f->mode&SF_AVAIL)
+ { /* only allow SF_STATIC to be already closed */
+ if(!(f->flags&SF_STATIC) )
+ return NIL(Sfio_t*);
+ sflags = f->flags;
+ oldf = NIL(Sfio_t*);
+ }
+ else
+ { /* reopening an open stream, close it first */
+ sflags = f->flags;
+
+ if(((f->mode&SF_RDWR) != f->mode && _sfmode(f,0,0) < 0) ||
+ SFCLOSE(f) < 0 )
+ return NIL(Sfio_t*);
+
+ if(f->data && ((flags&SF_STRING) || size != (size_t)SF_UNBOUND) )
+ { if(sflags&SF_MALLOC)
+ free((Void_t*)f->data);
+ f->data = NIL(uchar*);
+ }
+ if(!f->data)
+ sflags &= ~SF_MALLOC;
+ }
+ }
+
+ if(!f)
+ { /* reuse a standard stream structure if possible */
+ if(!(flags&SF_STRING) && file >= 0 && file <= 2)
+ { f = file == 0 ? sfstdin : file == 1 ? sfstdout : sfstderr;
+ if(f)
+ { if(f->mode&SF_AVAIL)
+ { sflags = f->flags;
+ SFCLEAR(f, f->mutex);
+ }
+ else f = NIL(Sfio_t*);
+ }
+ }
+
+ if(!f)
+ { if(!(f = (Sfio_t*)malloc(sizeof(Sfio_t))) )
+ return NIL(Sfio_t*);
+ SFCLEAR(f, NIL(Vtmutex_t*));
+ }
+ }
+
+ /* create a mutex */
+ if(!f->mutex)
+ f->mutex = vtmtxopen(NIL(Vtmutex_t*), VT_INIT);
+
+ /* stream type */
+ f->mode = (flags&SF_READ) ? SF_READ : SF_WRITE;
+ f->flags = (flags&SF_FLAGS) | (sflags&(SF_MALLOC|SF_STATIC));
+ f->bits = (flags&SF_RDWR) == SF_RDWR ? SF_BOTH : 0;
+ f->file = file;
+ f->here = f->extent = 0;
+ f->getr = f->tiny[0] = 0;
+
+ f->mode |= SF_INIT;
+ if(size != (size_t)SF_UNBOUND)
+ { f->size = size;
+ f->data = size <= 0 ? NIL(uchar*) : (uchar*)buf;
+ }
+ f->endb = f->endr = f->endw = f->next = f->data;
+
+ if(_Sfnotify)
+ (*_Sfnotify)(f, SF_NEW, (void*)((long)f->file));
+
+ if(f->flags&SF_STRING)
+ (void)_sfmode(f,f->mode&SF_RDWR,0);
+
+ return f;
+}
diff --git a/src/lib/libast/sfio/sfnotify.c b/src/lib/libast/sfio/sfnotify.c
new file mode 100644
index 0000000..06cc857
--- /dev/null
+++ b/src/lib/libast/sfio/sfnotify.c
@@ -0,0 +1,38 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+
+/* Set the function to be called when a stream is opened or closed
+**
+** Written by Kiem-Phong Vo.
+*/
+#if __STD_C
+int sfnotify(void(*notify)(Sfio_t*, int, void*))
+#else
+int sfnotify(notify)
+void (*notify)();
+#endif
+{
+ _Sfnotify = notify;
+ return 0;
+}
diff --git a/src/lib/libast/sfio/sfnputc.c b/src/lib/libast/sfio/sfnputc.c
new file mode 100644
index 0000000..58a1430
--- /dev/null
+++ b/src/lib/libast/sfio/sfnputc.c
@@ -0,0 +1,81 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Write out a character n times
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+ssize_t sfnputc(Sfio_t* f, int c, size_t n)
+#else
+ssize_t sfnputc(f,c,n)
+Sfio_t* f; /* file to write */
+int c; /* char to be written */
+size_t n; /* number of time to repeat */
+#endif
+{
+ reg uchar* ps;
+ reg ssize_t p, w;
+ uchar buf[128];
+ reg int local;
+ SFMTXDECL(f); /* declare a local stream variable for multithreading */
+
+ SFMTXENTER(f,-1);
+
+ GETLOCAL(f,local);
+ if(SFMODE(f,local) != SF_WRITE && _sfmode(f,SF_WRITE,local) < 0)
+ SFMTXRETURN(f, -1);
+
+ SFLOCK(f,local);
+
+ /* write into a suitable buffer */
+ if((size_t)(p = (f->endb-(ps = f->next))) < n)
+ { ps = buf; p = sizeof(buf); }
+ if((size_t)p > n)
+ p = n;
+ MEMSET(ps,c,p);
+ ps -= p;
+
+ w = n;
+ if(ps == f->next)
+ { /* simple sfwrite */
+ f->next += p;
+ if(c == '\n')
+ (void)SFFLSBUF(f,-1);
+ goto done;
+ }
+
+ for(;;)
+ { /* hard write of data */
+ if((p = SFWRITE(f,(Void_t*)ps,p)) <= 0 || (n -= p) <= 0)
+ { w -= n;
+ goto done;
+ }
+ if((size_t)p > n)
+ p = n;
+ }
+done :
+ SFOPEN(f,local);
+ SFMTXRETURN(f, w);
+}
diff --git a/src/lib/libast/sfio/sfopen.c b/src/lib/libast/sfio/sfopen.c
new file mode 100644
index 0000000..522bd9e
--- /dev/null
+++ b/src/lib/libast/sfio/sfopen.c
@@ -0,0 +1,40 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/*
+ * _sfopen() wrapper to allow user sfopen() intercept
+ */
+
+extern Sfio_t* _sfopen _ARG_((Sfio_t*, const char*, const char*));
+
+#if __STD_C
+Sfio_t* sfopen(Sfio_t* f, const char* file, const char* mode)
+#else
+Sfio_t* sfopen(f,file,mode)
+Sfio_t* f; /* old stream structure */
+char* file; /* file/string to be opened */
+reg char* mode; /* mode of the stream */
+#endif
+{
+ return _sfopen(f, file, mode);
+}
diff --git a/src/lib/libast/sfio/sfpeek.c b/src/lib/libast/sfio/sfpeek.c
new file mode 100644
index 0000000..22cf807
--- /dev/null
+++ b/src/lib/libast/sfio/sfpeek.c
@@ -0,0 +1,89 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Safe access to the internal stream buffer.
+** This function is obsolete. sfreserve() should be used.
+**
+** Written by Kiem-Phong Vo (06/27/90).
+*/
+
+#if _BLD_sfio && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#if __STD_C
+extern ssize_t sfpeek(reg Sfio_t* f, Void_t** bp, reg size_t size)
+#else
+extern ssize_t sfpeek(f,bp,size)
+reg Sfio_t* f; /* file to peek */
+Void_t** bp; /* start of data area */
+reg size_t size; /* size of peek */
+#endif
+{ reg ssize_t n, sz;
+ reg int mode;
+
+ /* query for the extent of the remainder of the buffer */
+ if((sz = size) == 0 || !bp)
+ { if(f->mode&SF_INIT)
+ (void)_sfmode(f,0,0);
+
+ if((f->flags&SF_RDWRSTR) == SF_RDWRSTR)
+ { SFSTRSIZE(f);
+ n = (f->data+f->here) - f->next;
+ }
+ else n = f->endb - f->next;
+
+ if(!bp)
+ return n;
+ else if(n > 0) /* size == 0 */
+ { *bp = (Void_t*)f->next;
+ return 0;
+ }
+ /* else fall down and fill buffer */
+ }
+
+ if(!(mode = f->flags&SF_READ) )
+ mode = SF_WRITE;
+ if((int)f->mode != mode && _sfmode(f,mode,0) < 0)
+ return -1;
+
+ *bp = sfreserve(f, sz <= 0 ? 0 : sz > f->size ? f->size : sz, 0);
+
+ if(*bp && sz >= 0)
+ return sz;
+
+ if((n = sfvalue(f)) > 0)
+ { *bp = (Void_t*)f->next;
+ if(sz < 0)
+ { f->mode |= SF_PEEK;
+ f->endr = f->endw = f->data;
+ }
+ else
+ { if(sz > n)
+ sz = n;
+ f->next += sz;
+ }
+ }
+
+ return (sz >= 0 && n >= sz) ? sz : n;
+}
diff --git a/src/lib/libast/sfio/sfpkrd.c b/src/lib/libast/sfio/sfpkrd.c
new file mode 100644
index 0000000..2572e6d
--- /dev/null
+++ b/src/lib/libast/sfio/sfpkrd.c
@@ -0,0 +1,325 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+#if !_PACKAGE_ast
+#ifndef FIONREAD
+#if _sys_ioctl
+#include <sys/ioctl.h>
+#endif
+#endif
+#endif
+
+/* Read/Peek a record from an unseekable device
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#define STREAM_PEEK 001
+#define SOCKET_PEEK 002
+
+#if __STD_C
+ssize_t sfpkrd(int fd, Void_t* argbuf, size_t n, int rc, long tm, int action)
+#else
+ssize_t sfpkrd(fd, argbuf, n, rc, tm, action)
+int fd; /* file descriptor */
+Void_t* argbuf; /* buffer to read data */
+size_t n; /* buffer size */
+int rc; /* record character */
+long tm; /* time-out */
+int action; /* >0: peeking, if rc>=0, get action records,
+ <0: no peeking, if rc>=0, get -action records,
+ =0: no peeking, if rc>=0, must get a single record
+ */
+#endif
+{
+ reg ssize_t r;
+ reg int ntry, t;
+ reg char *buf = (char*)argbuf, *endbuf;
+
+ if(rc < 0 && tm < 0 && action <= 0)
+ return sysreadf(fd,buf,n);
+
+ t = (action > 0 || rc >= 0) ? (STREAM_PEEK|SOCKET_PEEK) : 0;
+#if !_stream_peek
+ t &= ~STREAM_PEEK;
+#endif
+#if !_socket_peek
+ t &= ~SOCKET_PEEK;
+#endif
+
+ for(ntry = 0; ntry < 2; ++ntry)
+ {
+ r = -1;
+#if _stream_peek
+ if((t&STREAM_PEEK) && (ntry == 1 || tm < 0) )
+ {
+#ifdef __sun
+ /*
+ * I_PEEK on stdin can hang rsh+ksh on solaris
+ * this kludge will have to do until sun^H^H^Horacle fixes I_PEEK/rsh
+ */
+ static int stream_peek;
+ if (stream_peek == 0) /* this will be done just once */
+ { char *e;
+ stream_peek = (
+ getenv("LOGNAME") == 0 &&
+ getenv("MAIL") == 0 &&
+ ((e = getenv("LANG")) == 0 || strcmp(e, "C") == 0) &&
+ ((e = getenv("PATH")) == 0 || strncmp(e, "/usr/bin:", 9) == 0)
+ ) ? -1 : 1;
+ }
+ if(stream_peek < 0)
+ t &= ~STREAM_PEEK;
+ else
+#endif
+ { struct strpeek pbuf;
+ pbuf.flags = 0;
+ pbuf.ctlbuf.maxlen = -1;
+ pbuf.ctlbuf.len = 0;
+ pbuf.ctlbuf.buf = NIL(char*);
+ pbuf.databuf.maxlen = n;
+ pbuf.databuf.buf = buf;
+ pbuf.databuf.len = 0;
+
+ if((r = ioctl(fd,I_PEEK,&pbuf)) < 0)
+ { if(errno == EINTR)
+ return -1;
+ t &= ~STREAM_PEEK;
+ }
+ else
+ { t &= ~SOCKET_PEEK;
+ if(r > 0 && (r = pbuf.databuf.len) <= 0)
+ { if(action <= 0) /* read past eof */
+ r = sysreadf(fd,buf,1);
+ return r;
+ }
+ if(r == 0)
+ r = -1;
+ else if(r > 0)
+ break;
+ }
+ }
+ }
+#endif /* stream_peek */
+
+ if(ntry == 1)
+ break;
+
+ /* poll or select to see if data is present. */
+ while(tm >= 0 || action > 0 ||
+ /* block until there is data before peeking again */
+ ((t&STREAM_PEEK) && rc >= 0) ||
+ /* let select be interrupted instead of recv which autoresumes */
+ (t&SOCKET_PEEK) )
+ { r = -2;
+#if _lib_poll
+ if(r == -2)
+ {
+ struct pollfd po;
+ po.fd = fd;
+ po.events = POLLIN;
+ po.revents = 0;
+
+ if((r = SFPOLL(&po,1,tm)) < 0)
+ { if(errno == EINTR)
+ return -1;
+ else if(errno == EAGAIN)
+ { errno = 0;
+ continue;
+ }
+ else r = -2;
+ }
+ else r = (po.revents&POLLIN) ? 1 : -1;
+ }
+#endif /*_lib_poll*/
+#if _lib_select
+ if(r == -2)
+ {
+#if _hpux_threads && vt_threaded
+#define fd_set int
+#endif
+ fd_set rd;
+ struct timeval tmb, *tmp;
+ FD_ZERO(&rd);
+ FD_SET(fd,&rd);
+ if(tm < 0)
+ tmp = NIL(struct timeval*);
+ else
+ { tmp = &tmb;
+ tmb.tv_sec = tm/SECOND;
+ tmb.tv_usec = (tm%SECOND)*SECOND;
+ }
+ r = select(fd+1,&rd,NIL(fd_set*),NIL(fd_set*),tmp);
+ if(r < 0)
+ { if(errno == EINTR)
+ return -1;
+ else if(errno == EAGAIN)
+ { errno = 0;
+ continue;
+ }
+ else r = -2;
+ }
+ else r = FD_ISSET(fd,&rd) ? 1 : -1;
+ }
+#endif /*_lib_select*/
+ if(r == -2)
+ {
+#if !_lib_poll && !_lib_select /* both poll and select can't be used */
+#ifdef FIONREAD /* quick and dirty check for availability */
+ long nsec = tm < 0 ? 0 : (tm+999)/1000;
+ while(nsec > 0 && r < 0)
+ { long avail = -1;
+ if((r = ioctl(fd,FIONREAD,&avail)) < 0)
+ { if(errno == EINTR)
+ return -1;
+ else if(errno == EAGAIN)
+ { errno = 0;
+ continue;
+ }
+ else /* ioctl failed completely */
+ { r = -2;
+ break;
+ }
+ }
+ else r = avail <= 0 ? -1 : (ssize_t)avail;
+
+ if(r < 0 && nsec-- > 0)
+ sleep(1);
+ }
+#endif
+#endif
+ }
+
+ if(r > 0) /* there is data now */
+ { if(action <= 0 && rc < 0)
+ return sysreadf(fd,buf,n);
+ else r = -1;
+ }
+ else if(tm >= 0) /* timeout exceeded */
+ return -1;
+ else r = -1;
+ break;
+ }
+
+#if _socket_peek
+ if(t&SOCKET_PEEK)
+ {
+#if __MACH__ && __APPLE__ /* check 10.4 recv(MSG_PEEK) bug that consumes pipe data */
+ static int recv_peek_pipe;
+ if (recv_peek_pipe == 0) /* this will be done just once */
+ { int fds[2], r;
+ char tst[2];
+
+ tst[0] = 'a'; tst[1] = 'z';
+
+ /* open a pipe and write to it */
+ recv_peek_pipe = 1;
+ if(recv_peek_pipe == 1 && pipe(fds) < 0)
+ recv_peek_pipe = -1;
+ if(recv_peek_pipe == 1 && write(fds[1], tst, 2) != 2)
+ recv_peek_pipe = -1;
+
+ /* try recv() to see if it gets anything */
+ tst[0] = tst[1] = 0;
+ if(recv_peek_pipe == 1 && (r = recv(fds[0], tst, 1, MSG_PEEK)) != 1)
+ recv_peek_pipe = -1;
+ if(recv_peek_pipe == 1 && tst[0] != 'a')
+ recv_peek_pipe = -1;
+
+ /* make sure that recv() did not consume data */
+ tst[0] = tst[1] = 0;
+ if(recv_peek_pipe == 1 && (r = recv(fds[0], tst, 2, MSG_PEEK)) != 2)
+ recv_peek_pipe = -1;
+ if(recv_peek_pipe == 1 && (tst[0] != 'a' || tst[1] != 'z') )
+ recv_peek_pipe = -1;
+
+ close(fds[0]);
+ close(fds[1]);
+ }
+
+ if(recv_peek_pipe < 0)
+ { struct stat st; /* recv should work on sockets */
+ if(fstat(fd, &st) < 0 || !S_ISSOCK(st.st_mode) )
+ { r = -1;
+ t &= ~SOCKET_PEEK;
+ }
+ }
+#endif
+ while((t&SOCKET_PEEK) && (r = recv(fd,(char*)buf,n,MSG_PEEK)) < 0)
+ { if(errno == EINTR)
+ return -1;
+ else if(errno == EAGAIN)
+ errno = 0;
+ else t &= ~SOCKET_PEEK;
+ }
+ if(r >= 0)
+ { t &= ~STREAM_PEEK;
+ if(r > 0)
+ break;
+ else /* read past eof */
+ { if(action <= 0)
+ r = sysreadf(fd,buf,1);
+ return r;
+ }
+ }
+ }
+#endif
+ }
+
+ if(r < 0)
+ { if(tm >= 0 || action > 0)
+ return -1;
+ else /* get here means: tm < 0 && action <= 0 && rc >= 0 */
+ { /* number of records read at a time */
+ if((action = action ? -action : 1) > (int)n)
+ action = n;
+ r = 0;
+ while((t = sysreadf(fd,buf,action)) > 0)
+ { r += t;
+ for(endbuf = buf+t; buf < endbuf;)
+ if(*buf++ == rc)
+ action -= 1;
+ if(action == 0 || (int)(n-r) < action)
+ break;
+ }
+ return r == 0 ? t : r;
+ }
+ }
+
+ /* successful peek, find the record end */
+ if(rc >= 0)
+ { reg char* sp;
+
+ t = action == 0 ? 1 : action < 0 ? -action : action;
+ for(endbuf = (sp = buf)+r; sp < endbuf; )
+ if(*sp++ == rc)
+ if((t -= 1) == 0)
+ break;
+ r = sp - buf;
+ }
+
+ /* advance */
+ if(action <= 0)
+ r = sysreadf(fd,buf,r);
+
+ return r;
+}
diff --git a/src/lib/libast/sfio/sfpoll.c b/src/lib/libast/sfio/sfpoll.c
new file mode 100644
index 0000000..09110aa
--- /dev/null
+++ b/src/lib/libast/sfio/sfpoll.c
@@ -0,0 +1,250 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Poll a set of streams to see if any is available for I/O.
+** Ready streams are moved to front of array but retain the
+** same relative order.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+int sfpoll(Sfio_t** fa, reg int n, int tm)
+#else
+int sfpoll(fa, n, tm)
+Sfio_t** fa; /* array of streams to poll */
+reg int n; /* number of streams in array */
+int tm; /* time in millisecs for select/poll */
+#endif
+{
+ reg int r, c, m, np, eintr;
+ reg Sfio_t* f;
+ reg int *status, *check;
+
+ if(n <= 0 || !fa)
+ return -1;
+
+ if(!(status = (int*)malloc(2*n*sizeof(int))) )
+ return -1;
+ check = status+n; /* streams that need polling */
+
+ /* a SF_READ stream is ready if there is buffered read data */
+#define RDREADY(f) (((f->mode&SF_READ) && f->next < f->endb) || \
+ ((f->mode&SF_WRITE) && f->proc && f->proc->ndata > 0) )
+
+ /* a SF_WRITE stream is ready if there is no write data */
+#define WRREADY(f) (!(f->mode&SF_WRITE) || f->next == f->data)
+
+#define HASAUXFD(f) (f->proc && f->proc->file >= 0 && f->proc->file != f->file)
+
+ for(r = c = eintr = 0; r < n; ++r) /* compute streams that must be checked */
+ { f = fa[r];
+ status[r] = 0;
+
+ /* terminate poll on interrupt? */
+ if(f->flags&SF_IOINTR)
+ eintr++;
+ /* check accessibility */
+ m = f->mode&SF_RDWR;
+ if((int)f->mode != m && _sfmode(f,m,0) < 0)
+ continue;
+
+ if((f->flags&SF_READ) && RDREADY(f))
+ status[r] |= SF_READ;
+
+ if((f->flags&SF_WRITE) && WRREADY(f))
+ status[r] |= SF_WRITE;
+
+ if((f->flags&SF_RDWR) == status[r])
+ continue;
+
+ /* has discipline, ask its opinion */
+ if(f->disc && f->disc->exceptf)
+ { if((m = (*f->disc->exceptf)(f,SF_DPOLL,&tm,f->disc)) < 0)
+ continue;
+ else if(m > 0)
+ { status[r] = m&SF_RDWR;
+ continue;
+ }
+ }
+
+ if(f->extent < 0) /* unseekable stream, must poll/select */
+ check[c++] = r;
+ else /* seekable streams are always ready */
+ { if(f->flags&SF_READ)
+ status[r] |= SF_READ;
+ if(f->flags&SF_WRITE)
+ status[r] |= SF_WRITE;
+ }
+ }
+ /* terminate poll on interrupt only if all streams marked SF_IOINTR */
+ eintr = eintr == n ? -1 : EINTR;
+
+ np = -1;
+#if _lib_poll
+ if(c > 0)
+ { struct pollfd* fds;
+
+ /* construct the poll array */
+ for(m = 0, r = 0; r < c; ++r, ++m)
+ { f = fa[check[r]];
+ if(HASAUXFD(f))
+ m += 1;
+ }
+ if(!(fds = (struct pollfd*)malloc(m*sizeof(struct pollfd))) )
+ return -1;
+
+ for(m = 0, r = 0; r < c; ++r, ++m)
+ { f = fa[check[r]];
+
+ fds[m].fd = f->file;
+ fds[m].events = fds[m].revents = 0;
+
+ if((f->flags&SF_WRITE) && !WRREADY(f) )
+ fds[m].events |= POLLOUT;
+
+ if((f->flags&SF_READ) && !RDREADY(f) )
+ { /* a sfpopen situation with two file descriptors */
+ if((f->mode&SF_WRITE) && HASAUXFD(f))
+ { m += 1;
+ fds[m].fd = f->proc->file;
+ fds[m].revents = 0;
+ }
+
+ fds[m].events |= POLLIN;
+ }
+ }
+
+ while((np = SFPOLL(fds,m,tm)) < 0 )
+ { if(errno == eintr || errno == EAGAIN)
+ errno = 0;
+ else break;
+ }
+ if(np > 0) /* poll succeeded */
+ np = c;
+
+ for(m = 0, r = 0; r < np; ++r, ++m)
+ { f = fa[check[r]];
+
+ if((f->flags&SF_WRITE) && !WRREADY(f) )
+ { if(fds[m].revents&POLLOUT)
+ status[check[r]] |= SF_WRITE;
+ }
+
+ if((f->flags&SF_READ) && !RDREADY(f))
+ { if((f->mode&SF_WRITE) && HASAUXFD(f))
+ m += 1;
+ if(fds[m].revents&POLLIN)
+ status[check[r]] |= SF_READ;
+ }
+ }
+
+ free((Void_t*)fds);
+ }
+#endif /*_lib_poll*/
+
+#if _lib_select
+ if(np < 0 && c > 0)
+ { fd_set rd, wr;
+ struct timeval tmb, *tmp;
+
+ FD_ZERO(&rd);
+ FD_ZERO(&wr);
+ m = 0;
+ for(r = 0; r < c; ++r)
+ { f = fa[check[r]];
+
+ if(f->file > m)
+ m = f->file;
+
+ if((f->flags&SF_WRITE) && !WRREADY(f))
+ FD_SET(f->file,&wr);
+
+ if((f->flags&SF_READ) && !RDREADY(f))
+ { if((f->mode&SF_WRITE) && HASAUXFD(f))
+ { if(f->proc->file > m)
+ m = f->proc->file;
+ FD_SET(f->proc->file, &rd);
+ }
+ else FD_SET(f->file,&rd);
+ }
+ }
+ if(tm < 0)
+ tmp = NIL(struct timeval*);
+ else
+ { tmp = &tmb;
+ tmb.tv_sec = tm/SECOND;
+ tmb.tv_usec = (tm%SECOND)*SECOND;
+ }
+
+ while((np = select(m+1,&rd,&wr,NIL(fd_set*),tmp)) < 0 )
+ { if(errno == eintr)
+ errno = 0;
+ else break;
+ }
+ if(np > 0)
+ np = c;
+
+ for(r = 0; r < np; ++r)
+ { f = fa[check[r]];
+
+ if((f->flags&SF_WRITE) && !WRREADY(f) )
+ { if(FD_ISSET(f->file,&wr) )
+ status[check[r]] |= SF_WRITE;
+ }
+
+ if((f->flags&SF_READ) && !RDREADY(f) )
+ { if((f->mode&SF_WRITE) && HASAUXFD(f) )
+ { if(FD_ISSET(f->proc->file, &rd) )
+ status[check[r]] |= SF_READ;
+ }
+ else
+ { if(FD_ISSET(f->file,&rd) )
+ status[check[r]] |= SF_READ;
+ }
+ }
+ }
+ }
+#endif /*_lib_select*/
+
+ for(r = c = 0; c < n; ++c)
+ { if(status[c] == 0)
+ continue;
+
+ f = fa[c];
+ f->val = (ssize_t)status[c];
+
+ /* announce status */
+ if(f->disc && f->disc->exceptf)
+ (*f->disc->exceptf)(f,SF_READY,(Void_t*)(long)status[c],f->disc);
+
+ if(c > r) /* move to front of list */
+ { fa[c] = fa[r];
+ fa[r] = f;
+ }
+ r += 1;
+ }
+
+ free((Void_t*)status);
+ return r ? r : np < 0 ? -1 : 0;
+}
diff --git a/src/lib/libast/sfio/sfpool.c b/src/lib/libast/sfio/sfpool.c
new file mode 100644
index 0000000..dbfc045
--- /dev/null
+++ b/src/lib/libast/sfio/sfpool.c
@@ -0,0 +1,369 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Management of pools of streams.
+** If pf is not nil, f is pooled with pf and f becomes current;
+** otherwise, f is isolated from its pool. flag can be one of
+** 0 or SF_SHARE.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+/* Note that we do not free the space for a pool once it is allocated.
+** This is to prevent memory faults in calls such as sfsync(NULL) that walk the pool
+** link list and during such walks may free up streams&pools. Free pools will be
+** reused in newpool().
+*/
+#if __STD_C
+static int delpool(reg Sfpool_t* p)
+#else
+static int delpool(p)
+reg Sfpool_t* p;
+#endif
+{
+ POOLMTXENTER(p);
+
+ if(p->s_sf && p->sf != p->array)
+ free((Void_t*)p->sf);
+ p->mode = SF_AVAIL;
+
+ POOLMTXRETURN(p,0);
+}
+
+#if __STD_C
+static Sfpool_t* newpool(reg int mode)
+#else
+static Sfpool_t* newpool(mode)
+reg int mode;
+#endif
+{
+ reg Sfpool_t *p, *last = &_Sfpool;
+
+ /* look to see if there is a free pool */
+ for(last = &_Sfpool, p = last->next; p; last = p, p = p->next)
+ { if(p->mode == SF_AVAIL )
+ { p->mode = 0;
+ break;
+ }
+ }
+
+ if(!p)
+ { POOLMTXLOCK(last);
+
+ if(!(p = (Sfpool_t*) malloc(sizeof(Sfpool_t))) )
+ { POOLMTXUNLOCK(last);
+ return NIL(Sfpool_t*);
+ }
+
+ (void)vtmtxopen(&p->mutex, VT_INIT); /* initialize mutex */
+
+ p->mode = 0;
+ p->n_sf = 0;
+ p->next = NIL(Sfpool_t*);
+ last->next = p;
+
+ POOLMTXUNLOCK(last);
+ }
+
+ POOLMTXENTER(p);
+
+ p->mode = mode&SF_SHARE;
+ p->s_sf = sizeof(p->array)/sizeof(p->array[0]);
+ p->sf = p->array;
+
+ POOLMTXRETURN(p,p);
+}
+
+/* move a stream to head */
+#if __STD_C
+static int _sfphead(Sfpool_t* p, Sfio_t* f, int n)
+#else
+static int _sfphead(p, f, n)
+Sfpool_t* p; /* the pool */
+Sfio_t* f; /* the stream */
+int n; /* current position in pool */
+#endif
+{
+ reg Sfio_t* head;
+ reg ssize_t k, w, v;
+ reg int rv;
+
+ POOLMTXENTER(p);
+
+ if(n == 0)
+ POOLMTXRETURN(p,0);
+
+ head = p->sf[0];
+ if(SFFROZEN(head) )
+ POOLMTXRETURN(p,-1);
+
+ SFLOCK(head,0);
+ rv = -1;
+
+ if(!(p->mode&SF_SHARE) || (head->mode&SF_READ) || (f->mode&SF_READ) )
+ { if(SFSYNC(head) < 0)
+ goto done;
+ }
+ else /* shared pool of write-streams, data can be moved among streams */
+ { if(SFMODE(head,1) != SF_WRITE && _sfmode(head,SF_WRITE,1) < 0)
+ goto done;
+ /**/ASSERT(f->next == f->data);
+
+ v = head->next - head->data; /* pending data */
+ if((k = v - (f->endb-f->data)) <= 0)
+ k = 0;
+ else /* try to write out amount exceeding f's capacity */
+ { if((w = SFWR(head,head->data,k,head->disc)) == k)
+ v -= k;
+ else /* write failed, recover buffer then quit */
+ { if(w > 0)
+ { v -= w;
+ memcpy(head->data,(head->data+w),v);
+ }
+ head->next = head->data+v;
+ goto done;
+ }
+ }
+
+ /* move data from head to f */
+ if((head->data+k) != f->data )
+ memcpy(f->data,(head->data+k),v);
+ f->next = f->data+v;
+ }
+
+ f->mode &= ~SF_POOL;
+ head->mode |= SF_POOL;
+ head->next = head->endr = head->endw = head->data; /* clear write buffer */
+
+ p->sf[n] = head;
+ p->sf[0] = f;
+ rv = 0;
+
+done:
+ head->mode &= ~SF_LOCK; /* partially unlock because it's no longer head */
+
+ POOLMTXRETURN(p,rv);
+}
+
+/* delete a stream from its pool */
+#if __STD_C
+static int _sfpdelete(Sfpool_t* p, Sfio_t* f, int n)
+#else
+static int _sfpdelete(p, f, n)
+Sfpool_t* p; /* the pool */
+Sfio_t* f; /* the stream */
+int n; /* position in pool */
+#endif
+{
+ POOLMTXENTER(p);
+
+ p->n_sf -= 1;
+ for(; n < p->n_sf; ++n)
+ p->sf[n] = p->sf[n+1];
+
+ f->pool = NIL(Sfpool_t*);
+ f->mode &= ~SF_POOL;
+
+ if(p->n_sf == 0 || p == &_Sfpool)
+ { if(p != &_Sfpool)
+ delpool(p);
+ goto done;
+ }
+
+ /* !_Sfpool, make sure head stream is an open stream */
+ for(n = 0; n < p->n_sf; ++n)
+ if(!SFFROZEN(p->sf[n]))
+ break;
+ if(n < p->n_sf && n > 0)
+ { f = p->sf[n];
+ p->sf[n] = p->sf[0];
+ p->sf[0] = f;
+ }
+
+ /* head stream has SF_POOL off */
+ f = p->sf[0];
+ f->mode &= ~SF_POOL;
+ if(!SFFROZEN(f))
+ _SFOPEN(f);
+
+ /* if only one stream left, delete pool */
+ if(p->n_sf == 1 )
+ { _sfpdelete(p,f,0);
+ _sfsetpool(f);
+ }
+
+done:
+ POOLMTXRETURN(p,0);
+}
+
+#if __STD_C
+static int _sfpmove(reg Sfio_t* f, reg int type)
+#else
+static int _sfpmove(f,type)
+reg Sfio_t* f;
+reg int type; /* <0 : deleting, 0: move-to-front, >0: inserting */
+#endif
+{
+ reg Sfpool_t* p;
+ reg int n;
+
+ if(type > 0)
+ return _sfsetpool(f);
+ else
+ { if(!(p = f->pool) )
+ return -1;
+ for(n = p->n_sf-1; n >= 0; --n)
+ if(p->sf[n] == f)
+ break;
+ if(n < 0)
+ return -1;
+
+ return type == 0 ? _sfphead(p,f,n) : _sfpdelete(p,f,n);
+ }
+}
+
+#if __STD_C
+Sfio_t* sfpool(reg Sfio_t* f, reg Sfio_t* pf, reg int mode)
+#else
+Sfio_t* sfpool(f,pf,mode)
+reg Sfio_t* f;
+reg Sfio_t* pf;
+reg int mode;
+#endif
+{
+ int k;
+ Sfpool_t* p;
+ Sfio_t* rv;
+
+ _Sfpmove = _sfpmove;
+
+ if(!f) /* return head of pool of pf regardless of lock states */
+ { if(!pf)
+ return NIL(Sfio_t*);
+ else if(!pf->pool || pf->pool == &_Sfpool)
+ return pf;
+ else return pf->pool->sf[0];
+ }
+
+ if(f) /* check for permissions */
+ { SFMTXLOCK(f);
+ if((f->mode&SF_RDWR) != f->mode && _sfmode(f,0,0) < 0)
+ { SFMTXUNLOCK(f);
+ return NIL(Sfio_t*);
+ }
+ if(f->disc == _Sfudisc)
+ (void)sfclose((*_Sfstack)(f,NIL(Sfio_t*)));
+ }
+ if(pf)
+ { SFMTXLOCK(pf);
+ if((pf->mode&SF_RDWR) != pf->mode && _sfmode(pf,0,0) < 0)
+ { if(f)
+ SFMTXUNLOCK(f);
+ SFMTXUNLOCK(pf);
+ return NIL(Sfio_t*);
+ }
+ if(pf->disc == _Sfudisc)
+ (void)sfclose((*_Sfstack)(pf,NIL(Sfio_t*)));
+ }
+
+ /* f already in the same pool with pf */
+ if(f == pf || (pf && f->pool == pf->pool && f->pool != &_Sfpool) )
+ { if(f)
+ SFMTXUNLOCK(f);
+ if(pf)
+ SFMTXUNLOCK(pf);
+ return pf;
+ }
+
+ /* lock streams before internal manipulations */
+ rv = NIL(Sfio_t*);
+ SFLOCK(f,0);
+ if(pf)
+ SFLOCK(pf,0);
+
+ if(!pf) /* deleting f from its current pool */
+ { if((p = f->pool) != NIL(Sfpool_t*) && p != &_Sfpool)
+ for(k = 0; k < p->n_sf && pf == NIL(Sfio_t*); ++k)
+ if(p->sf[k] != f) /* a stream != f represents the pool */
+ pf = p->sf[k];
+ if(!pf) /* already isolated */
+ { rv = f; /* just return self */
+ goto done;
+ }
+
+ if(_sfpmove(f,-1) < 0 || _sfsetpool(f) < 0)
+ goto done; /* can't delete */
+
+ if(!pf->pool || pf->pool == &_Sfpool || pf->pool->n_sf <= 0 )
+ rv = pf;
+ else rv = pf->pool->sf[0]; /* return head of old pool */
+ goto done;
+ }
+
+ if(pf->pool && pf->pool != &_Sfpool) /* always use current mode */
+ mode = pf->pool->mode;
+
+ if(mode&SF_SHARE) /* can only have write streams */
+ { if(SFMODE(f,1) != SF_WRITE && _sfmode(f,SF_WRITE,1) < 0)
+ goto done;
+ if(SFMODE(pf,1) != SF_WRITE && _sfmode(pf,SF_WRITE,1) < 0)
+ goto done;
+ if(f->next > f->data && SFSYNC(f) < 0) /* start f clean */
+ goto done;
+ }
+
+ if(_sfpmove(f,-1) < 0) /* isolate f from current pool */
+ goto done;
+
+ if(!(p = pf->pool) || p == &_Sfpool) /* making a new pool */
+ { if(!(p = newpool(mode)) )
+ goto done;
+ if(_sfpmove(pf,-1) < 0) /* isolate pf from its current pool */
+ goto done;
+ pf->pool = p;
+ p->sf[0] = pf;
+ p->n_sf += 1;
+ }
+
+ f->pool = p; /* add f to pf's pool */
+ if(_sfsetpool(f) < 0)
+ goto done;
+
+ /**/ASSERT(p->sf[0] == pf && p->sf[p->n_sf-1] == f);
+ SFOPEN(pf,0);
+ SFOPEN(f,0);
+ if(_sfpmove(f,0) < 0) /* make f head of pool */
+ goto done;
+ rv = pf;
+
+done:
+ if(f)
+ { SFOPEN(f,0);
+ SFMTXUNLOCK(f);
+ }
+ if(pf)
+ { SFOPEN(pf,0);
+ SFMTXUNLOCK(pf);
+ }
+ return rv;
+}
diff --git a/src/lib/libast/sfio/sfpopen.c b/src/lib/libast/sfio/sfpopen.c
new file mode 100644
index 0000000..ed3ea7f
--- /dev/null
+++ b/src/lib/libast/sfio/sfpopen.c
@@ -0,0 +1,293 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Create a coprocess.
+** Written by Kiem-Phong Vo.
+*/
+
+#if _PACKAGE_ast
+#include <proc.h>
+#else
+
+#define EXIT_NOTFOUND 127
+
+#define READ 0
+#define WRITE 1
+
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+static char Meta[1<<CHAR_BIT], **Path;
+
+/* execute command directly if possible; else use the shell */
+#if __STD_C
+static void execute(const char* argcmd)
+#else
+static void execute(argcmd)
+char* argcmd;
+#endif
+{
+ reg char *s, *cmd, **argv, **p, *interp;
+ reg int n;
+
+ /* define interpreter */
+ if(!(interp = getenv("SHELL")) || !interp[0])
+ interp = "/bin/sh";
+
+ if(strcmp(interp,"/bin/sh") != 0 && strcmp(interp,"/bin/ksh") != 0 )
+ { if(access(interp,X_OK) == 0)
+ goto do_interp;
+ else interp = "/bin/sh";
+ }
+
+ /* if there is a meta character, let the shell do it */
+ for(s = (char*)argcmd; *s; ++s)
+ if(Meta[(uchar)s[0]])
+ goto do_interp;
+
+ /* try to construct argv */
+ if(!(cmd = (char*)malloc(strlen(argcmd)+1)) )
+ goto do_interp;
+ strcpy(cmd,argcmd);
+ if(!(argv = (char**)malloc(16*sizeof(char*))) )
+ goto do_interp;
+ for(n = 0, s = cmd;; )
+ { while(isspace(s[0]))
+ s += 1;
+ if(s[0] == 0)
+ break;
+
+ /* new argument */
+ argv[n++] = s;
+ if((n%16) == 0 && !(argv = (char**)realloc(argv,(n+16)*sizeof(char*))) )
+ goto do_interp;
+
+ /* make this into a C string */
+ while(s[0] && !isspace(s[0]))
+ s += 1;
+ if(!s[0])
+ *s++ = 0;
+ }
+ if(n == 0)
+ goto do_interp;
+ argv[n] = NIL(char*);
+
+ /* get the command name */
+ cmd = argv[0];
+ for(s = cmd+strlen(cmd)-1; s >= cmd; --s)
+ if(*s == '/')
+ break;
+ argv[0] = s+1;
+
+ /* Non-standard pathnames as in nDFS should be handled by the shell */
+ for(s = cmd+strlen(cmd)-1; s >= cmd+2; --s)
+ if(s[0] == '.' && s[-1] == '.' && s[-2] == '.')
+ goto do_interp;
+
+ if(cmd[0] == '/' ||
+ (cmd[0] == '.' && cmd[1] == '/') ||
+ (cmd[0] == '.' && cmd[1] == '.' && cmd[2] == '/') )
+ { if(access(cmd,X_OK) != 0)
+ goto do_interp;
+ else execv(cmd,argv);
+ }
+ else
+ { for(p = Path; *p; ++p)
+ { s = sfprints("%s/%s", *p, cmd);
+ if(access(s,X_OK) == 0)
+ execv(s,argv);
+ }
+ }
+
+ /* if get here, let the interpreter do it */
+do_interp:
+ for(s = interp+strlen(interp)-1; s >= interp; --s)
+ if(*s == '/')
+ break;
+ execl(interp, s+1, "-c", argcmd, NIL(char*));
+ _exit(EXIT_NOTFOUND);
+}
+
+#endif /*_PACKAGE_ast*/
+
+#if __STD_C
+Sfio_t* sfpopen(Sfio_t* f, const char* command, const char* mode)
+#else
+Sfio_t* sfpopen(f,command,mode)
+Sfio_t* f;
+char* command; /* command to execute */
+char* mode; /* mode of the stream */
+#endif
+{
+#if _PACKAGE_ast
+ reg Proc_t* proc;
+ reg int sflags;
+ reg long flags;
+ reg int pflags;
+ char* av[4];
+
+ if (!command || !command[0] || !mode)
+ return 0;
+ sflags = _sftype(mode, NiL, NiL);
+
+ if(f == (Sfio_t*)(-1))
+ { /* stdio compatibility mode */
+ f = NIL(Sfio_t*);
+ pflags = 1;
+ }
+ else pflags = 0;
+
+ flags = 0;
+ if (sflags & SF_READ)
+ flags |= PROC_READ;
+ if (sflags & SF_WRITE)
+ flags |= PROC_WRITE;
+ av[0] = "sh";
+ av[1] = "-c";
+ av[2] = (char*)command;
+ av[3] = 0;
+ if (!(proc = procopen(0, av, 0, 0, flags)))
+ return 0;
+ if (!(f = sfnew(f, NIL(Void_t*), (size_t)SF_UNBOUND,
+ (sflags&SF_READ) ? proc->rfd : proc->wfd, sflags|((sflags&SF_RDWR)?0:SF_READ))) ||
+ _sfpopen(f, (sflags&SF_READ) ? proc->wfd : -1, proc->pid, pflags) < 0)
+ {
+ if (f) sfclose(f);
+ procclose(proc);
+ return 0;
+ }
+ procfree(proc);
+ return f;
+#else
+ reg int pid, fd, pkeep, ckeep, sflags;
+ int stdio, parent[2], child[2];
+ Sfio_t sf;
+
+ /* set shell meta characters */
+ if(Meta[0] == 0)
+ { reg char* s;
+ Meta[0] = 1;
+ for(s = "!@#$%&*(){}[]:;<>~`'|\"\\"; *s; ++s)
+ Meta[(uchar)s[0]] = 1;
+ }
+ if(!Path)
+ Path = _sfgetpath("PATH");
+
+ /* sanity check */
+ if(!command || !command[0] || !mode)
+ return NIL(Sfio_t*);
+ sflags = _sftype(mode,NIL(int*),NIL(int*));
+
+ /* make pipes */
+ parent[0] = parent[1] = child[0] = child[1] = -1;
+ if(sflags&SF_RDWR)
+ { if(syspipef(parent) < 0)
+ goto error;
+ if((sflags&SF_RDWR) == SF_RDWR && syspipef(child) < 0)
+ goto error;
+ }
+
+ switch((pid = fork()) )
+ {
+ default : /* in parent process */
+ if(sflags&SF_READ)
+ { pkeep = READ; ckeep = WRITE; }
+ else { pkeep = WRITE; ckeep = READ; }
+
+ if(f == (Sfio_t*)(-1))
+ { /* stdio compatibility mode */
+ f = NIL(Sfio_t*);
+ stdio = 1;
+ }
+ else stdio = 0;
+
+ /* make the streams */
+ if(!(f = sfnew(f,NIL(Void_t*),(size_t)SF_UNBOUND,parent[pkeep],sflags|((sflags&SF_RDWR)?0:SF_READ))))
+ goto error;
+ if(sflags&SF_RDWR)
+ { CLOSE(parent[!pkeep]);
+ SETCLOEXEC(parent[pkeep]);
+ if((sflags&SF_RDWR) == SF_RDWR)
+ { CLOSE(child[!ckeep]);
+ SETCLOEXEC(child[ckeep]);
+ }
+ }
+
+ /* save process info */
+ fd = (sflags&SF_RDWR) == SF_RDWR ? child[ckeep] : -1;
+ if(_sfpopen(f,fd,pid,stdio) < 0)
+ { (void)sfclose(f);
+ goto error;
+ }
+
+ return f;
+
+ case 0 : /* in child process */
+ /* determine what to keep */
+ if(sflags&SF_READ)
+ { pkeep = WRITE; ckeep = READ; }
+ else { pkeep = READ; ckeep = WRITE; }
+
+ /* zap fd that we don't need */
+ if(sflags&SF_RDWR)
+ { CLOSE(parent[!pkeep]);
+ if((sflags&SF_RDWR) == SF_RDWR)
+ CLOSE(child[!ckeep]);
+ }
+
+ /* use sfsetfd to make these descriptors the std-ones */
+ SFCLEAR(&sf,NIL(Vtmutex_t*));
+
+ /* must be careful so not to close something useful */
+ if((sflags&SF_RDWR) == SF_RDWR && pkeep == child[ckeep])
+ if((child[ckeep] = sysdupf(pkeep)) < 0)
+ _exit(EXIT_NOTFOUND);
+
+ if(sflags&SF_RDWR)
+ { if (parent[pkeep] != pkeep)
+ { sf.file = parent[pkeep];
+ CLOSE(pkeep);
+ if(sfsetfd(&sf,pkeep) != pkeep)
+ _exit(EXIT_NOTFOUND);
+ }
+ if((sflags&SF_RDWR) == SF_RDWR && child[ckeep] != ckeep)
+ { sf.file = child[ckeep];
+ CLOSE(ckeep);
+ if(sfsetfd(&sf,ckeep) != ckeep)
+ _exit(EXIT_NOTFOUND);
+ }
+ }
+
+ execute(command);
+ return NIL(Sfio_t*);
+
+ case -1 : /* error */
+ error:
+ if(parent[0] >= 0)
+ { CLOSE(parent[0]); CLOSE(parent[1]); }
+ if(child[0] >= 0)
+ { CLOSE(child[0]); CLOSE(child[1]); }
+ return NIL(Sfio_t*);
+ }
+#endif /*_PACKAGE_ast*/
+}
diff --git a/src/lib/libast/sfio/sfprintf.c b/src/lib/libast/sfio/sfprintf.c
new file mode 100644
index 0000000..50b0804
--- /dev/null
+++ b/src/lib/libast/sfio/sfprintf.c
@@ -0,0 +1,114 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Print data with a given format
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+int sfprintf(Sfio_t* f, const char* form, ...)
+#else
+int sfprintf(va_alist)
+va_dcl
+#endif
+{
+ va_list args;
+ reg int rv;
+
+#if __STD_C
+ va_start(args,form);
+#else
+ reg Sfio_t* f;
+ reg char* form;
+ va_start(args);
+ f = va_arg(args,Sfio_t*);
+ form = va_arg(args,char*);
+#endif
+ rv = sfvprintf(f,form,args);
+
+ va_end(args);
+ return rv;
+}
+
+#if __STD_C
+ssize_t sfvsprintf(char* s, size_t n, const char* form, va_list args)
+#else
+ssize_t sfvsprintf(s, n, form, args)
+char* s;
+size_t n;
+char* form;
+va_list args;
+#endif
+{
+ Sfio_t *f;
+ ssize_t rv;
+
+ /* make a temp stream */
+ if(!(f = sfnew(NIL(Sfio_t*),NIL(char*),(size_t)SF_UNBOUND,
+ -1,SF_WRITE|SF_STRING)) )
+ return -1;
+
+ if((rv = sfvprintf(f,form,args)) >= 0 && s && n > 0)
+ { if((rv+1) >= n)
+ n--;
+ else
+ n = rv;
+ memcpy(s, f->data, n);
+ s[n] = 0;
+ }
+
+ sfclose(f);
+
+ _Sfi = rv;
+
+ return rv;
+}
+
+#if __STD_C
+ssize_t sfsprintf(char* s, size_t n, const char* form, ...)
+#else
+ssize_t sfsprintf(va_alist)
+va_dcl
+#endif
+{
+ va_list args;
+ ssize_t rv;
+
+#if __STD_C
+ va_start(args,form);
+#else
+ reg char* s;
+ reg size_t n;
+ reg char* form;
+ va_start(args);
+ s = va_arg(args,char*);
+ n = va_arg(args,size_t);
+ form = va_arg(args,char*);
+#endif
+
+ rv = sfvsprintf(s,n,form,args);
+ va_end(args);
+
+ return rv;
+}
diff --git a/src/lib/libast/sfio/sfprints.c b/src/lib/libast/sfio/sfprints.c
new file mode 100644
index 0000000..d69cc34
--- /dev/null
+++ b/src/lib/libast/sfio/sfprints.c
@@ -0,0 +1,125 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Construct a string with the given format and data.
+** These functions allocate space as necessary to store the string.
+** This avoids overflow problems typical with sprintf() in stdio.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+char* sfvprints(const char* form, va_list args)
+#else
+char* sfvprints(form, args)
+char* form;
+va_list args;
+#endif
+{
+ reg int rv;
+ static Sfio_t* f;
+
+ /* make a fake stream */
+ if(!f &&
+ !(f = sfnew(NIL(Sfio_t*),NIL(char*),(size_t)SF_UNBOUND,
+ -1,SF_WRITE|SF_STRING)) )
+ return NIL(char*);
+
+ sfseek(f,(Sfoff_t)0,SEEK_SET);
+ rv = sfvprintf(f,form,args);
+
+ if(rv < 0 || sfputc(f,'\0') < 0)
+ return NIL(char*);
+
+ _Sfi = (f->next - f->data) - 1;
+ return (char*)f->data;
+}
+
+#if __STD_C
+char* sfprints(const char* form, ...)
+#else
+char* sfprints(va_alist)
+va_dcl
+#endif
+{
+ char* s;
+ va_list args;
+
+#if __STD_C
+ va_start(args,form);
+#else
+ char *form;
+ va_start(args);
+ form = va_arg(args,char*);
+#endif
+ s = sfvprints(form, args);
+ va_end(args);
+
+ return s;
+}
+
+#if __STD_C
+ssize_t sfvaprints(char** sp, const char* form, va_list args)
+#else
+ssize_t sfvaprints(sp, form, args)
+char** sp;
+char* form;
+va_list args;
+#endif
+{
+ char *s;
+ ssize_t n;
+
+ if(!sp || !(s = sfvprints(form,args)) )
+ return -1;
+ else
+ { if(!(*sp = (char*)malloc(n = strlen(s)+1)) )
+ return -1;
+ memcpy(*sp, s, n);
+ return n-1;
+ }
+}
+
+#if __STD_C
+ssize_t sfaprints(char** sp, const char* form, ...)
+#else
+ssize_t sfaprints(va_alist)
+va_dcl
+#endif
+{
+ ssize_t n;
+ va_list args;
+
+#if __STD_C
+ va_start(args,form);
+#else
+ char **sp, *form;
+ va_start(args);
+ sp = va_arg(args, char**);
+ form = va_arg(args, char*);
+#endif
+ n = sfvaprints(sp, form, args);
+ va_end(args);
+
+ return n;
+}
diff --git a/src/lib/libast/sfio/sfpurge.c b/src/lib/libast/sfio/sfpurge.c
new file mode 100644
index 0000000..c3b4106
--- /dev/null
+++ b/src/lib/libast/sfio/sfpurge.c
@@ -0,0 +1,98 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Delete all pending data in the buffer
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+int sfpurge(Sfio_t* f)
+#else
+int sfpurge(f)
+Sfio_t* f;
+#endif
+{
+ reg int mode;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f,-1);
+
+ if((mode = f->mode&SF_RDWR) != (int)f->mode && _sfmode(f,mode|SF_SYNCED,0) < 0)
+ SFMTXRETURN(f, -1);
+
+ if((f->flags&SF_IOCHECK) && f->disc && f->disc->exceptf)
+ (void)(*f->disc->exceptf)(f,SF_PURGE,(Void_t*)((int)1),f->disc);
+
+ if(f->disc == _Sfudisc)
+ (void)sfclose((*_Sfstack)(f,NIL(Sfio_t*)));
+
+ /* cannot purge read string streams */
+ if((f->flags&SF_STRING) && (f->mode&SF_READ) )
+ goto done;
+
+ SFLOCK(f,0);
+
+ /* if memory map must be a read stream, pretend data is gone */
+#ifdef MAP_TYPE
+ if(f->bits&SF_MMAP)
+ { f->here -= f->endb - f->next;
+ if(f->data)
+ { SFMUNMAP(f,f->data,f->endb-f->data);
+ (void)SFSK(f,f->here,SEEK_SET,f->disc);
+ }
+ SFOPEN(f,0);
+ SFMTXRETURN(f, 0);
+ }
+#endif
+
+ switch(f->mode&~SF_LOCK)
+ {
+ default :
+ SFOPEN(f,0);
+ SFMTXRETURN(f, -1);
+ case SF_WRITE :
+ f->next = f->data;
+ if(!f->proc || !(f->flags&SF_READ) || !(f->mode&SF_WRITE) )
+ break;
+
+ /* 2-way pipe, must clear read buffer */
+ (void)_sfmode(f,SF_READ,1);
+ /* fall through */
+ case SF_READ:
+ if(f->extent >= 0 && f->endb > f->next)
+ { f->here -= f->endb-f->next;
+ (void)SFSK(f,f->here,SEEK_SET,f->disc);
+ }
+ f->endb = f->next = f->data;
+ break;
+ }
+
+ SFOPEN(f,0);
+
+done:
+ if((f->flags&SF_IOCHECK) && f->disc && f->disc->exceptf)
+ (void)(*f->disc->exceptf)(f,SF_PURGE,(Void_t*)((int)0),f->disc);
+
+ SFMTXRETURN(f, 0);
+}
diff --git a/src/lib/libast/sfio/sfputd.c b/src/lib/libast/sfio/sfputd.c
new file mode 100644
index 0000000..3129cd5
--- /dev/null
+++ b/src/lib/libast/sfio/sfputd.c
@@ -0,0 +1,35 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sfputd
+
+#if __STD_C
+int sfputd(reg Sfio_t* f, Sfdouble_t d)
+#else
+int sfputd(f,d)
+reg Sfio_t* f;
+reg Sfdouble_t d;
+#endif
+{
+ return __sf_putd(f,d);
+}
diff --git a/src/lib/libast/sfio/sfputl.c b/src/lib/libast/sfio/sfputl.c
new file mode 100644
index 0000000..ceaa6b9
--- /dev/null
+++ b/src/lib/libast/sfio/sfputl.c
@@ -0,0 +1,35 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sfputl
+
+#if __STD_C
+int sfputl(reg Sfio_t* f, Sflong_t l)
+#else
+int sfputl(f,l)
+reg Sfio_t* f;
+reg Sflong_t l;
+#endif
+{
+ return __sf_putl(f,l);
+}
diff --git a/src/lib/libast/sfio/sfputm.c b/src/lib/libast/sfio/sfputm.c
new file mode 100644
index 0000000..8082a7b
--- /dev/null
+++ b/src/lib/libast/sfio/sfputm.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sfputm
+
+#if __STD_C
+int sfputm(Sfio_t* f, Sfulong_t u, Sfulong_t m)
+#else
+int sfputm(f,u,m)
+Sfio_t* f;
+Sfulong_t u;
+Sfulong_t m;
+#endif
+{
+ return __sf_putm(f, u, m);
+}
diff --git a/src/lib/libast/sfio/sfputr.c b/src/lib/libast/sfio/sfputr.c
new file mode 100644
index 0000000..21bfb0a
--- /dev/null
+++ b/src/lib/libast/sfio/sfputr.c
@@ -0,0 +1,136 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Put out a null-terminated string
+**
+** Written by Kiem-Phong Vo.
+*/
+#if __STD_C
+ssize_t sfputr(Sfio_t* f, const char* s, int rc)
+#else
+ssize_t sfputr(f,s,rc)
+Sfio_t* f; /* write to this stream */
+char* s; /* string to write */
+int rc; /* record separator. */
+#endif
+{
+ ssize_t p, n, w, sn;
+ uchar *ps;
+ char *ss;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f,-1);
+
+ if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0)
+ SFMTXRETURN(f, -1);
+
+ SFLOCK(f,0);
+
+ f->val = sn = -1; ss = (char*)s;
+ for(w = 0; (*s || rc >= 0); )
+ { /* need to communicate string size to exception handler */
+ if((f->flags&SF_STRING) && f->next >= f->endb )
+ { sn = sn < 0 ? strlen(s) : (sn - (s-ss));
+ ss = (char*)s; /* save current checkpoint */
+ f->val = sn + (rc >= 0 ? 1 : 0); /* space requirement */
+ f->bits |= SF_PUTR; /* tell sfflsbuf to use f->val */
+ }
+
+ SFWPEEK(f,ps,p);
+ f->bits &= ~SF_PUTR; /* remove any trace of this */
+
+ if(p < 0 ) /* something not right about buffering */
+ break;
+
+ if(p == 0 || (f->flags&SF_WHOLE) )
+ { n = sn < 0 ? strlen(s) : sn - (s-ss);
+ if(p >= (n + (rc < 0 ? 0 : 1)) )
+ { /* buffer can hold everything */
+ if(n > 0)
+ { memcpy(ps, s, n);
+ ps += n;
+ w += n;
+ }
+ if(rc >= 0)
+ { *ps++ = rc;
+ w += 1;
+ }
+ f->next = ps;
+ }
+ else
+ { /* create a reserve buffer to hold data */
+ Sfrsrv_t* rsrv;
+
+ p = n + (rc >= 0 ? 1 : 0);
+ if(!(rsrv = _sfrsrv(f, p)) )
+ n = 0;
+ else
+ { if(n > 0)
+ memcpy(rsrv->data, s, n);
+ if(rc >= 0)
+ rsrv->data[n] = rc;
+ if((n = SFWRITE(f,rsrv->data,p)) < 0 )
+ n = 0;
+ }
+
+ w += n;
+ }
+ break;
+ }
+
+ if(*s == 0)
+ { *ps++ = rc;
+ f->next = ps;
+ w += 1;
+ break;
+ }
+
+#if _lib_memccpy && !__ia64 /* these guys may never get it right */
+ if((ps = (uchar*)memccpy(ps,s,'\0',p)) != NIL(uchar*))
+ ps -= 1;
+ else ps = f->next+p;
+ s += ps - f->next;
+#else
+ for(; p > 0; --p, ++ps, ++s)
+ if((*ps = *s) == 0)
+ break;
+#endif
+ w += ps - f->next;
+ f->next = ps;
+ }
+
+ /* sync unseekable shared streams */
+ if(f->extent < 0 && (f->flags&SF_SHARE) )
+ (void)SFFLSBUF(f,-1);
+
+ /* check for line buffering */
+ else if((f->flags&SF_LINE) && !(f->flags&SF_STRING) && (n = f->next-f->data) > 0)
+ { if(n > w)
+ n = w;
+ f->next -= n;
+ (void)SFWRITE(f,(Void_t*)f->next,n);
+ }
+
+ SFOPEN(f,0);
+ SFMTXRETURN(f, w);
+}
diff --git a/src/lib/libast/sfio/sfputu.c b/src/lib/libast/sfio/sfputu.c
new file mode 100644
index 0000000..17f1567
--- /dev/null
+++ b/src/lib/libast/sfio/sfputu.c
@@ -0,0 +1,35 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+#undef sfputu
+
+#if __STD_C
+int sfputu(reg Sfio_t* f, Sfulong_t u)
+#else
+int sfputu(f,u)
+reg Sfio_t* f;
+reg Sfulong_t u;
+#endif
+{
+ return __sf_putu(f,u);
+}
diff --git a/src/lib/libast/sfio/sfraise.c b/src/lib/libast/sfio/sfraise.c
new file mode 100644
index 0000000..7ea4ef3
--- /dev/null
+++ b/src/lib/libast/sfio/sfraise.c
@@ -0,0 +1,107 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Invoke event handlers for a stream
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+static int _sfraiseall(int type, Void_t* data)
+#else
+static int _sfraiseall(type, data)
+int type; /* type of event */
+Void_t* data; /* associated data */
+#endif
+{
+ Sfio_t *f;
+ Sfpool_t *p, *next;
+ int n, rv;
+
+ rv = 0;
+ for(p = &_Sfpool; p; p = next)
+ {
+ for(next = p->next; next; next = next->next)
+ if(next->n_sf > 0)
+ break;
+ for(n = 0; n < p->n_sf; ++n)
+ { f = p->sf[n];
+ if(sfraise(f, type, data) < 0)
+ rv -= 1;
+ }
+ }
+ return rv;
+}
+
+#if __STD_C
+int sfraise(Sfio_t* f, int type, Void_t* data)
+#else
+int sfraise(f, type, data)
+Sfio_t* f; /* stream */
+int type; /* type of event */
+Void_t* data; /* associated data */
+#endif
+{
+ reg Sfdisc_t *disc, *next, *d;
+ reg int local, rv;
+ SFMTXDECL(f);
+
+ if(!f)
+ return _sfraiseall(type,data);
+
+ SFMTXENTER(f, -1);
+
+ GETLOCAL(f,local);
+ if(!SFKILLED(f) &&
+ !(local &&
+ (type == SF_NEW || type == SF_CLOSING ||
+ type == SF_FINAL || type == SF_ATEXIT)) &&
+ SFMODE(f,local) != (f->mode&SF_RDWR) && _sfmode(f,0,local) < 0)
+ SFMTXRETURN(f, -1);
+ SFLOCK(f,local);
+
+ for(disc = f->disc; disc; )
+ { next = disc->disc;
+ if(type == SF_FINAL)
+ f->disc = next;
+
+ if(disc->exceptf)
+ { SFOPEN(f,0);
+ if((rv = (*disc->exceptf)(f,type,data,disc)) != 0 )
+ SFMTXRETURN(f, rv);
+ SFLOCK(f,0);
+ }
+
+ if((disc = next) )
+ { /* make sure that "next" hasn't been popped */
+ for(d = f->disc; d; d = d->disc)
+ if(d == disc)
+ break;
+ if(!d)
+ disc = f->disc;
+ }
+ }
+
+ SFOPEN(f,local);
+ SFMTXRETURN(f, 0);
+}
diff --git a/src/lib/libast/sfio/sfrd.c b/src/lib/libast/sfio/sfrd.c
new file mode 100644
index 0000000..09a493c
--- /dev/null
+++ b/src/lib/libast/sfio/sfrd.c
@@ -0,0 +1,317 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Internal function to do a hard read.
+** This knows about discipline and memory mapping, peek read.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+/* synchronize unseekable write streams */
+#if __STD_C
+static void _sfwrsync(void)
+#else
+static void _sfwrsync()
+#endif
+{ reg Sfpool_t* p;
+ reg Sfio_t* f;
+ reg int n;
+
+ /* sync all pool heads */
+ for(p = _Sfpool.next; p; p = p->next)
+ { if(p->n_sf <= 0)
+ continue;
+ f = p->sf[0];
+ if(!SFFROZEN(f) && f->next > f->data &&
+ (f->mode&SF_WRITE) && f->extent < 0 )
+ (void)_sfflsbuf(f,-1);
+ }
+
+ /* and all the ones in the discrete pool */
+ for(n = 0; n < _Sfpool.n_sf; ++n)
+ { f = _Sfpool.sf[n];
+
+ if(!SFFROZEN(f) && f->next > f->data &&
+ (f->mode&SF_WRITE) && f->extent < 0 )
+ (void)_sfflsbuf(f,-1);
+ }
+}
+
+#if __STD_C
+ssize_t sfrd(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc)
+#else
+ssize_t sfrd(f,buf,n,disc)
+Sfio_t* f;
+Void_t* buf;
+size_t n;
+Sfdisc_t* disc;
+#endif
+{
+ Sfoff_t r;
+ reg Sfdisc_t* dc;
+ reg int local, rcrv, dosync, oerrno;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f,-1);
+
+ GETLOCAL(f,local);
+ if((rcrv = f->mode & (SF_RC|SF_RV)) )
+ f->mode &= ~(SF_RC|SF_RV);
+ f->bits &= ~SF_JUSTSEEK;
+
+ if(f->mode&SF_PKRD)
+ SFMTXRETURN(f, -1);
+
+ if(!local && !(f->bits&SF_DCDOWN)) /* an external user's call */
+ { if(f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0)
+ SFMTXRETURN(f, -1);
+ if(f->next < f->endb)
+ { if(SFSYNC(f) < 0)
+ SFMTXRETURN(f, -1);
+ if((f->mode&(SF_SYNCED|SF_READ)) == (SF_SYNCED|SF_READ) )
+ { f->endb = f->next = f->endr = f->data;
+ f->mode &= ~SF_SYNCED;
+ }
+#ifdef MAP_TYPE
+ if((f->bits&SF_MMAP) && f->data)
+ { SFMUNMAP(f, f->data, f->endb-f->data);
+ f->data = NIL(uchar*);
+ }
+#endif
+ f->next = f->endb = f->endr = f->endw = f->data;
+ }
+ }
+
+ for(dosync = 0;;)
+ { /* stream locked by sfsetfd() */
+ if(!(f->flags&SF_STRING) && f->file < 0)
+ SFMTXRETURN(f, 0);
+
+ f->flags &= ~(SF_EOF|SF_ERROR);
+
+ dc = disc;
+ if(f->flags&SF_STRING)
+ { if((r = (f->data+f->extent) - f->next) < 0)
+ r = 0;
+ if(r <= 0)
+ goto do_except;
+ SFMTXRETURN(f, (ssize_t)r);
+ }
+
+ /* warn that a read is about to happen */
+ SFDISC(f,dc,readf);
+ if(dc && dc->exceptf && (f->flags&SF_IOCHECK) )
+ { reg int rv;
+ if(local)
+ SETLOCAL(f);
+ if((rv = _sfexcept(f,SF_READ,n,dc)) > 0)
+ n = rv;
+ else if(rv < 0)
+ { f->flags |= SF_ERROR;
+ SFMTXRETURN(f, (ssize_t)rv);
+ }
+ }
+
+#ifdef MAP_TYPE
+ if(f->bits&SF_MMAP)
+ { reg ssize_t a, round;
+ sfstat_t st;
+
+ /* determine if we have to copy data to buffer */
+ if((uchar*)buf >= f->data && (uchar*)buf <= f->endb)
+ { n += f->endb - f->next;
+ buf = NIL(char*);
+ }
+
+ /* actual seek location */
+ if((f->flags&(SF_SHARE|SF_PUBLIC)) == (SF_SHARE|SF_PUBLIC) &&
+ (r = SFSK(f,(Sfoff_t)0,SEEK_CUR,dc)) != f->here)
+ f->here = r;
+ else f->here -= f->endb-f->next;
+
+ /* before mapping, make sure we have data to map */
+ if((f->flags&SF_SHARE) || (size_t)(r = f->extent-f->here) < n)
+ { if((r = sysfstatf(f->file,&st)) < 0)
+ goto do_except;
+ if((r = (f->extent = st.st_size) - f->here) <= 0 )
+ { r = 0; /* eof */
+ goto do_except;
+ }
+ }
+
+ /* make sure current position is page aligned */
+ if((a = (size_t)(f->here%_Sfpage)) != 0)
+ { f->here -= a;
+ r += a;
+ }
+
+ /* map minimal requirement */
+ if(r > (round = (1 + (n+a)/f->size)*f->size) )
+ r = round;
+
+ if(f->data)
+ SFMUNMAP(f, f->data, f->endb-f->data);
+
+ for(;;)
+ { f->data = (uchar*) sysmmapf((caddr_t)0, (size_t)r,
+ (PROT_READ|PROT_WRITE),
+ MAP_PRIVATE,
+ f->file, (sfoff_t)f->here);
+ if(f->data && (caddr_t)f->data != (caddr_t)(-1))
+ break;
+ else
+ { f->data = NIL(uchar*);
+ if((r >>= 1) < (_Sfpage*SF_NMAP) ||
+ (errno != EAGAIN && errno != ENOMEM) )
+ break;
+ }
+ }
+
+ if(f->data)
+ { if(f->bits&SF_SEQUENTIAL)
+ SFMMSEQON(f,f->data,r);
+ f->next = f->data+a;
+ f->endr = f->endb = f->data+r;
+ f->endw = f->data;
+ f->here += r;
+
+ /* make known our seek location */
+ (void)SFSK(f,f->here,SEEK_SET,dc);
+
+ if(buf)
+ { if(n > (size_t)(r-a))
+ n = (ssize_t)(r-a);
+ memcpy(buf,f->next,n);
+ f->next += n;
+ }
+ else n = f->endb - f->next;
+
+ SFMTXRETURN(f, n);
+ }
+ else
+ { r = -1;
+ f->here += a;
+
+ /* reset seek pointer to its physical location */
+ (void)SFSK(f,f->here,SEEK_SET,dc);
+
+ /* make a buffer */
+ (void)SFSETBUF(f,(Void_t*)f->tiny,(size_t)SF_UNBOUND);
+
+ if(!buf)
+ { buf = (Void_t*)f->data;
+ n = f->size;
+ }
+ }
+ }
+#endif
+
+ /* sync unseekable write streams to prevent deadlock */
+ if(!dosync && f->extent < 0)
+ { dosync = 1;
+ _sfwrsync();
+ }
+
+ /* make sure file pointer is right */
+ if(f->extent >= 0 && (f->flags&SF_SHARE) )
+ { if(!(f->flags&SF_PUBLIC) )
+ f->here = SFSK(f,f->here,SEEK_SET,dc);
+ else f->here = SFSK(f,(Sfoff_t)0,SEEK_CUR,dc);
+ }
+
+ oerrno = errno;
+ errno = 0;
+
+ if(dc && dc->readf)
+ { int share = f->flags&SF_SHARE;
+
+ if(rcrv) /* pass on rcrv for possible continuations */
+ f->mode |= rcrv;
+ /* tell readf that no peeking necessary */
+ else f->flags &= ~SF_SHARE;
+
+ SFDCRD(f,buf,n,dc,r);
+
+ /* reset flags */
+ if(rcrv)
+ f->mode &= ~rcrv;
+ else f->flags |= share;
+ }
+ else if(SFISNULL(f))
+ r = 0;
+ else if(f->extent < 0 && (f->flags&SF_SHARE) && rcrv)
+ { /* try peek read */
+ r = sfpkrd(f->file, (char*)buf, n,
+ (rcrv&SF_RC) ? (int)f->getr : -1,
+ -1L, (rcrv&SF_RV) ? 1 : 0);
+ if(r > 0)
+ { if(rcrv&SF_RV)
+ f->mode |= SF_PKRD;
+ else f->mode |= SF_RC;
+ }
+ }
+ else r = sysreadf(f->file,buf,n);
+
+ if(errno == 0 )
+ errno = oerrno;
+
+ if(r > 0 )
+ { if(!(f->bits&SF_DCDOWN) ) /* not a continuation call */
+ { if(!(f->mode&SF_PKRD) )
+ { f->here += r;
+ if(f->extent >= 0 && f->extent < f->here)
+ f->extent = f->here;
+ }
+ if((uchar*)buf >= f->data &&
+ (uchar*)buf < f->data+f->size)
+ f->endb = f->endr = ((uchar*)buf) + r;
+ }
+
+ SFMTXRETURN(f, (ssize_t)r);
+ }
+
+ do_except:
+ if(local)
+ SETLOCAL(f);
+ switch(_sfexcept(f,SF_READ,(ssize_t)r,dc))
+ {
+ case SF_ECONT :
+ goto do_continue;
+ case SF_EDONE :
+ n = local ? 0 : (ssize_t)r;
+ SFMTXRETURN(f,n);
+ case SF_EDISC :
+ if(!local && !(f->flags&SF_STRING))
+ goto do_continue;
+ /* else fall thru */
+ case SF_ESTACK :
+ SFMTXRETURN(f, -1);
+ }
+
+ do_continue:
+ for(dc = f->disc; dc; dc = dc->disc)
+ if(dc == disc)
+ break;
+ disc = dc;
+ }
+}
diff --git a/src/lib/libast/sfio/sfread.c b/src/lib/libast/sfio/sfread.c
new file mode 100644
index 0000000..a3aed97
--- /dev/null
+++ b/src/lib/libast/sfio/sfread.c
@@ -0,0 +1,140 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Read n bytes from a stream into a buffer
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+ssize_t sfread(Sfio_t* f, Void_t* buf, size_t n)
+#else
+ssize_t sfread(f,buf,n)
+Sfio_t* f; /* read from this stream. */
+Void_t* buf; /* buffer to read into */
+size_t n; /* number of bytes to be read. */
+#endif
+{
+ reg uchar *s, *begs;
+ reg ssize_t r;
+ reg int local, justseek;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f, (ssize_t)(-1));
+
+ GETLOCAL(f,local);
+ justseek = f->bits&SF_JUSTSEEK; f->bits &= ~SF_JUSTSEEK;
+
+ if(!buf)
+ SFMTXRETURN(f, (ssize_t)(n == 0 ? 0 : -1) );
+
+ /* release peek lock */
+ if(f->mode&SF_PEEK)
+ { if(!(f->mode&SF_READ) )
+ SFMTXRETURN(f, (ssize_t)(-1));
+
+ if(f->mode&SF_GETR)
+ { if(((uchar*)buf + f->val) != f->next &&
+ (!f->rsrv || f->rsrv->data != (uchar*)buf) )
+ SFMTXRETURN(f, (ssize_t)(-1));
+ f->mode &= ~SF_PEEK;
+ SFMTXRETURN(f, 0);
+ }
+ else
+ { if((uchar*)buf != f->next)
+ SFMTXRETURN(f, (ssize_t)(-1));
+ f->mode &= ~SF_PEEK;
+ if(f->mode&SF_PKRD)
+ { /* actually read the data now */
+ f->mode &= ~SF_PKRD;
+ if(n > 0)
+ n = (r = sysreadf(f->file,f->data,n)) < 0 ? 0 : r;
+ f->endb = f->data+n;
+ f->here += n;
+ }
+ f->next += n;
+ f->endr = f->endb;
+ SFMTXRETURN(f, n);
+ }
+ }
+
+ s = begs = (uchar*)buf;
+ for(;; f->mode &= ~SF_LOCK)
+ { /* check stream mode */
+ if(SFMODE(f,local) != SF_READ && _sfmode(f,SF_READ,local) < 0)
+ { n = s > begs ? s-begs : (size_t)(-1);
+ SFMTXRETURN(f, (ssize_t)n);
+ }
+
+ SFLOCK(f,local);
+
+ if((r = f->endb - f->next) > 0) /* has buffered data */
+ { if(r > (ssize_t)n)
+ r = (ssize_t)n;
+ if(s != f->next)
+ memcpy(s, f->next, r);
+ f->next += r;
+ s += r;
+ n -= r;
+ }
+
+ if(n <= 0) /* all done */
+ break;
+
+ if(!(f->flags&SF_STRING) && !(f->bits&SF_MMAP) )
+ { f->next = f->endb = f->data;
+
+ /* exact IO is desirable for these cases */
+ if(SFDIRECT(f,n) ||
+ ((f->flags&SF_SHARE) && f->extent < 0) )
+ r = (ssize_t)n;
+ else if(justseek && n <= f->iosz && f->iosz <= f->size)
+ r = f->iosz; /* limit buffering */
+ else r = f->size; /* full buffering */
+
+ /* if read almost full size, then just do it direct */
+ if(r > (ssize_t)n && (r - r/8) <= (ssize_t)n)
+ r = (ssize_t)n;
+
+ /* read directly to user's buffer */
+ if(r == (ssize_t)n && (r = SFRD(f,s,r,f->disc)) >= 0)
+ { s += r;
+ n -= r;
+ if(r == 0 || n == 0) /* eof or eob */
+ break;
+ }
+ else goto do_filbuf;
+ }
+ else
+ { do_filbuf:
+ if(justseek)
+ f->bits |= SF_JUSTSEEK;
+ if(SFFILBUF(f,-1) <= 0)
+ break;
+ }
+ }
+
+ SFOPEN(f,local);
+ r = s-begs;
+ SFMTXRETURN(f, r);
+}
diff --git a/src/lib/libast/sfio/sfreserve.c b/src/lib/libast/sfio/sfreserve.c
new file mode 100644
index 0000000..29772a2
--- /dev/null
+++ b/src/lib/libast/sfio/sfreserve.c
@@ -0,0 +1,210 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Reserve a segment of data or buffer.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+Void_t* sfreserve(Sfio_t* f, ssize_t size, int type)
+#else
+Void_t* sfreserve(f,size,type)
+Sfio_t* f; /* file to peek */
+ssize_t size; /* size of peek */
+int type; /* LOCKR: lock stream, LASTR: last record */
+#endif
+{
+ reg ssize_t n, now, sz, iosz;
+ reg Sfrsrv_t* rsrv;
+ reg Void_t* data;
+ reg int mode, local;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f,NIL(Void_t*));
+
+ sz = size < 0 ? -size : size;
+
+ /* see if we need to bias toward SF_WRITE instead of the default SF_READ */
+ if(type < 0)
+ mode = 0;
+ else if((mode = type&SF_WRITE) )
+ type &= ~SF_WRITE;
+
+ /* return the last record */
+ if(type == SF_LASTR )
+ { if((n = f->endb - f->next) > 0 && n == f->val )
+ { data = (Void_t*)f->next;
+ f->next += n;
+ }
+ else if((rsrv = f->rsrv) && (n = -rsrv->slen) > 0)
+ { rsrv->slen = 0;
+ _Sfi = f->val = n;
+ data = (Void_t*)rsrv->data;
+ }
+ else
+ { _Sfi = f->val = -1;
+ data = NIL(Void_t*);
+ }
+
+ SFMTXRETURN(f, data);
+ }
+
+ if(type > 0)
+ { if(type == 1 ) /* upward compatibility mode */
+ type = SF_LOCKR;
+ else if(type != SF_LOCKR)
+ SFMTXRETURN(f, NIL(Void_t*));
+ }
+
+ if(size == 0 && (type < 0 || type == SF_LOCKR) )
+ { if((f->mode&SF_RDWR) != f->mode && _sfmode(f,0,0) < 0)
+ SFMTXRETURN(f, NIL(Void_t*));
+
+ SFLOCK(f,0);
+ if((n = f->endb - f->next) < 0)
+ n = 0;
+
+ goto done;
+ }
+
+ /* iterate until get to a stream that has data or buffer space */
+ for(local = 0;; local = SF_LOCAL)
+ { _Sfi = f->val = -1;
+
+ if(!mode && !(mode = f->flags&SF_READ) )
+ mode = SF_WRITE;
+ if((int)f->mode != mode && _sfmode(f,mode,local) < 0)
+ { SFOPEN(f,0);
+ SFMTXRETURN(f, NIL(Void_t*));
+ }
+
+ SFLOCK(f,local);
+
+ if((n = now = f->endb - f->next) < 0)
+ n = 0;
+ if(n > 0 && n >= sz) /* all done */
+ break;
+
+ /* set amount to perform IO */
+ if(size == 0 || (f->mode&SF_WRITE))
+ iosz = -1;
+ else if(size < 0 && n == 0 && f->push) /* maybe stack-pop */
+ { if((iosz = f->push->endb - f->push->next) == 0)
+ iosz = f->push->size;
+ if(iosz < sz)
+ iosz = sz; /* so only get what is asked for */
+ }
+ else
+ { iosz = sz - n; /* get enough to fulfill requirement */
+ if(size < 0 && iosz < (f->size - n) )
+ iosz = f->size - n; /* get as much as possible */
+ if(iosz <= 0) /* nothing to do */
+ break;
+ }
+
+ /* do a buffer refill or flush */
+ now = n;
+ if(f->mode&SF_WRITE)
+ (void)SFFLSBUF(f, iosz);
+ else if(type == SF_LOCKR && f->extent < 0 && (f->flags&SF_SHARE) )
+ { if(n == 0) /* peek-read only if there is no buffered data */
+ { f->mode |= SF_RV;
+ (void)SFFILBUF(f, iosz );
+ }
+ if((n = f->endb - f->next) < sz)
+ { if(f->mode&SF_PKRD)
+ { f->endb = f->endr = f->next;
+ f->mode &= ~SF_PKRD;
+ }
+ break;
+ }
+ }
+ else
+ { /* sfreserve(f,0,0) == sfread(f, sfreserve(f,-1,SF_LOCKR), 0) */
+ if(size == 0 && type == 0)
+ f->mode |= SF_RV;
+
+ (void)SFFILBUF(f, iosz );
+ }
+
+ if((n = f->endb - f->next) <= 0)
+ n = 0;
+
+ if(n >= sz) /* got it */
+ break;
+
+ if(n == now || sferror(f) || sfeof(f)) /* no progress */
+ break;
+
+ /* request was only to assess data availability */
+ if(type == SF_LOCKR && size > 0 && n > 0 )
+ break;
+ }
+
+done: /* compute the buffer to be returned */
+ data = NIL(Void_t*);
+ if(size == 0 || n == 0)
+ { if(n > 0) /* got data */
+ data = (Void_t*)f->next;
+ else if(type == SF_LOCKR && size == 0 && (rsrv = _sfrsrv(f,0)) )
+ data = (Void_t*)rsrv->data;
+ }
+ else if(n >= sz) /* got data */
+ data = (Void_t*)f->next;
+ else if(f->flags&SF_STRING) /* try extending string buffer */
+ { if((f->mode&SF_WRITE) && (f->flags&SF_MALLOC) )
+ { (void)SFWR(f,f->next,sz,f->disc);
+ if((n = f->endb - f->next) >= sz )
+ data = (Void_t*)f->next;
+ }
+ }
+ else if(f->mode&SF_WRITE) /* allocate side buffer */
+ { if(type == SF_LOCKR && (rsrv = _sfrsrv(f, sz)) )
+ data = (Void_t*)rsrv->data;
+ }
+ else if(type != SF_LOCKR && sz > f->size && (rsrv = _sfrsrv(f,sz)) )
+ { if((n = SFREAD(f,(Void_t*)rsrv->data,sz)) >= sz) /* read side buffer */
+ data = (Void_t*)rsrv->data;
+ else rsrv->slen = -n;
+ }
+
+ SFOPEN(f,0);
+
+ if(data)
+ { if(type == SF_LOCKR)
+ { f->mode |= SF_PEEK;
+ if((f->mode & SF_READ) && size == 0 && data != f->next)
+ f->mode |= SF_GETR; /* so sfread() will unlock */
+ f->endr = f->endw = f->data;
+ }
+ else
+ { if(data == (Void_t*)f->next)
+ f->next += (size >= 0 ? size : n);
+ }
+ }
+
+ _Sfi = f->val = n; /* return true buffer size */
+
+ SFMTXRETURN(f, data);
+}
diff --git a/src/lib/libast/sfio/sfresize.c b/src/lib/libast/sfio/sfresize.c
new file mode 100644
index 0000000..ae5c83c
--- /dev/null
+++ b/src/lib/libast/sfio/sfresize.c
@@ -0,0 +1,83 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Resize a stream.
+ Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+int sfresize(Sfio_t* f, Sfoff_t size)
+#else
+int sfresize(f, size)
+Sfio_t* f;
+Sfoff_t size;
+#endif
+{
+ SFMTXDECL(f);
+
+ SFMTXENTER(f, -1);
+
+ if(size < 0 || f->extent < 0 ||
+ (f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0) )
+ SFMTXRETURN(f, -1);
+
+ SFLOCK(f,0);
+
+ if(f->flags&SF_STRING)
+ { SFSTRSIZE(f);
+
+ if(f->extent >= size)
+ { if((f->flags&SF_MALLOC) && (f->next - f->data) <= size)
+ { size_t s = (((size_t)size + 1023)/1024)*1024;
+ Void_t* d;
+ if(s < f->size && (d = realloc(f->data, s)) )
+ { f->data = d;
+ f->size = s;
+ f->extent = s;
+ }
+ }
+ memclear((char*)(f->data+size), (int)(f->extent-size));
+ }
+ else
+ { if(SFSK(f, size, SEEK_SET, f->disc) != size)
+ SFMTXRETURN(f, -1);
+ memclear((char*)(f->data+f->extent), (int)(size-f->extent));
+ }
+ }
+ else
+ { if(f->next > f->data)
+ SFSYNC(f);
+#if _lib_ftruncate
+ if(ftruncate(f->file, (sfoff_t)size) < 0)
+ SFMTXRETURN(f, -1);
+#else
+ SFMTXRETURN(f, -1);
+#endif
+ }
+
+ f->extent = size;
+
+ SFOPEN(f, 0);
+
+ SFMTXRETURN(f, 0);
+}
diff --git a/src/lib/libast/sfio/sfscanf.c b/src/lib/libast/sfio/sfscanf.c
new file mode 100644
index 0000000..12eec1a
--- /dev/null
+++ b/src/lib/libast/sfio/sfscanf.c
@@ -0,0 +1,102 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Read formated data from a stream
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+int sfscanf(Sfio_t* f, const char* form, ...)
+#else
+int sfscanf(va_alist)
+va_dcl
+#endif
+{
+ va_list args;
+ reg int rv;
+
+#if __STD_C
+ va_start(args,form);
+#else
+ reg Sfio_t* f;
+ reg char* form;
+ va_start(args);
+ f = va_arg(args,Sfio_t*);
+ form = va_arg(args,char*);
+#endif
+
+ rv = (f && form) ? sfvscanf(f,form,args) : -1;
+ va_end(args);
+ return rv;
+}
+
+#if __STD_C
+int sfvsscanf(const char* s, const char* form, va_list args)
+#else
+int sfvsscanf(s, form, args)
+char* s;
+char* form;
+va_list args;
+#endif
+{
+ Sfio_t f;
+
+ if(!s || !form)
+ return -1;
+
+ /* make a fake stream */
+ SFCLEAR(&f,NIL(Vtmutex_t*));
+ f.flags = SF_STRING|SF_READ;
+ f.bits = SF_PRIVATE;
+ f.mode = SF_READ;
+ f.size = strlen((char*)s);
+ f.data = f.next = f.endw = (uchar*)s;
+ f.endb = f.endr = f.data+f.size;
+
+ return sfvscanf(&f,form,args);
+}
+
+#if __STD_C
+int sfsscanf(const char* s, const char* form,...)
+#else
+int sfsscanf(va_alist)
+va_dcl
+#endif
+{
+ va_list args;
+ reg int rv;
+#if __STD_C
+ va_start(args,form);
+#else
+ reg char* s;
+ reg char* form;
+ va_start(args);
+ s = va_arg(args,char*);
+ form = va_arg(args,char*);
+#endif
+
+ rv = (s && form) ? sfvsscanf(s,form,args) : -1;
+ va_end(args);
+ return rv;
+}
diff --git a/src/lib/libast/sfio/sfseek.c b/src/lib/libast/sfio/sfseek.c
new file mode 100644
index 0000000..1f446ba
--- /dev/null
+++ b/src/lib/libast/sfio/sfseek.c
@@ -0,0 +1,281 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Set the IO pointer to a specific location in the stream
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+static void newpos(Sfio_t* f, Sfoff_t p)
+#else
+static void newpos(f, p)
+Sfio_t* f;
+Sfoff_t p;
+#endif
+{
+#ifdef MAP_TYPE
+ if((f->bits&SF_MMAP) && f->data)
+ { SFMUNMAP(f, f->data, f->endb-f->data);
+ f->data = NIL(uchar*);
+ }
+#endif
+ f->next = f->endr = f->endw = f->data;
+ f->endb = (f->mode&SF_WRITE) ? f->data+f->size : f->data;
+ if((f->here = p) < 0)
+ { f->extent = -1;
+ f->here = 0;
+ }
+}
+
+#if __STD_C
+Sfoff_t sfseek(Sfio_t* f, Sfoff_t p, int type)
+#else
+Sfoff_t sfseek(f,p,type)
+Sfio_t* f; /* seek to a new location in this stream */
+Sfoff_t p; /* place to seek to */
+int type; /* 0: from org, 1: from here, 2: from end */
+#endif
+{
+ Sfoff_t r, s;
+ int mode, local, hardseek, mustsync;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f, (Sfoff_t)(-1));
+
+ GETLOCAL(f,local);
+
+ hardseek = (type|f->flags)&(SF_SHARE|SF_PUBLIC);
+
+ if(hardseek && f->mode == (SF_READ|SF_SYNCED) )
+ { newpos(f,f->here);
+ f->mode = SF_READ;
+ }
+
+ /* set and initialize the stream to a definite mode */
+ if((int)SFMODE(f,local) != (mode = f->mode&SF_RDWR))
+ { int flags = f->flags;
+
+ if(hardseek&SF_PUBLIC) /* seek ptr must follow file descriptor */
+ f->flags |= SF_SHARE|SF_PUBLIC;
+ mode = _sfmode(f,mode,local);
+ if(hardseek&SF_PUBLIC)
+ f->flags = flags;
+
+ if(mode < 0)
+ SFMTXRETURN(f, (Sfoff_t)(-1));
+ }
+
+ mustsync = (type&SF_SHARE) && !(type&SF_PUBLIC) &&
+ (f->mode&SF_READ) && !(f->flags&SF_STRING);
+
+ /* Xopen-compliant */
+ if((type &= (SEEK_SET|SEEK_CUR|SEEK_END)) != SEEK_SET &&
+ type != SEEK_CUR && type != SEEK_END )
+ { errno = EINVAL;
+ SFMTXRETURN(f, (Sfoff_t)(-1));
+ }
+
+ if(f->extent < 0)
+ { /* let system call set errno */
+ (void)SFSK(f,(Sfoff_t)0,SEEK_CUR,f->disc);
+ SFMTXRETURN(f, (Sfoff_t)(-1));
+ }
+
+ /* throw away ungetc data */
+ if(f->disc == _Sfudisc)
+ (void)sfclose((*_Sfstack)(f,NIL(Sfio_t*)));
+
+ /* lock the stream for internal manipulations */
+ SFLOCK(f,local);
+
+ /* clear error and eof bits */
+ f->flags &= ~(SF_EOF|SF_ERROR);
+
+ while(f->flags&SF_STRING)
+ { SFSTRSIZE(f);
+
+ if(type == SEEK_CUR)
+ r = p + (f->next - f->data);
+ else if(type == SEEK_END)
+ r = p + f->extent;
+ else r = p;
+
+ if(r >= 0 && r <= f->size)
+ { p = r;
+ f->next = f->data+p;
+ f->here = p;
+ if(p > f->extent)
+ memclear((char*)(f->data+f->extent),(int)(p-f->extent));
+ goto done;
+ }
+
+ /* check exception handler, note that this may pop stream */
+ if(SFSK(f,r,SEEK_SET,f->disc) != r)
+ { p = -1;
+ goto done;
+ }
+ else if(!(f->flags&SF_STRING))
+ { p = r;
+ goto done;
+ }
+ }
+
+ if(f->mode&SF_WRITE)
+ { /* see if we can avoid flushing buffer */
+ if(!hardseek && type < SEEK_END && !(f->flags&SF_APPENDWR) )
+ { s = f->here + (f->next - f->data);
+ r = p + (type == SEEK_SET ? 0 : s);
+ if(r == s)
+ { p = r;
+ goto done;
+ }
+ }
+
+ if(f->next > f->data && SFSYNC(f) < 0)
+ { p = -1;
+ goto done;
+ }
+ }
+
+ if(type == SEEK_END || (f->mode&SF_WRITE) )
+ { if((hardseek&SF_PUBLIC) || type == SEEK_END)
+ p = SFSK(f, p, type, f->disc);
+ else
+ { r = p + (type == SEEK_CUR ? f->here : 0);
+ p = (hardseek || r != f->here) ? SFSK(f,r,SEEK_SET,f->disc) : r;
+ }
+ if(p >= 0)
+ newpos(f,p);
+
+ goto done;
+ }
+
+ /* if get here, must be a read stream */
+ s = f->here - (f->endb - f->next);
+ r = p + (type == SEEK_CUR ? s : 0);
+ if(r <= f->here && r >= (f->here - (f->endb-f->data)) )
+ { if((hardseek || (type == SEEK_CUR && p == 0)) )
+ { if((s = SFSK(f, (Sfoff_t)0, SEEK_CUR, f->disc)) == f->here ||
+ (s >= 0 && !(hardseek&SF_PUBLIC) &&
+ (s = SFSK(f, f->here, SEEK_SET, f->disc)) == f->here) )
+ goto near_done;
+ else if(s < 0)
+ { p = -1;
+ goto done;
+ }
+ else
+ { newpos(f,s);
+ hardseek = 0;
+ }
+ }
+ else
+ { near_done:
+ f->next = f->endb - (f->here - r);
+ p = r;
+ goto done;
+ }
+ }
+
+ /* desired position */
+ if((p += type == SEEK_CUR ? s : 0) < 0)
+ goto done;
+
+#ifdef MAP_TYPE
+ if(f->bits&SF_MMAP)
+ { /* if mmap is not great, stop mmaping if moving around too much */
+#if _mmap_worthy < 2
+ if((f->next - f->data) < ((f->endb - f->data)/4) )
+ { SFSETBUF(f,(Void_t*)f->tiny,(size_t)SF_UNBOUND);
+ hardseek = 1; /* this forces a hard seek below */
+ }
+ else
+#endif
+ { /* for mmap, f->here can be virtual except for hardseek */
+ newpos(f,p);
+ if(!hardseek)
+ goto done;
+ }
+ }
+#endif
+
+ if(f->endb > f->next)
+ { /* reduce wastage in future buffer fillings */
+ f->iosz = (f->next - f->data) + (f->endb - f->next)/2;
+ f->iosz = ((f->iosz + f->blksz-1)/f->blksz)*f->blksz;
+ }
+ if(f->iosz >= f->size)
+ f->iosz = 0;
+
+ /* buffer is now considered empty */
+ f->next = f->endr = f->endb = f->data;
+
+ /* small backseeks often come in bunches, so seek back as far as possible */
+ if(p < f->lpos && f->size > f->blksz && (p + f->blksz) > s)
+ { if((r = s - f->size) < 0)
+ r = 0;
+ }
+ /* try to align buffer to block boundary to enhance I/O speed */
+ else if(f->blksz > 0 && f->size >= 2*f->blksz)
+ r = p - (p%f->blksz);
+ else
+ { r = p;
+
+ /* seeking around and wasting data, be conservative */
+ if(f->iosz > 0 && (p > f->lpos || p < f->lpos-f->size) )
+ f->bits |= SF_JUSTSEEK;
+ }
+
+ if((hardseek || r != f->here) && (f->here = SFSK(f,r,SEEK_SET,f->disc)) != r)
+ { if(r < p) /* now try to just get to p */
+ f->here = SFSK(f,p,SEEK_SET,f->disc);
+ if(f->here != p)
+ p = -1;
+ goto done;
+ }
+
+ if(r < p) /* read to cover p */
+ { (void)SFRD(f, f->data, f->size, f->disc);
+ if(p <= f->here && p >= (f->here - (f->endb - f->data)) )
+ f->next = f->endb - (size_t)(f->here-p);
+ else /* recover from read failure by just seeking to p */
+ { f->next = f->endb = f->data;
+ if((f->here = SFSK(f,p,SEEK_SET,f->disc)) != p)
+ p = -1;
+ }
+ }
+
+done :
+ if(f->here < 0) /* hasn't been the best of time */
+ { f->extent = -1;
+ f->here = 0;
+ }
+
+ f->lpos = p;
+
+ SFOPEN(f,local);
+
+ if(mustsync)
+ sfsync(f);
+ SFMTXRETURN(f, p);
+}
diff --git a/src/lib/libast/sfio/sfset.c b/src/lib/libast/sfio/sfset.c
new file mode 100644
index 0000000..a18662e
--- /dev/null
+++ b/src/lib/libast/sfio/sfset.c
@@ -0,0 +1,99 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Set some control flags or file descript for the stream
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+int sfset(Sfio_t* f, int flags, int set)
+#else
+int sfset(f,flags,set)
+Sfio_t* f;
+int flags;
+int set;
+#endif
+{
+ reg int oflags, tflags, rv;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f,0);
+
+ if(flags == 0 && set == 0)
+ SFMTXRETURN(f, (f->flags&SF_FLAGS));
+
+ if((oflags = (f->mode&SF_RDWR)) != (int)f->mode)
+ { /* avoid sfsetbuf() isatty() call if user sets (SF_LINE|SF_WCWIDTH) */
+ if(set && (flags & (SF_LINE|SF_WCWIDTH)) && !(f->flags & (SF_LINE|SF_WCWIDTH)))
+ { tflags = (SF_LINE|SF_WCWIDTH);
+ f->flags |= tflags;
+ }
+ else tflags = 0;
+ rv = _sfmode(f,oflags,0);
+ if(tflags)
+ f->flags &= ~tflags;
+ if(rv < 0)
+ SFMTXRETURN(f, 0);
+ }
+ if(flags == 0)
+ SFMTXRETURN(f, (f->flags&SF_FLAGS));
+
+ SFLOCK(f,0);
+
+ /* preserve at least one rd/wr flag */
+ oflags = f->flags;
+ if(!(f->bits&SF_BOTH) || (flags&SF_RDWR) == SF_RDWR )
+ flags &= ~SF_RDWR;
+
+ /* set the flag */
+ if(set)
+ f->flags |= (flags&SF_SETS);
+ else f->flags &= ~(flags&SF_SETS);
+
+ /* must have at least one of read/write */
+ if(!(f->flags&SF_RDWR))
+ f->flags |= (oflags&SF_RDWR);
+
+ if(f->extent < 0)
+ f->flags &= ~SF_APPENDWR;
+
+ /* turn to appropriate mode as necessary */
+ if((flags &= SF_RDWR) )
+ { if(!set)
+ { if(flags == SF_READ)
+ flags = SF_WRITE;
+ else flags = SF_READ;
+ }
+ if((flags == SF_WRITE && !(f->mode&SF_WRITE)) ||
+ (flags == SF_READ && !(f->mode&(SF_READ|SF_SYNCED))) )
+ (void)_sfmode(f,flags,1);
+ }
+
+ /* if not shared or unseekable, public means nothing */
+ if(!(f->flags&SF_SHARE) || f->extent < 0)
+ f->flags &= ~SF_PUBLIC;
+
+ SFOPEN(f,0);
+ SFMTXRETURN(f, (oflags&SF_FLAGS));
+}
diff --git a/src/lib/libast/sfio/sfsetbuf.c b/src/lib/libast/sfio/sfsetbuf.c
new file mode 100644
index 0000000..cb0240b
--- /dev/null
+++ b/src/lib/libast/sfio/sfsetbuf.c
@@ -0,0 +1,426 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide getpagesize
+#else
+#define getpagesize ______getpagesize
+#endif
+
+#include "sfhdr.h"
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide getpagesize
+#else
+#undef getpagesize
+#endif
+
+#if _lib_getpagesize
+_BEGIN_EXTERNS_
+extern int getpagesize _ARG_((void));
+_END_EXTERNS_
+#endif
+
+/* Set a (new) buffer for a stream.
+** If size < 0, it is assigned a suitable value depending on the
+** kind of stream. The actual buffer size allocated is dependent
+** on how much memory is available.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if !_sys_stat
+struct stat
+{ int st_mode;
+ int st_size;
+};
+#undef sysfstatf
+#define sysfstatf(fd,st) (-1)
+#endif /*_sys_stat*/
+
+#if _PACKAGE_ast && !defined(SFSETLINEMODE)
+#define SFSETLINEMODE 1
+#endif
+
+#if SFSETLINEMODE
+
+static int sfsetlinemode()
+{ char* astsfio;
+ char* endw;
+
+ static int modes = -1;
+ static const char sf_line[] = "SF_LINE";
+ static const char sf_maxr[] = "SF_MAXR=";
+ static const char sf_wcwidth[] = "SF_WCWIDTH";
+
+#define ISSEPAR(c) ((c) == ',' || (c) == ' ' || (c) == '\t')
+ if (modes < 0)
+ { modes = 0;
+ if(astsfio = getenv("SFIO_OPTIONS"))
+ { for(; *astsfio != 0; astsfio = endw)
+ { while(ISSEPAR(*astsfio) )
+ ++astsfio;
+ for(endw = astsfio; *endw && !ISSEPAR(*endw); ++endw)
+ ;
+ if((endw-astsfio) > (sizeof(sf_line)-1) &&
+ strncmp(astsfio,sf_line,sizeof(sf_line)-1) == 0)
+ modes |= SF_LINE;
+ else if((endw-astsfio) > (sizeof(sf_maxr)-1) &&
+ strncmp(astsfio,sf_maxr,sizeof(sf_maxr)-1) == 0)
+#if _PACKAGE_ast
+ _Sfmaxr = (ssize_t)strtonll(astsfio+sizeof(sf_maxr)-1,NiL,NiL,0);
+#else
+ _Sfmaxr = (ssize_t)strtol(astsfio+sizeof(sf_maxr)-1,NiL,0);
+#endif
+ else if((endw-astsfio) > (sizeof(sf_wcwidth)-1) &&
+ strncmp(astsfio,sf_wcwidth,sizeof(sf_wcwidth)-1) == 0)
+ modes |= SF_WCWIDTH;
+ }
+ }
+ }
+ return modes;
+}
+
+#endif
+
+#if __STD_C
+Void_t* sfsetbuf(Sfio_t* f, Void_t* buf, size_t size)
+#else
+Void_t* sfsetbuf(f,buf,size)
+Sfio_t* f; /* stream to be buffered */
+Void_t* buf; /* new buffer */
+size_t size; /* buffer size, -1 for default size */
+#endif
+{
+ int sf_malloc, oflags, init, okmmap, local;
+ ssize_t bufsize, blksz;
+ Sfdisc_t* disc;
+ sfstat_t st;
+ uchar* obuf = NIL(uchar*);
+ ssize_t osize = 0;
+ SFMTXDECL(f);
+
+ SFONCE();
+
+ SFMTXENTER(f,NIL(Void_t*));
+
+ GETLOCAL(f,local);
+
+ if(size == 0 && buf)
+ { /* special case to get buffer info */
+ _Sfi = f->val = (f->bits&SF_MMAP) ? (f->endb-f->data) : f->size;
+ SFMTXRETURN(f, (Void_t*)f->data);
+ }
+
+ /* cleanup actions already done, don't allow write buffering any more */
+ if(_Sfexiting && !(f->flags&SF_STRING) && (f->mode&SF_WRITE))
+ { buf = NIL(Void_t*);
+ size = 0;
+ }
+
+ if((init = f->mode&SF_INIT) )
+ { if(!f->pool && _sfsetpool(f) < 0)
+ SFMTXRETURN(f, NIL(Void_t*));
+ }
+ else if((f->mode&SF_RDWR) != SFMODE(f,local) && _sfmode(f,0,local) < 0)
+ SFMTXRETURN(f, NIL(Void_t*));
+
+ if(init)
+ f->mode = (f->mode&SF_RDWR)|SF_LOCK;
+ else
+ { int rv;
+
+ /* make sure there is no hidden read data */
+ if(f->proc && (f->flags&SF_READ) && (f->mode&SF_WRITE) &&
+ _sfmode(f,SF_READ,local) < 0)
+ SFMTXRETURN(f, NIL(Void_t*));
+
+ /* synchronize first */
+ SFLOCK(f,local); rv = SFSYNC(f); SFOPEN(f,local);
+ if(rv < 0)
+ SFMTXRETURN(f, NIL(Void_t*));
+
+ /* turn off the SF_SYNCED bit because buffer is changing */
+ f->mode &= ~SF_SYNCED;
+ }
+
+ SFLOCK(f,local);
+
+ if((Sfio_t*)buf != f)
+ blksz = -1;
+ else /* setting alignment size only */
+ { blksz = (ssize_t)size;
+
+ if(!init) /* stream already initialized */
+ { obuf = f->data;
+ osize = f->size;
+ goto done;
+ }
+ else /* initialize stream as if in the default case */
+ { buf = NIL(Void_t*);
+ size = (size_t)SF_UNBOUND;
+ }
+ }
+
+ bufsize = 0;
+ oflags = f->flags;
+
+ /* see if memory mapping is possible (see sfwrite for SF_BOTH) */
+ okmmap = (buf || (f->flags&SF_STRING) || (f->flags&SF_RDWR) == SF_RDWR) ? 0 : 1;
+
+ /* save old buffer info */
+#ifdef MAP_TYPE
+ if(f->bits&SF_MMAP)
+ { if(f->data)
+ { SFMUNMAP(f,f->data,f->endb-f->data);
+ f->data = NIL(uchar*);
+ }
+ } else
+#endif
+ if(f->data == f->tiny)
+ { f->data = NIL(uchar*);
+ f->size = 0;
+ }
+ obuf = f->data;
+ osize = f->size;
+
+ f->flags &= ~SF_MALLOC;
+ f->bits &= ~SF_MMAP;
+
+ /* pure read/string streams must have a valid string */
+ if((f->flags&(SF_RDWR|SF_STRING)) == SF_RDSTR &&
+ (size == (size_t)SF_UNBOUND || !buf))
+ size = 0;
+
+ /* set disc to the first discipline with a seekf */
+ for(disc = f->disc; disc; disc = disc->disc)
+ if(disc->seekf)
+ break;
+
+ if((init || local) && !(f->flags&SF_STRING))
+ { /* ASSERT(f->file >= 0) */
+ st.st_mode = 0;
+
+ /* if has discipline, set size by discipline if possible */
+ if(!_sys_stat || disc)
+ { if((f->here = SFSK(f,(Sfoff_t)0,SEEK_CUR,disc)) < 0)
+ goto unseekable;
+ else
+ { Sfoff_t e;
+ if((e = SFSK(f,(Sfoff_t)0,SEEK_END,disc)) >= 0)
+ f->extent = e > f->here ? e : f->here;
+ (void)SFSK(f,f->here,SEEK_SET,disc);
+ goto setbuf;
+ }
+ }
+
+ /* get file descriptor status */
+ if(sysfstatf((int)f->file,&st) < 0)
+ f->here = -1;
+ else
+ {
+#if _sys_stat && _stat_blksize /* preferred io block size */
+ f->blksz = (size_t)st.st_blksize;
+#endif
+ bufsize = 64 * 1024;
+ if(S_ISDIR(st.st_mode) || (Sfoff_t)st.st_size < (Sfoff_t)SF_GRAIN)
+ okmmap = 0;
+ if(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))
+ f->here = SFSK(f,(Sfoff_t)0,SEEK_CUR,f->disc);
+ else f->here = -1;
+
+#if O_TEXT /* no memory mapping with O_TEXT because read()/write() alter data stream */
+ if(okmmap && f->here >= 0 &&
+ (sysfcntlf((int)f->file,F_GETFL,0) & O_TEXT) )
+ okmmap = 0;
+#endif
+ }
+
+#if SFSETLINEMODE
+ if(init)
+ f->flags |= sfsetlinemode();
+#endif
+
+ if(f->here >= 0)
+ { f->extent = (Sfoff_t)st.st_size;
+
+ /* seekable std-devices are share-public by default */
+ if(f == sfstdin || f == sfstdout || f == sfstderr)
+ f->flags |= SF_SHARE|SF_PUBLIC;
+ }
+ else
+ {
+ unseekable:
+ f->extent = -1;
+ f->here = 0;
+
+ if(init)
+ { if(S_ISCHR(st.st_mode) )
+ { int oerrno = errno;
+
+ bufsize = SF_GRAIN;
+
+ /* set line mode for terminals */
+ if(!(f->flags&(SF_LINE|SF_WCWIDTH)) && isatty(f->file))
+ f->flags |= SF_LINE|SF_WCWIDTH;
+#if _sys_stat
+ else /* special case /dev/null */
+ { reg int dev, ino;
+ static int null_checked, null_dev, null_ino;
+ dev = (int)st.st_dev;
+ ino = (int)st.st_ino;
+ if(!null_checked)
+ { if(sysstatf(DEVNULL,&st) < 0)
+ null_checked = -1;
+ else
+ { null_checked = 1;
+ null_dev = (int)st.st_dev;
+ null_ino = (int)st.st_ino;
+ }
+ }
+ if(null_checked >= 0 && dev == null_dev && ino == null_ino)
+ SFSETNULL(f);
+ }
+#endif
+ errno = oerrno;
+ }
+
+ /* initialize side buffer for r+w unseekable streams */
+ if(!f->proc && (f->bits&SF_BOTH) )
+ (void)_sfpopen(f,-1,-1,1);
+ }
+ }
+
+ /* set page size, this is also the desired default buffer size */
+ if(_Sfpage <= 0)
+ {
+#if _lib_getpagesize
+ if((_Sfpage = (size_t)getpagesize()) <= 0)
+#endif
+ _Sfpage = SF_PAGE;
+ }
+ }
+
+#ifdef MAP_TYPE
+ if(okmmap && size && (f->mode&SF_READ) && f->extent >= 0 )
+ { /* see if we can try memory mapping */
+ if(!disc)
+ for(disc = f->disc; disc; disc = disc->disc)
+ if(disc->readf)
+ break;
+ if(!disc)
+ { f->bits |= SF_MMAP;
+ if(size == (size_t)SF_UNBOUND)
+ { if(bufsize > _Sfpage)
+ size = bufsize * SF_NMAP;
+ else size = _Sfpage * SF_NMAP;
+ if(size > 256*1024)
+ size = 256*1024;
+ }
+ }
+ }
+#endif
+
+ /* get buffer space */
+setbuf:
+ if(size == (size_t)SF_UNBOUND)
+ { /* define a default size suitable for block transfer */
+ if(init && osize > 0)
+ size = osize;
+ else if(f == sfstderr && (f->mode&SF_WRITE))
+ size = 0;
+ else if(f->flags&SF_STRING )
+ size = SF_GRAIN;
+ else if((f->flags&SF_READ) && !(f->bits&SF_BOTH) &&
+ f->extent > 0 && f->extent < (Sfoff_t)_Sfpage )
+ size = (((size_t)f->extent + SF_GRAIN-1)/SF_GRAIN)*SF_GRAIN;
+ else if((ssize_t)(size = _Sfpage) < bufsize)
+ size = bufsize;
+
+ buf = NIL(Void_t*);
+ }
+
+ sf_malloc = 0;
+ if(size > 0 && !buf && !(f->bits&SF_MMAP))
+ { /* try to allocate a buffer */
+ if(obuf && size == (size_t)osize && init)
+ { buf = (Void_t*)obuf;
+ obuf = NIL(uchar*);
+ sf_malloc = (oflags&SF_MALLOC);
+ }
+ if(!buf)
+ { /* do allocation */
+ while(!buf && size > 0)
+ { if((buf = (Void_t*)malloc(size)) )
+ break;
+ else size /= 2;
+ }
+ if(size > 0)
+ sf_malloc = SF_MALLOC;
+ }
+ }
+
+ if(size == 0 && !(f->flags&SF_STRING) && !(f->bits&SF_MMAP) && (f->mode&SF_READ))
+ { /* use the internal buffer */
+ size = sizeof(f->tiny);
+ buf = (Void_t*)f->tiny;
+ }
+
+ /* set up new buffer */
+ f->size = size;
+ f->next = f->data = f->endr = f->endw = (uchar*)buf;
+ f->endb = (f->mode&SF_READ) ? f->data : f->data+size;
+ if(f->flags&SF_STRING)
+ { /* these fields are used to test actual size - see sfseek() */
+ f->extent = (!sf_malloc &&
+ ((f->flags&SF_READ) || (f->bits&SF_BOTH)) ) ? size : 0;
+ f->here = 0;
+
+ /* read+string stream should have all data available */
+ if((f->mode&SF_READ) && !sf_malloc)
+ f->endb = f->data+size;
+ }
+
+ f->flags = (f->flags & ~SF_MALLOC)|sf_malloc;
+
+ if(obuf && obuf != f->data && osize > 0 && (oflags&SF_MALLOC))
+ { free((Void_t*)obuf);
+ obuf = NIL(uchar*);
+ }
+
+done:
+ _Sfi = f->val = obuf ? osize : 0;
+
+ /* blksz is used for aligning disk block boundary while reading data to
+ ** optimize data transfer from disk (eg, via direct I/O). blksz can be
+ ** at most f->size/2 so that data movement in buffer can be optimized.
+ ** blksz should also be a power-of-2 for optimal disk seeks.
+ */
+ if(blksz <= 0 || (blksz & (blksz-1)) != 0 )
+ blksz = SF_GRAIN;
+ while(blksz > f->size/2)
+ blksz /= 2;
+ f->blksz = blksz;
+
+ SFOPEN(f,local);
+
+ SFMTXRETURN(f, (Void_t*)obuf);
+}
diff --git a/src/lib/libast/sfio/sfsetfd.c b/src/lib/libast/sfio/sfsetfd.c
new file mode 100644
index 0000000..9ca3732
--- /dev/null
+++ b/src/lib/libast/sfio/sfsetfd.c
@@ -0,0 +1,136 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Change the file descriptor
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+static int _sfdup(int fd, int newfd)
+#else
+static int _sfdup(fd,newfd)
+int fd;
+int newfd;
+#endif
+{
+ reg int dupfd;
+
+#ifdef F_DUPFD /* the simple case */
+ while((dupfd = sysfcntlf(fd,F_DUPFD,newfd)) < 0 && errno == EINTR)
+ errno = 0;
+ return dupfd;
+
+#else /* do it the hard way */
+ if((dupfd = sysdupf(fd)) < 0 || dupfd >= newfd)
+ return dupfd;
+
+ /* dup() succeeded but didn't get the right number, recurse */
+ newfd = _sfdup(fd,newfd);
+
+ /* close the one that didn't match */
+ CLOSE(dupfd);
+
+ return newfd;
+#endif
+}
+
+#if __STD_C
+int sfsetfd(Sfio_t* f, int newfd)
+#else
+int sfsetfd(f,newfd)
+Sfio_t *f;
+int newfd;
+#endif
+{
+ reg int oldfd;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f, -1);
+
+ if(f->flags&SF_STRING)
+ SFMTXRETURN(f, -1);
+
+ if((f->mode&SF_INIT) && f->file < 0)
+ { /* restoring file descriptor after a previous freeze */
+ if(newfd < 0)
+ SFMTXRETURN(f, -1);
+ }
+ else
+ { /* change file descriptor */
+ if((f->mode&SF_RDWR) != f->mode && _sfmode(f,0,0) < 0)
+ SFMTXRETURN(f, -1);
+ SFLOCK(f,0);
+
+ oldfd = f->file;
+ if(oldfd >= 0)
+ { if(newfd >= 0)
+ { if((newfd = _sfdup(oldfd,newfd)) < 0)
+ { SFOPEN(f,0);
+ SFMTXRETURN(f, -1);
+ }
+ CLOSE(oldfd);
+ }
+ else
+ { /* sync stream if necessary */
+ if(((f->mode&SF_WRITE) && f->next > f->data) ||
+ (f->mode&SF_READ) || f->disc == _Sfudisc)
+ { if(SFSYNC(f) < 0)
+ { SFOPEN(f,0);
+ SFMTXRETURN(f, -1);
+ }
+ }
+
+ if(((f->mode&SF_WRITE) && f->next > f->data) ||
+ ((f->mode&SF_READ) && f->extent < 0 &&
+ f->next < f->endb) )
+ { SFOPEN(f,0);
+ SFMTXRETURN(f, -1);
+ }
+
+#ifdef MAP_TYPE
+ if((f->bits&SF_MMAP) && f->data)
+ { SFMUNMAP(f,f->data,f->endb-f->data);
+ f->data = NIL(uchar*);
+ }
+#endif
+
+ /* make stream appears uninitialized */
+ f->endb = f->endr = f->endw = f->data;
+ f->extent = f->here = 0;
+ f->mode = (f->mode&SF_RDWR)|SF_INIT;
+ f->bits &= ~SF_NULL; /* off /dev/null handling */
+ }
+ }
+
+ SFOPEN(f,0);
+ }
+
+ /* notify changes */
+ if(_Sfnotify)
+ (*_Sfnotify)(f, SF_SETFD, (void*)((long)newfd));
+
+ f->file = newfd;
+
+ SFMTXRETURN(f,newfd);
+}
diff --git a/src/lib/libast/sfio/sfsize.c b/src/lib/libast/sfio/sfsize.c
new file mode 100644
index 0000000..7b6d4aa
--- /dev/null
+++ b/src/lib/libast/sfio/sfsize.c
@@ -0,0 +1,109 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Get the size of a stream.
+**
+** Written by Kiem-Phong Vo.
+*/
+#if __STD_C
+Sfoff_t sfsize(Sfio_t* f)
+#else
+Sfoff_t sfsize(f)
+Sfio_t* f;
+#endif
+{
+ Sfdisc_t* disc;
+ reg int mode;
+ Sfoff_t s;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f, (Sfoff_t)(-1));
+
+ if((mode = f->mode&SF_RDWR) != (int)f->mode && _sfmode(f,mode,0) < 0)
+ SFMTXRETURN(f, (Sfoff_t)(-1));
+
+ if(f->flags&SF_STRING)
+ { SFSTRSIZE(f);
+ SFMTXRETURN(f, f->extent);
+ }
+
+ SFLOCK(f,0);
+
+ s = f->here;
+
+ if(f->extent >= 0)
+ { if(f->flags&(SF_SHARE|SF_APPENDWR))
+ { for(disc = f->disc; disc; disc = disc->disc)
+ if(disc->seekf)
+ break;
+ if(!_sys_stat || disc)
+ { Sfoff_t e;
+ if((e = SFSK(f,0,SEEK_END,disc)) >= 0)
+ f->extent = e;
+ if(SFSK(f,f->here,SEEK_SET,disc) != f->here)
+ f->here = SFSK(f,(Sfoff_t)0,SEEK_CUR,disc);
+ }
+#if _sys_stat
+ else
+ { sfstat_t st;
+ if(sysfstatf(f->file,&st) < 0)
+ f->extent = -1;
+ else if((f->extent = st.st_size) < f->here)
+ f->here = SFSK(f,(Sfoff_t)0,SEEK_CUR,disc);
+ }
+#endif
+ }
+
+ if((f->flags&(SF_SHARE|SF_PUBLIC)) == (SF_SHARE|SF_PUBLIC))
+ f->here = SFSK(f,(Sfoff_t)0,SEEK_CUR,f->disc);
+ }
+
+ if(f->here != s && (f->mode&SF_READ) )
+ { /* buffered data is known to be invalid */
+#ifdef MAP_TYPE
+ if((f->bits&SF_MMAP) && f->data)
+ { SFMUNMAP(f,f->data,f->endb-f->data);
+ f->data = NIL(uchar*);
+ }
+#endif
+ f->next = f->endb = f->endr = f->endw = f->data;
+ }
+
+ if(f->here < 0)
+ f->extent = -1;
+ else if(f->extent < f->here)
+ f->extent = f->here;
+
+ if((s = f->extent) >= 0)
+ { if(f->flags&SF_APPENDWR)
+ s += (f->next - f->data);
+ else if(f->mode&SF_WRITE)
+ { s = f->here + (f->next - f->data);
+ if(s < f->extent)
+ s = f->extent;
+ }
+ }
+
+ SFOPEN(f,0);
+ SFMTXRETURN(f, s);
+}
diff --git a/src/lib/libast/sfio/sfsk.c b/src/lib/libast/sfio/sfsk.c
new file mode 100644
index 0000000..4b82a4d
--- /dev/null
+++ b/src/lib/libast/sfio/sfsk.c
@@ -0,0 +1,106 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Seek function that knows discipline
+**
+** Written by Kiem-Phong Vo.
+*/
+#if __STD_C
+Sfoff_t sfsk(Sfio_t* f, Sfoff_t addr, int type, Sfdisc_t* disc)
+#else
+Sfoff_t sfsk(f,addr,type,disc)
+Sfio_t* f;
+Sfoff_t addr;
+int type;
+Sfdisc_t* disc;
+#endif
+{
+ Sfoff_t p;
+ reg Sfdisc_t* dc;
+ reg ssize_t s;
+ reg int local, mode;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f, (Sfoff_t)(-1));
+
+ GETLOCAL(f,local);
+ if(!local && !(f->bits&SF_DCDOWN))
+ { if((mode = f->mode&SF_RDWR) != (int)f->mode && _sfmode(f,mode,0) < 0)
+ SFMTXRETURN(f, (Sfoff_t)(-1));
+ if(SFSYNC(f) < 0)
+ SFMTXRETURN(f, (Sfoff_t)(-1));
+#ifdef MAP_TYPE
+ if(f->mode == SF_READ && (f->bits&SF_MMAP) && f->data)
+ { SFMUNMAP(f, f->data, f->endb-f->data);
+ f->data = NIL(uchar*);
+ }
+#endif
+ f->next = f->endb = f->endr = f->endw = f->data;
+ }
+
+ if((type &= (SEEK_SET|SEEK_CUR|SEEK_END)) > SEEK_END)
+ SFMTXRETURN(f, (Sfoff_t)(-1));
+
+ for(;;)
+ { dc = disc;
+ if(f->flags&SF_STRING)
+ { SFSTRSIZE(f);
+ if(type == SEEK_SET)
+ s = (ssize_t)addr;
+ else if(type == SEEK_CUR)
+ s = (ssize_t)(addr + f->here);
+ else s = (ssize_t)(addr + f->extent);
+ }
+ else
+ { SFDISC(f,dc,seekf);
+ if(dc && dc->seekf)
+ { SFDCSK(f,addr,type,dc,p);
+ }
+ else
+ { p = syslseekf(f->file,(sfoff_t)addr,type);
+ }
+ if(p >= 0)
+ SFMTXRETURN(f,p);
+ s = -1;
+ }
+
+ if(local)
+ SETLOCAL(f);
+ switch(_sfexcept(f,SF_SEEK,s,dc))
+ {
+ case SF_EDISC:
+ case SF_ECONT:
+ if(f->flags&SF_STRING)
+ SFMTXRETURN(f, (Sfoff_t)s);
+ goto do_continue;
+ default:
+ SFMTXRETURN(f, (Sfoff_t)(-1));
+ }
+
+ do_continue:
+ for(dc = f->disc; dc; dc = dc->disc)
+ if(dc == disc)
+ break;
+ disc = dc;
+ }
+}
diff --git a/src/lib/libast/sfio/sfstack.c b/src/lib/libast/sfio/sfstack.c
new file mode 100644
index 0000000..bc2ab13
--- /dev/null
+++ b/src/lib/libast/sfio/sfstack.c
@@ -0,0 +1,115 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+
+/* Push/pop streams
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#define STKMTXLOCK(f1,f2) \
+ { if(f1) SFMTXLOCK(f1); \
+ if(f2) SFMTXLOCK(f2); \
+ }
+#define STKMTXRETURN(f1,f2,rv) \
+ { if(f1) SFMTXUNLOCK(f1); \
+ if(f2) SFMTXUNLOCK(f2); \
+ return(rv); \
+ }
+
+#if __STD_C
+Sfio_t* sfstack(Sfio_t* f1, Sfio_t* f2)
+#else
+Sfio_t* sfstack(f1,f2)
+Sfio_t* f1; /* base of stack */
+Sfio_t* f2; /* top of stack */
+#endif
+{
+ reg int n;
+ reg Sfio_t* rf;
+ reg Sfrsrv_t* rsrv;
+ reg Void_t* mtx;
+
+ STKMTXLOCK(f1,f2);
+
+ if(f1 && (f1->mode&SF_RDWR) != f1->mode && _sfmode(f1,0,0) < 0)
+ STKMTXRETURN(f1,f2, NIL(Sfio_t*));
+ if(f2 && (f2->mode&SF_RDWR) != f2->mode && _sfmode(f2,0,0) < 0)
+ STKMTXRETURN(f1,f2, NIL(Sfio_t*));
+ if(!f1)
+ STKMTXRETURN(f1,f2, f2);
+
+ /* give access to other internal functions */
+ _Sfstack = sfstack;
+
+ if(f2 == SF_POPSTACK)
+ { if(!(f2 = f1->push))
+ STKMTXRETURN(f1,f2, NIL(Sfio_t*));
+ f2->mode &= ~SF_PUSH;
+ }
+ else
+ { if(f2->push)
+ STKMTXRETURN(f1,f2, NIL(Sfio_t*));
+ if(f1->pool && f1->pool != &_Sfpool && f1->pool != f2->pool &&
+ f1 == f1->pool->sf[0])
+ { /* get something else to pool front since f1 will be locked */
+ for(n = 1; n < f1->pool->n_sf; ++n)
+ { if(SFFROZEN(f1->pool->sf[n]) )
+ continue;
+ (*_Sfpmove)(f1->pool->sf[n],0);
+ break;
+ }
+ }
+ }
+
+ if(f2->pool && f2->pool != &_Sfpool && f2 != f2->pool->sf[0])
+ (*_Sfpmove)(f2,0);
+
+ /* swap streams */
+ sfswap(f1,f2);
+
+ /* but the reserved buffer and mutex must remain the same */
+ rsrv = f1->rsrv; f1->rsrv = f2->rsrv; f2->rsrv = rsrv;
+ mtx = f1->mutex; f1->mutex = f2->mutex; f2->mutex = mtx;
+
+ SFLOCK(f1,0);
+ SFLOCK(f2,0);
+
+ if(f2->push != f2)
+ { /* freeze the pushed stream */
+ f2->mode |= SF_PUSH;
+ f1->push = f2;
+ rf = f1;
+ }
+ else
+ { /* unfreeze the just exposed stream */
+ f1->mode &= ~SF_PUSH;
+ f2->push = NIL(Sfio_t*);
+ rf = f2;
+ }
+
+ SFOPEN(f1,0);
+ SFOPEN(f2,0);
+
+ STKMTXRETURN(f1,f2, rf);
+}
diff --git a/src/lib/libast/sfio/sfstrtod.c b/src/lib/libast/sfio/sfstrtod.c
new file mode 100644
index 0000000..375d09f
--- /dev/null
+++ b/src/lib/libast/sfio/sfstrtod.c
@@ -0,0 +1,157 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Convert a Sfdouble_t value represented in an ASCII format into
+** the internal Sfdouble_t representation.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#define BATCH (2*sizeof(int)) /* accumulate this many digits at a time */
+#define IPART 0 /* doing integer part */
+#define FPART 1 /* doing fractional part */
+#define EPART 2 /* doing exponent part */
+
+#if __STD_C
+static Sfdouble_t sfpow10(reg int n)
+#else
+static Sfdouble_t sfpow10(n)
+reg int n;
+#endif
+{
+ Sfdouble_t dval;
+
+ switch(n)
+ { case -3: return .001;
+ case -2: return .01;
+ case -1: return .1;
+ case 0: return 1.;
+ case 1: return 10.;
+ case 2: return 100.;
+ case 3: return 1000.;
+ }
+
+ if(n < 0)
+ { dval = .0001;
+ for(n += 4; n < 0; n += 1)
+ dval /= 10.;
+ }
+ else
+ { dval = 10000.;
+ for(n -= 4; n > 0; n -= 1)
+ dval *= 10.;
+ }
+
+ return dval;
+}
+
+#if __STD_C
+Sfdouble_t _sfstrtod(reg const char* s, char** retp)
+#else
+Sfdouble_t _sfstrtod(s,retp)
+reg char* s; /* string to convert */
+char** retp; /* to return the remainder of string */
+#endif
+{
+ reg int n, c, m;
+ reg int mode, fexp, sign, expsign;
+ Sfdouble_t dval;
+#if _lib_locale
+ int decpoint = 0;
+ int thousand = 0;
+ SFSETLOCALE(&decpoint,&thousand);
+#else
+#define decpoint '.'
+#endif
+
+ /* skip initial blanks */
+ while(isspace(*s))
+ ++s;
+
+ /* get the sign */
+ if((sign = (*s == '-')) || *s == '+')
+ s += 1;
+
+ mode = IPART;
+ fexp = expsign = 0;
+ dval = 0.;
+ while(*s)
+ { /* accumulate a handful of the digits */
+ for(m = BATCH, n = 0; m > 0; --m, ++s)
+ { /* get and process a char */
+ c = *s;
+ if(isdigit(c))
+ n = 10*n + (c - '0');
+ else break;
+ }
+
+ /* number of digits accumulated */
+ m = BATCH-m;
+
+ if(mode == IPART)
+ { /* doing the integer part */
+ if(dval == 0.)
+ dval = (Sfdouble_t)n;
+ else dval = dval*sfpow10(m) + (Sfdouble_t)n;
+ }
+ else if(mode == FPART)
+ { /* doing the fractional part */
+ fexp -= m;
+ if(n > 0)
+ dval += n*sfpow10(fexp);
+ }
+ else if(n)
+ { /* doing the exponent part */
+ if(expsign)
+ n = -n;
+ dval *= sfpow10(n);
+ }
+
+ if(!c)
+ break;
+
+ if(m < BATCH)
+ { /* detected a non-digit */
+ if(c == decpoint)
+ { /* start the fractional part or no match */
+ if(mode != IPART)
+ break;
+ mode = FPART;
+ s += 1;
+ }
+ else if(c == 'e' || c == 'E')
+ { if(mode == EPART)
+ break;
+ mode = EPART;
+ c = *++s;
+ if((expsign = (c == '-')) || c == '+')
+ s += 1;
+ }
+ else break;
+ }
+ }
+
+ if(retp)
+ *retp = (char*)s;
+ return sign ? -dval : dval;
+}
diff --git a/src/lib/libast/sfio/sfstrtof.h b/src/lib/libast/sfio/sfstrtof.h
new file mode 100644
index 0000000..37b28ec
--- /dev/null
+++ b/src/lib/libast/sfio/sfstrtof.h
@@ -0,0 +1,568 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * AT&T Research
+ * Glenn Fowler & Phong Vo
+ *
+ * common header and implementation for
+ *
+ * strtof strtod strtold _sfdscan
+ * strntof strntod strntold
+ *
+ * define these macros to instantiate an implementation:
+ *
+ * S2F_function the function name
+ * S2F_static <0:export =0:extern >0:static
+ * S2F_type 0:float 1:double 2:long.double
+ * S2F_qualifier 1 for optional [fFlL] qualifier suffix
+ * S2F_size 1 for interface with size_t second arg
+ * S2F_scan 1 for alternate interface with these arguments:
+ * void* handle
+ * int (*getchar)(void* handle, int flag)
+ * exactly one extra (*getchar)() is done, i.e.,
+ * the caller must do the pushback
+ * flag==0 get next char
+ * flag==1 no number seen
+ * return 0 on error or EOF
+ */
+
+#include "sfhdr.h"
+#include "FEATURE/float"
+
+/*
+ * the default is _sfdscan for standalone sfio compatibility
+ */
+
+#if !defined(S2F_function)
+#define S2F_function _sfdscan
+#define S2F_static 1
+#define S2F_type 2
+#define S2F_scan 1
+#ifndef elementsof
+#define elementsof(a) (sizeof(a)/sizeof(a[0]))
+#endif
+#endif
+
+#if S2F_type == 2 && _ast_fltmax_double
+#undef S2F_type
+#define S2F_type 1
+#endif
+
+#if S2F_type == 0
+#define S2F_number float
+#define S2F_ldexp ldexp
+#define S2F_pow10 _Sffpow10
+#define S2F_inf _Sffinf
+#define S2F_nan _Sffnan
+#define S2F_min (FLT_MIN)
+#define S2F_max (FLT_MAX)
+#define S2F_exp_10_min (FLT_MIN_10_EXP)
+#define S2F_exp_10_max (FLT_MAX_10_EXP)
+#define S2F_exp_2_min (FLT_MIN_EXP)
+#define S2F_exp_2_max (FLT_MAX_EXP)
+#endif
+#if S2F_type == 1
+#define S2F_number double
+#define S2F_ldexp ldexp
+#define S2F_pow10 _Sfdpow10
+#define S2F_inf _Sfdinf
+#define S2F_nan _Sfdnan
+#define S2F_min (DBL_MIN)
+#define S2F_max (DBL_MAX)
+#define S2F_exp_10_min (DBL_MIN_10_EXP)
+#define S2F_exp_10_max (DBL_MAX_10_EXP)
+#define S2F_exp_2_min (DBL_MIN_EXP)
+#define S2F_exp_2_max (DBL_MAX_EXP)
+#endif
+#if S2F_type == 2
+#define S2F_number long double
+#define S2F_ldexp ldexpl
+#define S2F_pow10 _Sflpow10
+#define S2F_inf _Sflinf
+#define S2F_nan _Sflnan
+#define S2F_min (LDBL_MIN)
+#define S2F_max (LDBL_MAX)
+#define S2F_exp_10_min (LDBL_MIN_10_EXP)
+#define S2F_exp_10_max (LDBL_MAX_10_EXP)
+#define S2F_exp_2_min (LDBL_MIN_EXP)
+#define S2F_exp_2_max (LDBL_MAX_EXP)
+#endif
+
+#if -S2F_exp_10_min < S2F_exp_10_max
+#define S2F_exp_10_abs (-S2F_exp_10_min)
+#else
+#define S2F_exp_10_abs S2F_exp_10_max
+#endif
+
+#define S2F_batch _ast_flt_unsigned_max_t
+
+#undef ERR /* who co-opted this namespace? */
+
+#if S2F_scan
+
+typedef int (*S2F_get_f)_ARG_((void*, int));
+
+#define ERR(e)
+#define GET(p) (*get)(p,0)
+#define NON(p) (*get)(p,1)
+#define PUT(p)
+#define REV(p,t,b)
+#define SET(p,t,b)
+
+#else
+
+#define ERR(e) (errno=(e))
+#define NON(p)
+
+#if S2F_size
+#define GET(p) (((p)<(z))?(*p++):(back=0))
+#define PUT(p) (end?(*end=(char*)p-back):(char*)0)
+#define REV(p,t,b) (p=t,back=b)
+#define SET(p,t,b) (t=p,b=back)
+#else
+#define GET(p) (*p++)
+#define PUT(p) (end?(*end=(char*)p-1):(char*)0)
+#define REV(p,t,b) (p=t)
+#define SET(p,t,b) (t=p)
+#endif
+
+#endif
+
+typedef struct S2F_part_s
+{
+ S2F_batch batch;
+ int digits;
+} S2F_part_t;
+
+#if !defined(ERANGE)
+#define ERANGE EINVAL
+#endif
+
+#if S2F_static > 0
+static
+#else
+#if S2F_static < 0 || !defined(S2F_static)
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+extern
+#undef extern
+#endif
+#endif
+S2F_number
+#if S2F_scan
+#if __STD_C
+S2F_function(void* s, S2F_get_f get)
+#else
+S2F_function(s, get) void* s; S2F_get_f get;
+#endif
+#else
+#if S2F_size
+#if __STD_C
+S2F_function(const char* str, size_t size, char** end)
+#else
+S2F_function(str, size, end) char* str; size_t size; char** end;
+#endif
+#else
+#if __STD_C
+S2F_function(const char* str, char** end)
+#else
+S2F_function(str, end) char* str; char** end;
+#endif
+#endif
+#endif
+{
+#if !S2F_scan
+ register unsigned char* s = (unsigned char*)str;
+#if S2F_size
+ register unsigned char* z = s + size;
+ int back = 1;
+ int b;
+#endif
+ unsigned char* t;
+#endif
+ register S2F_batch n;
+ register int c;
+ register int digits;
+ register int m;
+ register unsigned char* cv;
+ int negative;
+ int enegative;
+ int fraction;
+ int decimal = 0;
+ int thousand = 0;
+ int part = 0;
+ int back_part;
+ S2F_batch back_n;
+ S2F_number v;
+ S2F_number p;
+ S2F_part_t parts[16];
+
+ /*
+ * radix char and thousands separator are locale specific
+ */
+
+ SFSETLOCALE(&decimal, &thousand);
+ SFCVINIT();
+
+ /*
+ * skip initial blanks
+ */
+
+ do c = GET(s); while (isspace(c));
+ SET(s, t, b);
+
+ /*
+ * get the sign
+ */
+
+ if ((negative = (c == '-')) || c == '+')
+ c = GET(s);
+
+ /*
+ * drop leading 0's
+ */
+
+ digits = 0;
+ fraction = -1;
+ if (c == '0')
+ {
+ c = GET(s);
+ if (c == 'x' || c == 'X')
+ {
+ /*
+ * hex floating point -- easy
+ */
+
+ cv = _Sfcv36;
+ v = 0;
+ for (;;)
+ {
+ c = GET(s);
+ if ((part = cv[c]) < 16)
+ {
+ digits++;
+ v *= 16;
+ v += part;
+ }
+ else if (c == decimal)
+ {
+ decimal = -1;
+ fraction = digits;
+ }
+ else
+ break;
+ }
+ m = 0;
+ if (c == 'p' || c == 'P')
+ {
+ c = GET(s);
+ if ((enegative = c == '-') || c == '+')
+ c = GET(s);
+ while (c >= '0' && c <= '9')
+ {
+ m = (m << 3) + (m << 1) + (c - '0');
+ c = GET(s);
+ }
+ if (enegative)
+ m = -m;
+ }
+
+#if S2F_qualifier
+
+ /*
+ * consume the optional suffix
+ */
+
+ switch (c)
+ {
+ case 'f':
+ case 'F':
+ case 'l':
+ case 'L':
+ c = GET(s);
+ break;
+ }
+#endif
+ PUT(s);
+ if (v == 0)
+ return negative ? -v : v;
+ if (fraction >= 0)
+ m -= 4 * (digits - fraction);
+ if (m < S2F_exp_2_min)
+ {
+ if ((m -= S2F_exp_2_min) < S2F_exp_2_min)
+ {
+ ERR(ERANGE);
+ return 0;
+ }
+ v = S2F_ldexp(v, S2F_exp_2_min);
+ }
+ else if (m > S2F_exp_2_max)
+ {
+ ERR(ERANGE);
+ return negative ? -S2F_inf : S2F_inf;
+ }
+ v = S2F_ldexp(v, m);
+ goto check;
+ }
+ while (c == '0')
+ c = GET(s);
+ }
+ else if (c == decimal)
+ {
+ decimal = -1;
+ fraction = 0;
+ for (;;)
+ {
+ c = GET(s);
+ if (c != '0')
+ break;
+ digits++;
+ }
+ }
+ else if (c == 'i' || c == 'I')
+ {
+ if ((c = GET(s)) != 'n' && c != 'N' ||
+ (c = GET(s)) != 'f' && c != 'F')
+ {
+ REV(s, t, b);
+ PUT(s);
+ return 0;
+ }
+ c = GET(s);
+ SET(s, t, b);
+ if (((c) == 'i' || c == 'I') &&
+ ((c = GET(s)) == 'n' || c == 'N') &&
+ ((c = GET(s)) == 'i' || c == 'I') &&
+ ((c = GET(s)) == 't' || c == 'T') &&
+ ((c = GET(s)) == 'y' || c == 'Y'))
+ {
+ c = GET(s);
+ SET(s, t, b);
+ }
+ REV(s, t, b);
+ PUT(s);
+ return negative ? -S2F_inf : S2F_inf;
+ }
+ else if (c == 'n' || c == 'N')
+ {
+ if ((c = GET(s)) != 'a' && c != 'A' ||
+ (c = GET(s)) != 'n' && c != 'N')
+ {
+ REV(s, t, b);
+ PUT(s);
+ return 0;
+ }
+ do c = GET(s); while (c && !isspace(c));
+ PUT(s);
+ return negative ? -S2F_nan : S2F_nan;
+ }
+ else if (c < '1' || c > '9')
+ {
+ REV(s, t, b);
+ PUT(s);
+ NON(s);
+ return 0;
+ }
+
+ /*
+ * consume the integral and fractional parts
+ */
+
+ n = 0;
+ m = 0;
+ for (;;)
+ {
+ if (c >= '0' && c <= '9')
+ {
+ digits++;
+ n = (n << 3) + (n << 1) + (c - '0');
+ if (n >= ((~((S2F_batch)0)) / 10) && part < elementsof(parts))
+ {
+ parts[part].batch = n;
+ n = 0;
+ parts[part].digits = digits;
+ part++;
+ }
+ }
+ else if (m && (digits - m) != 3)
+ break;
+ else if (c == decimal)
+ {
+ decimal = -1;
+ thousand = -1;
+ m = 0;
+ fraction = digits;
+ }
+ else if (c != thousand)
+ break;
+ else if (!(m = digits))
+ {
+ SET(s, t, b);
+ break;
+ }
+ else
+ {
+ SET(s, t, b);
+ back_n = n;
+ back_part = part;
+ }
+ c = GET(s);
+ }
+ if (m && (digits - m) != 3)
+ {
+ REV(s, t, b);
+ n = back_n;
+ part = back_part;
+ }
+
+ /*
+ * don't forget the last part
+ */
+
+ if (n && part < elementsof(parts))
+ {
+ parts[part].batch = n;
+ parts[part].digits = digits;
+ part++;
+ }
+
+ /*
+ * consume the exponent
+ */
+
+ if (fraction >= 0)
+ digits = fraction;
+ if (c == 'e' || c == 'E')
+ {
+ c = GET(s);
+ if ((enegative = (c == '-')) || c == '+')
+ c = GET(s);
+ n = 0;
+ while (c >= '0' && c <= '9')
+ {
+ n = (n << 3) + (n << 1) + (c - '0');
+ c = GET(s);
+ }
+ if (enegative)
+ digits -= n;
+ else
+ digits += n;
+ }
+
+#if S2F_qualifier
+
+ /*
+ * consume the optional suffix
+ */
+
+ switch (c)
+ {
+ case 'f':
+ case 'F':
+ case 'l':
+ case 'L':
+ c = GET(s);
+ break;
+ }
+#endif
+ PUT(s);
+
+ /*
+ * adjust for at most one multiply per part
+ * and at most one divide overall
+ */
+
+ v = 0;
+ if (!part)
+ return negative ? -v : v;
+ else if ((m = parts[part-1].digits - digits) > 0)
+ digits += m;
+ else
+ m = 0;
+
+ /*
+ * combine the parts
+ */
+
+ while (part--)
+ {
+ p = parts[part].batch;
+ c = digits - parts[part].digits;
+ if (c > S2F_exp_10_max)
+ {
+ ERR(ERANGE);
+ return negative ? -S2F_inf : S2F_inf;
+ }
+ if (c > 0)
+ {
+#if _ast_mpy_overflow_fpe
+ if ((S2F_max / p) < S2F_pow10[c])
+ {
+ ERR(ERANGE);
+ return negative ? -S2F_inf : S2F_inf;
+ }
+#endif
+ p *= S2F_pow10[c];
+ }
+ v += p;
+ }
+ if (m)
+ {
+ while (m > S2F_exp_10_max)
+ {
+ m -= S2F_exp_10_max;
+ v /= S2F_pow10[S2F_exp_10_max];
+ }
+#if _ast_div_underflow_fpe
+ if ((S2F_min * p) > S2F_pow10[c])
+ {
+ ERR(ERANGE);
+ return negative ? -S2F_inf : S2F_inf;
+ }
+#endif
+ v /= S2F_pow10[m];
+ }
+
+ /*
+ * check the range
+ */
+
+ check:
+ if (v < S2F_min)
+ {
+ ERR(ERANGE);
+ v = 0;
+ }
+ else if (v > S2F_max)
+ {
+ ERR(ERANGE);
+ v = S2F_inf;
+ }
+
+ /*
+ * done
+ */
+
+ return negative ? -v : v;
+}
diff --git a/src/lib/libast/sfio/sfswap.c b/src/lib/libast/sfio/sfswap.c
new file mode 100644
index 0000000..4ffc614
--- /dev/null
+++ b/src/lib/libast/sfio/sfswap.c
@@ -0,0 +1,119 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Swap two streams. If the second argument is NULL,
+** a new stream will be created. Always return the second argument
+** or the new stream. Note that this function will always work
+** unless streams are locked by SF_PUSH.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+Sfio_t* sfswap(reg Sfio_t* f1, reg Sfio_t* f2)
+#else
+Sfio_t* sfswap(f1,f2)
+reg Sfio_t* f1;
+reg Sfio_t* f2;
+#endif
+{
+ Sfio_t tmp;
+ int f1pool, f2pool, f1mode, f2mode, f1flags, f2flags;
+
+ if(!f1 || (f1->mode&SF_AVAIL) || (SFFROZEN(f1) && (f1->mode&SF_PUSH)) )
+ return NIL(Sfio_t*);
+ if(f2 && SFFROZEN(f2) && (f2->mode&SF_PUSH) )
+ return NIL(Sfio_t*);
+ if(f1 == f2)
+ return f2;
+
+ f1mode = f1->mode;
+ SFLOCK(f1,0);
+ f1->mode |= SF_PUSH; /* make sure there is no recursion on f1 */
+
+ if(f2)
+ { f2mode = f2->mode;
+ SFLOCK(f2,0);
+ f2->mode |= SF_PUSH; /* make sure there is no recursion on f2 */
+ }
+ else
+ { f2 = f1->file == 0 ? sfstdin :
+ f1->file == 1 ? sfstdout :
+ f1->file == 2 ? sfstderr : NIL(Sfio_t*);
+ if((!f2 || !(f2->mode&SF_AVAIL)) )
+ { if(!(f2 = (Sfio_t*)malloc(sizeof(Sfio_t))) )
+ { f1->mode = f1mode;
+ SFOPEN(f1,0);
+ return NIL(Sfio_t*);
+ }
+
+ SFCLEAR(f2,NIL(Vtmutex_t*));
+ }
+ f2->mode = SF_AVAIL|SF_LOCK;
+ f2mode = SF_AVAIL;
+ }
+
+ if(!f1->pool)
+ f1pool = -1;
+ else for(f1pool = f1->pool->n_sf-1; f1pool >= 0; --f1pool)
+ if(f1->pool->sf[f1pool] == f1)
+ break;
+ if(!f2->pool)
+ f2pool = -1;
+ else for(f2pool = f2->pool->n_sf-1; f2pool >= 0; --f2pool)
+ if(f2->pool->sf[f2pool] == f2)
+ break;
+
+ f1flags = f1->flags;
+ f2flags = f2->flags;
+
+ /* swap image and pool entries */
+ memcpy((Void_t*)(&tmp),(Void_t*)f1,sizeof(Sfio_t));
+ memcpy((Void_t*)f1,(Void_t*)f2,sizeof(Sfio_t));
+ memcpy((Void_t*)f2,(Void_t*)(&tmp),sizeof(Sfio_t));
+ if(f2pool >= 0)
+ f1->pool->sf[f2pool] = f1;
+ if(f1pool >= 0)
+ f2->pool->sf[f1pool] = f2;
+
+ if(f2flags&SF_STATIC)
+ f2->flags |= SF_STATIC;
+ else f2->flags &= ~SF_STATIC;
+
+ if(f1flags&SF_STATIC)
+ f1->flags |= SF_STATIC;
+ else f1->flags &= ~SF_STATIC;
+
+ if(f2mode&SF_AVAIL) /* swapping to a closed stream */
+ { if(!(f1->flags&SF_STATIC) )
+ free(f1);
+ }
+ else
+ { f1->mode = f2mode;
+ SFOPEN(f1,0);
+ }
+
+ f2->mode = f1mode;
+ SFOPEN(f2,0);
+ return f2;
+}
diff --git a/src/lib/libast/sfio/sfsync.c b/src/lib/libast/sfio/sfsync.c
new file mode 100644
index 0000000..4a9d16f
--- /dev/null
+++ b/src/lib/libast/sfio/sfsync.c
@@ -0,0 +1,172 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Synchronize data in buffers with the file system.
+** If f is nil, all streams are sync-ed
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+static int _sfall(void)
+#else
+static int _sfall()
+#endif
+{
+ reg Sfpool_t *p, *next;
+ reg Sfio_t* f;
+ reg int n, rv;
+ reg int nsync, count, loop;
+#define MAXLOOP 3
+
+ for(loop = 0; loop < MAXLOOP; ++loop)
+ { rv = nsync = count = 0;
+ for(p = &_Sfpool; p; p = next)
+ { /* find the next legitimate pool */
+ for(next = p->next; next; next = next->next)
+ if(next->n_sf > 0)
+ break;
+
+ /* walk the streams for _Sfpool only */
+ for(n = 0; n < ((p == &_Sfpool) ? p->n_sf : 1); ++n)
+ { count += 1;
+ f = p->sf[n];
+
+ if(f->flags&SF_STRING )
+ goto did_sync;
+ if(SFFROZEN(f))
+ continue;
+ if((f->mode&SF_READ) && (f->mode&SF_SYNCED) )
+ goto did_sync;
+ if((f->mode&SF_READ) && !(f->bits&SF_MMAP) &&
+ f->next == f->endb)
+ goto did_sync;
+ if((f->mode&SF_WRITE) && !(f->bits&SF_HOLE) &&
+ f->next == f->data)
+ goto did_sync;
+
+ if(sfsync(f) < 0)
+ rv = -1;
+
+ did_sync:
+ nsync += 1;
+ }
+ }
+
+ if(nsync == count)
+ break;
+ }
+ return rv;
+}
+
+#if __STD_C
+int sfsync(reg Sfio_t* f)
+#else
+int sfsync(f)
+reg Sfio_t* f; /* stream to be synchronized */
+#endif
+{
+ int local, rv, mode, lock;
+ Sfio_t* origf;
+ SFMTXDECL(f);
+
+ if(!(origf = f) )
+ return _sfall();
+
+ SFMTXENTER(origf,-1);
+
+ GETLOCAL(origf,local);
+
+ if(origf->disc == _Sfudisc) /* throw away ungetc */
+ (void)sfclose((*_Sfstack)(origf,NIL(Sfio_t*)));
+
+ rv = 0;
+
+ lock = origf->mode&SF_LOCK;
+ if(origf->mode == (SF_SYNCED|SF_READ) ) /* already synced */
+ goto done;
+
+ if((origf->mode&SF_RDWR) != SFMODE(origf,local) && _sfmode(origf,0,local) < 0)
+ { rv = -1;
+ goto done;
+ }
+
+ for(; f; f = f->push)
+ {
+ if((f->flags&SF_IOCHECK) && f->disc && f->disc->exceptf)
+ (void)(*f->disc->exceptf)(f,SF_SYNC,(Void_t*)((int)1),f->disc);
+
+ SFLOCK(f,local);
+
+ /* pretend that this stream is not on a stack */
+ mode = f->mode&SF_PUSH;
+ f->mode &= ~SF_PUSH;
+
+ /* these streams do not need synchronization */
+ if((f->flags&SF_STRING) || (f->mode&SF_SYNCED))
+ goto next;
+
+ if((f->mode&SF_WRITE) && (f->next > f->data || (f->bits&SF_HOLE)) )
+ { /* sync the buffer, make sure pool don't move */
+ reg int pool = f->mode&SF_POOL;
+ f->mode &= ~SF_POOL;
+ if(f->next > f->data && (SFWRALL(f), SFFLSBUF(f,-1)) < 0)
+ rv = -1;
+ if(!SFISNULL(f) && (f->bits&SF_HOLE) )
+ { /* realize a previously created hole of 0's */
+ if(SFSK(f,(Sfoff_t)(-1),SEEK_CUR,f->disc) >= 0)
+ (void)SFWR(f,"",1,f->disc);
+ f->bits &= ~SF_HOLE;
+ }
+ f->mode |= pool;
+ }
+
+ if((f->mode&SF_READ) && f->extent >= 0 &&
+ ((f->bits&SF_MMAP) || f->next < f->endb) )
+ { /* make sure the file pointer is at the right place */
+ f->here -= (f->endb-f->next);
+ f->endr = f->endw = f->data;
+ f->mode = SF_READ|SF_SYNCED|lock;
+ (void)SFSK(f,f->here,SEEK_SET,f->disc);
+
+ if((f->flags&SF_SHARE) && !(f->flags&SF_PUBLIC) &&
+ !(f->bits&SF_MMAP) )
+ { f->endb = f->next = f->data;
+ f->mode &= ~SF_SYNCED;
+ }
+ }
+
+ next:
+ f->mode |= mode;
+ SFOPEN(f,local);
+
+ if((f->flags&SF_IOCHECK) && f->disc && f->disc->exceptf)
+ (void)(*f->disc->exceptf)(f,SF_SYNC,(Void_t*)((int)0),f->disc);
+ }
+
+done:
+ if(!local && f && (f->mode&SF_POOL) && f->pool && f != f->pool->sf[0])
+ SFSYNC(f->pool->sf[0]);
+
+ SFMTXRETURN(origf, rv);
+}
diff --git a/src/lib/libast/sfio/sftable.c b/src/lib/libast/sfio/sftable.c
new file mode 100644
index 0000000..c165bae
--- /dev/null
+++ b/src/lib/libast/sfio/sftable.c
@@ -0,0 +1,543 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+#include "FEATURE/float"
+
+/* Dealing with $ argument addressing stuffs.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+static char* sffmtint(const char* str, int* v)
+#else
+static char* sffmtint(str, v)
+char* str;
+int* v;
+#endif
+{
+ for(*v = 0; isdigit(*str); ++str)
+ *v = *v * 10 + (*str - '0');
+ *v -= 1;
+ return (char*)str;
+}
+
+#if __STD_C
+static Fmtpos_t* sffmtpos(Sfio_t* f,const char* form,va_list args,Sffmt_t* ft,int type)
+#else
+static Fmtpos_t* sffmtpos(f,form,args,ft,type)
+Sfio_t* f;
+char* form;
+va_list args;
+Sffmt_t* ft;
+int type; /* >0: scanf, =0: printf, -1: internal */
+#endif
+{
+ int base, fmt, flags, dot, width, precis;
+ ssize_t n_str, size;
+ char *t_str, *sp;
+ int v, n, skip, dollar, decimal, thousand;
+ Sffmt_t savft;
+ Fmtpos_t* fp; /* position array of arguments */
+ int argp, argn, maxp, need[FP_INDEX];
+#if _has_multibyte
+ SFMBDCL(fmbs)
+#endif
+
+ if(type < 0)
+ fp = NIL(Fmtpos_t*);
+ else if(!(fp = sffmtpos(f,form,args,ft,-1)) )
+ return NIL(Fmtpos_t*);
+
+ dollar = decimal = thousand = 0; argn = maxp = -1;
+ SFMBCLR(&fmbs);
+ while((n = *form) )
+ { if(n != '%') /* collect the non-pattern chars */
+ { sp = (char*)form;
+ for(;;)
+ { form += SFMBLEN(form, &fmbs);
+ if(*form == 0 || *form == '%')
+ break;
+ }
+ continue;
+ }
+ else form += 1;
+ if(*form == 0)
+ break;
+ else if(*form == '%')
+ { form += 1;
+ continue;
+ }
+
+ if(*form == '*' && type > 0) /* skip in scanning */
+ { skip = 1;
+ form += 1;
+ argp = -1;
+ }
+ else /* get the position of this argument */
+ { skip = 0;
+ sp = sffmtint(form,&argp);
+ if(*sp == '$')
+ { dollar = 1;
+ form = sp+1;
+ }
+ else argp = -1;
+ }
+
+ flags = dot = 0;
+ t_str = NIL(char*); n_str = 0;
+ size = width = precis = base = -1;
+ for(n = 0; n < FP_INDEX; ++n)
+ need[n] = -1;
+
+ loop_flags: /* LOOP FOR \0, %, FLAGS, WIDTH, PRECISION, BASE, TYPE */
+ switch((fmt = *form++) )
+ {
+ case LEFTP : /* get the type enclosed in balanced parens */
+ t_str = (char*)form;
+ for(v = 1;;)
+ { switch(*form++)
+ {
+ case 0 : /* not balancable, retract */
+ form = t_str;
+ t_str = NIL(char*);
+ n_str = 0;
+ goto loop_flags;
+ case LEFTP : /* increasing nested level */
+ v += 1;
+ continue;
+ case RIGHTP : /* decreasing nested level */
+ if((v -= 1) != 0)
+ continue;
+ n_str = form-t_str;
+ if(*t_str == '*')
+ { t_str = sffmtint(t_str+1,&n);
+ if(*t_str == '$')
+ dollar = 1;
+ else n = -1;
+ if((n = FP_SET(n,argn)) > maxp)
+ maxp = n;
+ if(fp && fp[n].ft.fmt == 0)
+ { fp[n].ft.fmt = LEFTP;
+ fp[n].ft.form = (char*)form;
+ }
+ need[FP_STR] = n;
+ }
+ goto loop_flags;
+ }
+ }
+
+ case '-' :
+ flags |= SFFMT_LEFT;
+ flags &= ~SFFMT_ZERO;
+ goto loop_flags;
+ case '0' :
+ if(!(flags&SFFMT_LEFT) )
+ flags |= SFFMT_ZERO;
+ goto loop_flags;
+ case ' ' :
+ if(!(flags&SFFMT_SIGN) )
+ flags |= SFFMT_BLANK;
+ goto loop_flags;
+ case '+' :
+ flags |= SFFMT_SIGN;
+ flags &= ~SFFMT_BLANK;
+ goto loop_flags;
+ case '#' :
+ flags |= SFFMT_ALTER;
+ goto loop_flags;
+ case QUOTE:
+ SFSETLOCALE(&decimal,&thousand);
+ if(thousand > 0)
+ flags |= SFFMT_THOUSAND;
+ goto loop_flags;
+
+ case '.' :
+ if((dot += 1) == 2)
+ base = 0; /* for %s,%c */
+ if(isdigit(*form))
+ { fmt = *form++;
+ goto dot_size;
+ }
+ else if(*form != '*')
+ goto loop_flags;
+ else form += 1; /* drop thru below */
+
+ case '*' :
+ form = sffmtint(form,&n);
+ if(*form == '$' )
+ { dollar = 1;
+ form += 1;
+ }
+ else n = -1;
+ if((n = FP_SET(n,argn)) > maxp)
+ maxp = n;
+ if(fp && fp[n].ft.fmt == 0)
+ { fp[n].ft.fmt = '.';
+ fp[n].ft.size = dot;
+ fp[n].ft.form = (char*)form;
+ }
+ if(dot <= 2)
+ need[dot] = n;
+ goto loop_flags;
+
+ case '1' : case '2' : case '3' :
+ case '4' : case '5' : case '6' :
+ case '7' : case '8' : case '9' :
+ dot_size :
+ for(v = fmt - '0', fmt = *form; isdigit(fmt); fmt = *++form)
+ v = v*10 + (fmt - '0');
+ if(dot == 0)
+ width = v;
+ else if(dot == 1)
+ precis = v;
+ else if(dot == 2)
+ base = v;
+ goto loop_flags;
+
+ case 'I' : /* object length */
+ size = -1; flags = (flags & ~SFFMT_TYPES) | SFFMT_IFLAG;
+ if(isdigit(*form) )
+ { for(size = 0, n = *form; isdigit(n); n = *++form)
+ size = size*10 + (n - '0');
+ }
+ else if(*form == '*')
+ { form = sffmtint(form+1,&n);
+ if(*form == '$' )
+ { dollar = 1;
+ form += 1;
+ }
+ else n = -1;
+ if((n = FP_SET(n,argn)) > maxp)
+ maxp = n;
+ if(fp && fp[n].ft.fmt == 0)
+ { fp[n].ft.fmt = 'I';
+ fp[n].ft.size = sizeof(int);
+ fp[n].ft.form = (char*)form;
+ }
+ need[FP_SIZE] = n;
+ }
+ goto loop_flags;
+
+ case 'l' :
+ size = -1; flags &= ~SFFMT_TYPES;
+ if(*form == 'l')
+ { form += 1;
+ flags |= SFFMT_LLONG;
+ }
+ else flags |= SFFMT_LONG;
+ goto loop_flags;
+ case 'h' :
+ size = -1; flags &= ~SFFMT_TYPES;
+ if(*form == 'h')
+ { form += 1;
+ flags |= SFFMT_SSHORT;
+ }
+ else flags |= SFFMT_SHORT;
+ goto loop_flags;
+ case 'L' :
+ size = -1; flags = (flags & ~SFFMT_TYPES) | SFFMT_LDOUBLE;
+ goto loop_flags;
+ }
+
+ /* set object size for scalars */
+ if(flags & SFFMT_TYPES)
+ { if((_Sftype[fmt]&(SFFMT_INT|SFFMT_UINT)) || fmt == 'n')
+ { if(flags&SFFMT_LONG)
+ size = sizeof(long);
+ else if(flags&SFFMT_SHORT)
+ size = sizeof(short);
+ else if(flags&SFFMT_SSHORT)
+ size = sizeof(char);
+ else if(flags&SFFMT_TFLAG)
+ size = sizeof(ptrdiff_t);
+ else if(flags&SFFMT_ZFLAG)
+ size = sizeof(size_t);
+ else if(flags&(SFFMT_LLONG|SFFMT_JFLAG) )
+ size = sizeof(Sflong_t);
+ else if(flags&SFFMT_IFLAG)
+ { if(size <= 0 ||
+ size == sizeof(Sflong_t)*CHAR_BIT )
+ size = sizeof(Sflong_t);
+ }
+ else if(size < 0)
+ size = sizeof(int);
+ }
+ else if(_Sftype[fmt]&SFFMT_FLOAT)
+ { if(flags&(SFFMT_LONG|SFFMT_LLONG))
+ size = sizeof(double);
+ else if(flags&SFFMT_LDOUBLE)
+ size = sizeof(Sfdouble_t);
+ else if(flags&SFFMT_IFLAG)
+ { if(size <= 0)
+ size = sizeof(Sfdouble_t);
+ }
+ else if(size < 0)
+ size = sizeof(float);
+ }
+ else if(_Sftype[fmt]&SFFMT_CHAR)
+ {
+#if _has_multibyte
+ if((flags&SFFMT_LONG) || fmt == 'C')
+ { size = sizeof(wchar_t) > sizeof(int) ?
+ sizeof(wchar_t) : sizeof(int);
+ } else
+#endif
+ if(size < 0)
+ size = sizeof(int);
+ }
+ }
+
+ if(skip)
+ continue;
+
+ if((argp = FP_SET(argp,argn)) > maxp)
+ maxp = argp;
+
+ if(dollar && fmt == '!')
+ return NIL(Fmtpos_t*);
+
+ if(fp && fp[argp].ft.fmt == 0)
+ { fp[argp].ft.form = (char*)form;
+ fp[argp].ft.fmt = fp[argp].fmt = fmt;
+ fp[argp].ft.size = size;
+ fp[argp].ft.flags = flags;
+ fp[argp].ft.width = width;
+ fp[argp].ft.precis = precis;
+ fp[argp].ft.base = base;
+ fp[argp].ft.t_str = t_str;
+ fp[argp].ft.n_str = n_str;
+ for(n = 0; n < FP_INDEX; ++n)
+ fp[argp].need[n] = need[n];
+ }
+ }
+
+ if(!fp) /* constructing position array only */
+ { if(!dollar || !(fp = (Fmtpos_t*)malloc((maxp+1)*sizeof(Fmtpos_t))) )
+ return NIL(Fmtpos_t*);
+ for(n = 0; n <= maxp; ++n)
+ fp[n].ft.fmt = 0;
+ return fp;
+ }
+
+ /* get value for positions */
+ if(ft)
+ memcpy(&savft, ft, sizeof(*ft));
+ for(n = 0; n <= maxp; ++n)
+ { if(fp[n].ft.fmt == 0) /* gap: pretend it's a 'd' pattern */
+ { fp[n].ft.fmt = 'd';
+ fp[n].ft.width = 0;
+ fp[n].ft.precis = 0;
+ fp[n].ft.base = 0;
+ fp[n].ft.size = 0;
+ fp[n].ft.t_str = 0;
+ fp[n].ft.n_str = 0;
+ fp[n].ft.flags = 0;
+ for(v = 0; v < FP_INDEX; ++v)
+ fp[n].need[v] = -1;
+ }
+
+ if(ft && ft->extf)
+ { fp[n].ft.version = ft->version;
+ fp[n].ft.extf = ft->extf;
+ fp[n].ft.eventf = ft->eventf;
+ if((v = fp[n].need[FP_WIDTH]) >= 0 && v < n)
+ fp[n].ft.width = fp[v].argv.i;
+ if((v = fp[n].need[FP_PRECIS]) >= 0 && v < n)
+ fp[n].ft.precis = fp[v].argv.i;
+ if((v = fp[n].need[FP_BASE]) >= 0 && v < n)
+ fp[n].ft.base = fp[v].argv.i;
+ if((v = fp[n].need[FP_STR]) >= 0 && v < n)
+ fp[n].ft.t_str = fp[v].argv.s;
+ if((v = fp[n].need[FP_SIZE]) >= 0 && v < n)
+ fp[n].ft.size = fp[v].argv.i;
+
+ memcpy(ft,&fp[n].ft,sizeof(Sffmt_t));
+ va_copy(ft->args,args);
+ ft->flags |= SFFMT_ARGPOS;
+ v = (*ft->extf)(f, (Void_t*)(&fp[n].argv), ft);
+ va_copy(args,ft->args);
+ memcpy(&fp[n].ft,ft,sizeof(Sffmt_t));
+ if(v < 0)
+ { memcpy(ft,&savft,sizeof(Sffmt_t));
+ ft = NIL(Sffmt_t*);
+ }
+
+ if(!(fp[n].ft.flags&SFFMT_VALUE) )
+ goto arg_list;
+ else if(_Sftype[fp[n].ft.fmt]&(SFFMT_INT|SFFMT_UINT) )
+ { if(fp[n].ft.size == sizeof(short))
+ { if(_Sftype[fp[n].ft.fmt]&SFFMT_INT)
+ fp[n].argv.i = fp[n].argv.h;
+ else fp[n].argv.i = fp[n].argv.uh;
+ }
+ else if(fp[n].ft.size == sizeof(char))
+ { if(_Sftype[fp[n].ft.fmt]&SFFMT_INT)
+ fp[n].argv.i = fp[n].argv.c;
+ else fp[n].argv.i = fp[n].argv.uc;
+ }
+ }
+ else if(_Sftype[fp[n].ft.fmt]&SFFMT_FLOAT )
+ { if(fp[n].ft.size == sizeof(float) )
+ fp[n].argv.d = fp[n].argv.f;
+ }
+ }
+ else
+ { arg_list:
+ if(fp[n].ft.fmt == LEFTP)
+ { fp[n].argv.s = va_arg(args, char*);
+ fp[n].ft.size = strlen(fp[n].argv.s);
+ }
+ else if(fp[n].ft.fmt == '.' || fp[n].ft.fmt == 'I')
+ fp[n].argv.i = va_arg(args, int);
+ else if(fp[n].ft.fmt == '!')
+ { if(ft)
+ memcpy(ft,&savft,sizeof(Sffmt_t));
+ fp[n].argv.ft = ft = va_arg(args, Sffmt_t*);
+ if(ft->form)
+ ft = NIL(Sffmt_t*);
+ if(ft)
+ memcpy(&savft,ft,sizeof(Sffmt_t));
+ }
+ else if(type > 0) /* from sfvscanf */
+ fp[n].argv.vp = va_arg(args, Void_t*);
+ else switch(_Sftype[fp[n].ft.fmt])
+ { case SFFMT_INT:
+ case SFFMT_UINT:
+#if !_ast_intmax_long
+ if(size == sizeof(Sflong_t) )
+ fp[n].argv.ll = va_arg(args, Sflong_t);
+ else
+#endif
+ if(size == sizeof(long) )
+ fp[n].argv.l = va_arg(args, long);
+ else fp[n].argv.i = va_arg(args, int);
+ break;
+ case SFFMT_FLOAT:
+#if !_ast_fltmax_double
+ if(size == sizeof(Sfdouble_t) )
+ fp[n].argv.ld = va_arg(args,Sfdouble_t);
+ else
+#endif
+ fp[n].argv.d = va_arg(args,double);
+ break;
+ case SFFMT_POINTER:
+ fp[n].argv.vp = va_arg(args,Void_t*);
+ break;
+ case SFFMT_CHAR:
+ if(fp[n].ft.base >= 0)
+ fp[n].argv.s = va_arg(args,char*);
+#if _has_multibyte
+ else if((fp[n].ft.flags & SFFMT_LONG) ||
+ fp[n].ft.fmt == 'C' )
+ { if(sizeof(wchar_t) <= sizeof(int) )
+ fp[n].argv.wc = (wchar_t)va_arg(args,int);
+ else fp[n].argv.wc = va_arg(args,wchar_t);
+ }
+#endif
+ /* observe promotion rule */
+ else fp[n].argv.i = va_arg(args,int);
+ break;
+ default: /* unknown pattern */
+ break;
+ }
+ }
+ }
+
+ if(ft)
+ memcpy(ft,&savft,sizeof(Sffmt_t));
+ return fp;
+}
+
+static const unsigned char flt_nan[] = { _ast_flt_nan_init };
+static const unsigned char flt_inf[] = { _ast_flt_inf_init };
+static const unsigned char dbl_nan[] = { _ast_dbl_nan_init };
+static const unsigned char dbl_inf[] = { _ast_dbl_inf_init };
+#ifdef _ast_ldbl_nan_init
+static const unsigned char ldbl_nan[] = { _ast_ldbl_nan_init };
+static const unsigned char ldbl_inf[] = { _ast_ldbl_inf_init };
+#endif
+
+/* function to initialize conversion tables */
+static int sfcvinit()
+{ reg int d, l;
+
+ for(d = 0; d <= SF_MAXCHAR; ++d)
+ { _Sfcv36[d] = SF_RADIX;
+ _Sfcv64[d] = SF_RADIX;
+ }
+
+ /* [0-9] */
+ for(d = 0; d < 10; ++d)
+ { _Sfcv36[(uchar)_Sfdigits[d]] = d;
+ _Sfcv64[(uchar)_Sfdigits[d]] = d;
+ }
+
+ /* [a-z] */
+ for(; d < 36; ++d)
+ { _Sfcv36[(uchar)_Sfdigits[d]] = d;
+ _Sfcv64[(uchar)_Sfdigits[d]] = d;
+ }
+
+ /* [A-Z] */
+ for(l = 10; d < 62; ++l, ++d)
+ { _Sfcv36[(uchar)_Sfdigits[d]] = l;
+ _Sfcv64[(uchar)_Sfdigits[d]] = d;
+ }
+
+ /* remaining digits */
+ for(; d < SF_RADIX; ++d)
+ { _Sfcv36[(uchar)_Sfdigits[d]] = d;
+ _Sfcv64[(uchar)_Sfdigits[d]] = d;
+ }
+
+ _Sftype['d'] = _Sftype['i'] = SFFMT_INT;
+ _Sftype['u'] = _Sftype['o'] = _Sftype['x'] = _Sftype['X'] = SFFMT_UINT;
+ _Sftype['e'] = _Sftype['E'] = _Sftype['a'] = _Sftype['A'] =
+ _Sftype['g'] = _Sftype['G'] = _Sftype['f'] = SFFMT_FLOAT;
+ _Sftype['s'] = _Sftype['n'] = _Sftype['p'] = _Sftype['!'] = SFFMT_POINTER;
+ _Sftype['c'] = SFFMT_CHAR;
+ _Sftype['['] = SFFMT_CLASS;
+#if _has_multibyte
+ _Sftype['S'] = SFFMT_POINTER;
+ _Sftype['C'] = SFFMT_CHAR;
+#endif
+
+ /* IEEE floating point computed constants */
+
+ memcpy((char*)&_Sffnan, (char*)flt_nan, sizeof(_Sffnan));
+ memcpy((char*)&_Sffinf, (char*)flt_inf, sizeof(_Sffinf));
+ memcpy((char*)&_Sfdnan, (char*)dbl_nan, sizeof(_Sfdnan));
+ memcpy((char*)&_Sfdinf, (char*)dbl_inf, sizeof(_Sfdinf));
+#ifdef _ast_ldbl_nan_init
+ memcpy((char*)&_Sflnan, (char*)ldbl_nan, sizeof(_Sflnan));
+ memcpy((char*)&_Sflinf, (char*)ldbl_inf, sizeof(_Sflinf));
+#else
+ memcpy((char*)&_Sflnan, (char*)dbl_nan, sizeof(_Sfdnan));
+ memcpy((char*)&_Sflinf, (char*)dbl_inf, sizeof(_Sfdinf));
+#endif
+
+ return 1;
+}
+
+/* table for floating point and integer conversions */
+#include "FEATURE/sfinit"
diff --git a/src/lib/libast/sfio/sftell.c b/src/lib/libast/sfio/sftell.c
new file mode 100644
index 0000000..49c183c
--- /dev/null
+++ b/src/lib/libast/sfio/sftell.c
@@ -0,0 +1,59 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Tell the current location in a given stream
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+Sfoff_t sftell(Sfio_t* f)
+#else
+Sfoff_t sftell(f)
+Sfio_t *f;
+#endif
+{
+ reg int mode;
+ Sfoff_t p;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f, (Sfoff_t)(-1));
+
+ /* set the stream to the right mode */
+ if((mode = f->mode&SF_RDWR) != (int)f->mode && _sfmode(f,mode,0) < 0)
+ SFMTXRETURN(f, (Sfoff_t)(-1));
+
+ /* throw away ungetc data */
+ if(f->disc == _Sfudisc)
+ (void)sfclose((*_Sfstack)(f,NIL(Sfio_t*)));
+
+ if(f->flags&SF_STRING)
+ SFMTXRETURN(f, (Sfoff_t)(f->next-f->data));
+
+ /* let sfseek() handle the hard case */
+ if(f->extent >= 0 && (f->flags&(SF_SHARE|SF_APPENDWR)) )
+ p = sfseek(f,(Sfoff_t)0,SEEK_CUR);
+ else p = f->here + ((f->mode&SF_WRITE) ? f->next-f->data : f->next-f->endb);
+
+ SFMTXRETURN(f,p);
+}
diff --git a/src/lib/libast/sfio/sftmp.c b/src/lib/libast/sfio/sftmp.c
new file mode 100644
index 0000000..4f804d6
--- /dev/null
+++ b/src/lib/libast/sfio/sftmp.c
@@ -0,0 +1,402 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Create a temporary stream for read/write.
+** The stream is originally created as a memory-resident stream.
+** When this memory is exceeded, a real temp file will be created.
+** The temp file creation sequence is somewhat convoluted so that
+** pool/stack/discipline will work correctly.
+**
+** Written by David Korn and Kiem-Phong Vo.
+*/
+
+#if _tmp_rmfail
+
+/* File not removable while there is an open file descriptor.
+** To ensure that temp files are properly removed, we need:
+** 1. A discipline to remove a file when the corresponding stream is closed.
+** Care must be taken to close the file descriptor before removing the
+** file because systems such as NT do not allow file removal while
+** there is an open file handle.
+** 2. An atexit() function is set up to close temp files when process exits.
+** 3. On systems with O_TEMPORARY (e.g., NT), this is used to further ensure
+** that temp files will be removed after the last handle is closed.
+*/
+
+typedef struct _file_s File_t;
+struct _file_s
+{ File_t* next; /* link list */
+ Sfio_t* f; /* associated stream */
+ char name[1]; /* temp file name */
+};
+
+static File_t* File; /* list pf temp files */
+
+#if __STD_C
+static int _tmprmfile(Sfio_t* f, int type, Void_t* val, Sfdisc_t* disc)
+#else
+static int _tmprmfile(f, type, val, disc)
+Sfio_t* f;
+int type;
+Void_t* val;
+Sfdisc_t* disc;
+#endif
+{
+ reg File_t *ff, *last;
+
+ NOTUSED(val);
+
+ if(type == SF_DPOP) /* don't allow this to pop */
+ return -1;
+
+ if(type == SF_CLOSING)
+ {
+ (void)vtmtxlock(_Sfmutex);
+ for(last = NIL(File_t*), ff = File; ff; last = ff, ff = ff->next)
+ if(ff->f == f)
+ break;
+ if(ff)
+ { if(!last)
+ File = ff->next;
+ else last->next = ff->next;
+
+ if(_Sfnotify)
+ (*_Sfnotify)(f,SF_CLOSING,f->file);
+ CLOSE(f->file);
+ f->file = -1;
+ while(sysremovef(ff->name) < 0 && errno == EINTR)
+ errno = 0;
+
+ free((Void_t*)ff);
+ }
+ (void)vtmtxunlock(_Sfmutex);
+ }
+
+ return 0;
+}
+
+#if __STD_C
+static void _rmfiles(void)
+#else
+static void _rmfiles()
+#endif
+{ reg File_t *ff, *next;
+
+ (void)vtmtxlock(_Sfmutex);
+ for(ff = File; ff; ff = next)
+ { next = ff->next;
+ _tmprmfile(ff->f, SF_CLOSING, NIL(Void_t*), ff->f->disc);
+ }
+ (void)vtmtxunlock(_Sfmutex);
+}
+
+static Sfdisc_t Rmdisc =
+ { NIL(Sfread_f), NIL(Sfwrite_f), NIL(Sfseek_f), _tmprmfile, NIL(Sfdisc_t*) };
+
+#endif /*_tmp_rmfail*/
+
+#if __STD_C
+static int _rmtmp(Sfio_t* f, char* file)
+#else
+static int _rmtmp(f, file)
+Sfio_t* f;
+char* file;
+#endif
+{
+#if _tmp_rmfail /* remove only when stream is closed */
+ reg File_t* ff;
+
+ if(!File)
+ atexit(_rmfiles);
+
+ if(!(ff = (File_t*)malloc(sizeof(File_t)+strlen(file))) )
+ return -1;
+ (void)vtmtxlock(_Sfmutex);
+ ff->f = f;
+ strcpy(ff->name,file);
+ ff->next = File;
+ File = ff;
+ (void)vtmtxunlock(_Sfmutex);
+
+#else /* can remove now */
+ while(sysremovef(file) < 0 && errno == EINTR)
+ errno = 0;
+#endif
+
+ return 0;
+}
+
+#if !_PACKAGE_ast
+#define TMPDFLT "/tmp"
+static char **Tmppath, **Tmpcur;
+
+#if __STD_C
+char** _sfgetpath(char* path)
+#else
+char** _sfgetpath(path)
+char* path;
+#endif
+{ reg char *p, **dirs;
+ reg int n;
+
+ if(!(path = getenv(path)) )
+ return NIL(char**);
+
+ for(p = path, n = 0;;) /* count number of directories */
+ { while(*p == ':')
+ ++p;
+ if(*p == 0)
+ break;
+ n += 1;
+ while(*p && *p != ':') /* skip dir name */
+ ++p;
+ }
+ if(n == 0 || !(dirs = (char**)malloc((n+1)*sizeof(char*))) )
+ return NIL(char**);
+ if(!(p = (char*)malloc(strlen(path)+1)) )
+ { free(dirs);
+ return NIL(char**);
+ }
+ strcpy(p,path);
+ for(n = 0;; ++n)
+ { while(*p == ':')
+ ++p;
+ if(*p == 0)
+ break;
+ dirs[n] = p;
+ while(*p && *p != ':')
+ ++p;
+ if(*p == ':')
+ *p++ = 0;
+ }
+ dirs[n] = NIL(char*);
+
+ return dirs;
+}
+
+#endif /*!_PACKAGE_ast*/
+
+#if __STD_C
+static int _tmpfd(Sfio_t* f)
+#else
+static int _tmpfd(f)
+Sfio_t* f;
+#endif
+{
+ reg char* file;
+ int fd;
+
+#if _PACKAGE_ast
+ if(!(file = pathtemp(NiL,PATH_MAX,NiL,"sf",&fd)))
+ return -1;
+ _rmtmp(f, file);
+ free(file);
+#else
+ int t;
+
+ /* set up path of dirs to create temp files */
+ if(!Tmppath && !(Tmppath = _sfgetpath("TMPPATH")) )
+ { if(!(Tmppath = (char**)malloc(2*sizeof(char*))) )
+ return -1;
+ if(!(file = getenv("TMPDIR")) )
+ file = TMPDFLT;
+ if(!(Tmppath[0] = (char*)malloc(strlen(file)+1)) )
+ { free(Tmppath);
+ Tmppath = NIL(char**);
+ return -1;
+ }
+ strcpy(Tmppath[0],file);
+ Tmppath[1] = NIL(char*);
+ }
+
+ /* set current directory to create this temp file */
+ if(Tmpcur)
+ Tmpcur += 1;
+ if(!Tmpcur || !Tmpcur[0])
+ Tmpcur = Tmppath;
+
+ fd = -1;
+ for(t = 0; t < 10; ++t)
+ { /* compute a random name */
+ static ulong Key, A;
+ if(A == 0 || t > 0) /* get a quasi-random coefficient */
+ { reg int r;
+ A = (ulong)time(NIL(time_t*)) ^ (((ulong)(&t)) >> 3);
+ if(Key == 0)
+ Key = (A >> 16) | ((A&0xffff)<<16);
+ A ^= Key;
+ if((r = (A-1) & 03) != 0) /* Knuth vol.2, page.16, Thm.A */
+ A += 4-r;
+ }
+
+ Key = A*Key + 987654321;
+ file = sfprints("%s/sf%3.3.32lu.%3.3.32lu",
+ Tmpcur[0], (Key>>15)&0x7fff, Key&0x7fff);
+ if(!file)
+ return -1;
+#if _has_oflags
+ if((fd = sysopenf(file,O_RDWR|O_CREAT|O_EXCL|O_TEMPORARY,SF_CREATMODE)) >= 0)
+ break;
+#else
+ if((fd = sysopenf(file,O_RDONLY)) >= 0)
+ { /* file already exists */
+ CLOSE(fd);
+ fd = -1;
+ }
+ else if((fd = syscreatf(file,SF_CREATMODE)) >= 0)
+ { /* reopen for read and write */
+ CLOSE(fd);
+ if((fd = sysopenf(file,O_RDWR)) >= 0)
+ break;
+
+ /* don't know what happened but must remove file */
+ while(sysremovef(file) < 0 && errno == EINTR)
+ errno = 0;
+ }
+#endif /* _has_oflags */
+ }
+ if(fd >= 0)
+ _rmtmp(f, file);
+#endif /* _PACKAGE_ast */
+ return fd;
+}
+
+#if __STD_C
+static int _tmpexcept(Sfio_t* f, int type, Void_t* val, Sfdisc_t* disc)
+#else
+static int _tmpexcept(f,type,val,disc)
+Sfio_t* f;
+int type;
+Void_t* val;
+Sfdisc_t* disc;
+#endif
+{
+ reg int fd, m;
+ reg Sfio_t* sf;
+ Sfio_t newf, savf;
+ void (*notifyf)_ARG_((Sfio_t*, int, void*));
+
+ NOTUSED(val);
+
+ /* the discipline needs to change only under the following exceptions */
+ if(type != SF_WRITE && type != SF_SEEK &&
+ type != SF_DPUSH && type != SF_DPOP && type != SF_DBUFFER)
+ return 0;
+
+ /* notify function */
+ notifyf = _Sfnotify;
+
+ /* try to create the temp file */
+ SFCLEAR(&newf,NIL(Vtmutex_t*));
+ newf.flags = SF_STATIC;
+ newf.mode = SF_AVAIL;
+
+ if((fd = _tmpfd(f)) < 0 )
+ return -1;
+
+ /* make sure that the notify function won't be called here since
+ we are only interested in creating the file, not the stream */
+ _Sfnotify = 0;
+ sf = sfnew(&newf,NIL(Void_t*),(size_t)SF_UNBOUND,fd,SF_READ|SF_WRITE);
+ _Sfnotify = notifyf;
+ if(!sf)
+ return -1;
+
+ if(newf.mutex) /* don't need a mutex for this stream */
+ { (void)vtmtxclrlock(newf.mutex);
+ (void)vtmtxclose(newf.mutex);
+ newf.mutex = NIL(Vtmutex_t*);
+ }
+
+ /* make sure that new stream has the same mode */
+ if((m = f->flags&(SF_READ|SF_WRITE)) != (SF_READ|SF_WRITE))
+ sfset(sf, ((~m)&(SF_READ|SF_WRITE)), 0);
+ sfset(sf, (f->mode&(SF_READ|SF_WRITE)), 1);
+
+ /* now remake the old stream into the new image */
+ memcpy((Void_t*)(&savf), (Void_t*)f, sizeof(Sfio_t));
+ memcpy((Void_t*)f, (Void_t*)sf, sizeof(Sfio_t));
+ f->push = savf.push;
+ f->pool = savf.pool;
+ f->rsrv = savf.rsrv;
+ f->proc = savf.proc;
+ f->mutex = savf.mutex;
+ f->stdio = savf.stdio;
+
+ if(savf.data)
+ { SFSTRSIZE(&savf);
+ if(!(savf.flags&SF_MALLOC) )
+ (void)sfsetbuf(f,(Void_t*)savf.data,savf.size);
+ if(savf.extent > 0)
+ (void)sfwrite(f,(Void_t*)savf.data,(size_t)savf.extent);
+ (void)sfseek(f,(Sfoff_t)(savf.next - savf.data),SEEK_SET);
+ if((savf.flags&SF_MALLOC) )
+ free((Void_t*)savf.data);
+ }
+
+ /* announce change of status */
+ if(notifyf)
+ (*notifyf)(f, SF_NEW, (void*)((long)f->file));
+
+ f->disc = disc->disc;
+
+ /* erase all traces of newf */
+ newf.data = newf.endb = newf.endr = newf.endw = NIL(uchar*);
+ newf.file = -1;
+ sfclose(&newf);
+
+ return 1;
+}
+
+#if __STD_C
+Sfio_t* sftmp(size_t s)
+#else
+Sfio_t* sftmp(s)
+size_t s;
+#endif
+{
+ Sfio_t* f;
+ static Sfdisc_t Tmpdisc =
+ { NIL(Sfread_f), NIL(Sfwrite_f), NIL(Sfseek_f), _tmpexcept,
+#if _tmp_rmfail
+ &Rmdisc
+#else
+ NIL(Sfdisc_t*)
+#endif
+ };
+
+ /* start with a memory resident stream */
+ if(!(f = sfnew(NIL(Sfio_t*),NIL(char*),s,-1,SF_STRING|SF_READ|SF_WRITE)) )
+ return NIL(Sfio_t*);
+
+ if(s != (size_t)SF_UNBOUND) /* set up a discipline for out-of-bound, etc. */
+ f->disc = &Tmpdisc;
+
+ /* make the file now */
+ if(s == 0 && _tmpexcept(f,SF_DPOP,NIL(Void_t*),f->disc) < 0)
+ { sfclose(f);
+ return NIL(Sfio_t*);
+ }
+
+ return f;
+}
diff --git a/src/lib/libast/sfio/sfungetc.c b/src/lib/libast/sfio/sfungetc.c
new file mode 100644
index 0000000..08ccc6d
--- /dev/null
+++ b/src/lib/libast/sfio/sfungetc.c
@@ -0,0 +1,108 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Push back one byte to a given SF_READ stream
+**
+** Written by Kiem-Phong Vo.
+*/
+#if __STD_C
+static int _uexcept(Sfio_t* f, int type, Void_t* val, Sfdisc_t* disc)
+#else
+static int _uexcept(f,type,val,disc)
+Sfio_t *f;
+int type;
+Void_t* val;
+Sfdisc_t *disc;
+#endif
+{
+ NOTUSED(val);
+
+ /* hmm! This should never happen */
+ if(disc != _Sfudisc)
+ return -1;
+
+ /* close the unget stream */
+ if(type != SF_CLOSING)
+ (void)sfclose((*_Sfstack)(f,NIL(Sfio_t*)));
+
+ return 1;
+}
+
+#if __STD_C
+int sfungetc(Sfio_t* f, int c)
+#else
+int sfungetc(f,c)
+Sfio_t* f; /* push back one byte to this stream */
+int c; /* the value to be pushed back */
+#endif
+{
+ reg Sfio_t* uf;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f, -1);
+
+ if(c < 0 || (f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0))
+ SFMTXRETURN(f, -1);
+ SFLOCK(f,0);
+
+ /* fast handling of the typical unget */
+ if(f->next > f->data && f->next[-1] == (uchar)c)
+ { f->next -= 1;
+ goto done;
+ }
+
+ /* make a string stream for unget characters */
+ if(f->disc != _Sfudisc)
+ { if(!(uf = sfnew(NIL(Sfio_t*),NIL(char*),(size_t)SF_UNBOUND,
+ -1,SF_STRING|SF_READ)))
+ { c = -1;
+ goto done;
+ }
+ _Sfudisc->exceptf = _uexcept;
+ sfdisc(uf,_Sfudisc);
+ SFOPEN(f,0); (void)sfstack(f,uf); SFLOCK(f,0);
+ }
+
+ /* space for data */
+ if(f->next == f->data)
+ { reg uchar* data;
+ if(f->size < 0)
+ f->size = 0;
+ if(!(data = (uchar*)malloc(f->size+16)))
+ { c = -1;
+ goto done;
+ }
+ f->flags |= SF_MALLOC;
+ if(f->data)
+ memcpy((char*)(data+16),(char*)f->data,f->size);
+ f->size += 16;
+ f->data = data;
+ f->next = data+16;
+ f->endb = data+f->size;
+ }
+
+ *--f->next = (uchar)c;
+done:
+ SFOPEN(f,0);
+ SFMTXRETURN(f, c);
+}
diff --git a/src/lib/libast/sfio/sfvprintf.c b/src/lib/libast/sfio/sfvprintf.c
new file mode 100644
index 0000000..3d1a1bd
--- /dev/null
+++ b/src/lib/libast/sfio/sfvprintf.c
@@ -0,0 +1,1445 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* The engine for formatting data.
+** 1. Argument positioning is done in sftable.c so any changes
+** made here should be reflected in sftable.c as well.
+** 2. For internationalization, Sfio only supports I/O of multibyte strings.
+** However, this code does provide minimal support so that Stdio functions
+** such as fwprintf/swprintf can be emulated (see stdvwprintf()).
+**
+** Written by Kiem-Phong Vo.
+*/
+#define HIGHBITI (~((~((uint)0)) >> 1))
+#define HIGHBITL (~((~((Sfulong_t)0)) >> 1))
+
+#define SFFMT_PREFIX (SFFMT_MINUS|SFFMT_SIGN|SFFMT_BLANK)
+
+#define FPRECIS 6 /* default precision for floats */
+
+#if _PACKAGE_ast
+#include <ccode.h>
+#else
+/* characters when using ebcdic or ascii */
+#if _chr_ebcdic
+#define CC_vt 013 /* vertical tab */
+#define CC_esc 047 /* escape */
+#define CC_bel 057 /* bell */
+#else
+#define CC_vt 013 /* vertical tab */
+#define CC_esc 033 /* escape */
+#define CC_bel 007 /* bell */
+#endif /* _chr_ebcdic */
+#endif /* _PACKAGE_ast */
+
+#if __STD_C
+static int chr2str(char* buf, int v)
+#else
+static int chr2str(buf, v)
+char* buf;
+int v;
+#endif
+{
+ if(isprint(v) && v != '\\')
+ { *buf++ = v;
+ return 1;
+ }
+ else
+ { *buf++ = '\\';
+ switch(v)
+ { case CC_bel: *buf++ = 'a'; return 2;
+ case CC_vt: *buf++ = 'v'; return 2;
+ case CC_esc: *buf++ = 'E'; return 2;
+ case '\b': *buf++ = 'b'; return 2;
+ case '\f': *buf++ = 'f'; return 2;
+ case '\n': *buf++ = 'n'; return 2;
+ case '\r': *buf++ = 'r'; return 2;
+ case '\t': *buf++ = 't'; return 2;
+ case '\\': *buf++ = '\\'; return 2;
+ default: *buf++ = '0' + ((v >> 6) & 03);
+ *buf++ = '0' + ((v >> 3) & 07);
+ *buf++ = '0' + ((v >> 0) & 07);
+ return 4;
+ }
+ }
+}
+
+/* On some platform(s), large functions are not compilable.
+** In such a case, the below macro should be defined non-zero so that
+** some in-lined macros will be made smaller, trading time for space.
+*/
+#if !defined(_sffmt_small) && defined(_UTS)
+#define _sffmt_small 1
+#endif
+
+#if __STD_C
+int sfvprintf(Sfio_t* f, const char* form, va_list args)
+#else
+int sfvprintf(f,form,args)
+Sfio_t* f; /* file to print to */
+char* form; /* format to use */
+va_list args; /* arg list if !argf */
+#endif
+{
+ int n, v, w, k, n_s, base, fmt, flags;
+ Sflong_t lv;
+ char *sp, *ssp, *endsp, *ep, *endep;
+ int dot, width, precis, sign, decpt;
+#if _PACKAGE_ast
+ int scale;
+#endif
+ ssize_t size;
+ Sfdouble_t dval;
+ Void_t* valp;
+ char *tls[2], **ls; /* for %..[separ]s */
+ char* t_str; /* stuff between () */
+ ssize_t n_str; /* its length */
+
+ Argv_t argv; /* for extf to return value */
+ Sffmt_t *ft; /* format environment */
+ Fmt_t *fm, *fmstk; /* stack contexts */
+
+ char* oform; /* original format string */
+ va_list oargs; /* original arg list */
+ Fmtpos_t* fp; /* arg position list */
+ int argp, argn; /* arg position and number */
+
+#define SLACK 1024
+ char buf[SF_MAXDIGITS+SLACK], tmp[SF_MAXDIGITS+1], data[SF_GRAIN];
+ int decimal = 0, thousand = 0;
+
+#if _has_multibyte
+ wchar_t* wsp;
+ SFMBDCL(fmbs) /* state of format string */
+ SFMBDCL(mbs) /* state of some string */
+#ifdef mbwidth
+ char* osp;
+ int n_w, wc;
+#endif
+#endif
+
+ /* local io system */
+ int o, n_output;
+#define SMputc(f,c) { if((o = SFFLSBUF(f,c)) >= 0 ) n_output += 1; \
+ else { SFBUF(f); goto done; } \
+ }
+#define SMnputc(f,c,n) { if((o = SFNPUTC(f,c,n)) > 0 ) n_output += 1; \
+ if(o != n) { SFBUF(f); goto done; } \
+ }
+#define SMwrite(f,s,n) { if((o = SFWRITE(f,(Void_t*)s,n)) > 0 ) n_output += o; \
+ if(o != n) { SFBUF(f); goto done; } \
+ }
+#if _sffmt_small /* these macros are made smaller at some performance cost */
+#define SFBUF(f)
+#define SFINIT(f) (n_output = 0)
+#define SFEND(f)
+#define SFputc(f,c) SMputc(f,c)
+#define SFnputc(f,c,n) SMnputc(f,c,n)
+#define SFwrite(f,s,n) SMwrite(f,s,n)
+#else
+ uchar *d, *endd;
+#define SFBUF(f) (d = f->next, endd = f->endb)
+#define SFINIT(f) (SFBUF(f), n_output = 0)
+#define SFEND(f) ((n_output += d - f->next), (f->next = d))
+#define SFputc(f,c) { if(d < endd) { *d++ = (uchar)c; } \
+ else { SFEND(f); SMputc(f,c); SFBUF(f); } \
+ }
+#define SFnputc(f,c,n) { if(d+n <= endd) { while(n--) *d++ = (uchar)(c); } \
+ else { SFEND(f); SMnputc(f,c,n); SFBUF(f); } \
+ }
+#define SFwrite(f,s,n) { if(d+n <= endd) { while(n--) *d++ = (uchar)(*s++); } \
+ else { SFEND(f); SMwrite(f,s,n); SFBUF(f); } \
+ }
+#endif /* _sffmt_small */
+
+ SFMTXDECL(f);
+
+ SFCVINIT(); /* initialize conversion tables */
+
+ SFMTXENTER(f,-1);
+
+ if(!form)
+ SFMTXRETURN(f, -1);
+
+ /* make sure stream is in write mode and buffer is not NULL */
+ if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0)
+ SFMTXRETURN(f, -1);
+
+ SFLOCK(f,0);
+
+ if(!f->data && !(f->flags&SF_STRING))
+ { f->data = f->next = (uchar*)data;
+ f->endb = f->data+sizeof(data);
+ }
+ SFINIT(f);
+
+ tls[1] = NIL(char*);
+
+ fmstk = NIL(Fmt_t*);
+ ft = NIL(Sffmt_t*);
+
+ oform = (char*)form;
+ va_copy(oargs,args);
+ argn = -1;
+ fp = NIL(Fmtpos_t*);
+
+loop_fmt :
+ SFMBCLR(&fmbs); /* clear multibyte states to parse the format string */
+ while((n = *form) )
+ { if(n != '%') /* collect the non-pattern chars */
+ { sp = (char*)form;
+ do
+ { if((n = SFMBLEN(form, &fmbs)) <= 0)
+ { n = 1;
+ SFMBCLR(&fmbs);
+ }
+ } while(*(form += n) && *form != '%');
+
+ n = form-sp;
+ SFwrite(f,sp,n);
+ continue;
+ }
+ else form += 1;
+
+ flags = 0;
+#if _PACKAGE_ast
+ scale = 0;
+#endif
+ size = width = precis = base = n_s = argp = -1;
+ ssp = _Sfdigits;
+ endep = ep = NIL(char*);
+ endsp = sp = buf+(sizeof(buf)-1);
+ t_str = NIL(char*);
+ n_str = dot = 0;
+
+ loop_flags: /* LOOP FOR \0, %, FLAGS, WIDTH, PRECISION, BASE, TYPE */
+ switch((fmt = *form++) )
+ {
+ case '\0':
+ SFputc(f,'%');
+ goto pop_fmt;
+ case '%' :
+ SFputc(f,'%');
+ continue;
+
+ case LEFTP : /* get the type enclosed in balanced parens */
+ t_str = (char*)form;
+ for(v = 1;;)
+ { switch(*form++)
+ {
+ case 0 : /* not balancable, retract */
+ form = t_str;
+ t_str = NIL(char*);
+ n_str = 0;
+ goto loop_flags;
+ case LEFTP : /* increasing nested level */
+ v += 1;
+ continue;
+ case RIGHTP : /* decreasing nested level */
+ if((v -= 1) != 0)
+ continue;
+ if(*t_str != '*' )
+ n_str = (form-1)-t_str;
+ else
+ { t_str = (*_Sffmtintf)(t_str+1,&n);
+ if(*t_str == '$')
+ { if(!fp &&
+ !(fp = (*_Sffmtposf)(f,oform,oargs,ft,0)) )
+ goto pop_fmt;
+ n = FP_SET(n,argn);
+ }
+ else n = FP_SET(-1,argn);
+
+ if(fp)
+ { t_str = fp[n].argv.s;
+ n_str = fp[n].ft.size;
+ }
+ else if(ft && ft->extf )
+ { FMTSET(ft, form,args,
+ LEFTP, 0, 0, 0,0,0,
+ NIL(char*),0);
+ n = (*ft->extf)
+ (f,(Void_t*)&argv,ft);
+ if(n < 0)
+ goto pop_fmt;
+ if(!(ft->flags&SFFMT_VALUE) )
+ goto t_arg;
+ if((t_str = argv.s) &&
+ (n_str = (int)ft->size) < 0)
+ n_str = strlen(t_str);
+ }
+ else
+ { t_arg:
+ if((t_str = va_arg(args,char*)) )
+ n_str = strlen(t_str);
+ }
+ }
+ goto loop_flags;
+ }
+ }
+
+ case '-' :
+ if(dot == 1)
+ { dot = 0;
+ precis = -1;
+ flags |= SFFMT_CHOP;
+ }
+ else
+ flags = (flags & ~(SFFMT_CENTER|SFFMT_ZERO)) | SFFMT_LEFT;
+ goto loop_flags;
+ case '0' :
+ if(!(flags&(SFFMT_LEFT|SFFMT_CENTER)) )
+ flags |= SFFMT_ZERO;
+ goto loop_flags;
+ case ' ' :
+ if(!(flags&SFFMT_SIGN) )
+ flags |= SFFMT_BLANK;
+ goto loop_flags;
+ case '+' :
+ flags = (flags & ~SFFMT_BLANK) | SFFMT_SIGN;
+ goto loop_flags;
+ case '=' :
+ flags = (flags & ~(SFFMT_LEFT|SFFMT_ZERO)) | SFFMT_CENTER;
+ goto loop_flags;
+ case '#' :
+ flags |= SFFMT_ALTER;
+ goto loop_flags;
+ case QUOTE:
+ SFSETLOCALE(&decimal,&thousand);
+ if(thousand > 0)
+ flags |= SFFMT_THOUSAND;
+ goto loop_flags;
+ case ',':
+ SFSETLOCALE(&decimal,&thousand);
+ if(thousand < 0)
+ thousand = fmt;
+ flags |= SFFMT_THOUSAND;
+ goto loop_flags;
+
+ case '.':
+ dot += 1;
+ if(dot == 1)
+ { /* so base can be defined without setting precis */
+ if(*form != '.' && !(flags & SFFMT_CHOP))
+ precis = 0;
+ }
+ else if(dot == 2)
+ { base = 0; /* for %s,%c */
+ v = form[0] == 'l' ? form[1] : form[0];
+ if(v == 'c' || v == 'C' || v == 's' || v == 'S')
+ goto loop_flags;
+ if(*form && !isalnum(*form))
+ { v = form[1] == 'l' ? form[2] : form[1];
+ if(v == 'c' || v == 'C' || v == 's' || v == 'S')
+ { if(*form == '*')
+ goto do_star;
+ else
+ { base = *form++;
+ goto loop_flags;
+ }
+ }
+ }
+ }
+
+ if(isdigit(*form) )
+ { fmt = *form++;
+ goto dot_size;
+ }
+ else if(*form != '*')
+ goto loop_flags;
+ do_star:
+ form += 1; /* fall thru for '*' */
+ case '*' :
+ form = (*_Sffmtintf)(form,&n);
+ if(*form == '$')
+ { form += 1;
+ if(!fp && !(fp = (*_Sffmtposf)(f,oform,oargs,ft,0)) )
+ goto pop_fmt;
+ n = FP_SET(n,argn);
+ }
+ else n = FP_SET(-1,argn);
+
+ if(fp)
+ v = fp[n].argv.i;
+ else if(ft && ft->extf)
+ { FMTSET(ft, form,args, '.',dot, 0, 0,0,0, NIL(char*), 0);
+ if((*ft->extf)(f, (Void_t*)(&argv), ft) < 0)
+ goto pop_fmt;
+ fmt = ft->fmt;
+ flags = (flags&~SFFMT_TYPES) | (ft->flags&SFFMT_TYPES);
+ if(ft->flags&SFFMT_VALUE)
+ v = argv.i;
+ else v = (dot <= 2) ? va_arg(args,int) : 0;
+ }
+ else v = dot <= 2 ? va_arg(args,int) : 0;
+ goto dot_set;
+
+ case '1' : case '2' : case '3' :
+ case '4' : case '5' : case '6' :
+ case '7' : case '8' : case '9' :
+ dot_size :
+ for(v = fmt - '0'; isdigit(*form); ++form)
+ v = v*10 + (*form - '0');
+ if(*form == '$')
+ { form += 1;
+ if(!fp && !(fp = (*_Sffmtposf)(f,oform,oargs,ft,0)) )
+ goto pop_fmt;
+ argp = v-1;
+ goto loop_flags;
+ }
+ dot_set :
+ if(dot == 0)
+ { if((width = v) < 0)
+ { width = -width;
+ flags = (flags & ~(SFFMT_CENTER|SFFMT_ZERO)) | SFFMT_LEFT;
+ }
+ }
+ else if(dot == 1)
+ precis = v;
+ else if(dot == 2)
+ base = v;
+ goto loop_flags;
+
+ case 'I' : /* object length */
+ size = -1; flags = (flags & ~SFFMT_TYPES) | SFFMT_IFLAG;
+ if(isdigit(*form) )
+ { for(size = 0, n = *form; isdigit(n); n = *++form)
+ size = size*10 + (n - '0');
+ }
+ else if(*form == '*')
+ { form = (*_Sffmtintf)(form+1,&n);
+ if(*form == '$')
+ { form += 1;
+ if(!fp &&
+ !(fp = (*_Sffmtposf)(f,oform,oargs,ft,0)))
+ goto pop_fmt;
+ n = FP_SET(n,argn);
+ }
+ else n = FP_SET(-1,argn);
+
+ if(fp) /* use position list */
+ size = fp[n].argv.i;
+ else if(ft && ft->extf)
+ { FMTSET(ft, form,args, 'I',sizeof(int), 0, 0,0,0,
+ NIL(char*), 0);
+ if((*ft->extf)(f, (Void_t*)(&argv), ft) < 0)
+ goto pop_fmt;
+ if(ft->flags&SFFMT_VALUE)
+ size = argv.i;
+ else size = va_arg(args,int);
+ }
+ else size = va_arg(args,int);
+ }
+ goto loop_flags;
+
+ case 'l' :
+ size = -1; flags &= ~SFFMT_TYPES;
+ if(*form == 'l')
+ { form += 1;
+ flags |= SFFMT_LLONG;
+ }
+ else flags |= SFFMT_LONG;
+ goto loop_flags;
+ case 'h' :
+ size = -1; flags &= ~SFFMT_TYPES;
+ if(*form == 'h')
+ { form += 1;
+ flags |= SFFMT_SSHORT;
+ }
+ else flags |= SFFMT_SHORT;
+ goto loop_flags;
+ case 'L' :
+ size = -1; flags = (flags & ~SFFMT_TYPES) | SFFMT_LDOUBLE;
+ goto loop_flags;
+
+ case 'j' :
+ size = -1; flags = (flags&~SFFMT_TYPES) | SFFMT_JFLAG;
+ goto loop_flags;
+ case 'z' :
+ size = -1; flags = (flags&~SFFMT_TYPES) | SFFMT_ZFLAG;
+ goto loop_flags;
+ case 't' :
+ size = -1; flags = (flags&~SFFMT_TYPES) | SFFMT_TFLAG;
+ goto loop_flags;
+ default:
+ break;
+ }
+
+ /* set object size for scalars */
+ if(flags & SFFMT_TYPES)
+ { if((_Sftype[fmt]&(SFFMT_INT|SFFMT_UINT)) || fmt == 'n')
+ { if(flags&SFFMT_LONG)
+ size = sizeof(long);
+ else if(flags&SFFMT_SHORT)
+ size = sizeof(short);
+ else if(flags&SFFMT_SSHORT)
+ size = sizeof(char);
+ else if(flags&SFFMT_TFLAG)
+ size = sizeof(ptrdiff_t);
+ else if(flags&SFFMT_ZFLAG)
+ size = sizeof(size_t);
+ else if(flags&(SFFMT_LLONG|SFFMT_JFLAG) )
+ size = sizeof(Sflong_t);
+ else if(flags&SFFMT_IFLAG)
+ { if(size <= 0 ||
+ size == sizeof(Sflong_t)*CHAR_BIT )
+ size = sizeof(Sflong_t);
+ }
+ else if(size < 0)
+ size = sizeof(int);
+ }
+ else if(_Sftype[fmt]&SFFMT_FLOAT)
+ { if(flags&SFFMT_LDOUBLE)
+ size = sizeof(Sfdouble_t);
+ else if(flags&(SFFMT_LONG|SFFMT_LLONG))
+ size = sizeof(double);
+ else if(flags&SFFMT_IFLAG)
+ { if(size <= 0)
+ size = sizeof(Sfdouble_t);
+ }
+ else if(size < 0)
+ size = sizeof(float);
+ }
+ else if(_Sftype[fmt]&SFFMT_CHAR)
+ {
+#if _has_multibyte
+ if((flags&SFFMT_LONG) || fmt == 'C')
+ { size = sizeof(wchar_t) > sizeof(int) ?
+ sizeof(wchar_t) : sizeof(int);
+ } else
+#endif
+ if(size < 0)
+ size = sizeof(int);
+ }
+ }
+
+ argp = FP_SET(argp,argn);
+ if(fp)
+ { if(ft && ft->extf && fp[argp].ft.fmt != fp[argp].fmt)
+ fmt = fp[argp].ft.fmt;
+ argv = fp[argp].argv;
+ size = fp[argp].ft.size;
+ }
+ else if(ft && ft->extf ) /* extended processing */
+ { FMTSET(ft, form,args, fmt, size,flags, width,precis,base,
+ t_str,n_str);
+ SFEND(f); SFOPEN(f,0);
+ v = (*ft->extf)(f, (Void_t*)(&argv), ft);
+ SFLOCK(f,0); SFBUF(f);
+
+ if(v < 0) /* no further processing */
+ goto pop_fmt;
+ else if(v > 0) /* extf output v bytes */
+ { n_output += v;
+ continue;
+ }
+ else /* extf did not output */
+ { FMTGET(ft, form,args, fmt, size,flags, width,precis,base);
+
+ if(!(ft->flags&SFFMT_VALUE))
+ goto arg_list;
+ else if(_Sftype[fmt]&(SFFMT_INT|SFFMT_UINT) )
+ { if(size == sizeof(short))
+ { if(_Sftype[fmt]&SFFMT_INT)
+ argv.i = argv.h;
+ else argv.i = argv.uh;
+ }
+ else if(size == sizeof(char))
+ { if(_Sftype[fmt]&SFFMT_INT)
+ argv.i = argv.c;
+ else argv.i = argv.uc;
+ }
+ }
+ else if(_Sftype[fmt]&SFFMT_FLOAT )
+ { if(size == sizeof(float) )
+ argv.d = argv.f;
+ }
+ else if(_Sftype[fmt]&SFFMT_CHAR)
+ { if(base < 0)
+ argv.i = (int)argv.c;
+ }
+ }
+ }
+ else
+ { arg_list:
+ switch(_Sftype[fmt])
+ { case SFFMT_INT:
+ case SFFMT_UINT:
+#if !_ast_intmax_long
+ if(size == sizeof(Sflong_t))
+ argv.ll = va_arg(args, Sflong_t);
+ else
+#endif
+ if(size == sizeof(long) )
+ argv.l = va_arg(args, long);
+ else argv.i = va_arg(args, int);
+ break;
+ case SFFMT_FLOAT:
+#if !_ast_fltmax_double
+ if(size == sizeof(Sfdouble_t))
+ argv.ld = va_arg(args,Sfdouble_t);
+ else
+#endif
+ argv.d = va_arg(args,double);
+ break;
+ case SFFMT_POINTER:
+ argv.vp = va_arg(args,Void_t*);
+ break;
+ case SFFMT_CHAR:
+ if(base >= 0)
+ argv.s = va_arg(args,char*);
+#if _has_multibyte
+ else if((flags & SFFMT_LONG) || fmt == 'C')
+ { if(sizeof(wchar_t) <= sizeof(uint) )
+ argv.wc = (wchar_t)va_arg(args,uint);
+ else argv.wc = va_arg(args,wchar_t);
+ }
+#endif
+ else argv.i = va_arg(args,int);
+ break;
+ default: /* unknown pattern */
+ break;
+ }
+ }
+
+ switch(fmt) /* PRINTF DIRECTIVES */
+ {
+ default : /* unknown directive */
+ form -= 1;
+ argn -= 1;
+ continue;
+
+ case '!' : /* stacking a new environment */
+ if(!fp)
+ fp = (*_Sffmtposf)(f,oform,oargs,ft,0);
+ else goto pop_fmt;
+
+ if(!argv.ft)
+ goto pop_fmt;
+ if(!argv.ft->form && ft ) /* change extension functions */
+ { if(ft->eventf &&
+ (*ft->eventf)(f,SF_DPOP,(Void_t*)form,ft) < 0)
+ continue;
+ fmstk->ft = ft = argv.ft;
+ }
+ else /* stack a new environment */
+ { if(!(fm = (Fmt_t*)malloc(sizeof(Fmt_t))) )
+ goto done;
+
+ ft = fm->ft = argv.ft;
+ SFMBSET(ft->mbs, &fmbs);
+ if(ft->form)
+ { fm->form = (char*)form; SFMBCPY(&fm->mbs,&fmbs);
+ va_copy(fm->args,args);
+
+ fm->oform = oform;
+ va_copy(fm->oargs,oargs);
+ fm->argn = argn;
+ fm->fp = fp;
+
+ form = ft->form; SFMBCLR(ft->mbs);
+ va_copy(args,ft->args);
+ argn = -1;
+ fp = NIL(Fmtpos_t*);
+ oform = (char*)form;
+ va_copy(oargs,args);
+ }
+ else fm->form = NIL(char*);
+
+ fm->eventf = ft->eventf;
+ fm->next = fmstk;
+ fmstk = fm;
+ }
+ continue;
+
+ case 'S':
+ flags = (flags & ~(SFFMT_TYPES|SFFMT_LDOUBLE)) | SFFMT_LONG;
+ case 's':
+#if _has_multibyte && defined(mbwidth)
+ wc = (flags & SFFMT_LDOUBLE) && mbwide();
+#endif
+ if(base >= 0) /* list of strings */
+ { if(!(ls = argv.sp) || !ls[0])
+ continue;
+ }
+ else
+ { if(!(sp = argv.s))
+ { sp = "(null)";
+ flags &= ~SFFMT_LONG;
+ }
+#if _PACKAGE_ast
+ str_cvt:
+ if(scale)
+ { size = base = -1;
+ flags &= ~SFFMT_LONG;
+ }
+#endif
+ ls = tls; tls[0] = sp;
+ }
+ for(sp = *ls;;)
+ { /* v: number of bytes w: print width of those v bytes */
+#if _has_multibyte
+ if(flags & SFFMT_LONG)
+ { v = 0;
+#ifdef mbwidth
+ w = 0;
+#endif
+ SFMBCLR(&mbs);
+ for(n = 0, wsp = (wchar_t*)sp;; ++wsp, ++n)
+ { if((size >= 0 && n >= size) ||
+ (size < 0 && *wsp == 0) )
+ break;
+ if((n_s = wcrtomb(buf, *wsp, &mbs)) <= 0)
+ break;
+#ifdef mbwidth
+ if(wc)
+ { n_w = mbwidth(*wsp);
+ if(precis >= 0 && (w+n_w) > precis )
+ break;
+ w += n_w;
+ }
+ else
+#endif
+ if(precis >= 0 && (v+n_s) > precis )
+ break;
+ v += n_s;
+ }
+#ifdef mbwidth
+ if(!wc)
+ w = v;
+#endif
+ }
+#ifdef mbwidth
+ else if (wc)
+ { w = 0;
+ SFMBCLR(&mbs);
+ ssp = sp;
+ for(;;)
+ { if((size >= 0 && w >= size) ||
+ (size < 0 && *ssp == 0) )
+ break;
+ osp = ssp;
+ n = mbchar(osp);
+ n_w = mbwidth(n);
+ if(precis >= 0 && (w+n_w) > precis )
+ break;
+ w += n_w;
+ ssp = osp;
+ }
+ v = ssp - sp;
+ }
+#endif
+ else
+#endif
+ { if((v = size) < 0)
+ for(v = 0; v != precis && sp[v]; ++v);
+ if(precis >= 0 && v > precis)
+ v = precis;
+ w = v;
+ }
+
+ if((n = width - w) > 0 && !(flags&SFFMT_LEFT) )
+ { if(flags&SFFMT_CENTER)
+ { n -= (k = n/2);
+ SFnputc(f, ' ', k);
+ }
+ else
+ { SFnputc(f, ' ', n);
+ n = 0;
+ }
+ }
+ if(n < 0 && (flags & SFFMT_CHOP) && width > 0 && precis < 0)
+ {
+#if _has_multibyte
+ if(flags & SFFMT_LONG)
+ { SFMBCLR(&mbs);
+ wsp = (wchar_t*)sp;
+ while(n < 0)
+ {
+#ifdef mbwidth
+ n += mbwidth(*wsp);
+#else
+ n++;
+#endif
+ wsp++;
+ w--;
+ }
+ sp = (char*)wsp;
+ }
+ else if (wc)
+ { SFMBCLR(&mbs);
+ osp = sp;
+ while(n < 0)
+ { ssp = sp;
+ if ((k = mbchar(sp)) <= 0)
+ { sp = ssp;
+ break;
+ }
+#ifdef mbwidth
+ n += mbwidth(k);
+#else
+ n++;
+#endif
+ }
+ v -= (sp - osp);
+ }
+#endif
+ else
+ { sp += -n;
+ v += n;
+ }
+ n = 0;
+ }
+#if _has_multibyte
+ if(flags & SFFMT_LONG)
+ { SFMBCLR(&mbs);
+ for(wsp = (wchar_t*)sp; w > 0; ++wsp, --w)
+ { if((n_s = wcrtomb(buf, *wsp, &mbs)) <= 0)
+ break;
+ sp = buf; SFwrite(f, sp, n_s);
+ }
+ }
+ else
+#endif
+ { SFwrite(f,sp,v); }
+ if(n > 0)
+ { SFnputc(f,' ',n); }
+ if(!(sp = *++ls))
+ break;
+ else if(base > 0)
+ { SFputc(f,base); }
+ }
+ continue;
+
+ case 'C':
+ flags = (flags & ~(SFFMT_TYPES|SFFMT_LDOUBLE)) | SFFMT_LONG;
+ case 'c':
+#if _has_multibyte && defined(mbwidth)
+ wc = (flags & SFFMT_LDOUBLE) && mbwide();
+#endif
+ if(precis <= 0) /* # of times to repeat a character */
+ precis = 1;
+#if _has_multibyte
+ if(flags & SFFMT_LONG)
+ { if(base >= 0)
+ { if(!(wsp = (wchar_t*)argv.s) )
+ continue;
+ for(size = 0; wsp[size]; ++size)
+ ;
+ }
+ else
+ { wsp = &argv.wc;
+ size = 1;
+ }
+ }
+ else
+#endif
+ { if(base >= 0)
+ { if(!(sp = argv.s) )
+ continue;
+ size = strlen(sp);
+ }
+ else
+ { argv.c = (char)(argv.i);
+ sp = &argv.c;
+ size = 1;
+ }
+ }
+
+ while(size > 0)
+ {
+#if _has_multibyte
+ if(flags&SFFMT_LONG)
+ { SFMBCLR(&mbs);
+ if((n_s = wcrtomb(buf, *wsp++, &mbs)) <= 0)
+ break;
+#ifdef mbwidth
+ if(wc)
+ n_s = mbwidth(*(wsp - 1));
+#endif
+ n = width - precis*n_s; /* padding amount */
+ }
+ else
+#endif
+ if(flags&SFFMT_ALTER)
+ { n_s = chr2str(buf, *sp++);
+ n = width - precis*n_s;
+ }
+ else
+ { fmt = *sp++;
+ n = width - precis;
+ }
+
+ if(n > 0 && !(flags&SFFMT_LEFT) )
+ { if(flags&SFFMT_CENTER)
+ { n -= (k = n/2);
+ SFnputc(f, ' ', k);
+ }
+ else
+ { SFnputc(f, ' ', n);
+ n = 0;
+ }
+ }
+
+ v = precis; /* need this because SFnputc may clear it */
+#if _has_multibyte
+ if(flags&SFFMT_LONG)
+ { for(; v > 0; --v)
+ { ssp = buf; k = n_s; SFwrite(f,ssp,k); }
+ }
+ else
+#endif
+ if(flags&SFFMT_ALTER)
+ { for(; v > 0; --v)
+ { ssp = buf; k = n_s; SFwrite(f,ssp,k); }
+ }
+ else
+ { SFnputc(f, fmt, v);
+ }
+
+ if(n > 0)
+ { SFnputc(f,' ',n); };
+
+ if((size -= 1) > 0 && base > 0)
+ { SFputc(f,base); }
+ }
+ continue;
+
+ case 'n': /* return current output length */
+ SFEND(f);
+#if !_ast_intmax_long
+ if(size == sizeof(Sflong_t) )
+ *((Sflong_t*)argv.vp) = (Sflong_t)n_output;
+ else
+#endif
+ if(size == sizeof(long))
+ *((long*)argv.vp) = (long)n_output;
+ else if(size == sizeof(short) )
+ *((short*)argv.vp) = (short)n_output;
+ else if(size == sizeof(uchar) )
+ *((uchar*)argv.vp) = (uchar)n_output;
+ else *((int*)argv.vp) = (int)n_output;
+
+ continue;
+
+ case 'p': /* pointer value */
+ fmt = 'x';
+ base = 16; n_s = 15; n = 4;
+ flags = (flags&~(SFFMT_SIGN|SFFMT_BLANK|SFFMT_ZERO))|SFFMT_ALTER;
+#if _more_void_int
+ lv = (Sflong_t)((Sfulong_t)argv.vp);
+ goto long_cvt;
+#else
+ v = (int)((uint)argv.vp);
+ goto int_cvt;
+#endif
+ case 'o':
+ base = 8; n_s = 7; n = 3;
+ flags &= ~(SFFMT_SIGN|SFFMT_BLANK);
+ goto int_arg;
+ case 'X':
+ ssp = "0123456789ABCDEF";
+ case 'x':
+ base = 16; n_s = 15; n = 4;
+ flags &= ~(SFFMT_SIGN|SFFMT_BLANK);
+ goto int_arg;
+ case 'i':
+#if _PACKAGE_ast
+ if((flags&SFFMT_ALTER) && base < 0)
+ { flags &= ~SFFMT_ALTER;
+ scale = 1024;
+ }
+#endif
+ fmt = 'd';
+ goto d_format;
+ case 'u':
+ flags &= ~(SFFMT_SIGN|SFFMT_BLANK);
+ case 'd':
+ d_format:
+#if _PACKAGE_ast
+ if((flags&SFFMT_ALTER) && base < 0)
+ { flags &= ~SFFMT_ALTER;
+ scale = 1000;
+ }
+#endif
+ if(base < 2 || base > SF_RADIX)
+ base = 10;
+ if((base&(n_s = base-1)) == 0)
+ { if(base < 8)
+ n = base < 4 ? 1 : 2;
+ else if(base < 32)
+ n = base < 16 ? 3 : 4;
+ else n = base < 64 ? 5 : 6;
+ }
+ else n_s = base == 10 ? -1 : 0;
+
+ int_arg:
+#if !_ast_intmax_long || _more_long_int || _more_void_int
+ if(size == sizeof(Sflong_t))
+ { lv = argv.ll;
+ goto long_cvt;
+ }
+ else if(sizeof(long) < sizeof(Sflong_t) && size == sizeof(long))
+ { if(fmt == 'd')
+ lv = (Sflong_t)argv.l;
+ else lv = (Sflong_t)argv.ul;
+ long_cvt:
+#if _PACKAGE_ast
+ if(scale)
+ { sp = fmtscale(lv, scale);
+#if _has_multibyte && defined(mbwidth)
+ wc = 0;
+#endif
+ goto str_cvt;
+ }
+#endif
+ if(lv == 0 && precis == 0)
+ break;
+ if(lv < 0 && fmt == 'd' )
+ { flags |= SFFMT_MINUS;
+ if(lv == HIGHBITL) /* avoid overflow */
+ { lv = (Sflong_t)(HIGHBITL/base);
+ *--sp = _Sfdigits[HIGHBITL -
+ ((Sfulong_t)lv)*base];
+ }
+ else lv = -lv;
+ }
+ if(n_s < 0) /* base 10 */
+ { Sflong_t nv;
+ sfucvt(lv,sp,nv,ssp,Sflong_t,Sfulong_t);
+ }
+ else if(n_s > 0) /* base power-of-2 */
+ { do
+ { *--sp = ssp[lv&n_s];
+ } while((lv = ((Sfulong_t)lv) >> n) );
+ }
+ else /* general base */
+ { do
+ { *--sp = ssp[((Sfulong_t)lv)%base];
+ } while((lv = ((Sfulong_t)lv)/base) );
+ }
+ } else
+#endif
+ if(sizeof(short) < sizeof(int) && size == sizeof(short) )
+ { if(fmt == 'd')
+ v = (int)((short)argv.i);
+ else v = (int)((ushort)argv.i);
+ goto int_cvt;
+ }
+ else if(size == sizeof(char))
+ { if(fmt != 'd')
+ v = (int)((uchar)argv.i);
+ else
+ {
+#if _key_signed
+ v = (int)((signed char)argv.i);
+#else
+ if(argv.i < 0)
+ v = -((int)((char)(-argv.i)));
+ else v = ((int)((char)( argv.i)));
+#endif
+ }
+ goto int_cvt;
+ }
+ else
+ { v = argv.i;
+ int_cvt:
+#if _PACKAGE_ast
+ if(scale)
+ { sp = fmtscale(v, scale);
+#if _has_multibyte && defined(mbwidth)
+ wc = 0;
+#endif
+ goto str_cvt;
+ }
+#endif
+ if(v == 0 && precis == 0)
+ break;
+ if(v < 0 && fmt == 'd' )
+ { flags |= SFFMT_MINUS;
+ if(v == HIGHBITI) /* avoid overflow */
+ { v = (int)(HIGHBITI/base);
+ *--sp = _Sfdigits[HIGHBITI -
+ ((uint)v)*base];
+ }
+ else v = -v;
+ }
+ if(n_s < 0) /* base 10 */
+ { sfucvt(v,sp,n,ssp,int,uint);
+ }
+ else if(n_s > 0) /* base power-of-2 */
+ { do
+ { *--sp = ssp[v&n_s];
+ } while((v = ((uint)v) >> n) );
+ }
+ else /* n_s == 0, general base */
+ { do
+ { *--sp = ssp[((uint)v)%base];
+ } while((v = ((uint)v)/base) );
+ }
+ }
+
+ if(n_s < 0 && (flags&SFFMT_THOUSAND) && (n = endsp-sp) > 3)
+ { if((n %= 3) == 0)
+ n = 3;
+ for(ep = buf+SLACK, endep = ep + n; ; )
+ { while(ep < endep)
+ *ep++ = *sp++;
+ if(sp == endsp)
+ break;
+ if(sp <= endsp-3)
+ *ep++ = thousand;
+ endep = ep+3;
+ }
+ sp = buf+SLACK;
+ endsp = ep;
+ }
+
+ /* zero padding for precision if have room in buffer */
+ if(precis > 0 && (precis -= (endsp-sp)) < (sp-buf)-64)
+ while(precis-- > 0)
+ *--sp = '0';
+
+ if(flags&SFFMT_ALTER) /* prefix */
+ { if(fmt == 'o')
+ { if(*sp != '0')
+ *--sp = '0';
+ }
+ else
+ { if(width > 0 && (flags&SFFMT_ZERO))
+ { /* do 0 padding first */
+ if(fmt == 'x' || fmt == 'X')
+ n = 0;
+ else if(dot < 2)
+ n = width;
+ else n = base < 10 ? 2 : 3;
+ n += (flags&(SFFMT_MINUS|SFFMT_SIGN)) ?
+ 1 : 0;
+ n = width - (n + (endsp-sp));
+ while(n-- > 0)
+ *--sp = '0';
+ }
+ if(fmt == 'x' || fmt == 'X')
+ { *--sp = (char)fmt;
+ *--sp = '0';
+ }
+ else if(dot >= 2)
+ { /* base#value notation */
+ *--sp = '#';
+ if(base < 10)
+ *--sp = (char)('0'+base);
+ else
+ { *--sp = _Sfdec[(base <<= 1)+1];
+ *--sp = _Sfdec[base];
+ }
+ }
+ }
+ }
+
+ break;
+
+ case 'g': case 'G': /* these ultimately become %e or %f */
+ case 'a': case 'A':
+ case 'e': case 'E':
+ case 'f': case 'F':
+#if !_ast_fltmax_double
+ if(size == sizeof(Sfdouble_t) )
+ { v = SFFMT_LDOUBLE;
+ valp = &argv.ld;
+ dval = argv.ld;
+ }
+ else
+#endif
+ { v = 0;
+ valp = &argv.d;
+ dval = argv.d;
+ }
+
+ if(fmt == 'e' || fmt == 'E' && (v |= SFFMT_UPPER))
+ { v |= SFFMT_EFORMAT;
+ n = (precis = precis < 0 ? FPRECIS : precis)+1;
+ ep = _sfcvt(valp,tmp+1,sizeof(tmp)-1, min(n,SF_FDIGITS),
+ &decpt, &sign, &n_s, v);
+ goto e_format;
+ }
+ else if(fmt == 'f' || fmt == 'F' && (v |= SFFMT_UPPER))
+ { precis = precis < 0 ? FPRECIS : precis;
+ ep = _sfcvt(valp,tmp+1,sizeof(tmp)-1, min(precis,SF_FDIGITS),
+ &decpt, &sign, &n_s, v);
+ goto f_format;
+ }
+ else if(fmt == 'a' || fmt == 'A' && (v |= SFFMT_UPPER))
+ { v |= SFFMT_AFORMAT;
+ if(precis < 0)
+ { if(v & SFFMT_LDOUBLE)
+ precis = 2*(sizeof(Sfdouble_t) - 2);
+ else precis = 2*(sizeof(double) - 2);
+ }
+ n = precis + 1;
+ ep = _sfcvt(valp,tmp+1,sizeof(tmp)-1, min(n,SF_FDIGITS),
+ &decpt, &sign, &n_s, v);
+
+ sp = endsp = buf+1; /* reserve space for sign */
+ *endsp++ = '0';
+ *endsp++ = fmt == 'a' ? 'x' : 'X';
+ if (!isxdigit(*ep))
+ goto infinite;
+ if (base < 0)
+ base = 0;
+ goto a_format;
+ }
+ else /* 'g' or 'G' format */
+ { precis = precis < 0 ? FPRECIS : precis == 0 ? 1 : precis;
+ if(fmt == 'G')
+ v |= SFFMT_UPPER;
+ v |= SFFMT_EFORMAT;
+ ep = _sfcvt(valp,tmp+1,sizeof(tmp)-1, min(precis,SF_FDIGITS),
+ &decpt, &sign, &n_s, v);
+ if(dval == 0.)
+ decpt = 1;
+ else if(*ep == 'I')
+ goto infinite;
+
+ if(!(flags&SFFMT_ALTER))
+ { /* zap trailing 0s */
+ if((n = n_s) > precis)
+ n = precis;
+ while((n -= 1) >= 1 && ep[n] == '0')
+ ;
+ n += 1;
+ }
+ else n = precis;
+
+ if(decpt < -3 || decpt > precis)
+ { precis = n-1;
+ goto e_format;
+ }
+ else
+ { precis = n - decpt;
+ goto f_format;
+ }
+ }
+
+ e_format: /* build the x.yyyy string */
+ if(isalpha(*ep))
+ goto infinite;
+ sp = endsp = buf+1; /* reserve space for sign */
+ if (base <= 0)
+ base = 2;
+ a_format:
+ *endsp++ = *ep ? *ep++ : '0';
+
+ SFSETLOCALE(&decimal,&thousand);
+ if(precis > 0 || (flags&SFFMT_ALTER))
+ *endsp++ = decimal;
+ ssp = endsp;
+ endep = ep+precis;
+ while((*endsp++ = *ep++) && ep <= endep)
+ ;
+ precis -= (endsp -= 1) - ssp;
+
+ /* build the exponent */
+ ep = endep = buf+(sizeof(buf)-1);
+ if(dval != 0.)
+ { if((n = decpt - 1) < 0)
+ n = -n;
+ while(n > 9)
+ { v = n; n /= 10;
+ *--ep = (char)('0' + (v - n*10));
+ }
+ }
+ else n = 0;
+ *--ep = (char)('0' + n);
+ while((endep-ep) < base && ep > (buf+2)) /* at least base digits in exponent */
+ *--ep = '0';
+
+ /* the e/Exponent separator and sign */
+ *--ep = (decpt > 0 || dval == 0.) ? '+' : '-';
+ *--ep = fmt == 'a' ? 'p' : fmt == 'A' ? 'P' :
+ isupper(fmt) ? 'E' : 'e';
+
+ goto end_aefg;
+
+ f_format: /* data before the decimal point */
+ if(isalpha(*ep))
+ {
+ infinite:
+ flags &= ~SFFMT_ZERO;
+ endsp = (sp = ep)+sfslen();
+ ep = endep;
+ precis = 0;
+ goto end_aefg;
+ }
+
+ SFSETLOCALE(&decimal,&thousand);
+ endsp = sp = buf+1; /* save a space for sign */
+ endep = ep+decpt;
+ if(decpt > 3 && (flags&SFFMT_THOUSAND) )
+ { if((n = decpt%3) == 0)
+ n = 3;
+ while(ep < endep && (*endsp++ = *ep++) )
+ { if(--n == 0 && (ep <= endep-3) )
+ { *endsp++ = thousand;
+ n = 3;
+ }
+ }
+ }
+ else
+ { while(ep < endep && (*endsp++ = *ep++))
+ ;
+ }
+ if(endsp == sp)
+ *endsp++ = '0';
+
+ if(precis > 0 || (flags&SFFMT_ALTER))
+ *endsp++ = decimal;
+
+ if((n = -decpt) > 0)
+ { /* output zeros for negative exponent */
+ ssp = endsp + min(n,precis);
+ precis -= n;
+ while(endsp < ssp)
+ *endsp++ = '0';
+ }
+
+ ssp = endsp;
+ endep = ep+precis;
+ while((*endsp++ = *ep++) && ep <= endep)
+ ;
+ precis -= (endsp -= 1) - ssp;
+ ep = endep;
+ end_aefg:
+ flags |= SFFMT_FLOAT;
+ if(sign)
+ flags |= SFFMT_MINUS;
+ break;
+ }
+
+ if(flags == 0 && width <= 0)
+ goto do_output;
+
+ if(flags&SFFMT_PREFIX)
+ fmt = (flags&SFFMT_MINUS) ? '-' : (flags&SFFMT_SIGN) ? '+' : ' ';
+
+ n = (endsp-sp) + (endep-ep) + (precis <= 0 ? 0 : precis) +
+ ((flags&SFFMT_PREFIX) ? 1 : 0);
+ if((v = width-n) <= 0)
+ v = 0;
+ else if(!(flags&SFFMT_ZERO)) /* right padding */
+ { if(flags&SFFMT_LEFT)
+ v = -v;
+ else if(flags&SFFMT_PREFIX) /* blank padding, output prefix now */
+ { *--sp = fmt;
+ flags &= ~SFFMT_PREFIX;
+ }
+ }
+
+ if(flags&SFFMT_PREFIX) /* put out the prefix */
+ { SFputc(f,fmt);
+ if(fmt != ' ')
+ flags |= SFFMT_ZERO;
+ }
+
+ if((n = v) > 0) /* left padding */
+ { v = (flags&SFFMT_ZERO) ? '0' : ' ';
+ SFnputc(f,v,n);
+ }
+
+ if((n = precis) > 0 && !(flags&SFFMT_FLOAT))
+ { /* padding for integer precision */
+ SFnputc(f,'0',n);
+ precis = 0;
+ }
+
+ do_output:
+ if((n = endsp-sp) > 0)
+ SFwrite(f,sp,n);
+
+ if(flags&(SFFMT_FLOAT|SFFMT_LEFT))
+ { /* SFFMT_FLOAT: right padding for float precision */
+ if((n = precis) > 0)
+ SFnputc(f,'0',n);
+
+ /* SFFMT_FLOAT: the exponent of %eE */
+ if((n = endep - (sp = ep)) > 0)
+ SFwrite(f,sp,n);
+
+ /* SFFMT_LEFT: right padding */
+ if((n = -v) > 0)
+ { SFnputc(f,' ',n); }
+ }
+ }
+
+pop_fmt:
+ if(fp)
+ { free(fp);
+ fp = NIL(Fmtpos_t*);
+ }
+ while((fm = fmstk) ) /* pop the format stack and continue */
+ { if(fm->eventf)
+ { if(!form || !form[0])
+ (*fm->eventf)(f,SF_FINAL,NIL(Void_t*),ft);
+ else if((*fm->eventf)(f,SF_DPOP,(Void_t*)form,ft) < 0)
+ goto loop_fmt;
+ }
+
+ fmstk = fm->next;
+ if((form = fm->form) )
+ { SFMBCPY(&fmbs,&fm->mbs);
+ va_copy(args, fm->args);
+ oform = fm->oform;
+ va_copy(oargs,fm->oargs);
+ argn = fm->argn;
+ fp = fm->fp;
+ }
+ ft = fm->ft;
+ free(fm);
+ if(form && form[0])
+ goto loop_fmt;
+ }
+
+done:
+ if(fp)
+ free(fp);
+ while((fm = fmstk) )
+ { if(fm->eventf)
+ (*fm->eventf)(f,SF_FINAL,NIL(Void_t*),fm->ft);
+ fmstk = fm->next;
+ free(fm);
+ }
+
+ SFEND(f);
+
+ n = f->next - f->data;
+ if((sp = (char*)f->data) == data)
+ f->endw = f->endr = f->endb = f->data = NIL(uchar*);
+ f->next = f->data;
+
+ if((((flags = f->flags)&SF_SHARE) && !(flags&SF_PUBLIC) ) ||
+ (n > 0 && (sp == data || (flags&SF_LINE) ) ) )
+ (void)SFWRITE(f,(Void_t*)sp,n);
+ else f->next += n;
+
+ SFOPEN(f,0);
+ SFMTXRETURN(f, n_output);
+}
diff --git a/src/lib/libast/sfio/sfvscanf.c b/src/lib/libast/sfio/sfvscanf.c
new file mode 100644
index 0000000..c0a1a0b
--- /dev/null
+++ b/src/lib/libast/sfio/sfvscanf.c
@@ -0,0 +1,1100 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* The main engine for reading formatted data
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#define MAXWIDTH (int)(((uint)~0)>>1) /* max amount to scan */
+
+/*
+ * pull in a private strtold()
+ */
+
+#include "sfstrtof.h"
+
+/* refresh stream buffer - taking care of unseekable/share streams too */
+#if __STD_C
+static void _sfbuf(Sfio_t* f, int* peek)
+#else
+static void _sfbuf(f, peek)
+Sfio_t* f;
+int* peek;
+#endif
+{
+ if(f->next >= f->endb)
+ { if(*peek) /* try peeking for a share stream if possible */
+ { f->mode |= SF_RV;
+ if(SFFILBUF(f,-1) > 0)
+ { f->mode |= SF_PEEK;
+ return;
+ }
+ *peek = 0; /* can't peek, back to normal reads */
+ }
+ (void)SFFILBUF(f,-1);
+ }
+}
+
+/* buffer used during scanning of a double value or a multi-byte
+ character. the fields mirror certain local variables in sfvscanf. */
+typedef struct _scan_s
+{ int error; /* get set by _sfdscan if no value specified */
+ int inp; /* last input character read */
+ int width; /* field width */
+ Sfio_t *f; /* stream being scanned */
+ uchar *d, *endd, *data; /* local buffering system */
+ int peek; /* != 0 if unseekable/share stream */
+ int n_input;/* number of input bytes processed */
+} Scan_t;
+
+/* ds != 0 for scanning double values */
+#define SCinit(sc,ds) ((sc)->inp = (sc)->error = -1, (sc)->f = f, \
+ ((sc)->width = (ds) ? width : -1), \
+ (sc)->d = d, (sc)->endd = endd, (sc)->data = data, \
+ (sc)->peek = peek, (sc)->n_input = n_input)
+#define SCend(sc,ds) (inp = (sc)->inp, f = (sc)->f, \
+ (width = (ds) ? (sc)->width : width), \
+ d = (sc)->d, endd = (sc)->endd, data = (sc)->data, \
+ peek = (sc)->peek, n_input = (sc)->n_input)
+
+#if __STD_C
+static int _scgetc(void* arg, int flag)
+#else
+static int _scgetc(arg, flag)
+void* arg;
+int flag;
+#endif
+{
+ Scan_t *sc = (Scan_t*)arg;
+
+ if (flag)
+ { sc->error = flag;
+ return 0;
+ }
+
+ /* if width >= 0, do not allow to exceed width number of bytes */
+ if(sc->width == 0)
+ { sc->inp = -1;
+ return 0;
+ }
+
+ if(sc->d >= sc->endd) /* refresh local buffer */
+ { sc->n_input += sc->d - sc->data;
+ if(sc->peek)
+ SFREAD(sc->f, sc->data, sc->d - sc->data);
+ else sc->f->next = sc->d;
+
+ _sfbuf(sc->f, &sc->peek);
+ sc->data = sc->d = sc->f->next;
+ sc->endd = sc->f->endb;
+
+ if(sc->d >= sc->endd)
+ { sc->inp = -1;
+ return 0;
+ }
+ }
+
+ if((sc->width -= 1) >= 0) /* from _sfdscan */
+ return (sc->inp = (int)(*sc->d++));
+ else return ((int)(*sc->d++));
+}
+
+/* structure to match characters in a character class */
+typedef struct _accept_s
+{ char ok[SF_MAXCHAR+1];
+ int yes;
+ char *form, *endf;
+#if _has_multibyte
+ wchar_t wc;
+#endif
+} Accept_t;
+
+#if __STD_C
+static char* _sfsetclass(const char* form, Accept_t* ac, int flags)
+#else
+static char* _sfsetclass(form, ac, flags)
+char* form; /* format string */
+Accept_t* ac; /* values of accepted characters */
+int flags; /* SFFMT_LONG for wchar_t */
+#endif
+{
+ int c, endc, n;
+#if _has_multibyte
+ SFMBDCL(mbs)
+#endif
+
+ if(*form == '^') /* complementing this set */
+ { ac->yes = 0;
+ form += 1;
+ }
+ else ac->yes = 1;
+
+ for(c = 0; c <= SF_MAXCHAR; ++c)
+ ac->ok[c] = !ac->yes;
+
+ if(*form == ']' || *form == '-') /* special first char */
+ { ac->ok[*form] = ac->yes;
+ form += 1;
+ }
+ ac->form = (char*)form;
+
+ if(flags&SFFMT_LONG)
+ SFMBCLR(&mbs);
+ for(n = 1; *form != ']'; form += n)
+ { if((c = *((uchar*)form)) == 0)
+ return NIL(char*);
+
+ if(*(form+1) == '-')
+ { endc = *((uchar*)(form+2));
+#if _has_multibyte
+ if(c >= 128 || endc >= 128 ) /* range must be ascii */
+ goto one_char;
+#endif
+ for(; c <= endc; ++c)
+ ac->ok[c] = ac->yes;
+ n = 3;
+ }
+ else
+ { one_char:
+#if _has_multibyte /* true multi-byte chars must be checked differently */
+ if((flags&SFFMT_LONG) && (n = (int)SFMBLEN(form,&mbs)) <= 0)
+ return NIL(char*);
+ if(n == 1)
+#endif
+ ac->ok[c] = ac->yes;
+ }
+ }
+
+ ac->endf = (char*)form;
+ return (char*)(form+1);
+}
+
+#if _has_multibyte
+#if __STD_C
+static int _sfwaccept(wchar_t wc, Accept_t* ac)
+#else
+static int _sfwaccept(wc, ac)
+wchar_t wc;
+Accept_t* ac;
+#endif
+{
+ int endc, c, n;
+ wchar_t fwc;
+ char *form = ac->form;
+ SFMBDCL(mbs)
+
+ SFMBCLR(&mbs);
+ for(n = 1; *form != ']'; form += n)
+ { if((c = *((uchar*)form)) == 0)
+ return 0;
+
+ if(*(form+1) == '-')
+ { endc = *((uchar*)(form+2));
+ if(c >= 128 || endc >= 128 ) /* range must be ascii */
+ goto one_char;
+ n = 3;
+ }
+ else
+ { one_char:
+ if((n = mbrtowc(&fwc, form, ac->endf-form, &mbs)) > 1 &&
+ wc == fwc )
+ return ac->yes;
+ }
+ }
+
+ return !ac->yes;
+}
+
+#if _has_multibyte == 1
+#define SFgetwc(sc,wc,fmt,ac,mbs) _sfgetwc(sc,wc,fmt,ac,(Void_t*)(mbs))
+#else
+#define SFgetwc(sc,wc,fmt,ac,mbs) _sfgetwc(sc,wc,fmt,ac,NIL(Void_t*))
+#endif
+
+#if __STD_C
+static int _sfgetwc(Scan_t* sc, wchar_t* wc, int fmt, Accept_t* ac, Void_t *mbs)
+#else
+static int _sfgetwc(sc, wc, fmt, ac, mbs)
+Scan_t* sc; /* the scanning handle */
+wchar_t* wc; /* to return a scanned wchar_t */
+int fmt; /* %s, %c, %[ */
+Accept_t* ac; /* accept handle for %[ */
+Void_t* mbs; /* multibyte parsing state */
+#endif
+{
+ int n, v;
+ char b[16]; /* assuming that SFMBMAX <= 16! */
+
+ /* shift left data so that there will be more room to back up on error.
+ this won't help streams with small buffers - c'est la vie! */
+ if(sc->d > sc->f->data && (n = sc->endd - sc->d) > 0 && n < SFMBMAX)
+ { memcpy(sc->f->data, sc->d, n);
+ if(sc->f->endr == sc->f->endb)
+ sc->f->endr = sc->f->data+n;
+ if(sc->f->endw == sc->f->endb)
+ sc->f->endw = sc->f->data+n;
+ sc->f->endb = sc->f->data+n;
+ sc->d = sc->data = sc->f->data;
+ sc->endd = sc->f->endb;
+ if(!mbs) sc->f->endb = sc->endd; /* stop cc's "unused mbs" warning */
+ }
+
+ for(n = 0; n < SFMBMAX; )
+ { if((v = _scgetc((Void_t*)sc, 0)) <= 0)
+ goto no_match;
+ else b[n++] = v;
+
+ if(mbrtowc(wc, b, n, (mbstate_t*)mbs) == (size_t)(-1))
+ goto no_match; /* malformed multi-byte char */
+ else
+ { /* multi-byte char converted successfully */
+ if(fmt == 'c')
+ return 1;
+ else if(fmt == 's')
+ { if(n > 1 || (n == 1 && !isspace(b[0]) ) )
+ return 1;
+ else goto no_match;
+ }
+ else if(fmt == '[')
+ { if((n == 1 && ac->ok[b[0]]) ||
+ (n > 1 && _sfwaccept(*wc,ac)) )
+ return 1;
+ else goto no_match;
+ }
+ else /* if(fmt == '1') match a single wchar_t */
+ { if(*wc == ac->wc)
+ return 1;
+ else goto no_match;
+ }
+ }
+ }
+
+no_match: /* this unget is lossy on a stream with small buffer */
+ if((sc->d -= n) < sc->data)
+ sc->d = sc->data;
+ return 0;
+}
+#endif /*_has_multibyte*/
+
+
+#if __STD_C
+int sfvscanf(Sfio_t* f, reg const char* form, va_list args)
+#else
+int sfvscanf(f,form,args)
+Sfio_t* f; /* file to be scanned */
+reg char* form; /* scanning format */
+va_list args;
+#endif
+{
+ reg int inp, shift, base, width;
+ ssize_t size;
+ int fmt, flags, dot, n_assign, v, n, n_input;
+ char *sp;
+
+ Accept_t acc;
+
+ Argv_t argv;
+ Sffmt_t *ft;
+ Fmt_t *fm, *fmstk;
+
+ Fmtpos_t* fp;
+ char *oform;
+ va_list oargs;
+ int argp, argn;
+
+ int decimal = 0, thousand = 0;
+
+#if _has_multibyte
+ wchar_t wc;
+ SFMBDCL(fmbs)
+ SFMBDCL(mbs)
+#endif
+
+ Void_t* value; /* location to assign scanned value */
+ char* t_str;
+ ssize_t n_str;
+
+ /* local buffering system */
+ Scan_t scd;
+ uchar *d, *endd, *data;
+ int peek;
+#define SFbuf(f) (_sfbuf(f,&peek), (data = d = f->next), (endd = f->endb) )
+#define SFlen(f) (d - data)
+#define SFinit(f) ((peek = f->extent < 0 && (f->flags&SF_SHARE)), SFbuf(f) )
+#define SFend(f) ((n_input += SFlen(f)), \
+ (peek ? SFREAD(f,(Void_t*)data,SFlen(f)) : ((f->next = d),0)) )
+#define SFgetc(f,c) ((c) = (d < endd || (SFend(f), SFbuf(f), d < endd)) ? \
+ (int)(*d++) : -1 )
+#define SFungetc(f,c) (d -= 1)
+
+ SFMTXDECL(f);
+
+ SFCVINIT(); /* initialize conversion tables */
+
+ SFMTXENTER(f,-1);
+
+ if(!form || f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0)
+ SFMTXRETURN(f, -1);
+ SFLOCK(f,0);
+
+ SFinit(f); /* initialize local buffering system */
+
+ n_assign = n_input = 0; inp = -1;
+
+ fmstk = NIL(Fmt_t*);
+ ft = NIL(Sffmt_t*);
+
+ fp = NIL(Fmtpos_t*);
+ argn = -1;
+ oform = (char*)form;
+ va_copy(oargs,args);
+
+ SFSETLOCALE(&decimal, &thousand);
+
+loop_fmt:
+ SFMBCLR(&fmbs);
+ while((fmt = *form++))
+ { if(fmt != '%')
+ { if(isspace(fmt))
+ { if(fmt != '\n' || !(f->flags&SF_LINE))
+ fmt = -1;
+ for(;;)
+ { if(SFgetc(f,inp) < 0 || inp == fmt)
+ goto loop_fmt;
+ else if(!isspace(inp))
+ { SFungetc(f,inp);
+ goto loop_fmt;
+ }
+ }
+ }
+ else
+ { match_1:
+#if _has_multibyte
+ if((n = (int)mbrtowc(&wc,form-1,SFMBMAX,&fmbs)) <= 0)
+ goto pop_fmt;
+ if(n > 1)
+ { acc.wc = wc;
+ SCinit(&scd,0); SFMBCLR(&mbs);
+ v = SFgetwc(&scd, &wc, '1', &acc, &mbs);
+ SCend(&scd,0);
+ if(v == 0)
+ goto pop_fmt;
+ form += n-1;
+ }
+ else
+#endif
+ if(SFgetc(f,inp) != fmt)
+ { if(inp < 0)
+ goto done;
+ SFungetc(f,inp);
+ goto pop_fmt;
+ }
+ }
+ continue;
+ }
+
+ if(*form == '%')
+ { form += 1;
+ do SFgetc(f,inp); while(isspace(inp)); /* skip starting blanks */
+ SFungetc(f,inp);
+ goto match_1;
+ }
+
+ if(*form == '\0')
+ goto pop_fmt;
+
+ if(*form == '*')
+ { flags = SFFMT_SKIP;
+ form += 1;
+ }
+ else flags = 0;
+
+ /* matching some pattern */
+ base = 10; size = -1;
+ width = dot = 0;
+ t_str = NIL(char*); n_str = 0;
+ value = NIL(Void_t*);
+ argp = -1;
+
+ loop_flags: /* LOOP FOR FLAGS, WIDTH, BASE, TYPE */
+ switch((fmt = *form++) )
+ {
+ case LEFTP : /* get the type which is enclosed in balanced () */
+ t_str = (char*)form;
+ for(v = 1;;)
+ { switch(*form++)
+ {
+ case 0 : /* not balanceable, retract */
+ form = t_str;
+ t_str = NIL(char*);
+ n_str = 0;
+ goto loop_flags;
+ case LEFTP : /* increasing nested level */
+ v += 1;
+ continue;
+ case RIGHTP : /* decreasing nested level */
+ if((v -= 1) != 0)
+ continue;
+ if(*t_str != '*' )
+ n_str = (form-1) - t_str;
+ else
+ { t_str = (*_Sffmtintf)(t_str+1,&n);
+ if(*t_str == '$')
+ { if(!fp &&
+ !(fp = (*_Sffmtposf)(f,oform,oargs,ft,1)) )
+ goto pop_fmt;
+ n = FP_SET(n,argn);
+ }
+ else n = FP_SET(-1,argn);
+
+ if(fp)
+ { t_str = fp[n].argv.s;
+ n_str = fp[n].ft.size;
+ }
+ else if(ft && ft->extf )
+ { FMTSET(ft, form,args,
+ LEFTP, 0, 0, 0,0,0,
+ NIL(char*),0);
+ n = (*ft->extf)
+ (f,(Void_t*)&argv,ft);
+ if(n < 0)
+ goto pop_fmt;
+ if(!(ft->flags&SFFMT_VALUE) )
+ goto t_arg;
+ if((t_str = argv.s) &&
+ (n_str = (int)ft->size) < 0)
+ n_str = strlen(t_str);
+ }
+ else
+ { t_arg:
+ if((t_str = va_arg(args,char*)) )
+ n_str = strlen(t_str);
+ }
+ }
+ goto loop_flags;
+ }
+ }
+
+ case '#' : /* alternative format */
+ flags |= SFFMT_ALTER;
+ goto loop_flags;
+
+ case '.' : /* width & base */
+ dot += 1;
+ if(isdigit(*form))
+ { fmt = *form++;
+ goto dot_size;
+ }
+ else if(*form == '*')
+ { form = (*_Sffmtintf)(form+1,&n);
+ if(*form == '$')
+ { form += 1;
+ if(!fp &&
+ !(fp = (*_Sffmtposf)(f,oform,oargs,ft,1)) )
+ goto pop_fmt;
+ n = FP_SET(n,argn);
+ }
+ else n = FP_SET(-1,argn);
+
+ if(fp)
+ v = fp[n].argv.i;
+ else if(ft && ft->extf )
+ { FMTSET(ft, form,args, '.',dot, 0, 0,0,0,
+ NIL(char*), 0);
+ if((*ft->extf)(f, (Void_t*)(&argv), ft) < 0)
+ goto pop_fmt;
+ if(ft->flags&SFFMT_VALUE)
+ v = argv.i;
+ else v = (dot <= 2) ? va_arg(args,int) : 0;
+ }
+ else v = (dot <= 2) ? va_arg(args,int) : 0;
+ if(v < 0)
+ v = 0;
+ goto dot_set;
+ }
+ else goto loop_flags;
+
+ case '0' : case '1' : case '2' : case '3' : case '4' :
+ case '5' : case '6' : case '7' : case '8' : case '9' :
+ dot_size :
+ for(v = fmt-'0'; isdigit(*form); ++form)
+ v = v*10 + (*form - '0');
+
+ if(*form == '$')
+ { form += 1;
+ if(!fp && !(fp = (*_Sffmtposf)(f,oform,oargs,ft,1)) )
+ goto pop_fmt;
+ argp = v-1;
+ goto loop_flags;
+ }
+
+ dot_set :
+ if(dot == 0 || dot == 1)
+ width = v;
+ else if(dot == 2)
+ base = v;
+ goto loop_flags;
+
+ case 'I' : /* object size */
+ size = -1; flags = (flags & ~SFFMT_TYPES) | SFFMT_IFLAG;
+ if(isdigit(*form))
+ { for(size = 0, n = *form; isdigit(n); n = *++form)
+ size = size*10 + (n - '0');
+ }
+ else if(*form == '*')
+ { form = (*_Sffmtintf)(form+1,&n);
+ if(*form == '$')
+ { form += 1;
+ if(!fp &&
+ !(fp = (*_Sffmtposf)(f,oform,oargs,ft,1)))
+ goto pop_fmt;
+ n = FP_SET(n,argn);
+ }
+ else n = FP_SET(-1,argn);
+
+ if(fp) /* use position list */
+ size = fp[n].argv.i;
+ else if(ft && ft->extf )
+ { FMTSET(ft, form,args, 'I',sizeof(int), 0, 0,0,0,
+ NIL(char*), 0);
+ if((*ft->extf)(f, (Void_t*)(&argv), ft) < 0)
+ goto pop_fmt;
+ if(ft->flags&SFFMT_VALUE)
+ size = argv.i;
+ else size = va_arg(args,int);
+ }
+ else size = va_arg(args,int);
+ }
+ goto loop_flags;
+
+ case 'l' :
+ size = -1; flags &= ~SFFMT_TYPES;
+ if(*form == 'l')
+ { form += 1;
+ flags |= SFFMT_LLONG;
+ }
+ else flags |= SFFMT_LONG;
+ goto loop_flags;
+ case 'h' :
+ size = -1; flags &= ~SFFMT_TYPES;
+ if(*form == 'h')
+ { form += 1;
+ flags |= SFFMT_SSHORT;
+ }
+ else flags |= SFFMT_SHORT;
+ goto loop_flags;
+ case 'L' :
+ size = -1; flags = (flags&~SFFMT_TYPES) | SFFMT_LDOUBLE;
+ goto loop_flags;
+ case 'j' :
+ size = -1; flags = (flags&~SFFMT_TYPES) | SFFMT_JFLAG;
+ goto loop_flags;
+ case 'z' :
+ size = -1; flags = (flags&~SFFMT_TYPES) | SFFMT_ZFLAG;
+ goto loop_flags;
+ case 't' :
+ size = -1; flags = (flags&~SFFMT_TYPES) | SFFMT_TFLAG;
+ goto loop_flags;
+ case QUOTE :
+ if(thousand > 0)
+ flags |= SFFMT_THOUSAND;
+ goto loop_flags;
+ }
+
+ /* set object size for scalars */
+ if(flags & SFFMT_TYPES)
+ { if((_Sftype[fmt]&(SFFMT_INT|SFFMT_UINT)) || fmt == 'n')
+ { if(flags&SFFMT_LONG)
+ size = sizeof(long);
+ else if(flags&SFFMT_SHORT)
+ size = sizeof(short);
+ else if(flags&SFFMT_SSHORT)
+ size = sizeof(char);
+ else if(flags&SFFMT_TFLAG)
+ size = sizeof(ptrdiff_t);
+ else if(flags&SFFMT_ZFLAG)
+ size = sizeof(size_t);
+ else if(flags&(SFFMT_LLONG|SFFMT_JFLAG) )
+ size = sizeof(Sflong_t);
+ else if(flags&SFFMT_IFLAG)
+ { if(size <= 0 ||
+ size == sizeof(Sflong_t)*CHAR_BIT )
+ size = sizeof(Sflong_t);
+ }
+ else if(size < 0)
+ size = sizeof(int);
+ }
+ else if(_Sftype[fmt]&SFFMT_FLOAT)
+ { if(flags&(SFFMT_LONG|SFFMT_LLONG))
+ size = sizeof(double);
+ else if(flags&SFFMT_LDOUBLE)
+ size = sizeof(Sfdouble_t);
+ else if(flags&SFFMT_IFLAG)
+ { if(size <= 0)
+ size = sizeof(Sfdouble_t);
+ }
+ else if(size < 0)
+ size = sizeof(float);
+ }
+ else if(_Sftype[fmt]&SFFMT_CHAR)
+ {
+#if _has_multibyte
+ if((flags&SFFMT_LONG) || fmt == 'C')
+ { size = sizeof(wchar_t) > sizeof(int) ?
+ sizeof(wchar_t) : sizeof(int);
+ } else
+#endif
+ if(size < 0)
+ size = sizeof(int);
+ }
+ }
+
+ argp = FP_SET(argp,argn);
+ if(fp)
+ { if(!(fp[argp].ft.flags&SFFMT_SKIP) )
+ { n_assign += 1;
+ value = fp[argp].argv.vp;
+ size = fp[argp].ft.size;
+ if(ft && ft->extf && fp[argp].ft.fmt != fp[argp].fmt)
+ fmt = fp[argp].ft.fmt;
+ }
+ else flags |= SFFMT_SKIP;
+ }
+ else if(ft && ft->extf)
+ { FMTSET(ft, form,args, fmt, size,flags, width,0,base, t_str,n_str);
+ SFend(f); SFOPEN(f,0);
+ v = (*ft->extf)(f, (Void_t*)&argv, ft);
+ SFLOCK(f,0); SFbuf(f);
+
+ if(v < 0)
+ goto pop_fmt;
+ else if(v > 0) /* extf comsumed v input bytes */
+ { n_input += v;
+ if(!(ft->flags&SFFMT_SKIP) )
+ n_assign += 1;
+ continue;
+ }
+ else /* if(v == 0): extf did not use input stream */
+ { FMTGET(ft, form,args, fmt, size, flags, width,n,base);
+
+ if((ft->flags&SFFMT_VALUE) && !(ft->flags&SFFMT_SKIP) )
+ value = argv.vp;
+ }
+ }
+
+ if(_Sftype[fmt] == 0) /* unknown pattern */
+ goto pop_fmt;
+
+ if(fmt == '!')
+ { if(!fp)
+ fp = (*_Sffmtposf)(f,oform,oargs,ft,1);
+ else goto pop_fmt;
+
+ if(!(argv.ft = va_arg(args,Sffmt_t*)) )
+ continue;
+ if(!argv.ft->form && ft ) /* change extension functions */
+ { if(ft->eventf &&
+ (*ft->eventf)(f,SF_DPOP,(Void_t*)form,ft) < 0)
+ continue;
+ fmstk->ft = ft = argv.ft;
+ }
+ else /* stack a new environment */
+ { if(!(fm = (Fmt_t*)malloc(sizeof(Fmt_t))) )
+ goto done;
+
+ ft = fm->ft = argv.ft;
+ SFMBSET(ft->mbs, &fmbs);
+ if(ft->form)
+ { fm->form = (char*)form; SFMBCPY(&fm->mbs,&fmbs);
+ va_copy(fm->args,args);
+
+ fm->oform = oform;
+ va_copy(fm->oargs,oargs);
+ fm->argn = argn;
+ fm->fp = fp;
+
+ form = ft->form; SFMBCLR(ft->mbs);
+ va_copy(args,ft->args);
+ argn = -1;
+ fp = NIL(Fmtpos_t*);
+ oform = (char*)form;
+ va_copy(oargs,args);
+ }
+ else fm->form = NIL(char*);
+
+ fm->eventf = ft->eventf;
+ fm->next = fmstk;
+ fmstk = fm;
+ }
+ continue;
+ }
+
+ /* get the address to assign value */
+ if(!value && !(flags&SFFMT_SKIP) )
+ value = va_arg(args,Void_t*);
+
+ if(fmt == 'n') /* return length of consumed input */
+ {
+#if !_ast_intmax_long
+ if(size == sizeof(Sflong_t) )
+ *((Sflong_t*)value) = (Sflong_t)(n_input+SFlen(f));
+ else
+#endif
+ if(size == sizeof(long) )
+ *((long*)value) = (long)(n_input+SFlen(f));
+ else if(size == sizeof(short) )
+ *((short*)value) = (short)(n_input+SFlen(f));
+ else if(size == sizeof(uchar))
+ *((uchar*)value) = (uchar)(n_input+SFlen(f));
+ else *((int*)value) = (int)(n_input+SFlen(f));
+ continue;
+ }
+
+ /* if get here, start scanning input */
+ if(width == 0)
+ width = fmt == 'c' ? 1 : MAXWIDTH;
+
+ /* define the first input character */
+ if(fmt == 'c' || fmt == '[' || fmt == 'C' )
+ SFgetc(f,inp);
+ else
+ { do { SFgetc(f,inp); }
+ while(isspace(inp)); /* skip starting blanks */
+ }
+ if(inp < 0)
+ goto done;
+
+ if(_Sftype[fmt] == SFFMT_FLOAT)
+ { SFungetc(f,inp); SCinit(&scd,1);
+ argv.ld = _sfdscan((Void_t*)(&scd), _scgetc);
+ SCend(&scd,1);
+
+ if(scd.error >= 0)
+ { if(inp >= 0)
+ SFungetc(f, inp);
+ goto pop_fmt;
+ }
+
+ if(value)
+ {
+#if !_ast_fltmax_double
+ if(size == sizeof(Sfdouble_t))
+ *((Sfdouble_t*)value) = argv.ld;
+ else
+#endif
+ if(size == sizeof(double))
+ *((double*)value) = (double)argv.ld;
+ else *((float*)value) = (float)argv.ld;
+
+ n_assign += 1;
+ }
+ }
+ else if(_Sftype[fmt] == SFFMT_UINT || fmt == 'p')
+ { if(inp == '-')
+ { SFungetc(f,inp);
+ goto pop_fmt;
+ }
+ else goto int_cvt;
+ }
+ else if(_Sftype[fmt] == SFFMT_INT)
+ { int_cvt:
+ if(inp == '-' || inp == '+')
+ { if(inp == '-')
+ flags |= SFFMT_MINUS;
+ while(--width > 0 && SFgetc(f,inp) >= 0)
+ if(!isspace(inp))
+ break;
+ }
+ if(inp < 0)
+ goto done;
+
+ if(fmt == 'o')
+ base = 8;
+ else if(fmt == 'x' || fmt == 'X' || fmt == 'p')
+ base = 16;
+ else if(fmt == 'i' && inp == '0') /* self-described data */
+ { base = 8;
+ if(width > 1) /* peek to see if it's a base-16 */
+ { if(SFgetc(f,inp) >= 0)
+ { if(inp == 'x' || inp == 'X')
+ base = 16;
+ SFungetc(f,inp);
+ }
+ inp = '0';
+ }
+ }
+
+ /* now convert */
+ argv.lu = 0;
+ if(base == 16)
+ { sp = (char*)_Sfcv36;
+ shift = 4;
+ if(sp[inp] >= 16)
+ { SFungetc(f,inp);
+ goto pop_fmt;
+ }
+ if(inp == '0' && --width > 0)
+ { /* skip leading 0x or 0X */
+ if(SFgetc(f,inp) >= 0 &&
+ (inp == 'x' || inp == 'X') && --width > 0)
+ SFgetc(f,inp);
+ }
+ if(inp >= 0 && sp[inp] < 16)
+ goto base_shift;
+ }
+ else if(base == 10)
+ { for(n = v = 0;; )
+ { /* fast base 10 conversion */
+#define TEN(x) (((x) << 3) + ((x) << 1) )
+ if (inp >= '0' && inp <= '9')
+ { argv.lu = TEN(argv.lu) + (inp-'0');
+ n += 1;
+ }
+ else if(inp == thousand)
+ { if((v && n != 3) || (!v && n > 3) )
+ break;
+ v = 1; n = 0;
+ }
+ else break;
+ if((width -= 1) <= 0 || SFgetc(f,inp) < 0)
+ break;
+ }
+ if (!n && !v)
+ { SFungetc(f,inp);
+ goto pop_fmt;
+ }
+
+ if(fmt == 'i' && inp == '#' && !(flags&SFFMT_ALTER) )
+ { base = (int)argv.lu;
+ if(base < 2 || base > SF_RADIX)
+ goto pop_fmt;
+ argv.lu = 0;
+ sp = (char*)(base <= 36 ? _Sfcv36 : _Sfcv64);
+ if(--width > 0 &&
+ SFgetc(f,inp) >= 0 && sp[inp] < base)
+ goto base_conv;
+ }
+ }
+ else
+ { /* other bases */
+ sp = (char*)(base <= 36 ? _Sfcv36 : _Sfcv64);
+ if(base < 2 || base > SF_RADIX || sp[inp] >= base)
+ { SFungetc(f,inp);
+ goto pop_fmt;
+ }
+
+ base_conv: /* check for power of 2 conversions */
+ if((base & ~(base-1)) == base)
+ { if(base < 8)
+ shift = base < 4 ? 1 : 2;
+ else if(base < 32)
+ shift = base < 16 ? 3 : 4;
+ else shift = base < 64 ? 5 : 6;
+
+ base_shift: do
+ { argv.lu = (argv.lu << shift) + sp[inp];
+ } while(--width > 0 &&
+ SFgetc(f,inp) >= 0 && sp[inp] < base);
+ }
+ else
+ { do
+ { argv.lu = (argv.lu * base) + sp[inp];
+ } while(--width > 0 &&
+ SFgetc(f,inp) >= 0 && sp[inp] < base);
+ }
+ }
+
+ if(flags&SFFMT_MINUS)
+ argv.ll = -argv.ll;
+
+ if(value)
+ { n_assign += 1;
+
+ if(fmt == 'p')
+#if _more_void_int
+ *((Void_t**)value) = (Void_t*)((ulong)argv.lu);
+#else
+ *((Void_t**)value) = (Void_t*)((uint)argv.lu);
+#endif
+#if !_ast_intmax_long
+ else if(size == sizeof(Sflong_t))
+ *((Sflong_t*)value) = argv.ll;
+#endif
+ else if(size == sizeof(long))
+ { if(fmt == 'd' || fmt == 'i')
+ *((long*)value) = (long)argv.ll;
+ else *((ulong*)value) = (ulong)argv.lu;
+ }
+ else if(size == sizeof(short))
+ { if(fmt == 'd' || fmt == 'i')
+ *((short*)value) = (short)argv.ll;
+ else *((ushort*)value) = (ushort)argv.lu;
+ }
+ else if(size == sizeof(char) )
+ { if(fmt == 'd' || fmt == 'i')
+ *((char*)value) = (char)argv.ll;
+ else *((uchar*)value) = (uchar)argv.lu;
+ }
+ else
+ { if(fmt == 'd' || fmt == 'i')
+ *((int*)value) = (int)argv.ll;
+ else *((uint*)value) = (uint)argv.lu;
+ }
+ }
+ }
+ else if(fmt == 'C' || fmt == 'S')
+ { fmt = fmt == 'C' ? 'c' : 's';
+ flags = (flags & ~SFFMT_TYPES) | SFFMT_LONG;
+ goto do_string;
+ }
+ else if(fmt == 's' || fmt == 'c' || fmt == '[' )
+ { do_string:
+ if(value)
+ { if(size < 0)
+ size = MAXWIDTH;
+ if(fmt != 'c')
+ size -= 1;
+#if _has_multibyte
+ if(flags&SFFMT_LONG)
+ argv.ws = (wchar_t*)value;
+ else
+#endif
+ argv.s = (char*)value;
+ }
+ else size = 0;
+
+ if(fmt == '[' && !(form = _sfsetclass(form,&acc,flags)) )
+ { SFungetc(f,inp);
+ goto pop_fmt;
+ }
+
+ n = 0; /* count number of scanned characters */
+#if _has_multibyte
+ if(flags&SFFMT_LONG)
+ { SFungetc(f,inp); SCinit(&scd,0); SFMBCLR(&mbs);
+ for(; width > 0; --width)
+ { if(SFgetwc(&scd,&wc,fmt,&acc,&mbs) == 0)
+ break;
+ if((n += 1) <= size)
+ *argv.ws++ = wc;
+ }
+ SCend(&scd,0);
+ }
+ else
+#endif
+
+ if(fmt == 's')
+ { do
+ { if(isspace(inp))
+ break;
+ if((n += 1) <= size)
+ *argv.s++ = inp;
+ } while(--width > 0 && SFgetc(f,inp) >= 0);
+ }
+ else if(fmt == 'c')
+ { do
+ { if((n += 1) <= size)
+ *argv.s++ = inp;
+ } while(--width > 0 && SFgetc(f,inp) >= 0);
+ }
+ else /* if(fmt == '[') */
+ { do
+ { if(!acc.ok[inp])
+ { if(n > 0 || (flags&SFFMT_ALTER) )
+ break;
+ else
+ { SFungetc(f,inp);
+ goto pop_fmt;
+ }
+ }
+ if((n += 1) <= size)
+ *argv.s++ = inp;
+ } while(--width > 0 && SFgetc(f,inp) >= 0);
+ }
+
+ if(value && (n > 0 || fmt == '[') )
+ { n_assign += 1;
+ if(fmt != 'c' && size >= 0)
+ {
+#if _has_multibyte
+ if(flags&SFFMT_LONG)
+ *argv.ws = 0;
+ else
+#endif
+ *argv.s = 0;
+ }
+ }
+ }
+
+ if(width > 0 && inp >= 0)
+ SFungetc(f,inp);
+ }
+
+pop_fmt:
+ if(fp)
+ { free(fp);
+ fp = NIL(Fmtpos_t*);
+ }
+ while((fm = fmstk) ) /* pop the format stack and continue */
+ { if(fm->eventf)
+ { if(!form || !form[0])
+ (*fm->eventf)(f,SF_FINAL,NIL(Void_t*),ft);
+ else if((*fm->eventf)(f,SF_DPOP,(Void_t*)form,ft) < 0)
+ goto loop_fmt;
+ }
+
+ fmstk = fm->next;
+ if((form = fm->form) )
+ { SFMBCPY(&fmbs,&fm->mbs);
+ va_copy(args, fm->args);
+ oform = fm->oform;
+ va_copy(oargs,fm->oargs);
+ argn = fm->argn;
+ fp = fm->fp;
+ }
+ ft = fm->ft;
+ free(fm);
+ if(form && form[0])
+ goto loop_fmt;
+ }
+
+done:
+ if(fp)
+ free(fp);
+ while((fm = fmstk) )
+ { if(fm->eventf)
+ (*fm->eventf)(f,SF_FINAL,NIL(Void_t*),fm->ft);
+ fmstk = fm->next;
+ free(fm);
+ }
+
+ SFend(f);
+
+ SFOPEN(f,0);
+
+ if(n_assign == 0 && inp < 0)
+ n_assign = -1;
+
+ SFMTXRETURN(f,n_assign);
+}
diff --git a/src/lib/libast/sfio/sfwalk.c b/src/lib/libast/sfio/sfwalk.c
new file mode 100644
index 0000000..7019863
--- /dev/null
+++ b/src/lib/libast/sfio/sfwalk.c
@@ -0,0 +1,67 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Walk streams and run operations on them
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+int sfwalk(Sfwalk_f walkf, Void_t* data, int type)
+#else
+int sfwalk(walkf, data, type)
+Sfwalk_f walkf; /* return <0: stop, >=0: continue */
+Void_t* data;
+int type; /* walk streams with all given flags */
+#endif
+{
+ Sfpool_t *p;
+ Sfio_t *f;
+ int n, rv;
+
+ /* truly initializing std-streams before walking */
+ if(sfstdin->mode & SF_INIT)
+ _sfmode(sfstdin, (sfstdin->mode & SF_RDWR), 0);
+ if(sfstdout->mode & SF_INIT)
+ _sfmode(sfstdout, (sfstdout->mode & SF_RDWR), 0);
+ if(sfstderr->mode & SF_INIT)
+ _sfmode(sfstderr, (sfstderr->mode & SF_RDWR), 0);
+
+ for(rv = 0, p = &_Sfpool; p; p = p->next)
+ { for(n = 0; n < p->n_sf; )
+ { f = p->sf[n];
+
+ if(type != 0 && (f->_flags&type) != type )
+ continue; /* not in the interested set */
+
+ if((rv = (*walkf)(f, data)) < 0)
+ return rv;
+
+ if(p->sf[n] == f) /* move forward to next stream */
+ n += 1;
+ /* else - a sfclose() was done on current stream */
+ }
+ }
+
+ return rv;
+}
diff --git a/src/lib/libast/sfio/sfwr.c b/src/lib/libast/sfio/sfwr.c
new file mode 100644
index 0000000..9f1c0f9
--- /dev/null
+++ b/src/lib/libast/sfio/sfwr.c
@@ -0,0 +1,252 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Write data with discipline.
+** In the case of a string stream, this is used mainly to extend
+** the buffer. However, this is done here so that exception handling
+** is done uniformly across all stream types.
+**
+** Written by Kiem-Phong Vo.
+*/
+
+/* hole preserving writes */
+#if __STD_C
+static ssize_t sfoutput(Sfio_t* f, char* buf, size_t n)
+#else
+static ssize_t sfoutput(f,buf,n)
+Sfio_t* f;
+char* buf;
+size_t n;
+#endif
+{ reg char *sp, *wbuf, *endbuf;
+ reg ssize_t s, w, wr;
+
+ s = w = 0;
+ wbuf = buf;
+ endbuf = buf+n;
+ while(n > 0)
+ { if((ssize_t)n < _Sfpage) /* no hole possible */
+ { buf += n;
+ s = n = 0;
+ }
+ else while((ssize_t)n >= _Sfpage)
+ { /* see if a hole of 0's starts here */
+ sp = buf+1;
+ if(buf[0] == 0 && buf[_Sfpage-1] == 0)
+ { /* check byte at a time until int-aligned */
+ while(((ulong)sp)%sizeof(int))
+ { if(*sp != 0)
+ goto chk_hole;
+ sp += 1;
+ }
+
+ /* check using int to speed up */
+ while(sp < endbuf)
+ { if(*((int*)sp) != 0)
+ goto chk_hole;
+ sp += sizeof(int);
+ }
+
+ /* check the remaining bytes */
+ if(sp > endbuf)
+ { sp -= sizeof(int);
+ while(sp < endbuf)
+ { if(*sp != 0)
+ goto chk_hole;
+ sp += 1;
+ }
+ }
+ }
+
+ chk_hole:
+ if((s = sp-buf) >= _Sfpage) /* found a hole */
+ break;
+
+ /* skip a dirty page */
+ n -= _Sfpage;
+ buf += _Sfpage;
+ }
+
+ /* write out current dirty pages */
+ if(buf > wbuf)
+ { if((ssize_t)n < _Sfpage)
+ { buf = endbuf;
+ n = s = 0;
+ }
+ if((wr = syswritef(f->file,wbuf,buf-wbuf)) > 0)
+ { w += wr;
+ f->bits &= ~SF_HOLE;
+ }
+ if(wr != (buf-wbuf))
+ break;
+ wbuf = buf;
+ }
+
+ /* seek to a rounded boundary within the hole */
+ if(s >= _Sfpage)
+ { s = (s/_Sfpage)*_Sfpage;
+ if(SFSK(f,(Sfoff_t)s,SEEK_CUR,NIL(Sfdisc_t*)) < 0)
+ break;
+ w += s;
+ n -= s;
+ wbuf = (buf += s);
+ f->bits |= SF_HOLE;
+
+ if(n > 0)
+ { /* next page must be dirty */
+ s = (ssize_t)n <= _Sfpage ? 1 : _Sfpage;
+ buf += s;
+ n -= s;
+ }
+ }
+ }
+
+ return w > 0 ? w : -1;
+}
+
+#if __STD_C
+ssize_t sfwr(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc)
+#else
+ssize_t sfwr(f,buf,n,disc)
+Sfio_t* f;
+Void_t* buf;
+size_t n;
+Sfdisc_t* disc;
+#endif
+{
+ reg ssize_t w;
+ reg Sfdisc_t* dc;
+ reg int local, oerrno;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f,(ssize_t)(-1));
+
+ GETLOCAL(f,local);
+ if(!local && !(f->bits&SF_DCDOWN)) /* an external user's call */
+ { if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0 )
+ SFMTXRETURN(f, (ssize_t)(-1));
+ if(f->next > f->data && SFSYNC(f) < 0 )
+ SFMTXRETURN(f, (ssize_t)(-1));
+ }
+
+ for(;;)
+ { /* stream locked by sfsetfd() */
+ if(!(f->flags&SF_STRING) && f->file < 0)
+ SFMTXRETURN(f,(ssize_t)0);
+
+ /* clear current error states */
+ f->flags &= ~(SF_EOF|SF_ERROR);
+
+ dc = disc;
+ if(f->flags&SF_STRING) /* just asking to extend buffer */
+ w = n + (f->next - f->data);
+ else
+ { /* warn that a write is about to happen */
+ SFDISC(f,dc,writef);
+ if(dc && dc->exceptf && (f->flags&SF_IOCHECK) )
+ { reg int rv;
+ if(local)
+ SETLOCAL(f);
+ if((rv = _sfexcept(f,SF_WRITE,n,dc)) > 0)
+ n = rv;
+ else if(rv < 0)
+ { f->flags |= SF_ERROR;
+ SFMTXRETURN(f, rv);
+ }
+ }
+
+ if(f->extent >= 0)
+ { /* make sure we are at the right place to write */
+ if(f->flags&SF_APPENDWR)
+ { if(f->here != f->extent || (f->flags&SF_SHARE))
+ { f->here = SFSK(f,(Sfoff_t)0,SEEK_END,dc);
+ f->extent = f->here;
+ }
+ }
+ else if((f->flags&SF_SHARE) && !(f->flags&SF_PUBLIC))
+ f->here = SFSK(f,f->here,SEEK_SET,dc);
+ }
+
+ oerrno = errno;
+ errno = 0;
+
+ if(dc && dc->writef)
+ { SFDCWR(f,buf,n,dc,w);
+ }
+ else if(SFISNULL(f))
+ w = n;
+ else if(f->flags&SF_WHOLE)
+ goto do_write;
+ else if((ssize_t)n >= _Sfpage &&
+ !(f->flags&(SF_SHARE|SF_APPENDWR)) &&
+ f->here == f->extent && (f->here%_Sfpage) == 0)
+ { if((w = sfoutput(f,(char*)buf,n)) <= 0)
+ goto do_write;
+ }
+ else
+ {
+ do_write:
+ if((w = syswritef(f->file,buf,n)) > 0)
+ f->bits &= ~SF_HOLE;
+ }
+
+ if(errno == 0)
+ errno = oerrno;
+
+ if(w > 0)
+ { if(!(f->bits&SF_DCDOWN) )
+ { if((f->flags&(SF_APPENDWR|SF_PUBLIC)) && f->extent >= 0 )
+ f->here = SFSK(f,(Sfoff_t)0,SEEK_CUR,dc);
+ else f->here += w;
+ if(f->extent >= 0 && f->here > f->extent)
+ f->extent = f->here;
+ }
+
+ SFMTXRETURN(f, (ssize_t)w);
+ }
+ }
+
+ if(local)
+ SETLOCAL(f);
+ switch(_sfexcept(f,SF_WRITE,w,dc))
+ {
+ case SF_ECONT :
+ goto do_continue;
+ case SF_EDONE :
+ w = local ? 0 : w;
+ SFMTXRETURN(f, (ssize_t)w);
+ case SF_EDISC :
+ if(!local && !(f->flags&SF_STRING))
+ goto do_continue;
+ /* else fall thru */
+ case SF_ESTACK :
+ SFMTXRETURN(f, (ssize_t)(-1));
+ }
+
+ do_continue:
+ for(dc = f->disc; dc; dc = dc->disc)
+ if(dc == disc)
+ break;
+ disc = dc;
+ }
+}
diff --git a/src/lib/libast/sfio/sfwrite.c b/src/lib/libast/sfio/sfwrite.c
new file mode 100644
index 0000000..170c863
--- /dev/null
+++ b/src/lib/libast/sfio/sfwrite.c
@@ -0,0 +1,171 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Write data out to the file system
+**
+** Written by Kiem-Phong Vo.
+*/
+
+#if __STD_C
+ssize_t sfwrite(Sfio_t* f, const Void_t* buf, size_t n)
+#else
+ssize_t sfwrite(f,buf,n)
+Sfio_t* f; /* write to this stream. */
+Void_t* buf; /* buffer to be written. */
+size_t n; /* number of bytes. */
+#endif
+{
+ reg uchar *s, *begs, *next;
+ reg ssize_t w;
+ reg int local;
+ SFMTXDECL(f);
+
+ SFMTXENTER(f, (ssize_t)(-1));
+
+ GETLOCAL(f,local);
+
+ if(!buf)
+ SFMTXRETURN(f, (ssize_t)(n == 0 ? 0 : -1) );
+
+ /* release peek lock */
+ if(f->mode&SF_PEEK)
+ { if(!(f->mode&SF_WRITE) && (f->flags&SF_RDWR) != SF_RDWR)
+ SFMTXRETURN(f, (ssize_t)(-1));
+
+ if((uchar*)buf != f->next &&
+ (!f->rsrv || f->rsrv->data != (uchar*)buf) )
+ SFMTXRETURN(f, (ssize_t)(-1));
+
+ f->mode &= ~SF_PEEK;
+
+ if(f->mode&SF_PKRD)
+ { /* read past peeked data */
+ char buf[16];
+ reg ssize_t r;
+
+ for(w = n; w > 0; )
+ { if((r = w) > sizeof(buf))
+ r = sizeof(buf);
+ if((r = sysreadf(f->file,buf,r)) <= 0)
+ { n -= w;
+ break;
+ }
+ else w -= r;
+ }
+
+ f->mode &= ~SF_PKRD;
+ f->endb = f->data + n;
+ f->here += n;
+ }
+
+ if((f->mode&SF_READ) && f->proc)
+ f->next += n;
+ }
+
+ s = begs = (uchar*)buf;
+ for(;; f->mode &= ~SF_LOCK)
+ { /* check stream mode */
+ if(SFMODE(f,local) != SF_WRITE && _sfmode(f,SF_WRITE,local) < 0 )
+ { w = s > begs ? s-begs : -1;
+ SFMTXRETURN(f,w);
+ }
+
+ SFLOCK(f,local);
+
+ w = f->endb - f->next;
+
+ if(s == f->next) /* after sfreserve */
+ { if(w > (ssize_t)n)
+ w = (ssize_t)n;
+ f->next = (s += w);
+ n -= w;
+ break;
+ }
+
+ /* attempt to create space in buffer */
+ if(w == 0 || ((f->flags&SF_WHOLE) && w < (ssize_t)n) )
+ { if(f->flags&SF_STRING) /* extend buffer */
+ { (void)SFWR(f, s, n-w, f->disc);
+ if((w = f->endb - f->next) < (ssize_t)n)
+ { if(!(f->flags&SF_STRING)) /* maybe sftmp */
+ { if(f->next > f->data)
+ goto fls_buf;
+ }
+ else if(w == 0)
+ break;
+ }
+ }
+ else if(f->next > f->data)
+ { fls_buf:
+ (void)SFFLSBUF(f, -1);
+ if((w = f->endb - f->next) < (ssize_t)n &&
+ (f->flags&SF_WHOLE) && f->next > f->data )
+ break;
+ }
+ }
+
+ if(!(f->flags&SF_STRING) && f->next == f->data &&
+ (((f->flags&SF_WHOLE) && w <= n) || SFDIRECT(f,n)) )
+ { /* bypass buffering */
+ if((w = SFWR(f,s,n,f->disc)) <= 0 )
+ break;
+ }
+ else
+ { if(w > (ssize_t)n)
+ w = (ssize_t)n;
+ if(w <= 0) /* no forward progress possible */
+ break;
+ memmove(f->next, s, w);
+ f->next += w;
+ }
+
+ s += w;
+ if((n -= w) <= 0)
+ break;
+ }
+
+ /* always flush buffer for share streams */
+ if(f->extent < 0 && (f->flags&SF_SHARE) && !(f->flags&SF_PUBLIC) )
+ (void)SFFLSBUF(f,-1);
+
+ /* check to see if buffer should be flushed */
+ else if(n == 0 && (f->flags&SF_LINE) && !(f->flags&SF_STRING))
+ { if((ssize_t)(n = f->next-f->data) > (w = s-begs))
+ n = w;
+ if(n > 0 && n < HIFORLINE)
+ { for(next = f->next-1; n > 0; --n, --next)
+ { if(*next == '\n')
+ { n = HIFORLINE;
+ break;
+ }
+ }
+ }
+ if(n >= HIFORLINE)
+ (void)SFFLSBUF(f,-1);
+ }
+
+ SFOPEN(f,local);
+
+ w = s-begs;
+ SFMTXRETURN(f,w);
+}
diff --git a/src/lib/libast/sfio/vthread.h b/src/lib/libast/sfio/vthread.h
new file mode 100644
index 0000000..4030958
--- /dev/null
+++ b/src/lib/libast/sfio/vthread.h
@@ -0,0 +1,219 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _VTHREAD_H
+#define _VTHREAD_H 1
+
+#define VTHREAD_VERSION 20001201L
+
+/* Header for the Vthread library.
+** Note that the macro vt_threaded may be defined
+** outside of vthread.h to suppress threading.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com
+*/
+
+#include <ast_common.h>
+#include <errno.h>
+
+/* ast doesn't do threads yet */
+#if _PACKAGE_ast && !defined(vt_threaded)
+#define vt_threaded 0
+#endif
+
+#if !defined(vt_threaded) || (defined(vt_threaded) && vt_threaded == 1)
+#define _may_use_threads 1
+#else
+#define _may_use_threads 0
+#endif
+#undef vt_threaded
+
+#if _may_use_threads && !defined(vt_threaded) && _hdr_pthread
+#define vt_threaded 1
+#include <pthread.h>
+typedef pthread_mutex_t _vtmtx_t;
+typedef pthread_once_t _vtonce_t;
+typedef pthread_t _vtself_t;
+typedef pthread_t _vtid_t;
+typedef pthread_attr_t _vtattr_t;
+
+#if !defined(PTHREAD_ONCE_INIT) && defined(pthread_once_init)
+#define PTHREAD_ONCE_INIT pthread_once_init
+#endif
+
+#endif
+
+#if _may_use_threads && !defined(vt_threaded) && _WIN32
+#define vt_threaded 1
+#include <windows.h>
+typedef CRITICAL_SECTION _vtmtx_t;
+typedef int _vtonce_t;
+typedef HANDLE _vtself_t;
+typedef DWORD _vtid_t;
+typedef SECURITY_ATTRIBUTES _vtattr_t;
+#endif
+
+#ifndef vt_threaded
+#define vt_threaded 0
+#endif
+
+/* common attributes for various structures */
+#define VT_RUNNING 000000001 /* thread is running */
+#define VT_SUSPENDED 000000002 /* thread is suspended */
+#define VT_WAITED 000000004 /* thread has been waited */
+#define VT_FREE 000010000 /* object can be freed */
+#define VT_INIT 000020000 /* object was initialized */
+#define VT_BITS 000030007 /* bits that we care about */
+
+/* directives for vtset() */
+#define VT_STACK 1 /* set stack size */
+
+typedef struct _vtmutex_s Vtmutex_t;
+typedef struct _vtonce_s Vtonce_t;
+typedef struct _vthread_s Vthread_t;
+
+#ifndef EINVAL
+#define EINVAL 22
+#endif
+#ifndef EBUSY
+#define EBUSY 16
+#endif
+#ifndef EDEADLK
+#define EDEADLK 45
+#endif
+#ifndef EPERM
+#define EPERM 1
+#endif
+
+_BEGIN_EXTERNS_
+
+extern Vthread_t* vtopen _ARG_((Vthread_t*, int));
+extern int vtclose _ARG_((Vthread_t*));
+extern int vtset _ARG_((Vthread_t*, int, Void_t*));
+extern int vtrun _ARG_((Vthread_t*, void*(*)(void*), void*));
+extern int vtkill _ARG_((Vthread_t*));
+extern int vtwait _ARG_((Vthread_t*));
+
+extern int vtonce _ARG_((Vtonce_t*, void(*)() ));
+
+extern Vtmutex_t* vtmtxopen _ARG_((Vtmutex_t*, int));
+extern int vtmtxclose _ARG_((Vtmutex_t*));
+extern int vtmtxlock _ARG_((Vtmutex_t*));
+extern int vtmtxtrylock _ARG_((Vtmutex_t*));
+extern int vtmtxunlock _ARG_((Vtmutex_t*));
+extern int vtmtxclrlock _ARG_((Vtmutex_t*));
+
+extern Void_t* vtstatus _ARG_((Vthread_t*));
+extern int vterror _ARG_((Vthread_t*));
+extern int vtmtxerror _ARG_((Vtmutex_t*));
+extern int vtonceerror _ARG_((Vtonce_t*));
+
+_END_EXTERNS_
+
+#if vt_threaded
+
+/* mutex structure */
+struct _vtmutex_s
+{ _vtmtx_t lock;
+ int count;
+ _vtid_t owner;
+ int state;
+ int error;
+};
+
+/* structure for states of thread */
+struct _vthread_s
+{ _vtself_t self; /* self-handle */
+ _vtid_t id; /* thread id */
+ _vtattr_t attrs; /* attributes */
+ size_t stack; /* stack size */
+ int state; /* execution state */
+ int error; /* error status */
+ Void_t* exit; /* exit value */
+};
+
+/* structure for exactly once execution */
+struct _vtonce_s
+{ int done;
+ _vtonce_t once;
+ int error;
+};
+
+#if _WIN32
+#define VTONCE_INITDATA {0, 0}
+#else
+#define VTONCE_INITDATA {0, PTHREAD_ONCE_INIT }
+#endif
+
+#define vtstatus(vt) ((vt)->exit)
+#define vterror(vt) ((vt)->error)
+#define vtmtxerror(mtx) ((mtx)->error)
+#define vtonceerror(once) ((once)->error)
+
+#endif /*vt_threaded*/
+
+/* fake structures and functions */
+#if !vt_threaded
+struct _vtmutex_s
+{ int error;
+};
+struct _vtattr_s
+{ int error;
+};
+struct _vthread_s
+{ int error;
+};
+struct _vtonce_s
+{ int error;
+};
+
+typedef int _vtmtx_t;
+typedef int _vtonce_t;
+typedef int _vtself_t;
+typedef int _vtid_t;
+typedef int _vtattr_t;
+
+#define VTONCE_INITDATA {0}
+
+#define vtopen(vt,flgs) ((Vthread_t*)0)
+#define vtclose(vt) (-1)
+#define vtkill(vt) (-1)
+#define vtwait(vt) (-1)
+#define vtrun(vt,fn,arg) (-1)
+
+#define vtset(vt,t,v) (-1)
+#define vtonce(on,fu) (-1)
+
+#define vtmtxopen(mtx,flgs) ((Vtmutex_t*)0)
+#define vtmtxclose(mtx) (-1)
+#define vtmtxlock(mtx) (-1)
+#define vtmtxtrylock(mtx) (-1)
+#define vtmtxunlock(mtx) (-1)
+#define vtmtxclrlock(mtx) (-1)
+
+#define vtstatus(vt) ((Void_t*)0)
+#define vterror(vt) (0)
+#define vtmtxerror(mtx) (0)
+#define vtonceerror(once) (0)
+
+#endif /*!vt_threaded*/
+
+#endif /*_VTHREAD_H*/
diff --git a/src/lib/libast/std/bytesex.h b/src/lib/libast/std/bytesex.h
new file mode 100644
index 0000000..d8a0783
--- /dev/null
+++ b/src/lib/libast/std/bytesex.h
@@ -0,0 +1,43 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * linux/gnu compatibility
+ */
+
+#ifndef _BYTESEX_H
+#define _BYTESEX_H
+
+#include <ast_common.h>
+
+#undef __BYTE_ORDER
+
+#if ( _ast_intswap & 3 ) == 3
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#else
+#if ( _ast_intswap & 3 ) == 1
+#define __BYTE_ORDER __PDP_ENDIAN
+#else
+#define __BYTE_ORDER __BIG_ENDIAN
+#endif
+#endif
+
+#endif
diff --git a/src/lib/libast/std/dirent.h b/src/lib/libast/std/dirent.h
new file mode 100644
index 0000000..de52967
--- /dev/null
+++ b/src/lib/libast/std/dirent.h
@@ -0,0 +1,22 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include <ast_dirent.h>
diff --git a/src/lib/libast/std/endian.h b/src/lib/libast/std/endian.h
new file mode 100644
index 0000000..c54e213
--- /dev/null
+++ b/src/lib/libast/std/endian.h
@@ -0,0 +1,54 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * linux/gnu compatibility
+ */
+
+#ifndef _ENDIAN_H
+#define _ENDIAN_H
+
+#include <bytesex.h>
+
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+#define __PDP_ENDIAN 3412
+
+#if defined (__USE_BSD) && !defined(__STRICT_ANSI__)
+
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN __LITTLE_ENDIAN
+#endif
+
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN __BIG_ENDIAN
+#endif
+
+#ifndef PDP_ENDIAN
+#define PDP_ENDIAN __PDP_ENDIAN
+#endif
+
+#undef BYTE_ORDER
+#define BYTE_ORDER __BYTE_ORDER
+
+#endif
+
+#endif
diff --git a/src/lib/libast/std/iconv.h b/src/lib/libast/std/iconv.h
new file mode 100644
index 0000000..fb82d62
--- /dev/null
+++ b/src/lib/libast/std/iconv.h
@@ -0,0 +1,22 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include <ast_iconv.h>
diff --git a/src/lib/libast/std/nl_types.h b/src/lib/libast/std/nl_types.h
new file mode 100644
index 0000000..99299a7
--- /dev/null
+++ b/src/lib/libast/std/nl_types.h
@@ -0,0 +1,22 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include <ast_nl_types.h>
diff --git a/src/lib/libast/std/stdio.h b/src/lib/libast/std/stdio.h
new file mode 100644
index 0000000..c3c09fe
--- /dev/null
+++ b/src/lib/libast/std/stdio.h
@@ -0,0 +1,22 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include <ast_stdio.h>
diff --git a/src/lib/libast/std/wchar.h b/src/lib/libast/std/wchar.h
new file mode 100644
index 0000000..9737c2d
--- /dev/null
+++ b/src/lib/libast/std/wchar.h
@@ -0,0 +1,22 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include <ast_wchar.h>
diff --git a/src/lib/libast/std/wctype.h b/src/lib/libast/std/wctype.h
new file mode 100644
index 0000000..1a3a94f
--- /dev/null
+++ b/src/lib/libast/std/wctype.h
@@ -0,0 +1,22 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include <ast_wctype.h>
diff --git a/src/lib/libast/stdio/_doprnt.c b/src/lib/libast/stdio/_doprnt.c
new file mode 100644
index 0000000..afa160d
--- /dev/null
+++ b/src/lib/libast/stdio/_doprnt.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+_doprnt(const char* fmt, va_list args, Sfio_t* f)
+{
+ STDIO_INT(f, "_doprnt", int, (const char*, va_list, Sfio_t*), (fmt, args, f))
+
+ return sfvprintf(f, fmt, args);
+}
diff --git a/src/lib/libast/stdio/_doscan.c b/src/lib/libast/stdio/_doscan.c
new file mode 100644
index 0000000..d112a40
--- /dev/null
+++ b/src/lib/libast/stdio/_doscan.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+_doscan(Sfio_t* f, const char* fmt, va_list args)
+{
+ STDIO_INT(f, "_doscan", int, (Sfio_t*, const char*, va_list), (f, fmt, args))
+
+ return sfvscanf(f, fmt, args);
+}
diff --git a/src/lib/libast/stdio/_filbuf.c b/src/lib/libast/stdio/_filbuf.c
new file mode 100644
index 0000000..f74e6d7
--- /dev/null
+++ b/src/lib/libast/stdio/_filbuf.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+_filbuf(Sfio_t* f)
+{
+ STDIO_INT(f, "_filbuf", int, (Sfio_t*), (f))
+
+ return _sffilbuf(f, 0);
+}
diff --git a/src/lib/libast/stdio/_flsbuf.c b/src/lib/libast/stdio/_flsbuf.c
new file mode 100644
index 0000000..51cbcda
--- /dev/null
+++ b/src/lib/libast/stdio/_flsbuf.c
@@ -0,0 +1,44 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+#if !STDIO_TRANSFER
+
+NoN(_flsbuf)
+
+#else
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int
+_flsbuf(int c, Sfio_t* f)
+{
+ STDIO_INT(f, "_flsbuf", int, (int, Sfio_t*), (c, f))
+
+ return _sfflsbuf(f, c);
+}
+
+#endif
diff --git a/src/lib/libast/stdio/_stdfun.c b/src/lib/libast/stdio/_stdfun.c
new file mode 100644
index 0000000..5858903
--- /dev/null
+++ b/src/lib/libast/stdio/_stdfun.c
@@ -0,0 +1,80 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if !_UWIN
+
+void _STUB_stdfun(){}
+
+#else
+
+#include <ast_windows.h>
+#include <uwin.h>
+#include <dlfcn.h>
+#include "FEATURE/uwin"
+
+#if _lib___iob_func
+#define IOB ((char*)__iob_func())
+#elif _lib___p__iob
+#define IOB ((char*)__p__iob())
+#elif _dat__iob
+#define IOB ((char*)_iob)
+#else
+#define IOB ((char*)_p__iob())
+#endif
+
+#define IOBMAX (512*32)
+
+#include "stdhdr.h"
+
+int
+_stdfun(Sfio_t* f, Funvec_t* vp)
+{
+ static char* iob;
+ static int init;
+ static void* bp;
+ static void* np;
+
+ if (!iob && !(iob = IOB))
+ return 0;
+ if (f && ((char*)f < iob || (char*)f > iob+IOBMAX))
+ return 0;
+ if (!vp->vec[1])
+ {
+ if (!init)
+ {
+ init = 1;
+ bp = dlopen("/usr/bin/stdio.dll", 0);
+ }
+ if (bp && (vp->vec[1] = (Fun_f)dlsym(bp, vp->name)))
+ return 1;
+ if (!np && !(np = dlopen("/sys/msvcrt.dll", 0)))
+ return -1;
+ if (!(vp->vec[1] = (Fun_f)dlsym(np, vp->name)))
+ return -1;
+ }
+ return 1;
+}
+
+#endif
diff --git a/src/lib/libast/stdio/_stdopen.c b/src/lib/libast/stdio/_stdopen.c
new file mode 100644
index 0000000..dc99778
--- /dev/null
+++ b/src/lib/libast/stdio/_stdopen.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/* OBSOLETE 20010101 -- use fdopen */
+
+#include "stdhdr.h"
+
+extern Sfio_t*
+_stdopen(int fd, const char* mode)
+{
+ return fdopen(fd, mode);
+}
diff --git a/src/lib/libast/stdio/_stdprintf.c b/src/lib/libast/stdio/_stdprintf.c
new file mode 100644
index 0000000..db57a8d
--- /dev/null
+++ b/src/lib/libast/stdio/_stdprintf.c
@@ -0,0 +1,38 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/* OBSOLETE 20010101 -- use printf */
+
+#include "stdhdr.h"
+
+extern int
+_stdprintf(const char* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+ v = sfvprintf(sfstdout, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/_stdscanf.c b/src/lib/libast/stdio/_stdscanf.c
new file mode 100644
index 0000000..386a0cb
--- /dev/null
+++ b/src/lib/libast/stdio/_stdscanf.c
@@ -0,0 +1,38 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/* OBSOLETE 20010101 -- use scanf */
+
+#include "stdhdr.h"
+
+extern int
+_stdscanf(const char* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+ v = sfvscanf(sfstdin, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/_stdsprnt.c b/src/lib/libast/stdio/_stdsprnt.c
new file mode 100644
index 0000000..71c8f74
--- /dev/null
+++ b/src/lib/libast/stdio/_stdsprnt.c
@@ -0,0 +1,38 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/* OBSOLETE 20010101 -- use sprintf */
+
+#include "stdhdr.h"
+
+extern int
+_stdsprintf(char* s, const char* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+ v = s ? sfvsprintf(s, SF_BUFSIZE, fmt, args) : -1;
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/_stdvbuf.c b/src/lib/libast/stdio/_stdvbuf.c
new file mode 100644
index 0000000..c9a2861
--- /dev/null
+++ b/src/lib/libast/stdio/_stdvbuf.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/* OBSOLETE 20010101 -- use setvbuf */
+
+#include "stdhdr.h"
+
+extern int
+_stdsetvbuf(Sfio_t* f, char* buf, int type, size_t size)
+{
+ return setvbuf(f, buf, type, size);
+}
diff --git a/src/lib/libast/stdio/_stdvsnprnt.c b/src/lib/libast/stdio/_stdvsnprnt.c
new file mode 100644
index 0000000..78fdf2d
--- /dev/null
+++ b/src/lib/libast/stdio/_stdvsnprnt.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/* OBSOLETE 20010101 -- use vsnprintf */
+
+#include "stdhdr.h"
+
+extern int
+_stdvsnprintf(char* s, int n, const char* fmt, va_list args)
+{
+ return vsnprintf(s, n, fmt, args);
+}
diff --git a/src/lib/libast/stdio/_stdvsprnt.c b/src/lib/libast/stdio/_stdvsprnt.c
new file mode 100644
index 0000000..a3b78e6
--- /dev/null
+++ b/src/lib/libast/stdio/_stdvsprnt.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/* OBSOLETE 20010101 -- use vsprintf */
+
+#include "stdhdr.h"
+
+extern int
+_stdvsprintf(char* s, const char* fmt, va_list args)
+{
+ return vsprintf(s, fmt, args);
+}
diff --git a/src/lib/libast/stdio/_stdvsscn.c b/src/lib/libast/stdio/_stdvsscn.c
new file mode 100644
index 0000000..0b1fd68
--- /dev/null
+++ b/src/lib/libast/stdio/_stdvsscn.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/* OBSOLETE 20010101 -- use vsscanf */
+
+#include "stdhdr.h"
+
+extern int
+_stdvsscanf(char* s, const char* fmt, va_list args)
+{
+ return vsscanf(s, fmt, args);
+}
diff --git a/src/lib/libast/stdio/asprintf.c b/src/lib/libast/stdio/asprintf.c
new file mode 100644
index 0000000..60f59cc
--- /dev/null
+++ b/src/lib/libast/stdio/asprintf.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+asprintf(char** s, const char* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+ v = vasprintf(s, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/clearerr.c b/src/lib/libast/stdio/clearerr.c
new file mode 100644
index 0000000..5d2e07c
--- /dev/null
+++ b/src/lib/libast/stdio/clearerr.c
@@ -0,0 +1,33 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+clearerr(Sfio_t* f)
+{
+ STDIO_INT(f, "clearerr", int, (Sfio_t*), (f))
+
+ sfclrerr(f);
+ return sfclrlock(f);
+}
diff --git a/src/lib/libast/stdio/fclose.c b/src/lib/libast/stdio/fclose.c
new file mode 100644
index 0000000..17063cb
--- /dev/null
+++ b/src/lib/libast/stdio/fclose.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+fclose(Sfio_t* f)
+{
+ STDIO_INT(f, "fclose", int, (Sfio_t*), (f))
+
+ return sfclose(f);
+}
diff --git a/src/lib/libast/stdio/fcloseall.c b/src/lib/libast/stdio/fcloseall.c
new file mode 100644
index 0000000..94c8553
--- /dev/null
+++ b/src/lib/libast/stdio/fcloseall.c
@@ -0,0 +1,57 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+#define MAXLOOP 3
+
+int
+fcloseall(void)
+{
+ Sfpool_t* p;
+ Sfpool_t* next;
+ int n;
+ int nclose;
+ int count;
+ int loop;
+
+ STDIO_INT(0, "fcloseall", int, (void), ())
+
+ for(loop = 0; loop < MAXLOOP; ++loop)
+ { nclose = count = 0;
+ for(p = &_Sfpool; p; p = next)
+ { /* find the next legitimate pool */
+ for(next = p->next; next; next = next->next)
+ if(next->n_sf > 0)
+ break;
+ for(n = 0; n < ((p == &_Sfpool) ? p->n_sf : 1); ++n)
+ { count += 1;
+ if(sfclose(p->sf[n]) >= 0)
+ nclose += 1;
+ }
+ }
+ if(nclose == count)
+ break;
+ }
+ return 0; /* always return 0 per GNU */
+}
diff --git a/src/lib/libast/stdio/fdopen.c b/src/lib/libast/stdio/fdopen.c
new file mode 100644
index 0000000..c707c83
--- /dev/null
+++ b/src/lib/libast/stdio/fdopen.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+Sfio_t*
+fdopen(int fd, const char* mode)
+{
+ int flags;
+
+ if (fd < 0 || !(flags = _sftype(mode, NiL, NiL)))
+ return 0;
+ return sfnew(NiL, NiL, (size_t)SF_UNBOUND, fd, flags);
+}
diff --git a/src/lib/libast/stdio/feof.c b/src/lib/libast/stdio/feof.c
new file mode 100644
index 0000000..2b77397
--- /dev/null
+++ b/src/lib/libast/stdio/feof.c
@@ -0,0 +1,42 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+#if !_UWIN
+
+NoN(feof)
+
+#else
+
+#undef feof
+
+int
+feof(Sfio_t* f)
+{
+ STDIO_INT(f, "feof", int, (Sfio_t*), (f))
+
+ return sfeof(f);
+}
+
+#endif
diff --git a/src/lib/libast/stdio/ferror.c b/src/lib/libast/stdio/ferror.c
new file mode 100644
index 0000000..d374df1
--- /dev/null
+++ b/src/lib/libast/stdio/ferror.c
@@ -0,0 +1,42 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+#if !_UWIN
+
+NoN(ferror)
+
+#else
+
+#undef ferror
+
+int
+ferror(Sfio_t* f)
+{
+ STDIO_INT(f, "ferror", int, (Sfio_t*), (f))
+
+ return sferror(f);
+}
+
+#endif
diff --git a/src/lib/libast/stdio/fflush.c b/src/lib/libast/stdio/fflush.c
new file mode 100644
index 0000000..de6574b
--- /dev/null
+++ b/src/lib/libast/stdio/fflush.c
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#ifndef _USE_GNU
+#define _USE_GNU
+#endif
+
+#include "stdhdr.h"
+
+int
+fflush(Sfio_t* f)
+{
+ if (!f)
+ return fcloseall();
+
+ STDIO_INT(f, "fflush", int, (Sfio_t*), (f))
+
+ if (f->extent > 0)
+ sfseek(f, (Sfoff_t)0, SEEK_CUR|SF_PUBLIC);
+ return (sfsync(f) < 0 || sfpurge(f) < 0) ? -1 : 0;
+}
diff --git a/src/lib/libast/stdio/fgetc.c b/src/lib/libast/stdio/fgetc.c
new file mode 100644
index 0000000..09d280f
--- /dev/null
+++ b/src/lib/libast/stdio/fgetc.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+fgetc(Sfio_t* f)
+{
+ STDIO_INT(f, "fgetc", int, (Sfio_t*), (f))
+
+ return sfgetc(f);
+}
diff --git a/src/lib/libast/stdio/fgetpos.c b/src/lib/libast/stdio/fgetpos.c
new file mode 100644
index 0000000..16da6fa
--- /dev/null
+++ b/src/lib/libast/stdio/fgetpos.c
@@ -0,0 +1,48 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#ifndef _NO_LARGEFILE64_SOURCE
+#define _NO_LARGEFILE64_SOURCE 1
+#endif
+
+#include "stdhdr.h"
+
+int
+fgetpos(Sfio_t* f, fpos_t* pos)
+{
+ STDIO_INT(f, "fgetpos", int, (Sfio_t*, fpos_t*), (f, pos))
+
+ return (pos->_sf_offset = sfseek(f, (Sfoff_t)0, SEEK_CUR)) >= 0 ? 0 : -1;
+}
+
+#ifdef _typ_int64_t
+
+int
+fgetpos64(Sfio_t* f, fpos64_t* pos)
+{
+ STDIO_INT(f, "fgetpos64", int, (Sfio_t*, fpos64_t*), (f, pos))
+
+ return (pos->_sf_offset = sfseek(f, (Sfoff_t)0, SEEK_CUR)) >= 0 ? 0 : -1;
+}
+
+#endif
diff --git a/src/lib/libast/stdio/fgets.c b/src/lib/libast/stdio/fgets.c
new file mode 100644
index 0000000..727974a
--- /dev/null
+++ b/src/lib/libast/stdio/fgets.c
@@ -0,0 +1,110 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+extern char*
+_stdgets(Sfio_t* f, char* us, int n, int isgets)
+{
+ int p;
+ unsigned char* is;
+ unsigned char* ps;
+
+ if(n <= 0 || !us || (f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0))
+ return NIL(char*);
+
+ SFLOCK(f,0);
+
+ n -= 1;
+ is = (uchar*)us;
+
+ while(n)
+ { /* peek the read buffer for data */
+ if((p = f->endb - (ps = f->next)) <= 0 )
+ { f->getr = '\n';
+ f->mode |= SF_RC;
+ if(SFRPEEK(f,ps,p) <= 0)
+ break;
+ }
+
+ if(p > n)
+ p = n;
+
+#if _lib_memccpy
+ if((ps = (uchar*)memccpy((char*)is,(char*)ps,'\n',p)) != NIL(uchar*))
+ p = ps-is;
+ is += p;
+ ps = f->next+p;
+#else
+ if(!(f->flags&(SF_BOTH|SF_MALLOC)))
+ { while(p-- && (*is++ = *ps++) != '\n')
+ ;
+ p = ps-f->next;
+ }
+ else
+ { reg int c = ps[p-1];
+ if(c != '\n')
+ ps[p-1] = '\n';
+ while((*is++ = *ps++) != '\n')
+ ;
+ if(c != '\n')
+ { f->next[p-1] = c;
+ if((ps-f->next) >= p)
+ is[-1] = c;
+ }
+ }
+#endif
+
+ /* gobble up read data and continue */
+ f->next = ps;
+ if(is[-1] == '\n')
+ break;
+ else if(n > 0)
+ n -= p;
+ }
+
+ if((_Sfi = is - ((uchar*)us)) <= 0)
+ us = NIL(char*);
+ else if(isgets && is[-1] == '\n')
+ { is[-1] = '\0';
+ _Sfi -= 1;
+ }
+ else *is = '\0';
+
+ SFOPEN(f,0);
+ return us;
+}
+
+char*
+fgets(char* s, int n, Sfio_t* f)
+{
+ STDIO_PTR(f, "fgets", char*, (char*, int, Sfio_t*), (s, n, f))
+
+ return _stdgets(f, s, n, 0);
+}
+
+char*
+gets(char* s)
+{
+ return _stdgets(sfstdin, s, BUFSIZ, 1);
+}
diff --git a/src/lib/libast/stdio/fgetwc.c b/src/lib/libast/stdio/fgetwc.c
new file mode 100644
index 0000000..64f7d83
--- /dev/null
+++ b/src/lib/libast/stdio/fgetwc.c
@@ -0,0 +1,35 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+wint_t
+fgetwc(Sfio_t* f)
+{
+ wchar_t c;
+
+ STDIO_INT(f, "fgetwc", wint_t, (Sfio_t*), (f))
+
+ FWIDE(f, WEOF);
+ return (sfread(f, &c, sizeof(c)) == sizeof(c)) ? c : WEOF;
+}
diff --git a/src/lib/libast/stdio/fgetws.c b/src/lib/libast/stdio/fgetws.c
new file mode 100644
index 0000000..d1adbed
--- /dev/null
+++ b/src/lib/libast/stdio/fgetws.c
@@ -0,0 +1,52 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+wchar_t*
+fgetws(wchar_t* s, int n, Sfio_t* f)
+{
+ register wchar_t* p = s;
+ register wchar_t* e = s + n - 1;
+ register wint_t c;
+
+ STDIO_PTR(f, "fgets", wchar_t*, (wchar_t*, int, Sfio_t*), (s, n, f))
+
+ FWIDE(f, 0);
+ while (p < e && (c = fgetwc(f)) != WEOF && (*p++ = c) != '\n');
+ *p = 0;
+ return s;
+}
+
+wchar_t*
+getws(wchar_t* s)
+{
+ register wchar_t* p = s;
+ register wchar_t* e = s + BUFSIZ - 1;
+ register wint_t c;
+
+ FWIDE(sfstdin, 0);
+ while (p < e && (c = fgetwc(sfstdin)) != WEOF && (*p++ = c) != '\n');
+ *p = 0;
+ return s;
+}
diff --git a/src/lib/libast/stdio/fileno.c b/src/lib/libast/stdio/fileno.c
new file mode 100644
index 0000000..5ca6de8
--- /dev/null
+++ b/src/lib/libast/stdio/fileno.c
@@ -0,0 +1,42 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+#if !_UWIN
+
+NoN(fileno)
+
+#else
+
+#undef fileno
+
+int
+fileno(Sfio_t* f)
+{
+ STDIO_INT(f, "fileno", int, (Sfio_t*), (f))
+
+ return sffileno(f);
+}
+
+#endif
diff --git a/src/lib/libast/stdio/flockfile.c b/src/lib/libast/stdio/flockfile.c
new file mode 100644
index 0000000..43141ec
--- /dev/null
+++ b/src/lib/libast/stdio/flockfile.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+void
+flockfile(Sfio_t* f)
+{
+ STDIO_VOID(f, "flockfile", void, (Sfio_t*), (f))
+
+ (void)sfmutex(f, SFMTX_LOCK);
+}
diff --git a/src/lib/libast/stdio/fmemopen.c b/src/lib/libast/stdio/fmemopen.c
new file mode 100644
index 0000000..dfb6317
--- /dev/null
+++ b/src/lib/libast/stdio/fmemopen.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+Sfio_t*
+fmemopen(void* buf, size_t size, const char* mode)
+{
+ STDIO_PTR(0, "fmemopen", Sfio_t*, (void*, size_t, const char*), (buf, size, mode))
+
+ return sfnew(NiL, buf, size, -1, SF_STRING|_sftype(mode, NiL, NiL));
+}
diff --git a/src/lib/libast/stdio/fopen.c b/src/lib/libast/stdio/fopen.c
new file mode 100644
index 0000000..4b99fef
--- /dev/null
+++ b/src/lib/libast/stdio/fopen.c
@@ -0,0 +1,30 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+Sfio_t*
+fopen(const char* path, const char* mode)
+{
+ return sfopen(NiL, path, mode);
+}
diff --git a/src/lib/libast/stdio/fprintf.c b/src/lib/libast/stdio/fprintf.c
new file mode 100644
index 0000000..0939cc7
--- /dev/null
+++ b/src/lib/libast/stdio/fprintf.c
@@ -0,0 +1,39 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+fprintf(Sfio_t* f, const char* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+
+ STDIO_INT(f, "vfprintf", int, (Sfio_t*, const char*, va_list), (f, fmt, args))
+
+ v = sfvprintf(f, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/fpurge.c b/src/lib/libast/stdio/fpurge.c
new file mode 100644
index 0000000..eeaea0d
--- /dev/null
+++ b/src/lib/libast/stdio/fpurge.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+fpurge(Sfio_t* f)
+{
+ STDIO_INT(f, "fpurge", int, (Sfio_t*), (f))
+
+ return sfpurge(f);
+}
diff --git a/src/lib/libast/stdio/fputc.c b/src/lib/libast/stdio/fputc.c
new file mode 100644
index 0000000..72cf874
--- /dev/null
+++ b/src/lib/libast/stdio/fputc.c
@@ -0,0 +1,42 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+#if !_UWIN
+
+NoN(fputc)
+
+#else
+
+#undef fputc
+
+int
+fputc(int c, Sfio_t* f)
+{
+ STDIO_INT(f, "fputc", int, (int, Sfio_t*), (c, f))
+
+ return sfputc(f, c);
+}
+
+#endif
diff --git a/src/lib/libast/stdio/fputs.c b/src/lib/libast/stdio/fputs.c
new file mode 100644
index 0000000..0fdc459
--- /dev/null
+++ b/src/lib/libast/stdio/fputs.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+fputs(const char* s, Sfio_t* f)
+{
+ STDIO_INT(f, "fputs", int, (const char*, Sfio_t*), (s, f))
+
+ return sfputr(f, s, -1);
+}
diff --git a/src/lib/libast/stdio/fputwc.c b/src/lib/libast/stdio/fputwc.c
new file mode 100644
index 0000000..1029a3b
--- /dev/null
+++ b/src/lib/libast/stdio/fputwc.c
@@ -0,0 +1,33 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+wint_t
+fputwc(wchar_t c, Sfio_t* f)
+{
+ STDIO_INT(f, "fputc", wint_t, (wchar_t, Sfio_t*), (c, f))
+
+ FWIDE(f, WEOF);
+ return (sfwrite(f, &c, sizeof(c)) == sizeof(c)) ? c : WEOF;
+}
diff --git a/src/lib/libast/stdio/fputws.c b/src/lib/libast/stdio/fputws.c
new file mode 100644
index 0000000..3e1034e
--- /dev/null
+++ b/src/lib/libast/stdio/fputws.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+fputws(const wchar_t* s, Sfio_t* f)
+{
+ size_t n;
+
+ STDIO_INT(f, "fputws", int, (const wchar_t*, Sfio_t*), (s, f))
+
+ FWIDE(f, WEOF);
+ n = wcslen(s) * sizeof(wchar_t);
+ return (sfwrite(f, s, n) == n) ? 0 : -1;
+}
diff --git a/src/lib/libast/stdio/fread.c b/src/lib/libast/stdio/fread.c
new file mode 100644
index 0000000..c96a1e7
--- /dev/null
+++ b/src/lib/libast/stdio/fread.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+size_t
+fread(void* p, size_t s, size_t n, Sfio_t* f)
+{
+ ssize_t v;
+
+ STDIO_INT(f, "fread", ssize_t, (void*, size_t, size_t, Sfio_t*), (p, s, n, f))
+
+ return ((v = sfread(f, p, s * n)) <= 0) ? 0 : (v / s);
+}
diff --git a/src/lib/libast/stdio/freopen.c b/src/lib/libast/stdio/freopen.c
new file mode 100644
index 0000000..e8de05b
--- /dev/null
+++ b/src/lib/libast/stdio/freopen.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+Sfio_t*
+freopen(const char* path, const char* mode, Sfio_t* f)
+{
+ STDIO_PTR(f, "freopen", Sfio_t*, (const char*, const char*, Sfio_t*), (path, mode, f))
+
+ return sfopen(f, path, mode);
+}
diff --git a/src/lib/libast/stdio/fscanf.c b/src/lib/libast/stdio/fscanf.c
new file mode 100644
index 0000000..2beb400
--- /dev/null
+++ b/src/lib/libast/stdio/fscanf.c
@@ -0,0 +1,39 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+fscanf(Sfio_t* f, const char* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+
+ STDIO_INT(f, "vfscanf", int, (Sfio_t*, const char*, va_list), (f, fmt, args))
+
+ v = sfvscanf(f, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/fseek.c b/src/lib/libast/stdio/fseek.c
new file mode 100644
index 0000000..1198a31
--- /dev/null
+++ b/src/lib/libast/stdio/fseek.c
@@ -0,0 +1,48 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#ifndef _NO_LARGEFILE64_SOURCE
+#define _NO_LARGEFILE64_SOURCE 1
+#endif
+
+#include "stdhdr.h"
+
+int
+fseek(Sfio_t* f, long off, int op)
+{
+ STDIO_INT(f, "fseek", int, (Sfio_t*, long, int), (f, off, op))
+
+ return sfseek(f, (Sfoff_t)off, op|SF_SHARE) >= 0 ? 0 : -1;
+}
+
+#ifdef _typ_int64_t
+
+int
+fseek64(Sfio_t* f, int64_t off, int op)
+{
+ STDIO_INT(f, "fseek64", int, (Sfio_t*, int64_t, int), (f, off, op))
+
+ return sfseek(f, (Sfoff_t)off, op|SF_SHARE) >= 0 ? 0 : -1;
+}
+
+#endif
diff --git a/src/lib/libast/stdio/fseeko.c b/src/lib/libast/stdio/fseeko.c
new file mode 100644
index 0000000..0cf3186
--- /dev/null
+++ b/src/lib/libast/stdio/fseeko.c
@@ -0,0 +1,48 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#ifndef _NO_LARGEFILE64_SOURCE
+#define _NO_LARGEFILE64_SOURCE 1
+#endif
+
+#include "stdhdr.h"
+
+int
+fseeko(Sfio_t* f, off_t off, int op)
+{
+ STDIO_INT(f, "fseeko", int, (Sfio_t*, off_t, int), (f, off, op))
+
+ return sfseek(f, (Sfoff_t)off, op|SF_SHARE) >= 0 ? 0 : -1;
+}
+
+#ifdef _typ_int64_t
+
+int
+fseeko64(Sfio_t* f, int64_t off, int op)
+{
+ STDIO_INT(f, "fseeko64", int, (Sfio_t*, int64_t, int), (f, off, op))
+
+ return sfseek(f, (Sfoff_t)off, op|SF_SHARE) >= 0 ? 0 : -1;
+}
+
+#endif
diff --git a/src/lib/libast/stdio/fsetpos.c b/src/lib/libast/stdio/fsetpos.c
new file mode 100644
index 0000000..cc9abbc
--- /dev/null
+++ b/src/lib/libast/stdio/fsetpos.c
@@ -0,0 +1,48 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#ifndef _NO_LARGEFILE64_SOURCE
+#define _NO_LARGEFILE64_SOURCE 1
+#endif
+
+#include "stdhdr.h"
+
+int
+fsetpos(Sfio_t* f, const fpos_t* pos)
+{
+ STDIO_INT(f, "fsetpos", int, (Sfio_t*, const fpos_t*), (f, pos))
+
+ return sfseek(f, (Sfoff_t)pos->_sf_offset, SF_PUBLIC) == (Sfoff_t)pos->_sf_offset ? 0 : -1;
+}
+
+#ifdef _typ_int64_t
+
+int
+fsetpos64(Sfio_t* f, const fpos64_t* pos)
+{
+ STDIO_INT(f, "fsetpos64", int, (Sfio_t*, const fpos64_t*), (f, pos))
+
+ return sfseek(f, (Sfoff_t)pos->_sf_offset, SF_PUBLIC) == (Sfoff_t)pos->_sf_offset ? 0 : -1;
+}
+
+#endif
diff --git a/src/lib/libast/stdio/ftell.c b/src/lib/libast/stdio/ftell.c
new file mode 100644
index 0000000..0437e48
--- /dev/null
+++ b/src/lib/libast/stdio/ftell.c
@@ -0,0 +1,48 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#ifndef _NO_LARGEFILE64_SOURCE
+#define _NO_LARGEFILE64_SOURCE 1
+#endif
+
+#include "stdhdr.h"
+
+long
+ftell(Sfio_t* f)
+{
+ STDIO_INT(f, "ftell", long, (Sfio_t*), (f))
+
+ return (long)sfseek(f, (Sfoff_t)0, SEEK_CUR);
+}
+
+#if _typ_int64_t
+
+int64_t
+ftell64(Sfio_t* f)
+{
+ STDIO_INT(f, "ftell64", int64_t, (Sfio_t*), (f))
+
+ return (int64_t)sfseek(f, (Sfoff_t)0, SEEK_CUR);
+}
+
+#endif
diff --git a/src/lib/libast/stdio/ftello.c b/src/lib/libast/stdio/ftello.c
new file mode 100644
index 0000000..f430fec
--- /dev/null
+++ b/src/lib/libast/stdio/ftello.c
@@ -0,0 +1,48 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#ifndef _NO_LARGEFILE64_SOURCE
+#define _NO_LARGEFILE64_SOURCE 1
+#endif
+
+#include "stdhdr.h"
+
+off_t
+ftello(Sfio_t* f)
+{
+ STDIO_INT(f, "ftello", off_t, (Sfio_t*), (f))
+
+ return sfseek(f, (Sfoff_t)0, SEEK_CUR);
+}
+
+#ifdef _typ_int64_t
+
+int64_t
+ftello64(Sfio_t* f)
+{
+ STDIO_INT(f, "ftello64", int64_t, (Sfio_t*), (f))
+
+ return sfseek(f, (Sfoff_t)0, SEEK_CUR) >= 0 ? 0 : -1;
+}
+
+#endif
diff --git a/src/lib/libast/stdio/ftrylockfile.c b/src/lib/libast/stdio/ftrylockfile.c
new file mode 100644
index 0000000..28501e8
--- /dev/null
+++ b/src/lib/libast/stdio/ftrylockfile.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+ftrylockfile(Sfio_t* f)
+{
+ STDIO_INT(f, "ftrylockfile", int, (Sfio_t*), (f))
+
+ return sfmutex(f, SFMTX_TRYLOCK);
+}
diff --git a/src/lib/libast/stdio/funlockfile.c b/src/lib/libast/stdio/funlockfile.c
new file mode 100644
index 0000000..33195d5
--- /dev/null
+++ b/src/lib/libast/stdio/funlockfile.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+void
+funlockfile(Sfio_t* f)
+{
+ STDIO_VOID(f, "funlockfile", void, (Sfio_t*), (f))
+
+ (void)sfmutex(f, SFMTX_UNLOCK);
+}
diff --git a/src/lib/libast/stdio/fwide.c b/src/lib/libast/stdio/fwide.c
new file mode 100644
index 0000000..efcb453
--- /dev/null
+++ b/src/lib/libast/stdio/fwide.c
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+fwide(Sfio_t* f, int mode)
+{
+ STDIO_INT(f, "fwide", int, (Sfio_t*, int), (f, mode))
+
+ if (mode > 0)
+ {
+ f->bits &= ~SF_MB;
+ f->bits |= SF_WC;
+ }
+ else if (mode < 0)
+ {
+ f->bits &= ~SF_WC;
+ f->bits |= SF_MB;
+ }
+ if (f->bits & SF_MB)
+ return -1;
+ if (f->bits & SF_WC)
+ return 1;
+ if ((f->flags & SF_SYNCED) || f->next > f->data)
+ {
+ f->bits |= SF_MB;
+ return -1;
+ }
+ return 0;
+}
diff --git a/src/lib/libast/stdio/fwprintf.c b/src/lib/libast/stdio/fwprintf.c
new file mode 100644
index 0000000..b4726e3
--- /dev/null
+++ b/src/lib/libast/stdio/fwprintf.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+fwprintf(Sfio_t* f, const wchar_t* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+ v = vfwprintf(f, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/fwrite.c b/src/lib/libast/stdio/fwrite.c
new file mode 100644
index 0000000..12bfe89
--- /dev/null
+++ b/src/lib/libast/stdio/fwrite.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+size_t
+fwrite(const void* p, size_t s, size_t n, Sfio_t* f)
+{
+ ssize_t v;
+
+ STDIO_INT(f, "fwrite", ssize_t, (const void*, size_t, size_t, Sfio_t*), (p, s, n, f))
+
+ return ((v = sfwrite(f, p, s * n)) <= 0) ? 0 : (v / s);
+}
diff --git a/src/lib/libast/stdio/fwscanf.c b/src/lib/libast/stdio/fwscanf.c
new file mode 100644
index 0000000..f64f203
--- /dev/null
+++ b/src/lib/libast/stdio/fwscanf.c
@@ -0,0 +1,39 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+fwscanf(Sfio_t* f, const wchar_t* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+
+ STDIO_INT(f, "vfwscanf", int, (Sfio_t*, const wchar_t*, va_list), (f, fmt, args))
+
+ v = vfwscanf(f, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/getc.c b/src/lib/libast/stdio/getc.c
new file mode 100644
index 0000000..b04507f
--- /dev/null
+++ b/src/lib/libast/stdio/getc.c
@@ -0,0 +1,42 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+#if !_UWIN
+
+NoN(getc)
+
+#else
+
+#undef getc
+
+int
+getc(Sfio_t* f)
+{
+ STDIO_INT(f, "getc", int, (Sfio_t*), (f))
+
+ return sfgetc(f);
+}
+
+#endif
diff --git a/src/lib/libast/stdio/getchar.c b/src/lib/libast/stdio/getchar.c
new file mode 100644
index 0000000..80781eb
--- /dev/null
+++ b/src/lib/libast/stdio/getchar.c
@@ -0,0 +1,40 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+#if !_UWIN
+
+NoN(getchar)
+
+#else
+
+#undef getchar
+
+int
+getchar(void)
+{
+ return sfgetc(sfstdin);
+}
+
+#endif
diff --git a/src/lib/libast/stdio/getdelim.c b/src/lib/libast/stdio/getdelim.c
new file mode 100644
index 0000000..331125a
--- /dev/null
+++ b/src/lib/libast/stdio/getdelim.c
@@ -0,0 +1,96 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+ssize_t
+getdelim(char** sp, size_t* np, int delim, Sfio_t* f)
+{
+ ssize_t m;
+ ssize_t n;
+ ssize_t k;
+ ssize_t p;
+ uchar* s;
+ uchar* ps;
+ SFMTXDECL(f);
+
+ STDIO_INT(f, "getdelim", ssize_t, (char**, size_t*, int, Sfio_t*), (sp, np, delim, f))
+
+ SFMTXENTER(f, -1);
+
+ if(delim < 0 || delim > 255 || !sp || !np) /* bad parameters */
+ SFMTXRETURN(f, -1);
+
+ if(f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0)
+ SFMTXRETURN(f, -1);
+
+ SFLOCK(f,0);
+
+ if(!(s = (uchar*)(*sp)) || (n = *np) < 0)
+ { s = NIL(uchar*); n = 0; }
+ for(m = 0;; )
+ { /* read new data */
+ if((p = f->endb - (ps = f->next)) <= 0 )
+ { f->getr = delim;
+ f->mode |= SF_RC;
+ if(SFRPEEK(f,ps,p) <= 0)
+ { m = -1;
+ break;
+ }
+ }
+
+ for(k = 0; k < p; ++k) /* find the delimiter */
+ { if(ps[k] == delim)
+ { k += 1; /* include delim in copying */
+ break;
+ }
+ }
+
+ if((m+k+1) >= n ) /* make sure there is space */
+ { n = ((m+k+15)/8)*8;
+ if(!(s = (uchar*)realloc(s, n)) )
+ { *sp = 0; *np = 0;
+ m = -1;
+ break;
+ }
+ *sp = (char*)s; *np = n;
+ }
+
+ memcpy(s+m, ps, k); m += k;
+ f->next = ps+k; /* skip copied data in buffer */
+
+ if(s[m-1] == delim)
+ { s[m] = 0; /* 0-terminated */
+ break;
+ }
+ }
+
+ SFOPEN(f,0);
+ SFMTXRETURN(f,m);
+}
+
+ssize_t
+__getdelim(char** sp, size_t* np, int delim, Sfio_t* f)
+{
+ return getdelim(sp, np, delim, f);
+}
diff --git a/src/lib/libast/stdio/getline.c b/src/lib/libast/stdio/getline.c
new file mode 100644
index 0000000..914a5c1
--- /dev/null
+++ b/src/lib/libast/stdio/getline.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#ifndef _USE_GNU
+#define _USE_GNU
+#endif
+
+#include "stdhdr.h"
+
+ssize_t
+getline(char** sp, size_t* np, Sfio_t* f)
+{
+ STDIO_INT(f, "getline", ssize_t, (char**, size_t*, Sfio_t*), (sp, np, f))
+
+ return getdelim(sp, np, '\n', f);
+}
diff --git a/src/lib/libast/stdio/getw.c b/src/lib/libast/stdio/getw.c
new file mode 100644
index 0000000..b0063be
--- /dev/null
+++ b/src/lib/libast/stdio/getw.c
@@ -0,0 +1,34 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+getw(Sfio_t* f)
+{
+ int v;
+
+ STDIO_INT(f, "getw", int, (Sfio_t*), (f))
+
+ return sfread(f, &v, sizeof(v)) == sizeof(v) ? v : -1;
+}
diff --git a/src/lib/libast/stdio/getwc.c b/src/lib/libast/stdio/getwc.c
new file mode 100644
index 0000000..7e4a39f
--- /dev/null
+++ b/src/lib/libast/stdio/getwc.c
@@ -0,0 +1,31 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+#include "ast_wchar.h"
+
+wint_t
+getwc(Sfio_t* f)
+{
+ return fgetwc(f);
+}
diff --git a/src/lib/libast/stdio/getwchar.c b/src/lib/libast/stdio/getwchar.c
new file mode 100644
index 0000000..4564c2a
--- /dev/null
+++ b/src/lib/libast/stdio/getwchar.c
@@ -0,0 +1,31 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+#include "ast_wchar.h"
+
+wint_t
+getwchar(void)
+{
+ return fgetwc(sfstdin);
+}
diff --git a/src/lib/libast/stdio/pclose.c b/src/lib/libast/stdio/pclose.c
new file mode 100644
index 0000000..b06b25a
--- /dev/null
+++ b/src/lib/libast/stdio/pclose.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+pclose(Sfio_t* f)
+{
+ STDIO_INT(f, "pclose", int, (Sfio_t*), (f))
+
+ return sfclose(f);
+}
diff --git a/src/lib/libast/stdio/popen.c b/src/lib/libast/stdio/popen.c
new file mode 100644
index 0000000..61968aa
--- /dev/null
+++ b/src/lib/libast/stdio/popen.c
@@ -0,0 +1,30 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+Sfio_t*
+popen(const char* cmd, const char* mode)
+{
+ return sfpopen((Sfio_t*)(-1), cmd, mode);
+}
diff --git a/src/lib/libast/stdio/printf.c b/src/lib/libast/stdio/printf.c
new file mode 100644
index 0000000..ca999f4
--- /dev/null
+++ b/src/lib/libast/stdio/printf.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+printf(const char* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+ v = sfvprintf(sfstdout, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/putc.c b/src/lib/libast/stdio/putc.c
new file mode 100644
index 0000000..34d1b14
--- /dev/null
+++ b/src/lib/libast/stdio/putc.c
@@ -0,0 +1,42 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+#if !_UWIN
+
+NoN(putc)
+
+#else
+
+#undef putc
+
+int
+putc(int c, Sfio_t* f)
+{
+ STDIO_INT(f, "putc", int, (int, Sfio_t*), (c, f))
+
+ return sfputc(f, c);
+}
+
+#endif
diff --git a/src/lib/libast/stdio/putchar.c b/src/lib/libast/stdio/putchar.c
new file mode 100644
index 0000000..5fb8217
--- /dev/null
+++ b/src/lib/libast/stdio/putchar.c
@@ -0,0 +1,40 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+#if !_UWIN
+
+NoN(putchar)
+
+#else
+
+#undef putchar
+
+int
+putchar(int c)
+{
+ return sfputc(sfstdout, c);
+}
+
+#endif
diff --git a/src/lib/libast/stdio/puts.c b/src/lib/libast/stdio/puts.c
new file mode 100644
index 0000000..3ef397b
--- /dev/null
+++ b/src/lib/libast/stdio/puts.c
@@ -0,0 +1,30 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+puts(const char* s)
+{
+ return sfputr(sfstdout, s, '\n');
+}
diff --git a/src/lib/libast/stdio/putw.c b/src/lib/libast/stdio/putw.c
new file mode 100644
index 0000000..626439d
--- /dev/null
+++ b/src/lib/libast/stdio/putw.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+putw(int v, Sfio_t* f)
+{
+ STDIO_INT(f, "putw", int, (int, Sfio_t*), (v, f))
+
+ return sfwrite(f, &v, sizeof(v)) == sizeof(v) ? 0 : -1;
+}
diff --git a/src/lib/libast/stdio/putwc.c b/src/lib/libast/stdio/putwc.c
new file mode 100644
index 0000000..8a4e86e
--- /dev/null
+++ b/src/lib/libast/stdio/putwc.c
@@ -0,0 +1,31 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+#include "ast_wchar.h"
+
+wint_t
+putwc(wchar_t c, Sfio_t* f)
+{
+ return fputwc(c, f);
+}
diff --git a/src/lib/libast/stdio/putwchar.c b/src/lib/libast/stdio/putwchar.c
new file mode 100644
index 0000000..70c967f
--- /dev/null
+++ b/src/lib/libast/stdio/putwchar.c
@@ -0,0 +1,31 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+#include "ast_wchar.h"
+
+wint_t
+putwchar(wchar_t c)
+{
+ return fputwc(c, sfstdout);
+}
diff --git a/src/lib/libast/stdio/rewind.c b/src/lib/libast/stdio/rewind.c
new file mode 100644
index 0000000..d82985c
--- /dev/null
+++ b/src/lib/libast/stdio/rewind.c
@@ -0,0 +1,33 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+void
+rewind(Sfio_t* f)
+{
+ STDIO_VOID(f, "rewind", void, (Sfio_t*), (f))
+
+ sfseek(f, (Sfoff_t)0, SEEK_SET|SF_PUBLIC);
+ sfclrlock(f);
+}
diff --git a/src/lib/libast/stdio/scanf.c b/src/lib/libast/stdio/scanf.c
new file mode 100644
index 0000000..5b2976e
--- /dev/null
+++ b/src/lib/libast/stdio/scanf.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+scanf(const char* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+ v = sfvscanf(sfstdin, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/setbuf.c b/src/lib/libast/stdio/setbuf.c
new file mode 100644
index 0000000..83d6132
--- /dev/null
+++ b/src/lib/libast/stdio/setbuf.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+void
+setbuf(Sfio_t* f, char* b)
+{
+ STDIO_VOID(f, "setbuf", void, (Sfio_t*, char*), (f, b))
+
+ sfsetbuf(f, b, b ? BUFSIZ : 0);
+}
diff --git a/src/lib/libast/stdio/setbuffer.c b/src/lib/libast/stdio/setbuffer.c
new file mode 100644
index 0000000..6211c72
--- /dev/null
+++ b/src/lib/libast/stdio/setbuffer.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+setbuffer(Sfio_t* f, char* b, int n)
+{
+ STDIO_INT(f, "setbuffer", int, (Sfio_t*, char*, int), (f, b, n))
+
+ return sfsetbuf(f, b, n) ? 0 : -1;
+}
diff --git a/src/lib/libast/stdio/setlinebuf.c b/src/lib/libast/stdio/setlinebuf.c
new file mode 100644
index 0000000..b18b151
--- /dev/null
+++ b/src/lib/libast/stdio/setlinebuf.c
@@ -0,0 +1,33 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+setlinebuf(Sfio_t* f)
+{
+ STDIO_INT(f, "setlinebuf", int, (Sfio_t*), (f))
+
+ sfset(f, SF_LINE, 1);
+ return 0;
+}
diff --git a/src/lib/libast/stdio/setvbuf.c b/src/lib/libast/stdio/setvbuf.c
new file mode 100644
index 0000000..c8a38f8
--- /dev/null
+++ b/src/lib/libast/stdio/setvbuf.c
@@ -0,0 +1,48 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+setvbuf(Sfio_t* f, char* buf, int type, size_t size)
+{
+ STDIO_INT(f, "setvbuf", int, (Sfio_t*, char*, int, size_t), (f, buf, type, size))
+
+ if (type == _IOLBF)
+ sfset(f, SF_LINE, 1);
+ else if (f->flags & SF_STRING)
+ return -1;
+ else if (type == _IONBF)
+ {
+ sfsync(f);
+ sfsetbuf(f, NiL, 0);
+ }
+ else if (type == _IOFBF)
+ {
+ if (size == 0)
+ size = SF_BUFSIZE;
+ sfsync(f);
+ sfsetbuf(f, (Void_t*)buf, size);
+ }
+ return 0;
+}
diff --git a/src/lib/libast/stdio/snprintf.c b/src/lib/libast/stdio/snprintf.c
new file mode 100644
index 0000000..f30c243
--- /dev/null
+++ b/src/lib/libast/stdio/snprintf.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+snprintf(char* s, int n, const char* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+ v = sfvsprintf(s, n, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/sprintf.c b/src/lib/libast/stdio/sprintf.c
new file mode 100644
index 0000000..3a8139a
--- /dev/null
+++ b/src/lib/libast/stdio/sprintf.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+sprintf(char* s, const char* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+ v = s ? sfvsprintf(s, INT_MAX, fmt, args) : -1;
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/sscanf.c b/src/lib/libast/stdio/sscanf.c
new file mode 100644
index 0000000..c04d2d3
--- /dev/null
+++ b/src/lib/libast/stdio/sscanf.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+sscanf(const char* s, const char* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+ v = sfvsscanf(s, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/stdhdr.h b/src/lib/libast/stdio/stdhdr.h
new file mode 100644
index 0000000..1b2a930
--- /dev/null
+++ b/src/lib/libast/stdio/stdhdr.h
@@ -0,0 +1,115 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#ifndef _STDHDR_H
+#define _STDHDR_H 1
+
+#ifndef _NO_LARGEFILE64_SOURCE
+#define _NO_LARGEFILE64_SOURCE 1
+#endif
+#undef _LARGEFILE64_SOURCE
+
+#define _ast_fseeko ______fseeko
+#define _ast_ftello ______ftello
+#include "sfhdr.h"
+#undef _ast_fseeko
+#undef _ast_ftello
+
+#include "stdio.h"
+
+#define SF_MB 010000
+#define SF_WC 020000
+
+#if _UWIN
+
+#define STDIO_TRANSFER 1
+
+typedef int (*Fun_f)();
+
+typedef struct Funvec_s
+{
+ const char* name;
+ Fun_f vec[2];
+} Funvec_t;
+
+extern int _stdfun(Sfio_t*, Funvec_t*);
+
+#define STDIO_INT(p,n,t,f,a) \
+ { \
+ typedef t (*_s_f)f; \
+ int _i; \
+ static Funvec_t _v = { n }; \
+ if ((_i = _stdfun(p, &_v)) < 0) \
+ return -1; \
+ else if (_i > 0) \
+ return ((_s_f)_v.vec[_i])a; \
+ }
+
+#define STDIO_PTR(p,n,t,f,a) \
+ { \
+ typedef t (*_s_f)f; \
+ int _i; \
+ static Funvec_t _v = { n }; \
+ if ((_i = _stdfun(p, &_v)) < 0) \
+ return 0; \
+ else if (_i > 0) \
+ return ((_s_f)_v.vec[_i])a; \
+ }
+
+#define STDIO_VOID(p,n,t,f,a) \
+ { \
+ typedef t (*_s_f)f; \
+ int _i; \
+ static Funvec_t _v = { n }; \
+ if ((_i = _stdfun(p, &_v)) < 0) \
+ return; \
+ else if (_i > 0) \
+ { \
+ ((_s_f)_v.vec[_i])a; \
+ return; \
+ } \
+ }
+
+#else
+
+#define STDIO_INT(p,n,t,f,a)
+#define STDIO_PTR(p,n,t,f,a)
+#define STDIO_VOID(p,n,t,f,a)
+
+#endif
+
+#define FWIDE(f,r) \
+ do \
+ { \
+ if (fwide(f, 0) < 0) \
+ return r; \
+ f->bits |= SF_WC; \
+ } while (0)
+
+#ifdef __EXPORT__
+#define extern __EXPORT__
+#endif
+
+extern int sfdcwide(Sfio_t*);
+
+#endif
diff --git a/src/lib/libast/stdio/stdio_c99.c b/src/lib/libast/stdio/stdio_c99.c
new file mode 100644
index 0000000..f8d0f8d
--- /dev/null
+++ b/src/lib/libast/stdio/stdio_c99.c
@@ -0,0 +1,118 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * C99 stdio extensions
+ */
+
+#include "stdhdr.h"
+
+void
+clearerr_unlocked(Sfio_t* sp)
+{
+ clearerr(sp);
+}
+
+int
+feof_unlocked(Sfio_t* sp)
+{
+ return feof(sp);
+}
+
+int
+ferror_unlocked(Sfio_t* sp)
+{
+ return ferror(sp);
+}
+
+int
+fflush_unlocked(Sfio_t* sp)
+{
+ return fflush(sp);
+}
+
+int
+fgetc_unlocked(Sfio_t* sp)
+{
+ return fgetc(sp);
+}
+
+char*
+fgets_unlocked(char* buf, int size, Sfio_t* sp)
+{
+ return fgets(buf, size, sp);
+}
+
+int
+fileno_unlocked(Sfio_t* sp)
+{
+ return fileno(sp);
+}
+
+int
+fputc_unlocked(int c, Sfio_t* sp)
+{
+ return fputc(c, sp);
+}
+
+int
+fputs_unlocked(char* buf, Sfio_t* sp)
+{
+ return fputs(buf, sp);
+}
+
+size_t
+fread_unlocked(void* buf, size_t size, size_t n, Sfio_t* sp)
+{
+ return fread(buf, size, n, sp);
+}
+
+size_t
+fwrite_unlocked(void* buf, size_t size, size_t n, Sfio_t* sp)
+{
+ return fwrite(buf, size, n, sp);
+}
+
+int
+getc_unlocked(Sfio_t* sp)
+{
+ return getc(sp);
+}
+
+int
+getchar_unlocked(void)
+{
+ return getchar();
+}
+
+int
+putc_unlocked(int c, Sfio_t* sp)
+{
+ return putc(c, sp);
+}
+
+int
+putchar_unlocked(int c)
+{
+ return putchar(c);
+}
diff --git a/src/lib/libast/stdio/swprintf.c b/src/lib/libast/stdio/swprintf.c
new file mode 100644
index 0000000..6bb0942
--- /dev/null
+++ b/src/lib/libast/stdio/swprintf.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+swprintf(wchar_t* s, size_t size, const wchar_t* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+ v = vswprintf(s, size, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/swscanf.c b/src/lib/libast/stdio/swscanf.c
new file mode 100644
index 0000000..00f27a4
--- /dev/null
+++ b/src/lib/libast/stdio/swscanf.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+swscanf(const wchar_t* s, const wchar_t* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+ v = vswscanf(s, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/tmpfile.c b/src/lib/libast/stdio/tmpfile.c
new file mode 100644
index 0000000..c913dc8
--- /dev/null
+++ b/src/lib/libast/stdio/tmpfile.c
@@ -0,0 +1,30 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+Sfio_t*
+tmpfile(void)
+{
+ return sftmp(0);
+}
diff --git a/src/lib/libast/stdio/ungetc.c b/src/lib/libast/stdio/ungetc.c
new file mode 100644
index 0000000..e448beb
--- /dev/null
+++ b/src/lib/libast/stdio/ungetc.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+ungetc(int c, Sfio_t* f)
+{
+ STDIO_INT(f, "ungetc", int, (int, Sfio_t*), (c, f))
+
+ return sfungetc(f, c);
+}
diff --git a/src/lib/libast/stdio/ungetwc.c b/src/lib/libast/stdio/ungetwc.c
new file mode 100644
index 0000000..4877f0c
--- /dev/null
+++ b/src/lib/libast/stdio/ungetwc.c
@@ -0,0 +1,39 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+wint_t
+ungetwc(wint_t c, Sfio_t* f)
+{
+ register unsigned char* s = (unsigned char*)&c;
+ register unsigned char* e = s + sizeof(c);
+
+ STDIO_INT(f, "ungetwc", wint_t, (wint_t, Sfio_t*), (c, f))
+
+ FWIDE(f, WEOF);
+ while (s < e)
+ if (sfungetc(f, *s++) == EOF)
+ return WEOF;
+ return c;
+}
diff --git a/src/lib/libast/stdio/vasprintf.c b/src/lib/libast/stdio/vasprintf.c
new file mode 100644
index 0000000..f03397f
--- /dev/null
+++ b/src/lib/libast/stdio/vasprintf.c
@@ -0,0 +1,45 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+vasprintf(char** s, const char* fmt, va_list args)
+{
+ Sfio_t* f;
+ int v;
+
+ if (f = sfstropen())
+ {
+ v = sfvprintf(f, fmt, args);
+ if (!(*s = strdup(sfstruse(f))))
+ v = -1;
+ sfstrclose(f);
+ }
+ else
+ {
+ *s = 0;
+ v = -1;
+ }
+ return v;
+}
diff --git a/src/lib/libast/stdio/vfprintf.c b/src/lib/libast/stdio/vfprintf.c
new file mode 100644
index 0000000..04a2e2f
--- /dev/null
+++ b/src/lib/libast/stdio/vfprintf.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+vfprintf(Sfio_t* f, const char* fmt, va_list args)
+{
+ STDIO_INT(f, "vfprintf", int, (Sfio_t*, const char*, va_list), (f, fmt, args))
+
+ return sfvprintf(f, fmt, args);
+}
diff --git a/src/lib/libast/stdio/vfscanf.c b/src/lib/libast/stdio/vfscanf.c
new file mode 100644
index 0000000..f9bcc01
--- /dev/null
+++ b/src/lib/libast/stdio/vfscanf.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+vfscanf(Sfio_t* f, const char* fmt, va_list args)
+{
+ STDIO_INT(f, "vfscanf", int, (Sfio_t*, const char*, va_list), (f, fmt, args))
+
+ return sfvscanf(f, fmt, args);
+}
diff --git a/src/lib/libast/stdio/vfwprintf.c b/src/lib/libast/stdio/vfwprintf.c
new file mode 100644
index 0000000..b396792
--- /dev/null
+++ b/src/lib/libast/stdio/vfwprintf.c
@@ -0,0 +1,68 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+vfwprintf(Sfio_t* f, const wchar_t* fmt, va_list args)
+{
+ char* m;
+ char* x;
+ wchar_t*w;
+ size_t n;
+ int v;
+ Sfio_t* t;
+
+ STDIO_INT(f, "vfwprintf", int, (Sfio_t*, const wchar_t*, va_list), (f, fmt, args))
+
+ FWIDE(f, WEOF);
+ n = wcstombs(NiL, fmt, 0);
+ if (m = malloc(n + 1))
+ {
+ if (t = sfstropen())
+ {
+ wcstombs(m, fmt, n + 1);
+ sfvprintf(t, m, args);
+ free(m);
+ if (!(x = sfstruse(t)))
+ v = -1;
+ else
+ {
+ n = mbstowcs(NiL, x, 0);
+ if (w = (wchar_t*)sfreserve(f, n * sizeof(wchar_t) + 1, 0))
+ v = mbstowcs(w, x, n + 1);
+ else
+ v = -1;
+ }
+ sfstrclose(t);
+ }
+ else
+ {
+ free(m);
+ v = -1;
+ }
+ }
+ else
+ v = -1;
+ return v;
+}
diff --git a/src/lib/libast/stdio/vfwscanf.c b/src/lib/libast/stdio/vfwscanf.c
new file mode 100644
index 0000000..ca23f9a
--- /dev/null
+++ b/src/lib/libast/stdio/vfwscanf.c
@@ -0,0 +1,129 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+typedef struct
+{
+ Sfdisc_t sfdisc; /* sfio discipline */
+ Sfio_t* f; /* original wide stream */
+ char fmt[1]; /* mb fmt */
+} Wide_t;
+
+/*
+ * wide exception handler
+ * free on close
+ */
+
+static int
+wideexcept(Sfio_t* f, int op, void* val, Sfdisc_t* dp)
+{
+ if (sffileno(f) >= 0)
+ return -1;
+ switch (op)
+ {
+ case SF_ATEXIT:
+ sfdisc(f, SF_POPDISC);
+ break;
+ case SF_CLOSING:
+ case SF_DPOP:
+ case SF_FINAL:
+ if (op != SF_CLOSING)
+ free(dp);
+ break;
+ }
+ return 0;
+}
+
+/*
+ * sfio wide discipline read
+ * 1 wchar_t at a time
+ * go pure multibyte for best performance
+ */
+
+static ssize_t
+wideread(Sfio_t* f, Void_t* buf, size_t size, Sfdisc_t* dp)
+{
+ register Wide_t* w = (Wide_t*)dp;
+ wchar_t wuf[2];
+
+#if 0
+ if (sfread(w->f, wuf, sizeof(wuf[0])) != sizeof(wuf[0]))
+ return -1;
+ wuf[1] = 0;
+ return wcstombs(buf, wuf, size);
+#else
+ ssize_t r;
+
+ r = sfread(w->f, wuf, sizeof(wuf[0]));
+ if (r != sizeof(wuf[0]))
+ return -1;
+ wuf[1] = 0;
+ r = wcstombs(buf, wuf, size);
+ return r;
+#endif
+}
+
+int
+vfwscanf(Sfio_t* f, const wchar_t* fmt, va_list args)
+{
+ size_t n;
+ int v;
+ Sfio_t* t;
+ Wide_t* w;
+ char buf[1024];
+
+ STDIO_INT(f, "vfwscanf", int, (Sfio_t*, const wchar_t*, va_list), (f, fmt, args))
+
+ FWIDE(f, WEOF);
+ n = wcstombs(NiL, fmt, 0);
+ if (w = newof(0, Wide_t, 1, n))
+ {
+ if (t = sfnew(NiL, buf, sizeof(buf), OPEN_MAX+1, SF_READ))
+ {
+ w->sfdisc.exceptf = wideexcept;
+ w->sfdisc.readf = wideread;
+ w->f = f;
+ if (sfdisc(t, &w->sfdisc) == &w->sfdisc)
+ {
+ wcstombs(w->fmt, fmt, n + 1);
+ v = sfvscanf(t, w->fmt, args);
+ }
+ else
+ {
+ free(w);
+ v = -1;
+ }
+ sfsetfd(t, -1);
+ sfclose(t);
+ }
+ else
+ {
+ free(w);
+ v = -1;
+ }
+ }
+ else
+ v = -1;
+ return v;
+}
diff --git a/src/lib/libast/stdio/vprintf.c b/src/lib/libast/stdio/vprintf.c
new file mode 100644
index 0000000..e8764f3
--- /dev/null
+++ b/src/lib/libast/stdio/vprintf.c
@@ -0,0 +1,30 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+vprintf(const char* fmt, va_list args)
+{
+ return sfvprintf(sfstdout, fmt, args);
+}
diff --git a/src/lib/libast/stdio/vscanf.c b/src/lib/libast/stdio/vscanf.c
new file mode 100644
index 0000000..33371d9
--- /dev/null
+++ b/src/lib/libast/stdio/vscanf.c
@@ -0,0 +1,30 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+vscanf(const char* fmt, va_list args)
+{
+ return sfvscanf(sfstdin, fmt, args);
+}
diff --git a/src/lib/libast/stdio/vsnprintf.c b/src/lib/libast/stdio/vsnprintf.c
new file mode 100644
index 0000000..5cde8fa
--- /dev/null
+++ b/src/lib/libast/stdio/vsnprintf.c
@@ -0,0 +1,52 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+vsnprintf(char* s, int n, const char* form, va_list args)
+{
+ Sfio_t* f;
+ ssize_t rv;
+
+ /* make a temp stream */
+ if(!(f = sfnew(NIL(Sfio_t*),NIL(char*),(size_t)SF_UNBOUND,
+ -1,SF_WRITE|SF_STRING)) )
+ return -1;
+
+ if((rv = sfvprintf(f,form,args)) >= 0 )
+ { if(s && n > 0)
+ { if((rv+1) >= n)
+ n--;
+ else
+ n = rv;
+ memcpy(s, f->data, n);
+ s[n] = 0;
+ }
+ _Sfi = rv;
+ }
+
+ sfclose(f);
+
+ return rv;
+}
diff --git a/src/lib/libast/stdio/vsprintf.c b/src/lib/libast/stdio/vsprintf.c
new file mode 100644
index 0000000..8e44614
--- /dev/null
+++ b/src/lib/libast/stdio/vsprintf.c
@@ -0,0 +1,30 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+vsprintf(char* s, const char* fmt, va_list args)
+{
+ return vsnprintf(s, 4 * SF_BUFSIZE, fmt, args);
+}
diff --git a/src/lib/libast/stdio/vsscanf.c b/src/lib/libast/stdio/vsscanf.c
new file mode 100644
index 0000000..b7f14d6
--- /dev/null
+++ b/src/lib/libast/stdio/vsscanf.c
@@ -0,0 +1,30 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+vsscanf(const char* s, const char* fmt, va_list args)
+{
+ return sfvsscanf(s, fmt, args);
+}
diff --git a/src/lib/libast/stdio/vswprintf.c b/src/lib/libast/stdio/vswprintf.c
new file mode 100644
index 0000000..ac09afb
--- /dev/null
+++ b/src/lib/libast/stdio/vswprintf.c
@@ -0,0 +1,55 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+vswprintf(wchar_t* s, size_t n, const wchar_t* fmt, va_list args)
+{
+ Sfio_t f;
+ int v;
+
+ if (!s)
+ return -1;
+
+ /*
+ * make a fake stream
+ */
+
+ SFCLEAR(&f, NiL);
+ f.flags = SF_STRING|SF_WRITE;
+ f.bits = SF_PRIVATE;
+ f.mode = SF_WRITE;
+ f.size = n - 1;
+ f.data = f.next = f.endr = (uchar*)s;
+ f.endb = f.endw = f.data + f.size;
+
+ /*
+ * call and adjust
+ */
+
+ v = vfwprintf(&f, fmt, args);
+ *f.next = 0;
+ _Sfi = f.next - f.data;
+ return v;
+}
diff --git a/src/lib/libast/stdio/vswscanf.c b/src/lib/libast/stdio/vswscanf.c
new file mode 100644
index 0000000..3f6d96c
--- /dev/null
+++ b/src/lib/libast/stdio/vswscanf.c
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+vswscanf(const wchar_t* s, const wchar_t* fmt, va_list args)
+{
+ Sfio_t f;
+
+ if (!s)
+ return -1;
+
+ /*
+ * make a fake stream
+ */
+
+ SFCLEAR(&f, NiL);
+ f.flags = SF_STRING|SF_READ;
+ f.bits = SF_PRIVATE;
+ f.mode = SF_READ;
+ f.size = wcslen(s) * sizeof(wchar_t);
+ f.data = f.next = f.endw = (uchar*)s;
+ f.endb = f.endr = f.data + f.size;
+
+ /*
+ * sfio does the rest
+ */
+
+ return vfwscanf(&f, fmt, args);
+}
diff --git a/src/lib/libast/stdio/vwprintf.c b/src/lib/libast/stdio/vwprintf.c
new file mode 100644
index 0000000..60e9dea
--- /dev/null
+++ b/src/lib/libast/stdio/vwprintf.c
@@ -0,0 +1,30 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+vwprintf(const wchar_t* fmt, va_list args)
+{
+ return vfwprintf(sfstdout, fmt, args);
+}
diff --git a/src/lib/libast/stdio/vwscanf.c b/src/lib/libast/stdio/vwscanf.c
new file mode 100644
index 0000000..dd5007f
--- /dev/null
+++ b/src/lib/libast/stdio/vwscanf.c
@@ -0,0 +1,30 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+vwscanf(const wchar_t* fmt, va_list args)
+{
+ return vfwscanf(sfstdin, fmt, args);
+}
diff --git a/src/lib/libast/stdio/wprintf.c b/src/lib/libast/stdio/wprintf.c
new file mode 100644
index 0000000..bf8949a
--- /dev/null
+++ b/src/lib/libast/stdio/wprintf.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+wprintf(const wchar_t* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+ v = vfwprintf(sfstdout, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/stdio/wscanf.c b/src/lib/libast/stdio/wscanf.c
new file mode 100644
index 0000000..7c783b8
--- /dev/null
+++ b/src/lib/libast/stdio/wscanf.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include "stdhdr.h"
+
+int
+wscanf(const wchar_t* fmt, ...)
+{
+ va_list args;
+ int v;
+
+ va_start(args, fmt);
+ v = vfwscanf(sfstdin, fmt, args);
+ va_end(args);
+ return v;
+}
diff --git a/src/lib/libast/string/base64.c b/src/lib/libast/string/base64.c
new file mode 100644
index 0000000..fc07986
--- /dev/null
+++ b/src/lib/libast/string/base64.c
@@ -0,0 +1,312 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * mime base64 encode/decode
+ *
+ * Glenn Fowler
+ * David Korn
+ * AT&T Research
+ */
+
+#include <ast.h>
+
+#define PAD '='
+
+#define B64_UC 3
+#define B64_EC 4
+#define B64_CHUNK 15
+#define B64_PAD 64
+#define B64_SPC 65
+#define B64_IGN 66
+
+static unsigned char map[UCHAR_MAX+1];
+
+static const char alp[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/*
+ * mime base64 encode
+ */
+
+ssize_t
+base64encode(const void* fb, size_t fz, void** fn, void* tb, size_t tz, void** tn)
+{
+ register unsigned char* fp;
+ register unsigned char* tp;
+ register unsigned char* fe;
+ register unsigned char* te;
+ register unsigned char* tc;
+ register unsigned char* m;
+ register unsigned long b;
+ size_t n;
+ unsigned char tmp[B64_EC * B64_CHUNK];
+
+ m = (unsigned char*)alp;
+ fp = fe = (unsigned char*)fb;
+ if (fz >= 3)
+ {
+ n = fz % 3;
+ fe += fz - n;
+ fz = n;
+ }
+ if (tp = (unsigned char*)tb)
+ {
+ te = tp + tz - B64_EC + 1;
+ n = 0;
+ }
+ else
+ {
+ if (fn)
+ *fn = fp;
+ if (tn)
+ *tn = 0;
+ tp = tmp;
+ te = tp + sizeof(tmp) - B64_EC + 1;
+ n = 1;
+ }
+ for (;;)
+ {
+ tc = tp + B64_EC * B64_CHUNK;
+ do
+ {
+ if (fp >= fe)
+ goto done;
+ if (tp >= te)
+ {
+ if (fn)
+ *fn = fp;
+ if (tn)
+ *tn = tp;
+ n = tp - (unsigned char*)tb + 1;
+ tp = tmp;
+ te = tp + sizeof(tmp) - B64_EC + 1;
+ }
+ b = *fp++ << 16;
+ b |= *fp++ << 8;
+ b |= *fp++;
+ *tp++ = m[b >> 18];
+ *tp++ = m[(b >> 12) & 077];
+ *tp++ = m[(b >> 6) & 077];
+ *tp++ = m[b & 077];
+ } while (tp < tc);
+ if (n)
+ {
+ n += tp - tmp + (fp < fe);
+ tp = tmp;
+ }
+ else
+ *tp++ = '\n';
+ }
+ done:
+ if (fz)
+ {
+ if (tp >= te)
+ {
+ if (fn)
+ *fn = fp;
+ if (tn)
+ *tn = tp;
+ n = tp - (unsigned char*)tb + 1;
+ tp = tmp;
+ te = tp + sizeof(tmp) - B64_EC + 1;
+ }
+ b = *fp++ << 16;
+ if (fz == 2)
+ b |= *fp++ << 8;
+ *tp++ = m[b >> 18];
+ *tp++ = m[(b >> 12) & 077];
+ *tp++ = (fz == 2) ? m[(b >> 6) & 077] : PAD;
+ *tp++ = PAD;
+ }
+ if (n)
+ n += (tp - tmp) - 1;
+ else
+ {
+ if (tp > (unsigned char*)tb && *(tp - 1) == '\n')
+ tp--;
+ if (tp < te)
+ *tp = 0;
+ n = tp - (unsigned char*)tb;
+ if (tn)
+ *tn = tp;
+ if (fn)
+ *fn = fp;
+ }
+ return n;
+}
+
+/*
+ * mime base64 decode
+ */
+
+ssize_t
+base64decode(const void* fb, size_t fz, void** fn, void* tb, size_t tz, void** tn)
+{
+ register unsigned char* fp;
+ register unsigned char* tp;
+ register unsigned char* fe;
+ register unsigned char* te;
+ register unsigned char* tx;
+ register unsigned char* m;
+ register int c;
+ register int state;
+ register unsigned long v;
+ unsigned char* fc;
+ ssize_t n;
+
+ if (!(m = map)[0])
+ {
+ memset(m, B64_IGN, sizeof(map));
+ for (tp = (unsigned char*)alp; c = *tp; tp++)
+ m[c] = tp - (unsigned char*)alp;
+ m[PAD] = B64_PAD;
+ m[' '] = m['\t'] = m['\n'] = B64_SPC;
+ }
+ fp = (unsigned char*)fb;
+ fe = fp + fz;
+ if (tp = (unsigned char*)tb)
+ {
+ te = tp + tz;
+ if (tz > 2)
+ tz = 2;
+ tx = te - tz;
+ n = 0;
+ }
+ else
+ {
+ te = tx = tp;
+ n = 1;
+ }
+ for (;;)
+ {
+ fc = fp;
+ state = 0;
+ v = 0;
+ while (fp < fe)
+ {
+ if ((c = m[*fp++]) < 64)
+ {
+ v = (v << 6) | c;
+ if (++state == 4)
+ {
+ if (tp >= tx)
+ {
+ if (n)
+ n += 3;
+ else
+ {
+ n = tp - (unsigned char*)tb + 4;
+ if (tp < te)
+ {
+ *tp++ = (v >> 16);
+ if (tp < te)
+ {
+ *tp++ = (v >> 8);
+ if (tp < te)
+ *tp++ = (v);
+ }
+ }
+ if (tn)
+ *tn = tp;
+ if (fn)
+ *fn = fc;
+ }
+ }
+ else
+ {
+ *tp++ = (v >> 16);
+ *tp++ = (v >> 8);
+ *tp++ = (v);
+ }
+ fc = fp;
+ state = 0;
+ v = 0;
+ }
+ }
+ else if (c == B64_PAD)
+ break;
+ }
+ switch (state)
+ {
+ case 0:
+ goto done;
+ case 2:
+ if (tp < te)
+ *tp++ = v >> 4;
+ else if (n)
+ n++;
+ else
+ {
+ n = tp - (unsigned char*)tb + 2;
+ if (tn)
+ *tn = tp;
+ if (fn)
+ *fn = fc;
+ }
+ break;
+ case 3:
+ if (tp < te)
+ {
+ *tp++ = v >> 10;
+ if (tp < te)
+ *tp++ = v >> 2;
+ else
+ {
+ n = tp - (unsigned char*)tb + 2;
+ if (tn)
+ *tn = tp;
+ if (fn)
+ *fn = fc;
+ }
+ }
+ else if (n)
+ n += 2;
+ else
+ {
+ n = tp - (unsigned char*)tb + 3;
+ if (tn)
+ *tn = tp;
+ if (fn)
+ *fn = fc;
+ }
+ break;
+ }
+ while (fp < fe && ((c = m[*fp++]) == B64_PAD || c == B64_SPC));
+ if (fp >= fe || c >= 64)
+ break;
+ fp--;
+ }
+ done:
+ if (n)
+ n--;
+ else
+ {
+ if (tp < te)
+ *tp = 0;
+ n = tp - (unsigned char*)tb;
+ if (fn)
+ *fn = fp;
+ if (tn)
+ *tn = tp;
+ }
+ return n;
+}
diff --git a/src/lib/libast/string/ccmap.c b/src/lib/libast/string/ccmap.c
new file mode 100644
index 0000000..a42ccb6
--- /dev/null
+++ b/src/lib/libast/string/ccmap.c
@@ -0,0 +1,746 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * dynamic single byte character code maps
+ */
+
+#include <ast.h>
+#include <ccode.h>
+
+#if !GENERATE
+
+/*
+ * catenated CC_ASCII to CC_* character code map table
+ * order determined by CC_* index definitions
+ * old definition values/indices must not change!
+ * each table is followed by its inverse
+ */
+
+static const unsigned char tab[] =
+{
+
+ /* ascii => ascii */
+
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+
+ /* ascii => ascii */
+
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+
+ /* ascii => ebcdic */
+
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
+ 0x16, 0x05, 0x25, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
+ 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
+ 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f,
+ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
+ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
+ 0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x9a, 0x6d,
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+ 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0x5f, 0x07,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x1b,
+ 0x30, 0x31, 0x1a, 0x33, 0x34, 0x35, 0x36, 0x08,
+ 0x38, 0x39, 0x3a, 0x3b, 0x04, 0x14, 0x3e, 0xe1,
+ 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+ 0x49, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+ 0x76, 0x77, 0x78, 0x80, 0x8a, 0x8b, 0x8c, 0x8d,
+ 0x8e, 0x8f, 0x90, 0x6a, 0x9b, 0x9c, 0x9d, 0x9e,
+ 0x9f, 0xa0, 0xaa, 0xab, 0xac, 0x4a, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xa1, 0xbe, 0xbf,
+ 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xda, 0xdb,
+ 0xdc, 0xdd, 0xde, 0xdf, 0xea, 0xeb, 0xec, 0xed,
+ 0xee, 0xef, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+
+ /* ebcdic => ascii */
+
+ 0x00, 0x01, 0x02, 0x03, 0x9c, 0x09, 0x86, 0x7f,
+ 0x97, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x9d, 0x85, 0x08, 0x87,
+ 0x18, 0x19, 0x92, 0x8f, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x0a, 0x17, 0x1b,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07,
+ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
+ 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a,
+ 0x20, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+ 0xa7, 0xa8, 0xd5, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,
+ 0x26, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x7e,
+ 0x2d, 0x2f, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xcb, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,
+ 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1,
+ 0xc2, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,
+ 0xc3, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
+ 0xca, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+ 0x71, 0x72, 0x5e, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
+ 0xd1, 0xe5, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0xd2, 0xd3, 0xd4, 0x5b, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0x5d, 0xe6, 0xe7,
+ 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed,
+ 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+ 0x51, 0x52, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3,
+ 0x5c, 0x9f, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+
+ /* ascii => ebcdic-i */
+
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
+ 0x16, 0x05, 0x25, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
+ 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
+ 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f,
+ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
+ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
+ 0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x5f, 0x6d,
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+ 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x1b,
+ 0x30, 0x31, 0x1a, 0x33, 0x34, 0x35, 0x36, 0x08,
+ 0x38, 0x39, 0x3a, 0x3b, 0x04, 0x14, 0x3e, 0xe1,
+ 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+ 0x49, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+ 0x76, 0x77, 0x78, 0x80, 0x8a, 0x8b, 0x8c, 0x8d,
+ 0x8e, 0x8f, 0x90, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e,
+ 0x9f, 0xa0, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xda, 0xdb,
+ 0xdc, 0xdd, 0xde, 0xdf, 0xea, 0xeb, 0xec, 0xed,
+ 0xee, 0xef, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+
+ /* ebcdic-i => ascii */
+
+ 0x00, 0x01, 0x02, 0x03, 0x9c, 0x09, 0x86, 0x7f,
+ 0x97, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x9d, 0x85, 0x08, 0x87,
+ 0x18, 0x19, 0x92, 0x8f, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x0a, 0x17, 0x1b,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07,
+ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
+ 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a,
+ 0x20, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+ 0xa7, 0xa8, 0x4a, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,
+ 0x26, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e,
+ 0x2d, 0x2f, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0x6a, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,
+ 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1,
+ 0xc2, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,
+ 0xc3, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
+ 0xca, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+ 0x71, 0x72, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0,
+ 0xd1, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0xd2, 0xd3, 0xd4, 0x5b, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0x5d, 0xe6, 0xe7,
+ 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed,
+ 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+ 0x51, 0x52, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3,
+ 0x5c, 0x9f, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+
+ /* ascii => ebcdic-o */
+
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
+ 0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
+ 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
+ 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f,
+ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
+ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
+ 0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x5f, 0x6d,
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+ 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x06, 0x17,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x1b,
+ 0x30, 0x31, 0x1a, 0x33, 0x34, 0x35, 0x36, 0x08,
+ 0x38, 0x39, 0x3a, 0x3b, 0x04, 0x14, 0x3e, 0xff,
+ 0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5,
+ 0xbb, 0xb4, 0x9a, 0x8a, 0xb0, 0xca, 0xaf, 0xbc,
+ 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3,
+ 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab,
+ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68,
+ 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77,
+ 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf,
+ 0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xba, 0xae, 0x59,
+ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48,
+ 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57,
+ 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1,
+ 0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf,
+
+ /* ebcdic-o => ascii */
+
+ 0x00, 0x01, 0x02, 0x03, 0x9c, 0x09, 0x86, 0x7f,
+ 0x97, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x9d, 0x0a, 0x08, 0x87,
+ 0x18, 0x19, 0x92, 0x8f, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1b,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07,
+ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
+ 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a,
+ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,
+ 0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,
+ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,
+ 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e,
+ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,
+ 0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,
+ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
+ 0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,
+ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1,
+ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+ 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4,
+ 0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae,
+ 0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,
+ 0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7,
+ 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5,
+ 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+ 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff,
+ 0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f,
+
+ /* ascii => ebcdic-s */
+
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
+ 0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
+ 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
+ 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f,
+ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
+ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
+ 0xe7, 0xe8, 0xe9, 0xbb, 0xbc, 0xbd, 0x6a, 0x6d,
+ 0x4a, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+ 0xa7, 0xa8, 0xa9, 0xfb, 0x4f, 0xfd, 0xff, 0x07,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x06, 0x17,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x1b,
+ 0x30, 0x31, 0x1a, 0x33, 0x34, 0x35, 0x36, 0x08,
+ 0x38, 0x39, 0x3a, 0x3b, 0x04, 0x14, 0x3e, 0x5f,
+ 0x41, 0xaa, 0xb0, 0xb1, 0x9f, 0xb2, 0xd0, 0xb5,
+ 0x79, 0xb4, 0x9a, 0x8a, 0xba, 0xca, 0xaf, 0xa1,
+ 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3,
+ 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab,
+ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68,
+ 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77,
+ 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf,
+ 0x80, 0xe0, 0xfe, 0xdd, 0xfc, 0xad, 0xae, 0x59,
+ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48,
+ 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57,
+ 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1,
+ 0x70, 0xc0, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf,
+
+ /* ebcdic-s => ascii */
+
+ 0x00, 0x01, 0x02, 0x03, 0x9c, 0x09, 0x86, 0x7f,
+ 0x97, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x9d, 0x0a, 0x08, 0x87,
+ 0x18, 0x19, 0x92, 0x8f, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1b,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07,
+ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
+ 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a,
+ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,
+ 0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,
+ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,
+ 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f,
+ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,
+ 0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,
+ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
+ 0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,
+ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1,
+ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+ 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4,
+ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae,
+ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,
+ 0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7,
+ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5,
+ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+ 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff,
+ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e,
+
+ /* ascii => ebcdic-h */
+
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
+ 0x16, 0x05, 0x25, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
+ 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
+ 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f,
+ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
+ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
+ 0xe7, 0xe8, 0xe9, 0xba, 0xe0, 0xbb, 0xb0, 0x6d,
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+ 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x1b,
+ 0x30, 0x31, 0x1a, 0x33, 0x34, 0x35, 0x36, 0x08,
+ 0x38, 0x39, 0x3a, 0x3b, 0x04, 0x14, 0x3e, 0xff,
+ 0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5,
+ 0xbd, 0xb4, 0x9a, 0x8a, 0x5f, 0xca, 0xaf, 0xbc,
+ 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3,
+ 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab,
+ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68,
+ 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77,
+ 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf,
+ 0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xad, 0xae, 0x59,
+ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48,
+ 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57,
+ 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1,
+ 0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf,
+
+ /* ebcdic-h => ascii */
+
+ 0x00, 0x01, 0x02, 0x03, 0x9c, 0x09, 0x86, 0x7f,
+ 0x97, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x9d, 0x85, 0x08, 0x87,
+ 0x18, 0x19, 0x92, 0x8f, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x0a, 0x17, 0x1b,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07,
+ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
+ 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a,
+ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,
+ 0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,
+ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,
+ 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0xac,
+ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,
+ 0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,
+ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
+ 0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,
+ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1,
+ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+ 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4,
+ 0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae,
+ 0x5e, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,
+ 0xbd, 0xbe, 0x5b, 0x5d, 0xaf, 0xa8, 0xb4, 0xd7,
+ 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5,
+ 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+ 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff,
+ 0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f,
+
+ /* ascii => ebcdic-m */
+
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
+ 0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26,
+ 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
+ 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f,
+ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
+ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
+ 0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x5f, 0x6d,
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+ 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x06, 0x17,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x1b,
+ 0x30, 0x31, 0x1a, 0x33, 0x34, 0x35, 0x36, 0x08,
+ 0x38, 0x39, 0x3a, 0x3b, 0x04, 0x14, 0x3e, 0xdf,
+ 0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5,
+ 0xbb, 0xb4, 0x9a, 0x8a, 0xb0, 0xca, 0xaf, 0xbc,
+ 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3,
+ 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab,
+ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68,
+ 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77,
+ 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf,
+ 0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xba, 0xae, 0x59,
+ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48,
+ 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57,
+ 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1,
+ 0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xff,
+
+ /* ebcdic-m => ascii */
+
+ 0x00, 0x01, 0x02, 0x03, 0x9c, 0x09, 0x86, 0x7f,
+ 0x97, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x9d, 0x0a, 0x08, 0x87,
+ 0x18, 0x19, 0x92, 0x8f, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x17, 0x1b,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07,
+ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,
+ 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a,
+ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,
+ 0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,
+ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,
+ 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e,
+ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,
+ 0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,
+ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,
+ 0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,
+ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1,
+ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+ 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4,
+ 0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae,
+ 0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,
+ 0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7,
+ 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5,
+ 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+ 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0x9f,
+ 0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0xff,
+
+ /* ascii => ebcdic-u */
+
+ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f,
+ 0x16, 0x05, 0x25, 0x0b, 0x0c, 0x0d, 0x0e, 0x9f,
+ 0x10, 0x11, 0x12, 0x13, 0xb6, 0xb5, 0x32, 0x26,
+ 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d,
+ 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f,
+ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
+ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
+ 0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x5f, 0x6d,
+ 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
+ 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07,
+ 0x68, 0xdc, 0x51, 0x42, 0x43, 0x44, 0x47, 0x48,
+ 0x52, 0x53, 0x54, 0x57, 0x56, 0x58, 0x63, 0x67,
+ 0x71, 0x9c, 0x9e, 0xcb, 0xcc, 0xcd, 0xdb, 0xdd,
+ 0xdf, 0xec, 0xfc, 0xb0, 0xb1, 0xb2, 0x3e, 0xb4,
+ 0x45, 0x55, 0xce, 0xde, 0x49, 0x69, 0x9a, 0x9b,
+ 0xab, 0x0f, 0xba, 0xb8, 0xb7, 0xaa, 0x8a, 0x8b,
+ 0x3c, 0x3d, 0x62, 0x6a, 0x64, 0x65, 0x66, 0x20,
+ 0x21, 0x22, 0x70, 0x23, 0x72, 0x73, 0x74, 0xbe,
+ 0x76, 0x77, 0x78, 0x80, 0x24, 0x15, 0x8c, 0x8d,
+ 0x8e, 0x41, 0x06, 0x17, 0x28, 0x29, 0x9d, 0x2a,
+ 0x2b, 0x2c, 0x09, 0x0a, 0xac, 0x4a, 0xae, 0xaf,
+ 0x1b, 0x30, 0x31, 0xfa, 0x1a, 0x33, 0x34, 0x35,
+ 0x36, 0x59, 0x08, 0x38, 0xbc, 0x39, 0xa0, 0xbf,
+ 0xca, 0x3a, 0xfe, 0x3b, 0x04, 0xcf, 0xda, 0x14,
+ 0xe1, 0x8f, 0x46, 0x75, 0xfd, 0xeb, 0xee, 0xed,
+ 0x90, 0xef, 0xb3, 0xfb, 0xb9, 0xea, 0xbb, 0xff,
+
+ /* ebcdic-u => ascii */
+
+ 0x00, 0x01, 0x02, 0x03, 0xec, 0x09, 0xca, 0x7f,
+ 0xe2, 0xd2, 0xd3, 0x0b, 0x0c, 0x0d, 0x0e, 0xa9,
+ 0x10, 0x11, 0x12, 0x13, 0xef, 0xc5, 0x08, 0xcb,
+ 0x18, 0x19, 0xdc, 0xd8, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0xb7, 0xb8, 0xb9, 0xbb, 0xc4, 0x0a, 0x17, 0x1b,
+ 0xcc, 0xcd, 0xcf, 0xd0, 0xd1, 0x05, 0x06, 0x07,
+ 0xd9, 0xda, 0x16, 0xdd, 0xde, 0xdf, 0xe0, 0x04,
+ 0xe3, 0xe5, 0xe9, 0xeb, 0xb0, 0xb1, 0x9e, 0x1a,
+ 0x20, 0xc9, 0x83, 0x84, 0x85, 0xa0, 0xf2, 0x86,
+ 0x87, 0xa4, 0xd5, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,
+ 0x26, 0x82, 0x88, 0x89, 0x8a, 0xa1, 0x8c, 0x8b,
+ 0x8d, 0xe1, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e,
+ 0x2d, 0x2f, 0xb2, 0x8e, 0xb4, 0xb5, 0xb6, 0x8f,
+ 0x80, 0xa5, 0xb3, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,
+ 0xba, 0x90, 0xbc, 0xbd, 0xbe, 0xf3, 0xc0, 0xc1,
+ 0xc2, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,
+ 0xc3, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0xae, 0xaf, 0xc6, 0xc7, 0xc8, 0xf1,
+ 0xf8, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,
+ 0x71, 0x72, 0xa6, 0xa7, 0x91, 0xce, 0x92, 0x0f,
+ 0xe6, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0xad, 0xa8, 0xd4, 0x5b, 0xd6, 0xd7,
+ 0x9b, 0x9c, 0x9d, 0xfa, 0x9f, 0x15, 0x14, 0xac,
+ 0xab, 0xfc, 0xaa, 0xfe, 0xe4, 0x5d, 0xbf, 0xe7,
+ 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0xe8, 0x93, 0x94, 0x95, 0xa2, 0xed,
+ 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
+ 0x51, 0x52, 0xee, 0x96, 0x81, 0x97, 0xa3, 0x98,
+ 0x5c, 0xf0, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0xfd, 0xf5, 0x99, 0xf7, 0xf6, 0xf9,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0xdb, 0xfb, 0x9a, 0xf4, 0xea, 0xff,
+
+};
+
+#define MAP 256
+#define MAPS (sizeof(tab)/MAP)
+
+struct Map_s; typedef struct Map_s Map_t;
+
+struct Map_s
+{
+ Map_t* next;
+ int op;
+ unsigned char map[MAP];
+};
+
+static Map_t* maps;
+
+/*
+ * generate and return ccode map from i to o
+ */
+
+unsigned char*
+_ccmap(int i, int o)
+{
+ register unsigned char* a;
+ register unsigned char* m;
+ register unsigned char* z;
+ register Map_t* map;
+ register int n;
+ int op;
+
+ if (!i && !o)
+ return (unsigned char*)tab;
+ if (CCCONVERT(i))
+ {
+ o = CCOUT(i);
+ i = CCIN(i);
+ }
+ else if (CCCONVERT(o))
+ {
+ i = CCIN(o);
+ o = CCOUT(o);
+ }
+ else
+ {
+ if (i == 0)
+ i = CC_NATIVE;
+ if (o == 0)
+ o = CC_NATIVE;
+ }
+ if (i == o || i < 1 || i > MAPS || o < 1 || o > MAPS)
+ return 0;
+ if (i == CC_ASCII)
+ return (unsigned char*)tab + MAP * (2 * (o - 1));
+ if (o == CC_ASCII)
+ return (unsigned char*)tab + MAP * (2 * (i - 1) + 1);
+ op = CCOP(i, o);
+ for (map = maps; map; map = map->next)
+ if (map->op == op)
+ return map->map;
+ if (!(map = newof(0, Map_t, 1, 0)))
+ return 0;
+ map->op = op;
+ a = (unsigned char*)tab + MAP * (2 * (o - 1));
+ z = (unsigned char*)tab + MAP * (2 * (i - 1) + 1);
+ m = map->map;
+ for (n = 0; n < MAP; n++)
+ m[n] = n;
+ for (n = MAP - 1; n >= 0; n--)
+ m[n] = a[z[n]];
+ map->next = maps;
+ maps = map;
+ return m;
+}
+
+void*
+_ccmapcpy(register unsigned char* m, void* b, const void* a, size_t n)
+{
+ register unsigned char* ub;
+ register unsigned char* ue;
+ register unsigned char* ua;
+
+ if (m)
+ {
+ ub = (unsigned char*)b;
+ ue = ub + n;
+ ua = (unsigned char*)a;
+ while (ub < ue)
+ *ub++ = m[*ua++];
+ }
+ else
+ memcpy(b, a, n);
+ return b;
+}
+
+void*
+_ccmapstr(register unsigned char* m, void* b, size_t n)
+{
+ register unsigned char* s;
+ register unsigned char* e;
+
+ if (m)
+ for (e = (s = (unsigned char*)b) + n; s < e; s++)
+ *s = m[*s];
+ return b;
+}
+
+#else
+
+static void
+dump(int from, int to)
+{
+ register const unsigned char* m;
+ register int c;
+ register int i;
+
+ m = ccmap(from, to);
+ sfprintf(sfstdout, "\n /* %s => %s */\n\n", ccmapname(from), ccmapname(to));
+ for (c = i = 0; c <= UCHAR_MAX; c++)
+ {
+ sfprintf(sfstdout, " 0x%02x,", m ? m[c] : c);
+ if (!(++i & 0x7))
+ {
+ i = 0;
+ sfprintf(sfstdout, "\n");
+ }
+ }
+}
+
+main(int argc, char** argv)
+{
+ register int i;
+
+ for (i = 1; i <= CC_MAPS; i++)
+ {
+ dump(CC_ASCII, i);
+ dump(i, CC_ASCII);
+ }
+ return 0;
+}
+
+#endif
diff --git a/src/lib/libast/string/ccmapid.c b/src/lib/libast/string/ccmapid.c
new file mode 100644
index 0000000..f18d46e
--- /dev/null
+++ b/src/lib/libast/string/ccmapid.c
@@ -0,0 +1,173 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * 8 bit character code map name/id lookup support
+ */
+
+#include <ast.h>
+#include <ccode.h>
+#include <ctype.h>
+
+static const Ccmap_t maps[] =
+{
+ {
+ "ascii",
+ "a|ascii|?(iso)?(-)646|?(iso)?(-)8859|latin",
+ "8 bit ascii",
+ "ISO-8859-%s",
+ "1",
+ CC_ASCII,
+ },
+
+ {
+ "ebcdic",
+ "e|ebcdic?(-)?([1e])",
+ "X/Open ebcdic",
+ "EBCDIC",
+ 0,
+ CC_EBCDIC_E,
+ },
+
+ {
+ "ebcdic-o",
+ "o|ebcdic?(-)[3o]|?(cp|ibm)1047|open?(-)edition",
+ "mvs OpenEdition ebcdic",
+ "EBCDIC-O",
+ 0,
+ CC_EBCDIC_O,
+ },
+
+ {
+ "ebcdic-h",
+ "h|ebcdic?(-)h|?(cp|ibm)?(00)37|[oa]s?(/-)400",
+ "ibm OS/400 AS/400 ebcdic",
+ "EBCDIC-H",
+ 0,
+ CC_EBCDIC_H,
+ },
+
+ {
+ "ebcdic-s",
+ "s|ebcdic?(-)s|siemens|posix-bc",
+ "siemens posix-bc ebcdic",
+ "EBCDIC-S",
+ 0,
+ CC_EBCDIC_S,
+ },
+
+ {
+ "ebcdic-i",
+ "i|ebcdic?(-)[2i]|ibm",
+ "X/Open ibm ebcdic (not idempotent)",
+ "EBCDIC-I",
+ 0,
+ CC_EBCDIC_I,
+ },
+
+ {
+ "ebcdic-m",
+ "m|ebcdic?(-)m|mvs",
+ "mvs ebcdic",
+ "EBCDIC-M",
+ 0,
+ CC_EBCDIC_M,
+ },
+
+ {
+ "ebcdic-u",
+ "u|ebcdic?(-)(u|mf)|microfocus",
+ "microfocus cobol ebcdic",
+ "EBCDIC-U",
+ 0,
+ CC_EBCDIC_U,
+ },
+
+ {
+ "native",
+ "n|native|local",
+ "native code set",
+ 0,
+ 0,
+ CC_NATIVE,
+ },
+
+ { 0 },
+};
+
+/*
+ * ccode map list iterator
+ */
+
+Ccmap_t*
+ccmaplist(Ccmap_t* mp)
+{
+ return !mp ? (Ccmap_t*)maps : (++mp)->name ? mp : (Ccmap_t*)0;
+}
+
+/*
+ * return ccode map id given name
+ */
+
+int
+ccmapid(const char* name)
+{
+ register const Ccmap_t* mp;
+ register int c;
+ const Ccmap_t* bp;
+ int n;
+ int sub[2];
+
+ bp = 0;
+ n = 0;
+ for (mp = maps; mp->name; mp++)
+ if (strgrpmatch(name, mp->match, sub, elementsof(sub) / 2, STR_MAXIMAL|STR_LEFT|STR_ICASE))
+ {
+ if (!(c = name[sub[1]]))
+ return mp->ccode;
+ if (sub[1] > n && !isalpha(c))
+ {
+ n = sub[1];
+ bp = mp;
+ }
+ }
+ return bp ? bp->ccode : -1;
+}
+
+/*
+ * return ccode map name given id
+ */
+
+char*
+ccmapname(register int id)
+{
+ register const Ccmap_t* mp;
+
+ for (mp = maps; mp->name; mp++)
+ if (id == mp->ccode)
+ return (char*)mp->name;
+ return 0;
+}
diff --git a/src/lib/libast/string/ccnative.c b/src/lib/libast/string/ccnative.c
new file mode 100644
index 0000000..500f165
--- /dev/null
+++ b/src/lib/libast/string/ccnative.c
@@ -0,0 +1,56 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * copy table with element size n
+ * indexed by CC_ASCII to table
+ * indexed by CC_NATIVE
+ */
+
+#include <ast.h>
+#include <ccode.h>
+
+void*
+ccnative(void* b, const void* a, size_t n)
+{
+#if CC_ASCII == CC_NATIVE
+ return memcpy(b, a, n * (UCHAR_MAX + 1));
+#else
+ register int c;
+ register const unsigned char* m;
+ register unsigned char* cb = (unsigned char*)b;
+ register unsigned char* ca = (unsigned char*)a;
+
+ m = CCMAP(CC_ASCII, CC_NATIVE);
+ if (n == sizeof(char))
+ for (c = 0; c <= UCHAR_MAX; c++)
+ cb[c] = ca[m[c]];
+ else
+ for (c = 0; c <= UCHAR_MAX; c++)
+ memcpy(cb + n * c, ca + n * m[c], n);
+ return b;
+#endif
+}
diff --git a/src/lib/libast/string/chresc.c b/src/lib/libast/string/chresc.c
new file mode 100644
index 0000000..9dd3704
--- /dev/null
+++ b/src/lib/libast/string/chresc.c
@@ -0,0 +1,235 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return the next character in the string s
+ * \ character constants are expanded
+ * *p is updated to point to the next character in s
+ * *m is 1 if return value is wide
+ */
+
+#include <ast.h>
+#include <ctype.h>
+
+#include <ccode.h>
+#if !_PACKAGE_astsa
+#include <regex.h>
+#endif
+
+int
+chrexp(register const char* s, char** p, int* m, register int flags)
+{
+ register const char* q;
+ register int c;
+ const char* e;
+ const char* b;
+ char* r;
+ int n;
+ int w;
+
+ w = 0;
+ for (;;)
+ {
+ b = s;
+ switch (c = mbchar(s))
+ {
+ case 0:
+ s--;
+ break;
+ case '\\':
+ switch (c = *s++)
+ {
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ if (!(flags & FMT_EXP_CHAR))
+ goto noexpand;
+ c -= '0';
+ q = s + 2;
+ while (s < q)
+ switch (*s)
+ {
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ c = (c << 3) + *s++ - '0';
+ break;
+ default:
+ q = s;
+ break;
+ }
+ break;
+ case 'a':
+ if (!(flags & FMT_EXP_CHAR))
+ goto noexpand;
+ c = CC_bel;
+ break;
+ case 'b':
+ if (!(flags & FMT_EXP_CHAR))
+ goto noexpand;
+ c = '\b';
+ break;
+ case 'c': /*DEPRECATED*/
+ case 'C':
+ if (!(flags & FMT_EXP_CHAR))
+ goto noexpand;
+ if (c = *s)
+ {
+ s++;
+ if (c == '\\')
+ {
+ c = chrexp(s - 1, &r, 0, flags);
+ s = (const char*)r;
+ }
+ if (islower(c))
+ c = toupper(c);
+ c = ccmapc(c, CC_NATIVE, CC_ASCII);
+ c ^= 0x40;
+ c = ccmapc(c, CC_ASCII, CC_NATIVE);
+ }
+ break;
+ case 'e': /*DEPRECATED*/
+ case 'E':
+ if (!(flags & FMT_EXP_CHAR))
+ goto noexpand;
+ c = CC_esc;
+ break;
+ case 'f':
+ if (!(flags & FMT_EXP_CHAR))
+ goto noexpand;
+ c = '\f';
+ break;
+ case 'M':
+ if (!(flags & FMT_EXP_CHAR))
+ goto noexpand;
+ if (*s == '-')
+ {
+ s++;
+ c = CC_esc;
+ }
+ break;
+ case 'n':
+ if (flags & FMT_EXP_NONL)
+ continue;
+ if (!(flags & FMT_EXP_LINE))
+ goto noexpand;
+ c = '\n';
+ break;
+ case 'r':
+ if (flags & FMT_EXP_NOCR)
+ continue;
+ if (!(flags & FMT_EXP_LINE))
+ goto noexpand;
+ c = '\r';
+ break;
+ case 't':
+ if (!(flags & FMT_EXP_CHAR))
+ goto noexpand;
+ c = '\t';
+ break;
+ case 'v':
+ if (!(flags & FMT_EXP_CHAR))
+ goto noexpand;
+ c = CC_vt;
+ break;
+ case 'u':
+ case 'U':
+ case 'x':
+ if (q = c == 'u' ? (s + 4) : c == 'U' ? (s + 8) : (char*)0)
+ {
+ if (!(flags & FMT_EXP_WIDE))
+ goto noexpand;
+ w = 1;
+ }
+ b = e = s;
+ n = 0;
+ c = 0;
+ while (!e || !q || s < q)
+ {
+ switch (*s)
+ {
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ c = (c << 4) + *s++ - 'a' + 10;
+ n++;
+ continue;
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ c = (c << 4) + *s++ - 'A' + 10;
+ n++;
+ continue;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ c = (c << 4) + *s++ - '0';
+ n++;
+ continue;
+ case '{':
+ case '[':
+ if (s != e)
+ break;
+ e = 0;
+ s++;
+ continue;
+ case '}':
+ case ']':
+ if (!e)
+ s++;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ if (n <= 2 && !(flags & FMT_EXP_CHAR) || n > 2 && (w = 1) && !(flags & FMT_EXP_WIDE))
+ {
+ c = '\\';
+ s = b;
+ }
+ break;
+ case 0:
+ s--;
+ break;
+ }
+ break;
+ default:
+ if ((s - b) > 1)
+ w = 1;
+ break;
+ }
+ break;
+ }
+ normal:
+ if (p)
+ *p = (char*)s;
+ if (m)
+ *m = w;
+ return c;
+ noexpand:
+ c = '\\';
+ s--;
+ goto normal;
+}
+
+int
+chresc(register const char* s, char** p)
+{
+ return chrexp(s, p, NiL, FMT_EXP_CHAR|FMT_EXP_LINE|FMT_EXP_WIDE);
+}
diff --git a/src/lib/libast/string/chrtoi.c b/src/lib/libast/string/chrtoi.c
new file mode 100644
index 0000000..2d8a3e1
--- /dev/null
+++ b/src/lib/libast/string/chrtoi.c
@@ -0,0 +1,55 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * convert a 0 terminated character constant string to an int
+ */
+
+#include <ast.h>
+
+int
+chrtoi(register const char* s)
+{
+ register int c;
+ register int n;
+ register int x;
+ char* p;
+
+ c = 0;
+ for (n = 0; n < sizeof(int) * CHAR_BIT; n += CHAR_BIT)
+ {
+ switch (x = *((unsigned char*)s++))
+ {
+ case '\\':
+ x = chresc(s - 1, &p);
+ s = (const char*)p;
+ break;
+ case 0:
+ return(c);
+ }
+ c = (c << CHAR_BIT) | x;
+ }
+ return(c);
+}
diff --git a/src/lib/libast/string/fmtbase.c b/src/lib/libast/string/fmtbase.c
new file mode 100644
index 0000000..a7262eb
--- /dev/null
+++ b/src/lib/libast/string/fmtbase.c
@@ -0,0 +1,70 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * return base b representation for n
+ * if p!=0 then base prefix is included
+ * otherwise if n==0 or b==0 then output is signed base 10
+ */
+
+#include <ast.h>
+
+char*
+fmtbase(intmax_t n, int b, int p)
+{
+ char* buf;
+ int z;
+
+ if (!p)
+ {
+ if (!n)
+ return "0";
+ if (!b)
+ return fmtint(n, 0);
+ if (b == 10)
+ return fmtint(n, 1);
+ }
+ buf = fmtbuf(z = 72);
+ sfsprintf(buf, z, p ? "%#..*I*u" : "%..*I*u", b, sizeof(n), n);
+ return buf;
+}
+
+#if __OBSOLETE__ < 20140101
+
+#undef fmtbasell
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char*
+fmtbasell(intmax_t n, int b, int p)
+{
+ return fmtbase(n, b, p);
+}
+
+#undef extern
+
+#endif
diff --git a/src/lib/libast/string/fmtbuf.c b/src/lib/libast/string/fmtbuf.c
new file mode 100644
index 0000000..bc96af6
--- /dev/null
+++ b/src/lib/libast/string/fmtbuf.c
@@ -0,0 +1,69 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+/*
+ * return small format buffer chunk of size n
+ * spin lock for thread access
+ * format buffers are short lived
+ * only one concurrent buffer with size > sizeof(buf)
+ */
+
+static char buf[16 * 1024];
+static char* nxt = buf;
+static int lck = -1;
+
+static char* big;
+static size_t bigsiz;
+
+char*
+fmtbuf(size_t n)
+{
+ register char* cur;
+
+ while (++lck)
+ lck--;
+ if (n > (&buf[elementsof(buf)] - nxt))
+ {
+ if (n > elementsof(buf))
+ {
+ if (n > bigsiz)
+ {
+ bigsiz = roundof(n, 8 * 1024);
+ if (!(big = newof(big, char, bigsiz, 0)))
+ {
+ lck--;
+ return 0;
+ }
+ }
+ lck--;
+ return big;
+ }
+ nxt = buf;
+ }
+ cur = nxt;
+ nxt += n;
+ lck--;
+ return cur;
+}
diff --git a/src/lib/libast/string/fmtclock.c b/src/lib/libast/string/fmtclock.c
new file mode 100644
index 0000000..6e54cfa
--- /dev/null
+++ b/src/lib/libast/string/fmtclock.c
@@ -0,0 +1,63 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * return pointer to formatted clock() tics t
+ * return value length is at most 6
+ */
+
+#include <ast.h>
+#include <tm.h>
+
+char*
+fmtclock(register Sfulong_t t)
+{
+ register int u;
+ char* buf;
+ int z;
+
+ static unsigned int clk_tck;
+
+ if (!clk_tck)
+ {
+#ifdef CLOCKS_PER_SEC
+ clk_tck = CLOCKS_PER_SEC;
+#else
+ if (!(clk_tck = (unsigned int)strtoul(astconf("CLK_TCK", NiL, NiL), NiL, 10)))
+ clk_tck = 60;
+#endif
+ }
+ if (t == 0)
+ return "0";
+ if (t == ((Sfulong_t)~0))
+ return "%";
+ t = (t * 1000000) / clk_tck;
+ if (t < 1000)
+ u = 'u';
+ else if ((t /= 1000) < 1000)
+ u = 'm';
+ else
+ return fmtelapsed(t / 10, 100);
+ buf = fmtbuf(z = 7);
+ sfsprintf(buf, z, "%I*u%cs", sizeof(t), t, u);
+ return buf;
+}
diff --git a/src/lib/libast/string/fmtdev.c b/src/lib/libast/string/fmtdev.c
new file mode 100644
index 0000000..9f20f5f
--- /dev/null
+++ b/src/lib/libast/string/fmtdev.c
@@ -0,0 +1,60 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * st_dev formatter
+ */
+
+#include <ast.h>
+#include <ctype.h>
+#include <ls.h>
+
+char*
+fmtdev(struct stat* st)
+{
+ char* buf;
+ unsigned long mm;
+ unsigned int ma;
+ unsigned int mi;
+ int z;
+
+ mm = (S_ISBLK(st->st_mode) || S_ISCHR(st->st_mode)) ? idevice(st) : st->st_dev;
+ ma = major(mm);
+ mi = minor(mm);
+ buf = fmtbuf(z = 17);
+ if (ma == '#' && isalnum(mi))
+ {
+ /*
+ * Plan? Nein!
+ */
+
+ buf[0] = ma;
+ buf[1] = mi;
+ buf[2] = 0;
+ }
+ else
+ sfsprintf(buf, z, "%03d,%03d", ma, mi);
+ return buf;
+}
diff --git a/src/lib/libast/string/fmtelapsed.c b/src/lib/libast/string/fmtelapsed.c
new file mode 100644
index 0000000..a1c5779
--- /dev/null
+++ b/src/lib/libast/string/fmtelapsed.c
@@ -0,0 +1,61 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * return pointer to formatted elapsed time for u 1/n secs
+ * compatible with strelapsed()
+ * return value length is at most 7
+ */
+
+#include <ast.h>
+
+char*
+fmtelapsed(register unsigned long u, register int n)
+{
+ register unsigned long t;
+ char* buf;
+ int z;
+
+ if (u == 0L)
+ return "0";
+ if (u == ~0L)
+ return "%";
+ buf = fmtbuf(z = 8);
+ t = u / n;
+ if (t < 60)
+ sfsprintf(buf, z, "%lu.%02lus", t, (u * 100 / n) % 100);
+ else if (t < 60*60)
+ sfsprintf(buf, z, "%lum%02lus", t / 60, t - (t / 60) * 60);
+ else if (t < 24*60*60)
+ sfsprintf(buf, z, "%luh%02lum", t / (60*60), (t - (t / (60*60)) * (60*60)) / 60);
+ else if (t < 7*24*60*60)
+ sfsprintf(buf, z, "%lud%02luh", t / (24*60*60), (t - (t / (24*60*60)) * (24*60*60)) / (60*60));
+ else if (t < 31*24*60*60)
+ sfsprintf(buf, z, "%luw%02lud", t / (7*24*60*60), (t - (t / (7*24*60*60)) * (7*24*60*60)) / (24*60*60));
+ else if (t < 365*24*60*60)
+ sfsprintf(buf, z, "%luM%02lud", (t * 12) / (365*24*60*60), ((t * 12) - ((t * 12) / (365*24*60*60)) * (365*24*60*60)) / (12*24*60*60));
+ else if (t < (365UL*4UL+1UL)*24UL*60UL*60UL)
+ sfsprintf(buf, z, "%luY%02luM", t / (365*24*60*60), ((t - (t / (365*24*60*60)) * (365*24*60*60)) * 5) / (152 * 24 * 60 * 60));
+ else
+ sfsprintf(buf, z, "%luY%02luM", (t * 4) / ((365UL*4UL+1UL)*24UL*60UL*60UL), (((t * 4) - ((t * 4) / ((365UL*4UL+1UL)*24UL*60UL*60UL)) * ((365UL*4UL+1UL)*24UL*60UL*60UL)) * 5) / ((4 * 152 + 1) * 24 * 60 * 60));
+ return buf;
+}
diff --git a/src/lib/libast/string/fmterror.c b/src/lib/libast/string/fmterror.c
new file mode 100644
index 0000000..eeeb5bc
--- /dev/null
+++ b/src/lib/libast/string/fmterror.c
@@ -0,0 +1,37 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return error message string given errno
+ */
+
+#include <ast.h>
+
+char*
+fmterror(int err)
+{
+ return strerror(err);
+}
diff --git a/src/lib/libast/string/fmtesc.c b/src/lib/libast/string/fmtesc.c
new file mode 100644
index 0000000..753b195
--- /dev/null
+++ b/src/lib/libast/string/fmtesc.c
@@ -0,0 +1,248 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return string with expanded escape chars
+ */
+
+#include <ast.h>
+#include <ccode.h>
+#include <ctype.h>
+#if _hdr_wchar && _hdr_wctype
+#include <wchar.h>
+#include <wctype.h>
+#endif
+
+/*
+ * quote string as of length n with qb...qe
+ * (flags&FMT_ALWAYS) always quotes, otherwise quote output only if necessary
+ * qe and the usual suspects are \... escaped
+ * (flags&FMT_WIDE) doesn't escape 8 bit chars
+ * (flags&FMT_ESCAPED) doesn't \... escape the usual suspects
+ * (flags&FMT_SHELL) escape $`"#;~&|()<>[]*?
+ */
+
+char*
+fmtquote(const char* as, const char* qb, const char* qe, size_t n, int flags)
+{
+ register unsigned char* s = (unsigned char*)as;
+ register unsigned char* e = s + n;
+ register char* b;
+ register int c;
+ register int m;
+ register int escaped;
+ register int spaced;
+ register int doublequote;
+ register int singlequote;
+ int shell;
+ char* f;
+ char* buf;
+
+ c = 4 * (n + 1);
+ if (qb)
+ c += strlen((char*)qb);
+ if (qe)
+ c += strlen((char*)qe);
+ b = buf = fmtbuf(c);
+ shell = 0;
+ doublequote = 0;
+ singlequote = 0;
+ if (qb)
+ {
+ if (qb[0] == '$' && qb[1] == '\'' && qb[2] == 0)
+ shell = 1;
+ else if ((flags & FMT_SHELL) && qb[1] == 0)
+ {
+ if (qb[0] == '"')
+ doublequote = 1;
+ else if (qb[0] == '\'')
+ singlequote = 1;
+ }
+ while (*b = *qb++)
+ b++;
+ }
+ else if (flags & FMT_SHELL)
+ doublequote = 1;
+ f = b;
+ escaped = spaced = !!(flags & FMT_ALWAYS);
+ while (s < e)
+ {
+ if ((m = mbsize(s)) > 1 && (s + m) <= e)
+ {
+#if _hdr_wchar && _hdr_wctype
+ c = mbchar(s);
+ if (!spaced && !escaped && (iswspace(c) || iswcntrl(c)))
+ spaced = 1;
+ s -= m;
+#endif
+ while (m--)
+ *b++ = *s++;
+ }
+ else
+ {
+ c = *s++;
+ if (!(flags & FMT_ESCAPED) && (iscntrl(c) || !isprint(c) || c == '\\'))
+ {
+ escaped = 1;
+ *b++ = '\\';
+ switch (c)
+ {
+ case CC_bel:
+ c = 'a';
+ break;
+ case '\b':
+ c = 'b';
+ break;
+ case '\f':
+ c = 'f';
+ break;
+ case '\n':
+ c = 'n';
+ break;
+ case '\r':
+ c = 'r';
+ break;
+ case '\t':
+ c = 't';
+ break;
+ case CC_vt:
+ c = 'v';
+ break;
+ case CC_esc:
+ c = 'E';
+ break;
+ case '\\':
+ break;
+ default:
+ if (!(flags & FMT_WIDE) || !(c & 0200))
+ {
+ *b++ = '0' + ((c >> 6) & 07);
+ *b++ = '0' + ((c >> 3) & 07);
+ c = '0' + (c & 07);
+ }
+ else
+ b--;
+ break;
+ }
+ }
+ else if (c == '\\')
+ {
+ escaped = 1;
+ *b++ = c;
+ if (*s)
+ c = *s++;
+ }
+ else if (qe && strchr(qe, c))
+ {
+ if (singlequote && c == '\'')
+ {
+ spaced = 1;
+ *b++ = '\'';
+ *b++ = '\\';
+ *b++ = '\'';
+ c = '\'';
+ }
+ else
+ {
+ escaped = 1;
+ *b++ = '\\';
+ }
+ }
+ else if (c == '$' || c == '`')
+ {
+ if (c == '$' && (flags & FMT_PARAM) && (*s == '{' || *s == '('))
+ {
+ if (singlequote || shell)
+ {
+ escaped = 1;
+ *b++ = '\'';
+ *b++ = c;
+ *b++ = *s++;
+ if (shell)
+ {
+ spaced = 1;
+ *b++ = '$';
+ }
+ c = '\'';
+ }
+ else
+ {
+ escaped = 1;
+ *b++ = c;
+ c = *s++;
+ }
+ }
+ else if (doublequote)
+ *b++ = '\\';
+ else if (singlequote || (flags & FMT_SHELL))
+ spaced = 1;
+ }
+ else if (!spaced && !escaped && (isspace(c) || ((flags & FMT_SHELL) || shell) && (strchr("\";~&|()<>[]*?", c) || c == '#' && (b == f || isspace(*(b - 1))))))
+ spaced = 1;
+ *b++ = c;
+ }
+ }
+ if (qb)
+ {
+ if (!escaped)
+ buf += shell + !spaced;
+ if (qe && (escaped || spaced))
+ while (*b = *qe++)
+ b++;
+ }
+ *b = 0;
+ return buf;
+}
+
+/*
+ * escape the usual suspects and quote chars in qs
+ * in length n string as
+ */
+
+char*
+fmtnesq(const char* as, const char* qs, size_t n)
+{
+ return fmtquote(as, NiL, qs, n, 0);
+}
+
+/*
+ * escape the usual suspects and quote chars in qs
+ */
+
+char*
+fmtesq(const char* as, const char* qs)
+{
+ return fmtquote(as, NiL, qs, strlen((char*)as), 0);
+}
+
+/*
+ * escape the usual suspects
+ */
+
+char*
+fmtesc(const char* as)
+{
+ return fmtquote(as, NiL, NiL, strlen((char*)as), 0);
+}
diff --git a/src/lib/libast/string/fmtfmt.c b/src/lib/libast/string/fmtfmt.c
new file mode 100644
index 0000000..639355b
--- /dev/null
+++ b/src/lib/libast/string/fmtfmt.c
@@ -0,0 +1,205 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return printf(3) format signature given format string
+ * the format signature contains one char per format optionally preceded
+ * by the number of `*' args
+ * c char
+ * d double
+ * D long double
+ * f float
+ * h short
+ * i int
+ * j long long
+ * l long
+ * p void*
+ * s string
+ * t ptrdiff_t
+ * z size_t
+ * ? unknown
+ */
+
+#include <ast.h>
+#include <ctype.h>
+
+char*
+fmtfmt(const char* as)
+{
+ register char* s = (char*)as;
+ char* buf;
+ int i;
+ int c;
+ int a;
+ int q;
+ int x;
+ int t;
+ int m;
+ int n;
+ int z;
+ char formats[256];
+ unsigned int extra[elementsof(formats)];
+
+ z = 1;
+ i = m = 0;
+ for (;;)
+ {
+ switch (*s++)
+ {
+ case 0:
+ break;
+ case '%':
+ if (*s == '%')
+ continue;
+ n = 0;
+ a = 0;
+ q = 0;
+ t = '?';
+ x = 0;
+ for (;;)
+ {
+ switch (c = *s++)
+ {
+ case 0:
+ s--;
+ break;
+ case '(':
+ q++;
+ continue;
+ case ')':
+ if (--q <= 0)
+ n = 0;
+ continue;
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case '8': case '9':
+ n = n * 10 + (c - '0');
+ continue;
+ case '$':
+ a = n;
+ n = 0;
+ continue;
+ case '*':
+ x++;
+ n = 0;
+ continue;
+ case 'h':
+ if (!q)
+ t = t == 'h' ? 'c' : 'h';
+ continue;
+ case 'l':
+ if (!q)
+ t = t == 'l' ? 'j' : 'l';
+ continue;
+ case 'j':
+ case 't':
+ case 'z':
+ if (!q)
+ t = c;
+ continue;
+ case 'c':
+ case 'p':
+ case 's':
+ if (!q)
+ {
+ t = c;
+ break;
+ }
+ continue;
+ case 'e':
+ case 'g':
+ if (!q)
+ {
+ switch (t)
+ {
+ case 'j':
+ t = 'D';
+ break;
+ default:
+ t = 'd';
+ break;
+ }
+ break;
+ }
+ continue;
+ case 'f':
+ if (!q)
+ {
+ switch (t)
+ {
+ case 'j':
+ t = 'D';
+ break;
+ case 'l':
+ t = 'd';
+ break;
+ default:
+ t = c;
+ break;
+ }
+ break;
+ }
+ continue;
+ default:
+ if (!q && isalpha(c))
+ {
+ if (t == '?')
+ t = 'i';
+ break;
+ }
+ n = 0;
+ continue;
+ }
+ break;
+ }
+ if (a)
+ i = a;
+ else
+ i++;
+ if (i < elementsof(formats))
+ {
+ formats[i] = t;
+ if (extra[i] = x)
+ do z++; while (x /= 10);
+ if (m < i)
+ m = i;
+ }
+ continue;
+ default:
+ continue;
+ }
+ break;
+ }
+ s = buf = fmtbuf(m + z);
+ for (i = 1; i <= m; i++)
+ {
+ if (extra[i])
+ s += sfsprintf(s, 10, "%d", extra[m]);
+ *s++ = formats[i];
+ }
+ *s = 0;
+ return buf;
+}
diff --git a/src/lib/libast/string/fmtfs.c b/src/lib/libast/string/fmtfs.c
new file mode 100644
index 0000000..1d89b11
--- /dev/null
+++ b/src/lib/libast/string/fmtfs.c
@@ -0,0 +1,100 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * return fs type string given stat
+ */
+
+#include <ast.h>
+#include <ls.h>
+#include <mnt.h>
+
+#include "FEATURE/fs"
+
+#if _str_st_fstype
+
+char*
+fmtfs(struct stat* st)
+{
+ return st->st_fstype;
+}
+
+#else
+
+#include <cdt.h>
+
+typedef struct Id_s
+{
+ Dtlink_t link;
+ dev_t id;
+ char name[1];
+} Id_t;
+
+char*
+fmtfs(struct stat* st)
+{
+ register Id_t* ip;
+ register void* mp;
+ register Mnt_t* mnt;
+ register char* s;
+ struct stat rt;
+ char* buf;
+
+ static Dt_t* dict;
+ static Dtdisc_t disc;
+
+ if (!dict)
+ {
+ disc.key = offsetof(Id_t, id);
+ disc.size = sizeof(dev_t);
+ dict = dtopen(&disc, Dtset);
+ }
+ else if (ip = (Id_t*)dtmatch(dict, &st->st_dev))
+ return ip->name;
+ s = FS_default;
+ if (mp = mntopen(NiL, "r"))
+ {
+ while ((mnt = mntread(mp)) && (stat(mnt->dir, &rt) || rt.st_dev != st->st_dev));
+ if (mnt && mnt->type)
+ s = mnt->type;
+ }
+ if (!dict || !(ip = newof(0, Id_t, 1, strlen(s))))
+ {
+ if (!mp)
+ return s;
+ buf = fmtbuf(strlen(s) + 1);
+ strcpy(buf, s);
+ mntclose(mp);
+ return buf;
+ }
+ strcpy(ip->name, s);
+ if (mp)
+ mntclose(mp);
+ dtinsert(dict, ip);
+ return ip->name;
+}
+
+#endif
diff --git a/src/lib/libast/string/fmtgid.c b/src/lib/libast/string/fmtgid.c
new file mode 100644
index 0000000..25ef158
--- /dev/null
+++ b/src/lib/libast/string/fmtgid.c
@@ -0,0 +1,101 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * cached gid number -> name
+ */
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide getgrgid
+#else
+#define getgrgid ______getgrgid
+#endif
+
+#include <ast.h>
+#include <cdt.h>
+#include <grp.h>
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide getgrgid
+#else
+#undef getgrgid
+#endif
+
+extern struct group* getgrgid(gid_t);
+
+typedef struct Id_s
+{
+ Dtlink_t link;
+ int id;
+ char name[1];
+} Id_t;
+
+/*
+ * return gid name given gid number
+ */
+
+char*
+fmtgid(int gid)
+{
+ register Id_t* ip;
+ register char* name;
+ register struct group* gr;
+ int z;
+
+ static Dt_t* dict;
+ static Dtdisc_t disc;
+
+ if (!dict)
+ {
+ disc.key = offsetof(Id_t, id);
+ disc.size = sizeof(int);
+ dict = dtopen(&disc, Dtset);
+ }
+ else if (ip = (Id_t*)dtmatch(dict, &gid))
+ return ip->name;
+ if (gr = getgrgid(gid))
+ {
+ name = gr->gr_name;
+#if _WINIX
+ if (streq(name, "Administrators"))
+ name = "sys";
+#endif
+ }
+ else if (gid == 0)
+ name = "sys";
+ else
+ {
+ name = fmtbuf(z = sizeof(gid) * 3 + 1);
+ sfsprintf(name, z, "%I*d", sizeof(gid), gid);
+ }
+ if (dict && (ip = newof(0, Id_t, 1, strlen(name))))
+ {
+ ip->id = gid;
+ strcpy(ip->name, name);
+ dtinsert(dict, ip);
+ return ip->name;
+ }
+ return name;
+}
diff --git a/src/lib/libast/string/fmtident.c b/src/lib/libast/string/fmtident.c
new file mode 100644
index 0000000..0ffab5c
--- /dev/null
+++ b/src/lib/libast/string/fmtident.c
@@ -0,0 +1,77 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+#include <ctype.h>
+
+#define IDENT 01
+#define USAGE 02
+
+/*
+ * format what(1) and/or ident(1) string a
+ */
+
+char*
+fmtident(const char* a)
+{
+ register char* s = (char*)a;
+ register char* t;
+ char* buf;
+ int i;
+
+ i = 0;
+ for (;;)
+ {
+ while (isspace(*s))
+ s++;
+ if (s[0] == '[')
+ {
+ while (*++s && *s != '\n');
+ i |= USAGE;
+ }
+ else if (s[0] == '@' && s[1] == '(' && s[2] == '#' && s[3] == ')')
+ s += 4;
+ else if (s[0] == '$' && s[1] == 'I' && s[2] == 'd' && s[3] == ':' && isspace(s[4]))
+ {
+ s += 5;
+ i |= IDENT;
+ }
+ else
+ break;
+ }
+ if (i)
+ {
+ i &= IDENT;
+ for (t = s; isprint(*t) && *t != '\n'; t++)
+ if (i && t[0] == ' ' && t[1] == '$')
+ break;
+ while (t > s && isspace(t[-1]))
+ t--;
+ i = t - s;
+ buf = fmtbuf(i + 1);
+ memcpy(buf, s, i);
+ s = buf;
+ s[i] = 0;
+ }
+ return s;
+}
diff --git a/src/lib/libast/string/fmtint.c b/src/lib/libast/string/fmtint.c
new file mode 100644
index 0000000..932fe1e
--- /dev/null
+++ b/src/lib/libast/string/fmtint.c
@@ -0,0 +1,122 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * format decimal integer
+ * David Korn
+ * AT&T Research
+ */
+
+#include <ast.h>
+
+static const char table[]=
+{
+ "000001002003004005006007008009010011012013014015016017018019"
+ "020021022023024025026027028029030031032033034035036037038039"
+ "040041042043044045046047048049050051052053054055056057058059"
+ "060061062063064065066067068069070071072073074075076077078079"
+ "080081082083084085086087088089090091092093094095096097098099"
+ "100101102103104105106107108109110111112113114115116117118119"
+ "120121122123124125126127128129130131132133134135136137138139"
+ "140141142143144145146147148149150151152153154155156157158159"
+ "160161162163164165166167168169170171172173174175176177178179"
+ "180181182183184185186187188189190191192193194195196197198199"
+ "200201202203204205206207208209210211212213214215216217218219"
+ "220221222223224225226227228229230231232233234235236237238239"
+ "240241242243244245246247248249250251252253254255256257258259"
+ "260261262263264265266267268269270271272273274275276277278279"
+ "280281282283284285286287288289290291292293294295296297298299"
+ "300301302303304305306307308309310311312313314315316317318319"
+ "320321322323324325326327328329330331332333334335336337338339"
+ "340341342343344345346347348349350351352353354355356357358359"
+ "360361362363364365366367368369370371372373374375376377378379"
+ "380381382383384385386387388389390391392393394395396397398399"
+ "400401402403404405406407408409410411412413414415416417418419"
+ "420421422423424425426427428429430431432433434435436437438439"
+ "440441442443444445446447448449450451452453454455456457458459"
+ "460461462463464465466467468469470471472473474475476477478479"
+ "480481482483484485486487488489490491492493494495496497498499"
+ "500501502503504505506507508509510511512513514515516517518519"
+ "520521522523524525526527528529530531532533534535536537538539"
+ "540541542543544545546547548549550551552553554555556557558559"
+ "560561562563564565566567568569570571572573574575576577578579"
+ "580581582583584585586587588589590591592593594595596597598599"
+ "600601602603604605606607608609610611612613614615616617618619"
+ "620621622623624625626627628629630631632633634635636637638639"
+ "640641642643644645646647648649650651652653654655656657658659"
+ "660661662663664665666667668669670671672673674675676677678679"
+ "680681682683684685686687688689690691692693694695696697698699"
+ "700701702703704705706707708709710711712713714715716717718719"
+ "720721722723724725726727728729730731732733734735736737738739"
+ "740741742743744745746747748749750751752753754755756757758759"
+ "760761762763764765766767768769770771772773774775776777778779"
+ "780781782783784785786787788789790791792793794795796797798799"
+ "800801802803804805806807808809810811812813814815816817818819"
+ "820821822823824825826827828829830831832833834835836837838839"
+ "840841842843844845846847848849850851852853854855856857858859"
+ "860861862863864865866867868869870871872873874875876877878879"
+ "880881882883884885886887888889890891892893894895896897898899"
+ "900901902903904905906907908909910911912913914915916917918919"
+ "920921922923924925926927928929930931932933934935936937938939"
+ "940941942943944945946947948949950951952953954955956957958959"
+ "960961962963964965966967968969970971972973974975976977978979"
+ "980981982983984985986987988989990991992993994995996997998999"
+};
+
+char*
+fmtint(intmax_t ll, int unsign)
+{
+ char *buff;
+ uintmax_t n,m;
+ int j=0,k=3*sizeof(ll);
+ if(unsign || ll>=0)
+ n = ll;
+ else
+ {
+ n = -ll;
+ j = 1;
+ }
+ if(n<10)
+ {
+ buff = fmtbuf(k=3);
+ buff[--k] = 0;
+ buff[--k] = '0' + n;
+ goto skip;
+ }
+ buff = fmtbuf(k);
+ buff[--k] = 0;
+ do
+ {
+ k -= 3;
+ if((m=n) >= 1000)
+ m = n%1000;
+ memcpy(buff+k,table+3*m,3);
+ n /= 1000;
+ }
+ while(n>0);
+ while(buff[k]=='0')
+ k++;
+skip:
+ if(j)
+ buff[--k] = '-';
+ return(&buff[k]);
+}
diff --git a/src/lib/libast/string/fmtip4.c b/src/lib/libast/string/fmtip4.c
new file mode 100644
index 0000000..3920c7f
--- /dev/null
+++ b/src/lib/libast/string/fmtip4.c
@@ -0,0 +1,43 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+/*
+ * format 4 byte local byte order ip address
+ * and optional prefix bits (if 0 <= bits <= 32)
+ */
+
+char*
+fmtip4(register uint32_t addr, int bits)
+{
+ char* buf;
+ int z;
+ int i;
+
+ buf = fmtbuf(z = 20);
+ i = sfsprintf(buf, z, "%d.%d.%d.%d", (addr>>24)&0xff, (addr>>16)&0xff, (addr>>8)&0xff, (addr)&0xff);
+ if (bits >= 0 && bits <= 32)
+ sfsprintf(buf + i, z - i, "/%d", bits);
+ return buf;
+}
diff --git a/src/lib/libast/string/fmtip6.c b/src/lib/libast/string/fmtip6.c
new file mode 100644
index 0000000..50bac43
--- /dev/null
+++ b/src/lib/libast/string/fmtip6.c
@@ -0,0 +1,175 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#if _PACKAGE_ast
+#include <ast.h>
+#endif
+
+#include <ip6.h>
+
+#if !_PACKAGE_ast
+
+/*
+ * return a pointer to n bytes from a circular re-use buffer
+ */
+
+static char*
+fmtbuf(int n)
+{
+ char* b;
+
+ static char buf[1024];
+ static char* p = buf;
+
+ if ((&buf[sizeof(buf)] - p) < n)
+ p = buf;
+ b = p;
+ p += n;
+ return b;
+}
+
+#endif
+
+/*
+ * copy p to s, then convert 0<=n<=999 to text
+ * next char in s returned
+ * caller ensures that s can take strlen(p)+3 bytes
+ */
+
+static char*
+dec(char* s, char* p, int n)
+{
+ while (*s = *p++)
+ s++;
+ if (n >= 100)
+ *s++ = '0' + ((n / 100) % 10);
+ if (n >= 10)
+ *s++ = '0' + ((n / 10) % 10);
+ *s++ = '0' + (n % 10);
+ return s;
+}
+
+/*
+ * return pointer to normalized ipv6 address addr
+ * with optional prefix bits if 0 <= bits <= 128
+ * return value in short-term circular buffer
+ */
+
+char*
+fmtip6(const unsigned char* addr, int bits)
+{
+ register const unsigned char* a = addr;
+ register int n = IP6ADDR;
+ register int i;
+ register int z;
+ register int k;
+ register int m;
+ unsigned char r[IP6ADDR];
+ char* b;
+ char* s;
+
+ static const char dig[] = "0123456789ABCDEF";
+
+ s = b = fmtbuf(44);
+ r[m = z = 0] = 0;
+ if (a[0] == 0x20 && a[1] == 0x02 && (a[2] || a[3] || a[4] || a[5]))
+ {
+ z = 6;
+ s = dec(s, "2002:", a[2]);
+ s = dec(s, ".", a[3]);
+ s = dec(s, ".", a[4]);
+ s = dec(s, ".", a[5]);
+ }
+ for (i = z; i < n; i += 2)
+ {
+ for (k = i; i < n - 1 && !a[i] && !a[i + 1]; i += 2);
+ if ((r[k] = i - k) > r[m] || r[k] == r[m] && i >= (n - 1))
+ m = k;
+ }
+ if (!m)
+ switch (r[m])
+ {
+ case 0:
+ m = -1;
+ break;
+ case 14:
+ if (!a[14] && a[15] <= 15)
+ break;
+ /*FALLTHROUGH*/
+ case 12:
+ s = dec(s, "::", a[12]);
+ s = dec(s, ".", a[13]);
+ s = dec(s, ".", a[14]);
+ s = dec(s, ".", a[15]);
+ n = 0;
+ break;
+ case 10:
+ if (a[10] == 0xFF && a[11] == 0xFF)
+ {
+ s = dec(s, "::FFFF:", a[12]);
+ s = dec(s, ".", a[13]);
+ s = dec(s, ".", a[14]);
+ s = dec(s, ".", a[15]);
+ n = 0;
+ }
+ break;
+ }
+ for (i = z; i < n; i++)
+ {
+ if (i == m)
+ {
+ *s++ = ':';
+ *s++ = ':';
+ if ((i += r[m]) >= n)
+ {
+ z = 1;
+ break;
+ }
+ z = 0;
+ }
+ else if (i && !(i & 1))
+ {
+ if (z)
+ z = 0;
+ else
+ *s++ = '0';
+ *s++ = ':';
+ }
+ if ((k = (a[i] >> 4) & 0xf) || z)
+ {
+ z = 1;
+ *s++ = dig[k];
+ }
+ if ((k = a[i] & 0xf) || z)
+ {
+ z = 1;
+ *s++ = dig[k];
+ }
+ }
+ if (!z && *(s - 1) == ':')
+ *s++ = '0';
+ if (bits >= 0 && bits <= 128)
+ s = dec(s, "/", bits);
+ *s = 0;
+ return b;
+}
diff --git a/src/lib/libast/string/fmtls.c b/src/lib/libast/string/fmtls.c
new file mode 100644
index 0000000..7b791dd
--- /dev/null
+++ b/src/lib/libast/string/fmtls.c
@@ -0,0 +1,120 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * ls formatter
+ */
+
+#include <ast.h>
+#include <ls.h>
+#include <tm.h>
+
+#ifndef LS_W_MAX
+#define LS_W_MAX 128
+#endif
+
+/*
+ * ls formatter
+ *
+ * buf results placed here
+ * name file name
+ * st file stat buffer
+ * info optional info
+ * link link text if != 0
+ * flags LS_* flags
+ *
+ * return end of formatted buf
+ */
+
+char*
+fmtls(char* buf, const char* name, register struct stat* st, const char* info, const char* link, register int flags)
+{
+ register char* s;
+ time_t tm;
+ Sfoff_t n;
+
+ s = buf;
+ if (flags & LS_INUMBER)
+ s += sfsprintf(s, LS_W_MAX, "%*I*u ", LS_W_INUMBER - 1, sizeof(st->st_ino), st->st_ino);
+ if (flags & LS_BLOCKS)
+ {
+ n = iblocks(st);
+ s += sfsprintf(s, LS_W_MAX, "%*I*u ", LS_W_BLOCKS - 1, sizeof(n), n);
+ }
+ if (flags & LS_LONG)
+ {
+ s += sfsprintf(s, LS_W_MAX, "%s%3u", fmtmode(st->st_mode, flags & LS_EXTERNAL), (unsigned int)st->st_nlink);
+ if (!(flags & LS_NOUSER))
+ {
+ if (flags & LS_NUMBER)
+ s += sfsprintf(s, LS_W_MAX, " %-*I*d", LS_W_NAME - 1, sizeof(st->st_uid), st->st_uid);
+ else
+ s += sfsprintf(s, LS_W_MAX, " %-*s", LS_W_NAME - 1, fmtuid(st->st_uid));
+ }
+ if (!(flags & LS_NOGROUP))
+ {
+ if (flags & LS_NUMBER)
+ s += sfsprintf(s, LS_W_MAX, " %-*I*d", LS_W_NAME - 1, sizeof(st->st_gid), st->st_gid);
+ else
+ s += sfsprintf(s, LS_W_MAX, " %-*s", LS_W_NAME - 1, fmtgid(st->st_gid));
+ }
+ if (S_ISBLK(st->st_mode) || S_ISCHR(st->st_mode))
+ s += sfsprintf(s, LS_W_MAX, "%8s ", fmtdev(st));
+ else
+ s += sfsprintf(s, LS_W_MAX, "%8I*u ", sizeof(st->st_size), st->st_size);
+ tm = (flags & LS_ATIME) ? st->st_atime : (flags & LS_CTIME) ? st->st_ctime : st->st_mtime;
+ s = tmfmt(s, LS_W_LONG / 2, "%?%QL", &tm);
+ *s++ = ' ';
+ }
+ if (info)
+ {
+ while (*s = *info++)
+ s++;
+ *s++ = ' ';
+ }
+ while (*s = *name++)
+ s++;
+ if (flags & LS_MARK)
+ {
+ if (S_ISDIR(st->st_mode))
+ *s++ = '/';
+#ifdef S_ISLNK
+ else if (S_ISLNK(st->st_mode))
+ *s++ = '@';
+#endif
+ else if (st->st_mode & (S_IXUSR|S_IXGRP|S_IXOTH))
+ *s++ = '*';
+ }
+ if (link)
+ {
+ s += sfsprintf(s, LS_W_MAX, " %s %s",
+#ifdef S_ISLNK
+ S_ISLNK(st->st_mode) ? "->" :
+#endif
+ "==", link);
+ }
+ *s = 0;
+ return s;
+}
diff --git a/src/lib/libast/string/fmtmatch.c b/src/lib/libast/string/fmtmatch.c
new file mode 100644
index 0000000..2daf2f7
--- /dev/null
+++ b/src/lib/libast/string/fmtmatch.c
@@ -0,0 +1,286 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return strmatch() expression given REG_AUGMENTED RE
+ * 0 returned for invalid RE
+ */
+
+#include <ast.h>
+
+char*
+fmtmatch(const char* as)
+{
+ register char* s = (char*)as;
+ register int c;
+ register char* t;
+ register char** p;
+ register char* b;
+ char* x;
+ char* y;
+ char* z;
+ int a;
+ int e;
+ int n;
+ char* buf;
+ char* stack[32];
+
+ c = 3 * (strlen(s) + 1);
+ buf = fmtbuf(c);
+ t = b = buf + 3;
+ p = stack;
+ if (a = *s == '^')
+ s++;
+ e = 0;
+ for (;;)
+ {
+ switch (c = *s++)
+ {
+ case 0:
+ break;
+ case '\\':
+ if (!(c = *s++))
+ return 0;
+ switch (*s)
+ {
+ case '*':
+ case '+':
+ case '?':
+ *t++ = *s++;
+ *t++ = '(';
+ *t++ = '\\';
+ *t++ = c;
+ c = ')';
+ break;
+ case '|':
+ case '&':
+ if (c == '(')
+ {
+ *t++ = c;
+ c = *s++;
+ goto logical;
+ }
+ break;
+ case '{':
+ case '}':
+ break;
+ default:
+ *t++ = '\\';
+ break;
+ }
+ *t++ = c;
+ continue;
+ case '[':
+ x = t;
+ *t++ = c;
+ if ((c = *s++) == '^')
+ {
+ *t++ = '!';
+ c = *s++;
+ }
+ else if (c == '!')
+ {
+ *t++ = '\\';
+ *t++ = c;
+ c = *s++;
+ }
+ for (;;)
+ {
+ if (!(*t++ = c))
+ return 0;
+ if (c == '\\')
+ *t++ = c;
+ if ((c = *s++) == ']')
+ {
+ *t++ = c;
+ break;
+ }
+ }
+ switch (*s)
+ {
+ case '*':
+ case '+':
+ case '?':
+ for (y = t + 2, t--; t >= x; t--)
+ *(t + 2) = *t;
+ *++t = *s++;
+ *++t = '(';
+ t = y;
+ *t++ = ')';
+ break;
+ }
+ continue;
+ case '(':
+ if (p >= &stack[elementsof(stack)])
+ return 0;
+ *p++ = t;
+ if (*s == '?')
+ {
+ s++;
+ if (*s == 'K' && *(s + 1) == ')')
+ {
+ s += 2;
+ p--;
+ while (*t = *s)
+ t++, s++;
+ continue;
+ }
+ *t++ = '~';
+ }
+ else
+ *t++ = '@';
+ *t++ = '(';
+ continue;
+ case ')':
+ if (p == stack)
+ return 0;
+ p--;
+ *t++ = c;
+ switch (*s)
+ {
+ case 0:
+ break;
+ case '*':
+ case '+':
+ case '?':
+ case '!':
+ **p = *s++;
+ if (*s == '?')
+ {
+ s++;
+ x = *p + 1;
+ for (y = ++t; y > x; y--)
+ *y = *(y - 1);
+ *x = '-';
+ }
+ continue;
+ case '{':
+ for (z = s; *z != '}'; z++)
+ if (!*z)
+ return 0;
+ n = z - s;
+ if (*++z == '?')
+ n++;
+ x = *p + n;
+ for (y = t += n; y > x; y--)
+ *y = *(y - n);
+ for (x = *p; s < z; *x++ = *s++);
+ if (*s == '?')
+ {
+ s++;
+ *x++ = '-';
+ }
+ continue;
+ default:
+ continue;
+ }
+ break;
+ case '.':
+ switch (*s)
+ {
+ case 0:
+ *t++ = '?';
+ break;
+ case '*':
+ s++;
+ *t++ = '*';
+ e = !*s;
+ continue;
+ case '+':
+ s++;
+ *t++ = '?';
+ *t++ = '*';
+ continue;
+ case '?':
+ s++;
+ *t++ = '?';
+ *t++ = '(';
+ *t++ = '?';
+ *t++ = ')';
+ continue;
+ default:
+ *t++ = '?';
+ continue;
+ }
+ break;
+ case '*':
+ case '+':
+ case '?':
+ case '{':
+ n = *(t - 1);
+ if (t == b || n == '(' || n == '|')
+ return 0;
+ *(t - 1) = c;
+ if (c == '{')
+ {
+ for (z = s; *z != '}'; z++)
+ if (!*z)
+ return 0;
+ for (; s <= z; *t++ = *s++);
+ }
+ if (*s == '?')
+ {
+ s++;
+ *t++ = '-';
+ }
+ *t++ = '(';
+ *t++ = n;
+ *t++ = ')';
+ continue;
+ case '|':
+ case '&':
+ if (t == b || *(t - 1) == '(')
+ return 0;
+ logical:
+ if (!*s || *s == ')')
+ return 0;
+ if (p == stack && b == buf + 3)
+ {
+ *--b = '(';
+ *--b = '@';
+ }
+ *t++ = c;
+ continue;
+ case '$':
+ if (e = !*s)
+ break;
+ /*FALLTHROUGH*/
+ default:
+ *t++ = c;
+ continue;
+ }
+ break;
+ }
+ if (p != stack)
+ return 0;
+ if (b != buf + 3)
+ *t++ = ')';
+ if (!a && (*b != '*' || *(b + 1) == '(' || (*(b + 1) == '-' || *(b + 1) == '~') && *(b + 2) == '('))
+ *--b = '*';
+ if (!e)
+ *t++ = '*';
+ *t = 0;
+ return b;
+}
diff --git a/src/lib/libast/string/fmtmode.c b/src/lib/libast/string/fmtmode.c
new file mode 100644
index 0000000..2f9dc4f
--- /dev/null
+++ b/src/lib/libast/string/fmtmode.c
@@ -0,0 +1,47 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * return ls -l style file mode string given file mode bits
+ * if external!=0 then mode is modex canonical
+ */
+
+#include "modelib.h"
+
+char*
+fmtmode(register int mode, int external)
+{
+ register char* s;
+ register struct modeop* p;
+ char* buf;
+
+ if (!external)
+ mode = modex(mode);
+ s = buf = fmtbuf(MODELEN + 1);
+ for (p = modetab; p < &modetab[MODELEN]; p++)
+ *s++ = p->name[((mode & p->mask1) >> p->shift1) | ((mode & p->mask2) >> p->shift2)];
+ *s = 0;
+ return buf;
+}
diff --git a/src/lib/libast/string/fmtnum.c b/src/lib/libast/string/fmtnum.c
new file mode 100644
index 0000000..49fb9c3
--- /dev/null
+++ b/src/lib/libast/string/fmtnum.c
@@ -0,0 +1,92 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return scaled number n
+ * string width is 5 chars or less
+ * if m>1 then n divided by m before scaling
+ */
+
+#include <ast.h>
+
+char*
+fmtnum(register unsigned long n, int m)
+{
+ register int i;
+ register unsigned long r;
+ char* buf;
+ int z;
+
+ char suf[2];
+
+ if (m > 1)
+ {
+ r = n;
+ n /= m;
+ r -= n;
+ }
+ else
+ r = 0;
+ suf[1] = 0;
+ if (n < 1024)
+ suf[0] = 0;
+ else if (n < 1024 * 1024)
+ {
+ suf[0] = 'k';
+ r = ((n % 1024) * 100) / 1024;
+ n /= 1024;
+ }
+ else if (n < 1024 * 1024 * 1024)
+ {
+ suf[0] = 'm';
+ r = ((n % (1024 * 1024)) * 100) / (1024 * 1024);
+ n /= 1024 * 1024;
+ }
+ else
+ {
+ suf[0] = 'g';
+ r = ((n % (1024 * 1024 * 1024)) * 100) / (1024 * 1024 * 1024);
+ n /= 1024 * 1024 * 1024;
+ }
+ if (r)
+ {
+ if (n >= 100)
+ r = 0;
+ else if (n >= 10)
+ {
+ i = 1;
+ if (r >= 10)
+ r /= 10;
+ }
+ else
+ i = 2;
+ }
+ buf = fmtbuf(z = 8);
+ if (r)
+ sfsprintf(buf, z, "%lu.%0*lu%s", n, i, r, suf);
+ else
+ sfsprintf(buf, z, "%lu%s", n, suf);
+ return buf;
+}
diff --git a/src/lib/libast/string/fmtperm.c b/src/lib/libast/string/fmtperm.c
new file mode 100644
index 0000000..c10d379
--- /dev/null
+++ b/src/lib/libast/string/fmtperm.c
@@ -0,0 +1,91 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * return strperm() expression for perm
+ */
+
+#include <ast.h>
+#include <ls.h>
+
+char*
+fmtperm(register int perm)
+{
+ register char* s;
+ char* buf;
+
+ s = buf = fmtbuf(32);
+
+ /*
+ * u
+ */
+
+ *s++ = 'u';
+ *s++ = '=';
+ if (perm & S_ISVTX)
+ *s++ = 't';
+ if (perm & S_ISUID)
+ *s++ = 's';
+ if (perm & S_IRUSR)
+ *s++ = 'r';
+ if (perm & S_IWUSR)
+ *s++ = 'w';
+ if (perm & S_IXUSR)
+ *s++ = 'x';
+ if ((perm & (S_ISGID|S_IXGRP)) == S_ISGID)
+ *s++ = 'l';
+
+ /*
+ * g
+ */
+
+ *s++ = ',';
+ *s++ = 'g';
+ *s++ = '=';
+ if ((perm & (S_ISGID|S_IXGRP)) == (S_ISGID|S_IXGRP))
+ *s++ = 's';
+ if (perm & S_IRGRP)
+ *s++ = 'r';
+ if (perm & S_IWGRP)
+ *s++ = 'w';
+ if (perm & S_IXGRP)
+ *s++ = 'x';
+
+ /*
+ * o
+ */
+
+ *s++ = ',';
+ *s++ = 'o';
+ *s++ = '=';
+ if (perm & S_IROTH)
+ *s++ = 'r';
+ if (perm & S_IWOTH)
+ *s++ = 'w';
+ if (perm & S_IXOTH)
+ *s++ = 'x';
+ *s = 0;
+ return buf;
+}
diff --git a/src/lib/libast/string/fmtre.c b/src/lib/libast/string/fmtre.c
new file mode 100644
index 0000000..a4a887b
--- /dev/null
+++ b/src/lib/libast/string/fmtre.c
@@ -0,0 +1,226 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return RE expression given strmatch() pattern
+ * 0 returned for invalid RE
+ */
+
+#include <ast.h>
+
+typedef struct Stack_s
+{
+ char* beg;
+ short len;
+ short min;
+} Stack_t;
+
+char*
+fmtre(const char* as)
+{
+ register char* s = (char*)as;
+ register int c;
+ register char* t;
+ register Stack_t* p;
+ char* x;
+ int n;
+ int end;
+ char* buf;
+ Stack_t stack[32];
+
+ end = 1;
+ c = 2 * strlen(s) + 1;
+ t = buf = fmtbuf(c);
+ p = stack;
+ if (*s != '*' || *(s + 1) == '(' || *(s + 1) == '-' && *(s + 2) == '(')
+ *t++ = '^';
+ else
+ s++;
+ for (;;)
+ {
+ switch (c = *s++)
+ {
+ case 0:
+ break;
+ case '\\':
+ if (!(c = *s++) || c == '{' || c == '}')
+ return 0;
+ *t++ = '\\';
+ if ((*t++ = c) == '(' && *s == '|')
+ {
+ *t++ = *s++;
+ goto logical;
+ }
+ continue;
+ case '[':
+ *t++ = c;
+ n = 0;
+ if ((c = *s++) == '!')
+ {
+ *t++ = '^';
+ c = *s++;
+ }
+ else if (c == '^')
+ {
+ if ((c = *s++) == ']')
+ {
+ *(t - 1) = '\\';
+ *t++ = '^';
+ continue;
+ }
+ n = '^';
+ }
+ for (;;)
+ {
+ if (!(*t++ = c))
+ return 0;
+ if ((c = *s++) == ']')
+ {
+ if (n)
+ *t++ = n;
+ *t++ = c;
+ break;
+ }
+ }
+ continue;
+ case '{':
+ for (x = s; *x && *x != '}'; x++);
+ if (*x++ && (*x == '(' || *x == '-' && *(x + 1) == '('))
+ {
+ if (p >= &stack[elementsof(stack)])
+ return 0;
+ p->beg = s - 1;
+ s = x;
+ p->len = s - p->beg;
+ if (p->min = *s == '-')
+ s++;
+ p++;
+ *t++ = *s++;
+ }
+ else
+ *t++ = c;
+ continue;
+ case '*':
+ if (!*s)
+ {
+ end = 0;
+ break;
+ }
+ /*FALLTHROUGH*/
+ case '?':
+ case '+':
+ case '@':
+ case '!':
+ case '~':
+ if (*s == '(' || c != '~' && *s == '-' && *(s + 1) == '(')
+ {
+ if (p >= &stack[elementsof(stack)])
+ return 0;
+ p->beg = s - 1;
+ if (c == '~')
+ {
+ if (*(s + 1) == 'E' && *(s + 2) == ')')
+ {
+ for (s += 3; *t = *s; t++, s++);
+ continue;
+ }
+ p->len = 0;
+ p->min = 0;
+ *t++ = *s++;
+ *t++ = '?';
+ }
+ else
+ {
+ p->len = c != '@';
+ if (p->min = *s == '-')
+ s++;
+ *t++ = *s++;
+ }
+ p++;
+ }
+ else
+ {
+ switch (c)
+ {
+ case '*':
+ *t++ = '.';
+ break;
+ case '?':
+ c = '.';
+ break;
+ case '+':
+ case '!':
+ *t++ = '\\';
+ break;
+ }
+ *t++ = c;
+ }
+ continue;
+ case '(':
+ if (p >= &stack[elementsof(stack)])
+ return 0;
+ p->beg = s - 1;
+ p->len = 0;
+ p->min = 0;
+ p++;
+ *t++ = c;
+ continue;
+ case ')':
+ if (p == stack)
+ return 0;
+ *t++ = c;
+ p--;
+ for (c = 0; c < p->len; c++)
+ *t++ = p->beg[c];
+ if (p->min)
+ *t++ = '?';
+ continue;
+ case '^':
+ case '.':
+ case '$':
+ *t++ = '\\';
+ *t++ = c;
+ continue;
+ case '|':
+ if (t == buf || *(t - 1) == '(')
+ return 0;
+ logical:
+ if (!*s || *s == ')')
+ return 0;
+ /*FALLTHROUGH*/
+ default:
+ *t++ = c;
+ continue;
+ }
+ break;
+ }
+ if (p != stack)
+ return 0;
+ if (end)
+ *t++ = '$';
+ *t = 0;
+ return buf;
+}
diff --git a/src/lib/libast/string/fmtscale.c b/src/lib/libast/string/fmtscale.c
new file mode 100644
index 0000000..5a35577
--- /dev/null
+++ b/src/lib/libast/string/fmtscale.c
@@ -0,0 +1,94 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return number n scaled to metric multiples of k { 1000 1024 }
+ * return string length is at most 5 chars + terminating nul
+ */
+
+#include <ast.h>
+#include <lclib.h>
+
+char*
+fmtscale(register Sfulong_t n, int k)
+{
+ register Sfulong_t m;
+ int r;
+ int z;
+ const char* u;
+ char suf[3];
+ char* s;
+ char* buf;
+ Lc_numeric_t* p = (Lc_numeric_t*)LCINFO(AST_LC_NUMERIC)->data;
+
+ static const char scale[] = "bkMGTPE";
+
+ u = scale;
+ if (n < 1000)
+ r = 0;
+ else
+ {
+ m = 0;
+ while (n >= k && *(u + 1))
+ {
+ m = n;
+ n /= k;
+ u++;
+ }
+ if ((r = (10 * (m % k) + (k / 2)) / k) > 9)
+ {
+ r = 0;
+ n++;
+ }
+ if (k == 1024 && n >= 1000)
+ {
+ n = 1;
+ r = 0;
+ u++;
+ }
+ }
+ buf = fmtbuf(z = 8);
+ s = suf;
+ if (u > scale)
+ {
+ if (k == 1024)
+ {
+ *s++ = *u == 'k' ? 'K' : *u;
+ *s++ = 'i';
+ }
+ else
+ *s++ = *u;
+ }
+ *s = 0;
+ if (n > 0 && n < 10)
+ sfsprintf(buf, z, "%I*u%c%d%s", sizeof(n), n, p->decimal >= 0 ? p->decimal : '.', r, suf);
+ else
+ {
+ if (r >= 5)
+ n++;
+ sfsprintf(buf, z, "%I*u%s", sizeof(n), n, suf);
+ }
+ return buf;
+}
diff --git a/src/lib/libast/string/fmtsignal.c b/src/lib/libast/string/fmtsignal.c
new file mode 100644
index 0000000..a802a1d
--- /dev/null
+++ b/src/lib/libast/string/fmtsignal.c
@@ -0,0 +1,62 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * if sig>=0 then return signal text for signal sig
+ * otherwise return signal name for signal -sig
+ */
+
+#include <ast.h>
+#include <sig.h>
+
+char*
+fmtsignal(register int sig)
+{
+ char* buf;
+ int z;
+
+ if (sig >= 0)
+ {
+ if (sig <= sig_info.sigmax)
+ buf = sig_info.text[sig];
+ else
+ {
+ buf = fmtbuf(z = 20);
+ sfsprintf(buf, z, "Signal %d", sig);
+ }
+ }
+ else
+ {
+ sig = -sig;
+ if (sig <= sig_info.sigmax)
+ buf = sig_info.name[sig];
+ else
+ {
+ buf = fmtbuf(z = 20);
+ sfsprintf(buf, z, "%d", sig);
+ }
+ }
+ return buf;
+}
diff --git a/src/lib/libast/string/fmttime.c b/src/lib/libast/string/fmttime.c
new file mode 100644
index 0000000..f2cfbce
--- /dev/null
+++ b/src/lib/libast/string/fmttime.c
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return tmfmt() formatted time
+ */
+
+#include "tm.h"
+
+char*
+fmttime(const char* format, time_t clock)
+{
+ char* buf;
+ int z;
+
+ buf = fmtbuf(z = 80);
+ tmfmt(buf, z, format, &clock);
+ return buf;
+}
diff --git a/src/lib/libast/string/fmttmx.c b/src/lib/libast/string/fmttmx.c
new file mode 100644
index 0000000..1a427ac
--- /dev/null
+++ b/src/lib/libast/string/fmttmx.c
@@ -0,0 +1,45 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <tmx.h>
+#include <tv.h>
+
+/*
+ * Time_t fmttime()
+ */
+
+char*
+fmttmx(const char* fmt, Time_t t)
+{
+ char* b;
+ char* e;
+ int z;
+
+ z = 0;
+ do
+ {
+ b = fmtbuf(z += 80);
+ e = tmxfmt(b, z, fmt, t);
+ } while (e == b + z);
+ return b;
+}
diff --git a/src/lib/libast/string/fmttv.c b/src/lib/libast/string/fmttv.c
new file mode 100644
index 0000000..f4cdf1b
--- /dev/null
+++ b/src/lib/libast/string/fmttv.c
@@ -0,0 +1,44 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <tv.h>
+#include <tm.h>
+
+/*
+ * Tv_t fmttime()
+ */
+
+char*
+fmttv(const char* fmt, Tv_t* tv)
+{
+ char* s;
+ char* t;
+ int n;
+
+ s = fmttime(fmt, (time_t)tv->tv_sec);
+ if (!tv->tv_nsec || tv->tv_nsec == TV_NSEC_IGNORE)
+ return s;
+ t = fmtbuf(n = strlen(s) + 11);
+ sfsprintf(t, n, "%s.%09lu", s, (unsigned long)tv->tv_nsec);
+ return t;
+}
diff --git a/src/lib/libast/string/fmtuid.c b/src/lib/libast/string/fmtuid.c
new file mode 100644
index 0000000..44a1d44
--- /dev/null
+++ b/src/lib/libast/string/fmtuid.c
@@ -0,0 +1,101 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * uid number -> name
+ */
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide getpwuid
+#else
+#define getpwuid ______getpwuid
+#endif
+
+#include <ast.h>
+#include <cdt.h>
+#include <pwd.h>
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide getpwuid
+#else
+#undef getpwuid
+#endif
+
+extern struct passwd* getpwuid(uid_t);
+
+typedef struct Id_s
+{
+ Dtlink_t link;
+ int id;
+ char name[1];
+} Id_t;
+
+/*
+ * return uid name given uid number
+ */
+
+char*
+fmtuid(int uid)
+{
+ register Id_t* ip;
+ register char* name;
+ register struct passwd* pw;
+ int z;
+
+ static Dt_t* dict;
+ static Dtdisc_t disc;
+
+ if (!dict)
+ {
+ disc.key = offsetof(Id_t, id);
+ disc.size = sizeof(int);
+ dict = dtopen(&disc, Dtset);
+ }
+ else if (ip = (Id_t*)dtmatch(dict, &uid))
+ return ip->name;
+ if (pw = getpwuid(uid))
+ {
+ name = pw->pw_name;
+#if _WINIX
+ if (streq(name, "Administrator"))
+ name = "root";
+#endif
+ }
+ else if (uid == 0)
+ name = "root";
+ else
+ {
+ name = fmtbuf(z = sizeof(uid) * 3 + 1);
+ sfsprintf(name, z, "%I*d", sizeof(uid), uid);
+ }
+ if (dict && (ip = newof(0, Id_t, 1, strlen(name))))
+ {
+ ip->id = uid;
+ strcpy(ip->name, name);
+ dtinsert(dict, ip);
+ return ip->name;
+ }
+ return name;
+}
diff --git a/src/lib/libast/string/fmtversion.c b/src/lib/libast/string/fmtversion.c
new file mode 100644
index 0000000..10f2fc9
--- /dev/null
+++ b/src/lib/libast/string/fmtversion.c
@@ -0,0 +1,53 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * return formatted <magicid.h> version string
+ */
+
+#include <ast.h>
+
+char*
+fmtversion(register unsigned long v)
+{
+ register char* cur;
+ register char* end;
+ char* buf;
+ int n;
+
+ buf = cur = fmtbuf(n = 18);
+ end = cur + n;
+ if (v >= 19700101L && v <= 29991231L)
+ sfsprintf(cur, end - cur, "%04lu-%02lu-%02lu", (v / 10000) % 10000, (v / 100) % 100, v % 100);
+ else
+ {
+ if (n = (v >> 24) & 0xff)
+ cur += sfsprintf(cur, end - cur, "%d.", n);
+ if (n = (v >> 16) & 0xff)
+ cur += sfsprintf(cur, end - cur, "%d.", n);
+ sfsprintf(cur, end - cur, "%ld.%ld", (v >> 8) & 0xff, v & 0xff);
+ }
+ return buf;
+}
diff --git a/src/lib/libast/string/memdup.c b/src/lib/libast/string/memdup.c
new file mode 100644
index 0000000..9282405
--- /dev/null
+++ b/src/lib/libast/string/memdup.c
@@ -0,0 +1,44 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+#if _lib_memdup
+
+NoN(memdup)
+
+#else
+
+/*
+ * return a copy of s of n chars using malloc
+ */
+
+void*
+memdup(register const void* s, register size_t n)
+{
+ register void* t;
+
+ return((t = (void*)newof(0, char, n, 0)) ? memcpy(t, s, n) : 0);
+}
+
+#endif
diff --git a/src/lib/libast/string/modedata.c b/src/lib/libast/string/modedata.c
new file mode 100644
index 0000000..dc10d62
--- /dev/null
+++ b/src/lib/libast/string/modedata.c
@@ -0,0 +1,69 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * fmtmode() and strperm() readonly data
+ * for external format modes
+ */
+
+#include "modelib.h"
+
+struct modeop modetab[MODELEN] =
+{
+ 0170000, 12, 0000000, 0, "-pc?d?b?-Cl?sDw?",
+ 0000400, 8, 0000000, 0, "-r",
+ 0000200, 7, 0000000, 0, "-w",
+ 0004000, 10, 0000100, 6, "-xSs",
+ 0000040, 5, 0000000, 0, "-r",
+ 0000020, 4, 0000000, 0, "-w",
+#ifdef S_ICCTYP
+ 0003000, 8, 0000010, 3, "-x-xSs-x",
+#else
+ 0002000, 9, 0000010, 3, "-xls",
+#endif
+ 0000004, 2, 0000000, 0, "-r",
+ 0000002, 1, 0000000, 0, "-w",
+#ifdef S_ICCTYP
+ 0003000, 8, 0000001, 0, "-xyY-xeE",
+#else
+ 0001000, 8, 0000001, 0, "-xTt",
+#endif
+};
+
+int permmap[PERMLEN] =
+{
+ S_ISUID, X_ISUID,
+ S_ISGID, X_ISGID,
+ S_ISVTX, X_ISVTX,
+ S_IRUSR, X_IRUSR,
+ S_IWUSR, X_IWUSR,
+ S_IXUSR, X_IXUSR,
+ S_IRGRP, X_IRGRP,
+ S_IWGRP, X_IWGRP,
+ S_IXGRP, X_IXGRP,
+ S_IROTH, X_IROTH,
+ S_IWOTH, X_IWOTH,
+ S_IXOTH, X_IXOTH
+};
diff --git a/src/lib/libast/string/modei.c b/src/lib/libast/string/modei.c
new file mode 100644
index 0000000..163d633
--- /dev/null
+++ b/src/lib/libast/string/modei.c
@@ -0,0 +1,55 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * mode_t representation support
+ */
+
+#include "modelib.h"
+
+/*
+ * convert external mode to internal
+ *
+ * NOTE: X_IFMT ignored
+ */
+
+#undef modei
+
+int
+modei(register int x)
+{
+#if _S_IDPERM
+ return(x & X_IPERM);
+#else
+ register int i;
+ register int c;
+
+ i = 0;
+ for (c = 0; c < PERMLEN; c += 2)
+ if (x & permmap[c + 1])
+ i |= permmap[c];
+ return(i);
+#endif
+}
diff --git a/src/lib/libast/string/modelib.h b/src/lib/libast/string/modelib.h
new file mode 100644
index 0000000..e654240
--- /dev/null
+++ b/src/lib/libast/string/modelib.h
@@ -0,0 +1,55 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * mode_t common definitions
+ */
+
+#ifndef _MODELIB_H
+#define _MODELIB_H
+
+#include <ast.h>
+#include <ls.h>
+#include <modex.h>
+
+#define MODELEN 10
+#define PERMLEN 24
+
+#define modetab _mode_table_ /* data hiding */
+#define permmap _mode_permmap_ /* data hiding */
+
+struct modeop /* ops for each char in mode string */
+{
+ int mask1; /* first mask */
+ int shift1; /* first shift count */
+ int mask2; /* second mask */
+ int shift2; /* second shift count */
+ char* name; /* mode char using mask/shift as index */
+};
+
+extern struct modeop modetab[];
+extern int permmap[];
+
+#endif
diff --git a/src/lib/libast/string/modex.c b/src/lib/libast/string/modex.c
new file mode 100644
index 0000000..a5e501a
--- /dev/null
+++ b/src/lib/libast/string/modex.c
@@ -0,0 +1,75 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * mode_t representation support
+ */
+
+#include "modelib.h"
+
+/*
+ * convert internal mode to external
+ */
+
+#undef modex
+
+int
+modex(register int i)
+{
+#if _S_IDPERM && _S_IDTYPE
+ return(i);
+#else
+ register int x;
+ register int c;
+
+ x = 0;
+#if _S_IDPERM
+ x |= (i & 07777);
+#else
+ for (c = 0; c < PERMLEN; c++)
+ if (i & permmap[c++])
+ x |= permmap[c];
+#endif
+#if _S_IDTYPE
+ x |= (i & X_IFMT);
+#else
+ if (S_ISREG(i)) x |= X_IFREG;
+ else if (S_ISDIR(i)) x |= X_IFDIR;
+#ifdef S_ISLNK
+ else if (S_ISLNK(i)) x |= X_IFLNK;
+#endif
+ else if (S_ISBLK(i)) x |= X_IFBLK;
+ else if (S_ISCHR(i)) x |= X_IFCHR;
+#ifdef S_ISCTG
+ else if (S_ISCTG(i)) x |= X_IFCTG;
+#endif
+ else if (S_ISFIFO(i)) x |= X_IFIFO;
+#ifdef S_ISSOCK
+ else if (S_ISSOCK(i)) x |= X_IFSOCK;
+#endif
+#endif
+ return(x);
+#endif
+}
diff --git a/src/lib/libast/string/stracmp.c b/src/lib/libast/string/stracmp.c
new file mode 100644
index 0000000..05b5401
--- /dev/null
+++ b/src/lib/libast/string/stracmp.c
@@ -0,0 +1,62 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * ccmapchr(ccmap(CC_NATIVE,CC_ASCII),c) and strcmp
+ */
+
+#include <ast.h>
+#include <ccode.h>
+
+#if _lib_stracmp
+
+NoN(stracmp)
+
+#else
+
+#include <ctype.h>
+
+int
+stracmp(const char* aa, const char* ab)
+{
+ register unsigned char* a;
+ register unsigned char* b;
+ register unsigned char* m;
+ register int c;
+ register int d;
+
+ if (!(m = ccmap(CC_NATIVE, CC_ASCII)))
+ return strcmp(aa, ab);
+ a = (unsigned char*)aa;
+ b = (unsigned char*)ab;
+ for (;;)
+ {
+ c = m[*a++];
+ if (d = c - m[*b++])
+ return d;
+ if (!c)
+ return 0;
+ }
+}
+
+#endif
diff --git a/src/lib/libast/string/strcopy.c b/src/lib/libast/string/strcopy.c
new file mode 100644
index 0000000..de169e7
--- /dev/null
+++ b/src/lib/libast/string/strcopy.c
@@ -0,0 +1,36 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+/*
+ * copy t into s, return a pointer to the end of s ('\0')
+ */
+
+char*
+strcopy(register char* s, register const char* t)
+{
+ if (!t) return(s);
+ while (*s++ = *t++);
+ return(--s);
+}
diff --git a/src/lib/libast/string/strdup.c b/src/lib/libast/string/strdup.c
new file mode 100644
index 0000000..7237fb7
--- /dev/null
+++ b/src/lib/libast/string/strdup.c
@@ -0,0 +1,60 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#undef VMDEBUG
+#define VMDEBUG 0
+
+#if defined(_MSVCRT_H)
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide strdup
+#else
+#define strdup ______strdup
+#endif
+#endif
+
+#include <ast.h>
+
+#if defined(_MSVCRT_H)
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide strdup
+#else
+#undef strdup
+#endif
+#endif
+
+/*
+ * return a copy of s using malloc
+ */
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char*
+strdup(register const char* s)
+{
+ register char* t;
+ register int n;
+
+ return (s && (t = newof(0, char, n = strlen(s) + 1, 0))) ? (char*)memcpy(t, s, n) : (char*)0;
+}
diff --git a/src/lib/libast/string/strelapsed.c b/src/lib/libast/string/strelapsed.c
new file mode 100644
index 0000000..fa7d919
--- /dev/null
+++ b/src/lib/libast/string/strelapsed.c
@@ -0,0 +1,154 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * parse elapsed time in 1/n secs from s
+ * compatible with fmtelapsed()
+ * also handles ps [day-][hour:]min:sec
+ * also handles coshell % for 'infinity'
+ * if e!=0 then it is set to first unrecognized char
+ */
+
+#include <ast.h>
+#include <ctype.h>
+
+unsigned long
+strelapsed(register const char* s, char** e, int n)
+{
+ register int c;
+ register unsigned long v;
+ unsigned long t = 0;
+ int f = 0;
+ int p = 0;
+ int z = 1;
+ int m;
+ const char* last;
+
+ for (;;)
+ {
+ while (isspace(*s) || *s == '_')
+ s++;
+ if (!*(last = s))
+ break;
+ if (z)
+ {
+ z = 0;
+ if (*s == '0' && (!(c = *(s + 1)) || isspace(c) || c == '_'))
+ {
+ last = s + 1;
+ break;
+ }
+ }
+ v = 0;
+ while ((c = *s++) >= '0' && c <= '9')
+ v = v * 10 + c - '0';
+ v *= n;
+ if (c == '.')
+ for (m = n; (c = *s++) >= '0' && c <= '9';)
+ f += (m /= 10) * (c - '0');
+ if (c == '%')
+ {
+ t = ~t;
+ last = s;
+ break;
+ }
+ if (s == last + 1)
+ break;
+ if (!p)
+ while (isspace(c) || c == '_')
+ c = *s++;
+ switch (c)
+ {
+ case 'S':
+ if (*s == 'E' || *s == 'e')
+ {
+ v += f;
+ f = 0;
+ }
+ else
+ v *= 20 * 12 * 4 * 7 * 24 * 60 * 60;
+ break;
+ case 'y':
+ case 'Y':
+ v *= 12 * 4 * 7 * 24 * 60 * 60;
+ break;
+ case 'M':
+ if (*s == 'I' || *s == 'i')
+ v *= 60;
+ else
+ v *= 4 * 7 * 24 * 60 * 60;
+ break;
+ case 'w':
+ v *= 7 * 24 * 60 * 60;
+ break;
+ case '-':
+ p = 1;
+ /*FALLTHROUGH*/
+ case 'd':
+ v *= 24 * 60 * 60;
+ break;
+ case 'h':
+ v *= 60 * 60;
+ break;
+ case ':':
+ p = 1;
+ v *= strchr(s, ':') ? (60 * 60) : 60;
+ break;
+ case 'm':
+ if (*s == 'o')
+ v *= 4 * 7 * 24 * 60 * 60;
+ else
+ v *= 60;
+ break;
+ case 's':
+ if (*s == 'c')
+ {
+ v *= 20 * 12 * 4 * 7 * 24 * 60 * 60;
+ break;
+ }
+ v += f;
+ f = 0;
+ break;
+ case 0:
+ s--;
+ v += f;
+ break;
+ default:
+ if (p)
+ {
+ last = s - 1;
+ t += v + f;
+ }
+ goto done;
+ }
+ t += v;
+ while (isalpha(*s))
+ s++;
+ }
+ done:
+ if (e)
+ *e = (char*)last;
+ return t;
+}
diff --git a/src/lib/libast/string/strerror.c b/src/lib/libast/string/strerror.c
new file mode 100644
index 0000000..1664126
--- /dev/null
+++ b/src/lib/libast/string/strerror.c
@@ -0,0 +1,148 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return error message string given errno
+ */
+
+#include "lclib.h"
+
+#include "FEATURE/errno"
+
+#undef strerror
+
+#if !defined(sys_errlist) && !_def_errno_sys_errlist
+#if _dat_sys_errlist
+extern char* sys_errlist[];
+#else
+#undef _dat_sys_nerr
+char* sys_errlist[] = { 0 };
+#endif
+#endif
+
+#if !defined(sys_nerr) && !_def_errno_sys_nerr
+#if _dat_sys_nerr
+extern int sys_nerr;
+#else
+#undef _dat_sys_nerr
+int sys_nerr = 0;
+#endif
+#endif
+
+#if _lib_strerror
+extern char* strerror(int);
+#endif
+
+#if _PACKAGE_astsa
+
+#define fmtbuf(n) ((n),tmp)
+
+static char tmp[32];
+
+#endif
+
+char*
+_ast_strerror(int err)
+{
+ char* msg;
+ int z;
+
+#if _lib_strerror
+ z = errno;
+ msg = strerror(err);
+ errno = z;
+#else
+ if (err > 0 && err <= sys_nerr)
+ msg = (char*)sys_errlist[err];
+ else
+ msg = 0;
+#endif
+ if (msg)
+ {
+#if !_PACKAGE_astsa
+ if (ERROR_translating())
+ {
+#if _lib_strerror
+ static int sys;
+
+ if (!sys)
+ {
+ char* s;
+ char* t;
+ char* p;
+
+#if _lib_strerror
+ /*
+ * stash the pending strerror() msg
+ */
+
+ msg = strcpy(fmtbuf(strlen(msg) + 1), msg);
+#endif
+
+ /*
+ * make sure that strerror() translates
+ */
+
+ if (!(s = strerror(1)))
+ sys = -1;
+ else
+ {
+ t = fmtbuf(z = strlen(s) + 1);
+ strcpy(t, s);
+ ast.locale.set |= AST_LC_internal;
+ p = setlocale(LC_MESSAGES, NiL);
+ setlocale(LC_MESSAGES, "C");
+ sys = (s = strerror(1)) && strcmp(s, t) ? 1 : -1;
+ setlocale(LC_MESSAGES, p);
+ ast.locale.set &= ~AST_LC_internal;
+ }
+ }
+ if (sys > 0)
+ return msg;
+#endif
+ return ERROR_translate(NiL, NiL, "errlist", msg);
+ }
+#endif
+ return msg;
+ }
+ msg = fmtbuf(z = 32);
+ sfsprintf(msg, z, ERROR_translate(NiL, NiL, "errlist", "Error %d"), err);
+ return msg;
+}
+
+#if !_lib_strerror
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern char*
+strerror(int err)
+{
+ return _ast_strerror(err);
+}
+
+#endif
diff --git a/src/lib/libast/string/stresc.c b/src/lib/libast/string/stresc.c
new file mode 100644
index 0000000..59ec6c9
--- /dev/null
+++ b/src/lib/libast/string/stresc.c
@@ -0,0 +1,67 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * convert \X character constants in s in place
+ * the length of the converted s is returned (may have embedded \0's)
+ * wide chars absent locale guidance default to UTF-8
+ * strexp() FMT_EXP_* flags passed to chrexp() for selective conversion
+ */
+
+#include <ast.h>
+
+int
+strexp(register char* s, int flags)
+{
+ register char* t;
+ register unsigned int c;
+ char* b;
+ char* e;
+ int w;
+
+ b = t = s;
+ while (c = *s++)
+ {
+ if (c == '\\')
+ {
+ c = chrexp(s - 1, &e, &w, flags);
+ s = e;
+ if (w)
+ {
+ t += mbwide() ? mbconv(t, c) : wc2utf8(t, c);
+ continue;
+ }
+ }
+ *t++ = c;
+ }
+ *t = 0;
+ return t - b;
+}
+
+int
+stresc(register char* s)
+{
+ return strexp(s, FMT_EXP_CHAR|FMT_EXP_LINE|FMT_EXP_WIDE);
+}
diff --git a/src/lib/libast/string/streval.c b/src/lib/libast/string/streval.c
new file mode 100644
index 0000000..d246184
--- /dev/null
+++ b/src/lib/libast/string/streval.c
@@ -0,0 +1,50 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * obsolete streval() interface to strexpr()
+ */
+
+#include <ast.h>
+
+typedef long (*Old_convert_t)(const char*, char**);
+
+typedef long (*Convert_t)(const char*, char**, void*);
+
+typedef struct
+{
+ Old_convert_t convert;
+} Handle_t;
+
+static long
+userconv(const char* s, char** end, void* handle)
+{
+ return((*((Handle_t*)handle)->convert)(s, end));
+}
+
+long
+streval(const char* s, char** end, Old_convert_t convert)
+{
+ Handle_t handle;
+
+ return((handle.convert = convert) ? strexpr(s, end, userconv, &handle) : strexpr(s, end, (Convert_t)0, NiL));
+}
diff --git a/src/lib/libast/string/strexpr.c b/src/lib/libast/string/strexpr.c
new file mode 100644
index 0000000..23be2f5
--- /dev/null
+++ b/src/lib/libast/string/strexpr.c
@@ -0,0 +1,294 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * G. S. Fowler
+ * D. G. Korn
+ * AT&T Bell Laboratories
+ *
+ * long integer arithmetic expression evaluator
+ * long constants may be represented as:
+ *
+ * 0ooo octal
+ * 0[xX]hhh hexadecimal
+ * ddd decimal
+ * n#ccc base n, 2 <= b <= 36
+ *
+ * NOTE: all operands are evaluated as both the parse
+ * and evaluation are done on the fly
+ */
+
+#include <ast.h>
+#include <ctype.h>
+
+#define getchr(ex) (*(ex)->nextchr++)
+#define peekchr(ex) (*(ex)->nextchr)
+#define ungetchr(ex) ((ex)->nextchr--)
+
+#define error(ex,msg) return(seterror(ex,msg))
+
+typedef struct /* expression handle */
+{
+ char* nextchr; /* next expression char */
+ char* errchr; /* next char after error */
+ char* errmsg; /* error message text */
+ long (*convert)(const char*, char**, void*);
+ void* handle; /* user convert handle */
+} Expr_t;
+
+/*
+ * set error message string
+ */
+
+static long
+seterror(register Expr_t* ex, char* msg)
+{
+ if (!ex->errmsg) ex->errmsg = msg;
+ ex->errchr = ex->nextchr;
+ ex->nextchr = "";
+ return(0);
+}
+
+/*
+ * evaluate a subexpression with precedence
+ */
+
+static long
+expr(register Expr_t* ex, register int precedence)
+{
+ register int c;
+ register long n;
+ register long x;
+ char* pos;
+ int operand = 1;
+
+ while (c = getchr(ex), isspace(c));
+ switch (c)
+ {
+ case 0:
+ ungetchr(ex);
+ if (!precedence) return(0);
+ error(ex, "more tokens expected");
+ case '-':
+ n = -expr(ex, 13);
+ break;
+ case '+':
+ n = expr(ex, 13);
+ break;
+ case '!':
+ n = !expr(ex, 13);
+ break;
+ case '~':
+ n = ~expr(ex, 13);
+ break;
+ default:
+ ungetchr(ex);
+ n = 0;
+ operand = 0;
+ break;
+ }
+ for (;;)
+ {
+ switch (c = getchr(ex))
+ {
+ case 0:
+ goto done;
+ case ')':
+ if (!precedence) error(ex, "too many )'s");
+ goto done;
+ case '(':
+ n = expr(ex, 1);
+ if (getchr(ex) != ')')
+ {
+ ungetchr(ex);
+ error(ex, "closing ) expected");
+ }
+ gotoperand:
+ if (operand) error(ex, "operator expected");
+ operand = 1;
+ continue;
+ case '?':
+ if (precedence > 1) goto done;
+ if (peekchr(ex) == ':')
+ {
+ getchr(ex);
+ x = expr(ex, 2);
+ if (!n) n = x;
+ }
+ else
+ {
+ x = expr(ex, 2);
+ if (getchr(ex) != ':')
+ {
+ ungetchr(ex);
+ error(ex, ": expected for ? operator");
+ }
+ if (n)
+ {
+ n = x;
+ expr(ex, 2);
+ }
+ else n = expr(ex, 2);
+ }
+ break;
+ case ':':
+ goto done;
+ case '|':
+ if (peekchr(ex) == '|')
+ {
+ if (precedence > 2) goto done;
+ getchr(ex);
+ x = expr(ex, 3);
+ n = n || x;
+ }
+ else
+ {
+ if (precedence > 4) goto done;
+ x = expr(ex, 5);
+ n |= x;
+ }
+ break;
+ case '^':
+ if (precedence > 5) goto done;
+ x = expr(ex, 6);
+ n ^= x;
+ break;
+ case '&':
+ if (peekchr(ex) == '&')
+ {
+ if (precedence > 3) goto done;
+ getchr(ex);
+ x = expr(ex, 4);
+ n = n && x;
+ }
+ else
+ {
+ if (precedence > 6) goto done;
+ x = expr(ex, 7);
+ n &= x;
+ }
+ break;
+ case '=':
+ case '!':
+ if (peekchr(ex) != '=') error(ex, "operator syntax error");
+ if (precedence > 7) goto done;
+ getchr(ex);
+ x = expr(ex, 8);
+ if (c == '=') n = n == x;
+ else n = n != x;
+ break;
+ case '<':
+ case '>':
+ if (peekchr(ex) == c)
+ {
+ if (precedence > 9) goto done;
+ getchr(ex);
+ x = expr(ex, 10);
+ if (c == '<') n <<= x;
+ else n >>= x;
+ }
+ else
+ {
+ if (precedence > 8) goto done;
+ if (peekchr(ex) == '=')
+ {
+ getchr(ex);
+ x = expr(ex, 9);
+ if (c == '<') n = n <= x;
+ else n = n >= x;
+ }
+ else
+ {
+ x = expr(ex, 9);
+ if (c == '<') n = n < x;
+ else n = n > x;
+ }
+ }
+ break;
+ case '+':
+ case '-':
+ if (precedence > 10) goto done;
+ x = expr(ex, 11);
+ if (c == '+') n += x;
+ else n -= x;
+ break;
+ case '*':
+ case '/':
+ case '%':
+ if (precedence > 11) goto done;
+ x = expr(ex, 12);
+ if (c == '*') n *= x;
+ else if (x == 0) error(ex, "divide by zero");
+ else if (c == '/') n /= x;
+ else n %= x;
+ break;
+ default:
+ if (isspace(c)) continue;
+ pos = --ex->nextchr;
+ if (isdigit(c)) n = strton(ex->nextchr, &ex->nextchr, NiL, 0);
+ else if (ex->convert) n = (*ex->convert)(ex->nextchr, &ex->nextchr, ex->handle);
+ if (ex->nextchr == pos) error(ex, "syntax error");
+ goto gotoperand;
+ }
+ if (ex->errmsg) return(0);
+ if (!operand) error(ex, "operand expected");
+ }
+ done:
+ ungetchr(ex);
+ if (!operand) error(ex, "operand expected");
+ return(n);
+}
+
+/*
+ * evaluate an integer arithmetic expression in s
+ *
+ * (long)(*convert)(const char* string, char** end, void* handle)
+ * is a user supplied conversion routine that is called when unknown
+ * chars are encountered; string points to the part to be
+ * converted and end is adjusted to point to the next non-converted
+ * character; if string is 0 then end points to an error message string
+ *
+ * NOTE: (*convert)() may call strexpr(ex, )
+ */
+
+long
+strexpr(const char* s, char** end, long(*convert)(const char*, char**, void*), void* handle)
+{
+ long n;
+ Expr_t ex;
+
+ ex.nextchr = (char*)s;
+ ex.errmsg = 0;
+ ex.convert = convert;
+ ex.handle = handle;
+ n = expr(&ex, 0);
+ if (peekchr(&ex) == ':')
+ seterror(&ex, "invalid use of :");
+ if (ex.errmsg)
+ {
+ if (convert) (*convert)(NiL, &ex.errmsg, handle);
+ ex.nextchr = ex.errchr;
+ n = 0;
+ }
+ if (end) *end = ex.nextchr;
+ return(n);
+}
diff --git a/src/lib/libast/string/strgid.c b/src/lib/libast/string/strgid.c
new file mode 100644
index 0000000..55ebe23
--- /dev/null
+++ b/src/lib/libast/string/strgid.c
@@ -0,0 +1,121 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * gid name -> number
+ */
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide getgrgid getgrnam getpwnam
+#else
+#define getgrgid ______getgrgid
+#define getgrnam ______getgrnam
+#define getpwnam ______getpwnam
+#endif
+
+#include <ast.h>
+#include <cdt.h>
+#include <pwd.h>
+#include <grp.h>
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide getgrgid getgrnam getpwnam
+#else
+#undef getgrgid
+#undef getgrnam
+#undef getpwnam
+#endif
+
+extern struct group* getgrgid(gid_t);
+extern struct group* getgrnam(const char*);
+extern struct passwd* getpwnam(const char*);
+
+typedef struct Id_s
+{
+ Dtlink_t link;
+ int id;
+ char name[1];
+} Id_t;
+
+/*
+ * return gid number given gid/uid name
+ * gid attempted first, then uid->pw_gid
+ * -1 on first error for a given name
+ * -2 on subsequent errors for a given name
+ */
+
+int
+strgid(const char* name)
+{
+ register Id_t* ip;
+ register struct group* gr;
+ register struct passwd* pw;
+ int id;
+ char* e;
+
+ static Dt_t* dict;
+ static Dtdisc_t disc;
+
+ if (!dict)
+ {
+ disc.key = offsetof(Id_t, name);
+ dict = dtopen(&disc, Dtset);
+ }
+ else if (ip = (Id_t*)dtmatch(dict, name))
+ return ip->id;
+ if (gr = getgrnam(name))
+ id = gr->gr_gid;
+ else if (pw = getpwnam(name))
+ id = pw->pw_gid;
+ else
+ {
+ id = strtol(name, &e, 0);
+#if _WINIX
+ if (!*e)
+ {
+ if (!getgrgid(id))
+ id = -1;
+ }
+ else if (!streq(name, "sys"))
+ id = -1;
+ else if (gr = getgrnam("Administrators"))
+ id = gr->gr_gid;
+ else if (pw = getpwnam("Administrator"))
+ id = pw->pw_gid;
+ else
+ id = -1;
+#else
+ if (*e || !getgrgid(id))
+ id = -1;
+#endif
+ }
+ if (dict && (ip = newof(0, Id_t, 1, strlen(name))))
+ {
+ strcpy(ip->name, name);
+ ip->id = id >= 0 ? id : -2;
+ dtinsert(dict, ip);
+ }
+ return id;
+}
diff --git a/src/lib/libast/string/strlcat.c b/src/lib/libast/string/strlcat.c
new file mode 100644
index 0000000..f5f17af
--- /dev/null
+++ b/src/lib/libast/string/strlcat.c
@@ -0,0 +1,83 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * strlcat implementation
+ */
+
+#define strlcat ______strlcat
+
+#include <ast.h>
+
+#undef strlcat
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+#if _lib_strlcat
+
+NoN(strlcat)
+
+#else
+
+/*
+ * append t onto s limiting total size of s to n
+ * s 0 terminated if n>0
+ * min(n,strlen(s))+strlen(t) returned
+ */
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern size_t
+strlcat(register char* s, register const char* t, register size_t n)
+{
+ register size_t m;
+ const char* o = t;
+
+ if (m = n)
+ {
+ while (n && *s)
+ {
+ n--;
+ s++;
+ }
+ m -= n;
+ if (n)
+ do
+ {
+ if (!--n)
+ {
+ *s = 0;
+ break;
+ }
+ } while (*s++ = *t++);
+ else
+ *s = 0;
+ }
+ if (!n)
+ while (*t++);
+ return (t - o) + m - 1;
+}
+
+#endif
diff --git a/src/lib/libast/string/strlcpy.c b/src/lib/libast/string/strlcpy.c
new file mode 100644
index 0000000..8410802
--- /dev/null
+++ b/src/lib/libast/string/strlcpy.c
@@ -0,0 +1,71 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * strlcpy implementation
+ */
+
+#define strlcpy ______strlcpy
+
+#include <ast.h>
+
+#undef strlcpy
+
+#undef _def_map_ast
+#include <ast_map.h>
+
+#if _lib_strlcpy
+
+NoN(strlcpy)
+
+#else
+
+/*
+ * copy at most n chars from t into s
+ * result 0 terminated if n>0
+ * strlen(t) returned
+ */
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern size_t
+strlcpy(register char* s, register const char* t, register size_t n)
+{
+ const char* o = t;
+
+ if (n)
+ do
+ {
+ if (!--n)
+ {
+ *s = 0;
+ break;
+ }
+ } while (*s++ = *t++);
+ if (!n)
+ while (*t++);
+ return t - o - 1;
+}
+
+#endif
diff --git a/src/lib/libast/string/strlook.c b/src/lib/libast/string/strlook.c
new file mode 100644
index 0000000..1868697
--- /dev/null
+++ b/src/lib/libast/string/strlook.c
@@ -0,0 +1,50 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+#include <ast.h>
+
+/*
+ * return pointer to name in tab with element size siz
+ * where the first member of each element is a char*
+ *
+ * the last name in tab must be 0
+ *
+ * 0 returned if name not found
+ */
+
+void*
+strlook(const void* tab, size_t siz, register const char* name)
+{
+ register char* t = (char*)tab;
+ register char* s;
+ register int c = *name;
+
+ for (; s = *((char**)t); t += siz)
+ if (*s == c && !strcmp(s, name))
+ return (void*)t;
+ return 0;
+}
diff --git a/src/lib/libast/string/strmatch.c b/src/lib/libast/string/strmatch.c
new file mode 100644
index 0000000..4114ee4
--- /dev/null
+++ b/src/lib/libast/string/strmatch.c
@@ -0,0 +1,171 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * D. G. Korn
+ * G. S. Fowler
+ * AT&T Research
+ *
+ * match shell file patterns
+ * this interface is a wrapper on regex
+ *
+ * sh pattern egrep RE description
+ * ---------- -------- -----------
+ * * .* 0 or more chars
+ * ? . any single char
+ * [.] [.] char class
+ * [!.] [^.] negated char class
+ * [[:.:]] [[:.:]] ctype class
+ * [[=.=]] [[=.=]] equivalence class
+ * [[...]] [[...]] collation element
+ * *(.) (.)* 0 or more of
+ * +(.) (.)+ 1 or more of
+ * ?(.) (.)? 0 or 1 of
+ * (.) (.) 1 of
+ * @(.) (.) 1 of
+ * a|b a|b a or b
+ * \# () subgroup back reference [1-9]
+ * a&b a and b
+ * !(.) none of
+ *
+ * \ used to escape metacharacters
+ *
+ * *, ?, (, |, &, ), [, \ must be \'d outside of [...]
+ * only ] must be \'d inside [...]
+ *
+ */
+
+#include <ast.h>
+#include <regex.h>
+
+static struct State_s
+{
+ regmatch_t* match;
+ int nmatch;
+} matchstate;
+
+/*
+ * subgroup match
+ * 0 returned if no match
+ * otherwise number of subgroups matched returned
+ * match group begin offsets are even elements of sub
+ * match group end offsets are odd elements of sub
+ * the matched string is from s+sub[0] up to but not
+ * including s+sub[1]
+ */
+
+int
+strgrpmatch(const char* b, const char* p, int* sub, int n, register int flags)
+{
+ register regex_t* re;
+ register int* end;
+ register int i;
+ register regflags_t reflags;
+
+ /*
+ * 0 and empty patterns are special
+ */
+
+ if (!p || !b)
+ {
+ if (!p && !b)
+ regcache(NiL, 0, NiL);
+ return 0;
+ }
+ if (!*p)
+ {
+ if (sub && n > 0)
+ sub[0] = sub[1] = 0;
+ return *b == 0;
+ }
+
+ /*
+ * convert flags
+ */
+
+ if (flags & REG_ADVANCE)
+ reflags = flags & ~REG_ADVANCE;
+ else
+ {
+ reflags = REG_SHELL|REG_AUGMENTED;
+ if (!(flags & STR_MAXIMAL))
+ reflags |= REG_MINIMAL;
+ if (flags & STR_GROUP)
+ reflags |= REG_SHELL_GROUP;
+ if (flags & STR_LEFT)
+ reflags |= REG_LEFT;
+ if (flags & STR_RIGHT)
+ reflags |= REG_RIGHT;
+ if (flags & STR_ICASE)
+ reflags |= REG_ICASE;
+ }
+ if (!sub || n <= 0)
+ reflags |= REG_NOSUB;
+ if (!(re = regcache(p, reflags, NiL)))
+ return 0;
+ if (n > matchstate.nmatch)
+ {
+ if (!(matchstate.match = newof(matchstate.match, regmatch_t, n, 0)))
+ return 0;
+ matchstate.nmatch = n;
+ }
+ if (regexec(re, b, n, matchstate.match, reflags & ~(REG_MINIMAL|REG_SHELL_GROUP|REG_LEFT|REG_RIGHT|REG_ICASE)))
+ return 0;
+ if (!sub || n <= 0)
+ return 1;
+ i = re->re_nsub;
+ end = sub + n * 2;
+ for (n = 0; sub < end && n <= i; n++)
+ {
+ *sub++ = matchstate.match[n].rm_so;
+ *sub++ = matchstate.match[n].rm_eo;
+ }
+ return i + 1;
+}
+
+/*
+ * compare the string s with the shell pattern p
+ * returns 1 for match 0 otherwise
+ */
+
+int
+strmatch(const char* s, const char* p)
+{
+ return strgrpmatch(s, p, NiL, 0, STR_MAXIMAL|STR_LEFT|STR_RIGHT);
+}
+
+/*
+ * leading substring match
+ * first char after end of substring returned
+ * 0 returned if no match
+ *
+ * OBSOLETE: use strgrpmatch()
+ */
+
+char*
+strsubmatch(const char* s, const char* p, int flags)
+{
+ int match[2];
+
+ return strgrpmatch(s, p, match, 1, (flags ? STR_MAXIMAL : 0)|STR_LEFT) ? (char*)s + match[1] : (char*)0;
+}
diff --git a/src/lib/libast/string/strmode.c b/src/lib/libast/string/strmode.c
new file mode 100644
index 0000000..8ec8749
--- /dev/null
+++ b/src/lib/libast/string/strmode.c
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * G. S. Fowler
+ * AT&T Bell Laboratories
+ *
+ * return modex canonical representation of file mode bits
+ * given ls -l style file mode string
+ */
+
+#include "modelib.h"
+
+int
+strmode(register const char* s)
+{
+ register int c;
+ register char* t;
+ register struct modeop* p;
+ int mode;
+
+ mode = 0;
+ for (p = modetab; (c = *s++) && p < &modetab[MODELEN]; p++)
+ for (t = p->name; *t; t++)
+ if (*t == c)
+ {
+ c = t - p->name;
+ mode |= (p->mask1 & (c << p->shift1)) | (p->mask2 & (c << p->shift2));
+ break;
+ }
+ return(mode);
+}
diff --git a/src/lib/libast/string/strnacmp.c b/src/lib/libast/string/strnacmp.c
new file mode 100644
index 0000000..4a6c9c6
--- /dev/null
+++ b/src/lib/libast/string/strnacmp.c
@@ -0,0 +1,66 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+/*
+ * ccmapc(c, CC_NATIVE, CC_ASCII) and strncmp
+ */
+
+#include <ast.h>
+#include <ccode.h>
+
+#if _lib_strnacmp
+
+NoN(strnacmp)
+
+#else
+
+#include <ctype.h>
+
+int
+strnacmp(const char* a, const char* b, size_t n)
+{
+#if CC_NATIVE == CC_ASCII
+ return strncmp(a, b, n);
+#else
+ register unsigned char* ua = (unsigned char*)a;
+ register unsigned char* ub = (unsigned char*)b;
+ register unsigned char* ue;
+ register unsigned char* m;
+ register int c;
+ register int d;
+
+ m = ccmap(CC_NATIVE, CC_ASCII);
+ ue = ua + n;
+ while (ua < ue)
+ {
+ c = m[*ua++];
+ if (d = c - m[*ub++])
+ return d;
+ if (!c)
+ return 0;
+ }
+ return 0;
+#endif
+}
+
+#endif
diff --git a/src/lib/libast/string/strncopy.c b/src/lib/libast/string/strncopy.c
new file mode 100644
index 0000000..65752ac
--- /dev/null
+++ b/src/lib/libast/string/strncopy.c
@@ -0,0 +1,46 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+/*
+ * copy up to n bytes of string f into t
+ * trailing 0 always added to t, even if n==0
+ * pointer to the copied 0 returned
+ */
+
+char*
+strncopy(register char* t, register const char* f, size_t n)
+{
+ register char* e = t + n - 1;
+
+ do
+ {
+ if (t >= e)
+ {
+ *t = 0;
+ return t;
+ }
+ } while (*t++ = *f++);
+ return t - 1;
+}
diff --git a/src/lib/libast/string/strnpcmp.c b/src/lib/libast/string/strnpcmp.c
new file mode 100644
index 0000000..e8a4172
--- /dev/null
+++ b/src/lib/libast/string/strnpcmp.c
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+/*
+ * path prefix strncmp(3) -- longest first!
+ */
+
+int
+strnpcmp(register const char* a, register const char* b, size_t n)
+{
+ register const char* e;
+
+ e = a + n;
+ for (;;)
+ {
+ if (a >= e)
+ return 0;
+ if (*a != *b)
+ break;
+ if (!*a++)
+ return 0;
+ b++;
+ }
+ if (*a == 0 && *b == '/')
+ return 1;
+ if (*a == '/' && *b == 0)
+ return -1;
+ return (a < b) ? -1 : 1;
+}
diff --git a/src/lib/libast/string/strntod.c b/src/lib/libast/string/strntod.c
new file mode 100644
index 0000000..e04969b
--- /dev/null
+++ b/src/lib/libast/string/strntod.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strntod() implementation
+ */
+
+#include <ast.h>
+
+#define S2F_function strntod
+#define S2F_type 1
+#define S2F_size 1
+
+#include "sfstrtof.h"
diff --git a/src/lib/libast/string/strntol.c b/src/lib/libast/string/strntol.c
new file mode 100644
index 0000000..e71de8e
--- /dev/null
+++ b/src/lib/libast/string/strntol.c
@@ -0,0 +1,31 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strntol() implementation
+ */
+
+#define S2I_function strntol
+#define S2I_number long
+#define S2I_unumber unsigned long
+#define S2I_size 1
+
+#include "strtoi.h"
diff --git a/src/lib/libast/string/strntold.c b/src/lib/libast/string/strntold.c
new file mode 100644
index 0000000..1b791e2
--- /dev/null
+++ b/src/lib/libast/string/strntold.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strntold() implementation
+ */
+
+#include <ast.h>
+
+#define S2F_function strntold
+#define S2F_type 2
+#define S2F_size 1
+
+#include "sfstrtof.h"
diff --git a/src/lib/libast/string/strntoll.c b/src/lib/libast/string/strntoll.c
new file mode 100644
index 0000000..7eb4772
--- /dev/null
+++ b/src/lib/libast/string/strntoll.c
@@ -0,0 +1,31 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strntoll() implementation
+ */
+
+#define S2I_function strntoll
+#define S2I_number intmax_t
+#define S2I_unumber uintmax_t
+#define S2I_size 1
+
+#include "strtoi.h"
diff --git a/src/lib/libast/string/strnton.c b/src/lib/libast/string/strnton.c
new file mode 100644
index 0000000..5d6e1bf
--- /dev/null
+++ b/src/lib/libast/string/strnton.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strnton() implementation
+ */
+
+#define S2I_function strnton
+#define S2I_number long
+#define S2I_unumber unsigned long
+#define S2I_multiplier 1
+#define S2I_size 1
+
+#include "strtoi.h"
diff --git a/src/lib/libast/string/strntonll.c b/src/lib/libast/string/strntonll.c
new file mode 100644
index 0000000..d55b335
--- /dev/null
+++ b/src/lib/libast/string/strntonll.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strntonll() implementation
+ */
+
+#define S2I_function strntonll
+#define S2I_number intmax_t
+#define S2I_unumber uintmax_t
+#define S2I_multiplier 1
+#define S2I_size 1
+
+#include "strtoi.h"
diff --git a/src/lib/libast/string/strntoul.c b/src/lib/libast/string/strntoul.c
new file mode 100644
index 0000000..f688985
--- /dev/null
+++ b/src/lib/libast/string/strntoul.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strntoul() implementation
+ */
+
+#define S2I_function strntoul
+#define S2I_number long
+#define S2I_unumber unsigned long
+#define S2I_size 1
+#define S2I_unsigned 1
+
+#include "strtoi.h"
diff --git a/src/lib/libast/string/strntoull.c b/src/lib/libast/string/strntoull.c
new file mode 100644
index 0000000..9eae4f1
--- /dev/null
+++ b/src/lib/libast/string/strntoull.c
@@ -0,0 +1,32 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strntoull() implementation
+ */
+
+#define S2I_function strntoull
+#define S2I_number intmax_t
+#define S2I_unumber uintmax_t
+#define S2I_size 1
+#define S2I_unsigned 1
+
+#include "strtoi.h"
diff --git a/src/lib/libast/string/strnvcmp.c b/src/lib/libast/string/strnvcmp.c
new file mode 100644
index 0000000..41d2414
--- /dev/null
+++ b/src/lib/libast/string/strnvcmp.c
@@ -0,0 +1,86 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+#include <ctype.h>
+
+/*
+ * version strncmp(3)
+ */
+
+int
+strnvcmp(register const char* a, register const char* b, size_t n)
+{
+ register const char* ae;
+ register const char* be;
+ register unsigned long na;
+ register unsigned long nb;
+
+ ae = a + n;
+ be = b + n;
+ for (;;)
+ {
+ if (a >= ae)
+ {
+ if (b >= be)
+ return 0;
+ return 1;
+ }
+ else if (b >= be)
+ return -1;
+ if (isdigit(*a) && isdigit(*b))
+ {
+ na = nb = 0;
+ while (a < ae && isdigit(*a))
+ na = na * 10 + *a++ - '0';
+ while (b < be && isdigit(*b))
+ nb = nb * 10 + *b++ - '0';
+ if (na < nb)
+ return -1;
+ if (na > nb)
+ return 1;
+ }
+ else if (*a != *b)
+ break;
+ else if (!*a)
+ return 0;
+ else
+ {
+ a++;
+ b++;
+ }
+ }
+ if (*a == 0)
+ return -1;
+ if (*b == 0)
+ return 1;
+ if (*a == '.')
+ return -1;
+ if (*b == '.')
+ return 1;
+ if (*a == '-')
+ return -1;
+ if (*b == '-')
+ return 1;
+ return *a < *b ? -1 : 1;
+}
diff --git a/src/lib/libast/string/stropt.c b/src/lib/libast/string/stropt.c
new file mode 100644
index 0000000..91bd351
--- /dev/null
+++ b/src/lib/libast/string/stropt.c
@@ -0,0 +1,188 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+#include <ast.h>
+#include <ctype.h>
+
+/*
+ * parse option expression in s using options in tab with element size siz
+ * first element in tab must be a char*
+ * options match
+ *
+ * [no]name[[:]=['"]value["']][, ]...
+ *
+ * f is called for each option
+ *
+ * (*f)(void* a, char* p, int n, char* v)
+ *
+ * a from stropt
+ * p matching tab entry, or name if no table
+ * n 0 if option had ``no'' prefix, -1 if :=, 1 otherwise
+ * v option value pointer
+ *
+ * for unmatched options p is 0 and v is the offending option
+ *
+ * names in s may be shorter than tab names
+ * longer names must have a prefix that matches a tab name
+ * the first match is returned
+ * \ escapes value using chresc()
+ */
+
+int
+stropt(const char* as, const void* tab, int siz, int(*f)(void*, const void*, int, const char*), void* a)
+{
+ register int c;
+ register char* s;
+ register char* v;
+ register char* t;
+ char** p;
+ char* u;
+ char* x;
+ char* e;
+ int n;
+ int ql;
+ int qr;
+ int qc;
+
+ if (!as) n = 0;
+ else if (!(x = s = strdup(as))) n = -1;
+ else
+ {
+ for (;;)
+ {
+ while (isspace(*s) || *s == ',') s++;
+ if (*s == 'n' && *(s + 1) == 'o')
+ {
+ s += 2;
+ n = 0;
+ }
+ else n = 1;
+ if (!*s)
+ {
+ n = 0;
+ break;
+ }
+ if (tab)
+ {
+ for (p = (char**)tab; t = *p; p = (char**)((char*)p + siz))
+ {
+ for (v = s; *t && *t++ == *v; v++);
+ if (!*t || isspace(*v) || *v == ',' || *v == '=')
+ break;
+ if (*v == ':' && *(v + 1) == '=')
+ {
+ v++;
+ n = -1;
+ break;
+ }
+ }
+ if (!t)
+ {
+ u = v = s;
+ p = 0;
+ }
+ }
+ else
+ {
+ p = (char**)(v = s);
+ t = 0;
+ }
+ while (*v && !isspace(*v) && *v != '=' && *v != ',')
+ if (*v++ == ':' && *v == '=')
+ {
+ if (!t)
+ *(v - 1) = 0;
+ n = -n;
+ break;
+ }
+ if (*v == '=')
+ {
+ if (!t)
+ *v = 0;
+ t = s = ++v;
+ ql = qr = 0;
+ while (c = *s++)
+ {
+ if (c == '\\')
+ {
+ *t++ = chresc(s - 1, &e);
+ s = e;
+ }
+ else if (c == qr)
+ {
+ if (qr != ql)
+ *t++ = c;
+ if (--qc <= 0)
+ qr = ql = 0;
+ }
+ else if (c == ql)
+ {
+ *t++ = c;
+ qc++;
+ }
+ else if (qr)
+ *t++ = c;
+ else if (c == ',' || isspace(c))
+ break;
+ else if (c == '"' || c == '\'')
+ {
+ ql = qr = c;
+ qc = 1;
+ }
+ else
+ {
+ *t++ = c;
+ if (c == '{')
+ {
+ ql = c;
+ qr = '}';
+ qc = 1;
+ }
+ else if (c == '(')
+ {
+ ql = c;
+ qr = ')';
+ qc = 1;
+ }
+ }
+ }
+ *t = 0;
+ }
+ else
+ {
+ s = v;
+ c = *s;
+ *s++ = 0;
+ }
+ n = p ? (*f)(a, p, n, v) : (*f)(a, p, v - u, u);
+ if (n || !c)
+ break;
+ }
+ free(x);
+ }
+ return n;
+}
diff --git a/src/lib/libast/string/strpcmp.c b/src/lib/libast/string/strpcmp.c
new file mode 100644
index 0000000..2c83d71
--- /dev/null
+++ b/src/lib/libast/string/strpcmp.c
@@ -0,0 +1,44 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+
+/*
+ * path prefix strcmp(3) -- longest first!
+ */
+
+int
+strpcmp(register const char* a, register const char* b)
+{
+ while (*a == *b)
+ {
+ if (!*a++)
+ return 0;
+ b++;
+ }
+ if (*a == 0 && *b == '/')
+ return 1;
+ if (*a == '/' && *b == 0)
+ return -1;
+ return (a < b) ? -1 : 1;
+}
diff --git a/src/lib/libast/string/strperm.c b/src/lib/libast/string/strperm.c
new file mode 100644
index 0000000..455d232
--- /dev/null
+++ b/src/lib/libast/string/strperm.c
@@ -0,0 +1,267 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * apply file permission expression expr to perm
+ *
+ * each expression term must match
+ *
+ * [ugoa]*[-&+|^=]?[rwxst0-7]*
+ *
+ * terms may be combined using ,
+ *
+ * if non-null, e points to the first unrecognized char in expr
+ */
+
+#include <ast.h>
+#include <ls.h>
+#include <modex.h>
+
+int
+strperm(const char* aexpr, char** e, register int perm)
+{
+ register char* expr = (char*)aexpr;
+ register int c;
+ register int typ;
+ register int who;
+ int num;
+ int op;
+ int mask;
+ int masked;
+
+ if (perm == -1)
+ {
+ perm = 0;
+ masked = 1;
+ mask = ~0;
+ }
+ else
+ masked = 0;
+ for (;;)
+ {
+ op = num = who = typ = 0;
+ for (;;)
+ {
+ switch (c = *expr++)
+ {
+ case 'u':
+ who |= S_ISVTX|S_ISUID|S_IRWXU;
+ continue;
+ case 'g':
+ who |= S_ISVTX|S_ISGID|S_IRWXG;
+ continue;
+ case 'o':
+ who |= S_ISVTX|S_IRWXO;
+ continue;
+ case 'a':
+ who = S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO;
+ continue;
+ default:
+ if (c >= '0' && c <= '7')
+ {
+ if (!who)
+ who = S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO;
+ c = '=';
+ }
+ expr--;
+ /*FALLTHROUGH*/
+ case '=':
+ if (who)
+ perm &= ~who;
+ else
+ perm = 0;
+ /*FALLTHROUGH*/
+ case '+':
+ case '|':
+ case '-':
+ case '&':
+ case '^':
+ op = c;
+ for (;;)
+ {
+ switch (c = *expr++)
+ {
+ case 'r':
+ typ |= S_IRUSR|S_IRGRP|S_IROTH;
+ continue;
+ case 'w':
+ typ |= S_IWUSR|S_IWGRP|S_IWOTH;
+ continue;
+ case 'X':
+ if (!S_ISDIR(perm) && !(perm & (S_IXUSR|S_IXGRP|S_IXOTH)))
+ continue;
+ /*FALLTHROUGH*/
+ case 'x':
+ typ |= S_IXUSR|S_IXGRP|S_IXOTH;
+ continue;
+ case 's':
+ typ |= S_ISUID|S_ISGID;
+ continue;
+ case 't':
+ typ |= S_ISVTX;
+ continue;
+ case 'l':
+ if (perm & S_IXGRP)
+ {
+ if (e)
+ *e = expr - 1;
+ return perm & S_IPERM;
+ }
+ typ |= S_ISGID;
+ continue;
+ case '=':
+ case '+':
+ case '|':
+ case '-':
+ case '&':
+ case '^':
+ case ',':
+ case 0:
+ if (who)
+ typ &= who;
+ else
+ switch (op)
+ {
+ case '=':
+ case '+':
+ case '|':
+ case '-':
+ case '&':
+ if (!masked)
+ {
+ masked = 1;
+ umask(mask = umask(0));
+ mask = ~mask;
+ }
+ typ &= mask;
+ break;
+ }
+ switch (op)
+ {
+ default:
+ if (who)
+ perm &= ~who;
+ else
+ perm = 0;
+ /*FALLTHROUGH*/
+ case '+':
+ case '|':
+ perm |= typ;
+ typ = 0;
+ break;
+ case '-':
+ perm &= ~typ;
+ typ = 0;
+ break;
+ case '&':
+ perm &= typ;
+ typ = 0;
+ break;
+ case '^':
+ if (typ &= perm)
+ {
+ /*
+ * propagate least restrictive to most restrictive
+ */
+
+ if (typ & S_IXOTH)
+ perm |= who & (S_IXUSR|S_IXGRP);
+ if (typ & S_IWOTH)
+ perm |= who & (S_IWUSR|S_IWGRP);
+ if (typ & S_IROTH)
+ perm |= who & (S_IRUSR|S_IRGRP);
+ if (typ & S_IXGRP)
+ perm |= who & S_IXUSR;
+ if (typ & S_IWGRP)
+ perm |= who & S_IWUSR;
+ if (typ & S_IRGRP)
+ perm |= who & S_IRUSR;
+
+ /*
+ * if any execute then read => execute
+ */
+
+ if ((typ |= perm) & (S_IXUSR|S_IXGRP|S_IXOTH))
+ {
+ if (typ & S_IRUSR)
+ perm |= who & S_IXUSR;
+ if (typ & S_IRGRP)
+ perm |= who & S_IXGRP;
+ if (typ & S_IROTH)
+ perm |= who & S_IXOTH;
+ }
+ typ = 0;
+ }
+ break;
+ }
+ switch (c)
+ {
+ case '=':
+ case '+':
+ case '|':
+ case '-':
+ case '&':
+ case '^':
+ op = c;
+ typ = 0;
+ continue;
+ }
+ if (c)
+ break;
+ /*FALLTHROUGH*/
+ default:
+ if (c < '0' || c > '7')
+ {
+ if (e)
+ *e = expr - 1;
+ if (typ)
+ {
+ if (who)
+ {
+ typ &= who;
+ perm &= ~who;
+ }
+ perm |= typ;
+ }
+ return perm & S_IPERM;
+ }
+ num = (num << 3) | (c - '0');
+ if (!who && (op == '+' || op == '-'))
+ who = S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO;
+ if (*expr < '0' || *expr > '7')
+ {
+ typ |= modei(num);
+ num = 0;
+ }
+ continue;
+ }
+ break;
+ }
+ break;
+ }
+ break;
+ }
+ }
+}
diff --git a/src/lib/libast/string/strpsearch.c b/src/lib/libast/string/strpsearch.c
new file mode 100644
index 0000000..69637d5
--- /dev/null
+++ b/src/lib/libast/string/strpsearch.c
@@ -0,0 +1,125 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+#include <ast.h>
+#include <ccode.h>
+#include <ctype.h>
+
+#if CC_NATIVE == CC_ASCII
+#define MAP(m,c) (c)
+#else
+#define MAP(m,c) m[c]
+#endif
+
+/*
+ * return a pointer to the isalpha() identifier matching
+ * name in the CC_ASCII sorted tab of num elements of
+ * size siz where the first member of each
+ * element is a char*
+ *
+ * [xxx] brackets optional identifier characters
+ * * starts optional identifier characters
+ *
+ * 0 returned if name not found
+ * otherwise if next!=0 then it points to the next
+ * unmatched char in name
+ */
+
+void*
+strpsearch(const void* tab, size_t num, size_t siz, const char* name, char** next)
+{
+ register char* lo = (char*)tab;
+ register char* hi = lo + (num - 1) * siz;
+ register char* mid;
+#if CC_NATIVE != CC_ASCII
+ register unsigned char* m;
+#endif
+ register unsigned char* s;
+ register unsigned char* t;
+ register int c;
+ register int v;
+ int sequential = 0;
+
+#if CC_NATIVE != CC_ASCII
+ m = ccmap(CC_NATIVE, CC_ASCII);
+#endif
+ c = MAP(m, *((unsigned char*)name));
+ while (lo <= hi)
+ {
+ mid = lo + (sequential ? 0 : (((hi - lo) / siz) / 2) * siz);
+ if (!(v = c - MAP(m, *(s = *((unsigned char**)mid)))) || *s == '[' && !(v = c - MAP(m, *++s)) && (v = 1))
+ {
+ t = (unsigned char*)name;
+ for (;;)
+ {
+ if (!v && (*s == '[' || *s == '*'))
+ {
+ v = 1;
+ s++;
+ }
+ else if (v && *s == ']')
+ {
+ v = 0;
+ s++;
+ }
+ else if (!isalpha(*t))
+ {
+ if (v || !*s)
+ {
+ if (next)
+ *next = (char*)t;
+ return (void*)mid;
+ }
+ if (!sequential)
+ {
+ while ((mid -= siz) >= lo && (s = *((unsigned char**)mid)) && ((c == MAP(m, *s)) || *s == '[' && c == MAP(m, *(s + 1))));
+ sequential = 1;
+ }
+ v = 1;
+ break;
+ }
+ else if (*t != *s)
+ {
+ v = MAP(m, *t) - MAP(m, *s);
+ break;
+ }
+ else
+ {
+ t++;
+ s++;
+ }
+ }
+ }
+ else if (sequential)
+ break;
+ if (v > 0)
+ lo = mid + siz;
+ else
+ hi = mid - siz;
+ }
+ return 0;
+}
diff --git a/src/lib/libast/string/strsearch.c b/src/lib/libast/string/strsearch.c
new file mode 100644
index 0000000..56d78fc
--- /dev/null
+++ b/src/lib/libast/string/strsearch.c
@@ -0,0 +1,57 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ */
+
+#include <ast.h>
+
+/*
+ * return a pointer to the element matching
+ * name in the (*comparf*)() sorted tab of num elements of
+ * size siz where the first member of each
+ * element is a char*
+ *
+ * 0 returned if name not found
+ */
+
+void*
+strsearch(const void* tab, size_t num, size_t siz, Strcmp_f comparf, const char* name, void* context)
+{
+ register char* lo = (char*)tab;
+ register char* hi = lo + (num - 1) * siz;
+ register char* mid;
+ register int v;
+
+ while (lo <= hi)
+ {
+ mid = lo + (((hi - lo) / siz) / 2) * siz;
+ if (!(v = context ? (*(Strcmp_context_f)comparf)(name, *((char**)mid), context) : (*comparf)(name, *((char**)mid))))
+ return (void*)mid;
+ else if (v > 0)
+ lo = mid + siz;
+ else hi = mid - siz;
+ }
+ return 0;
+}
diff --git a/src/lib/libast/string/strsort.c b/src/lib/libast/string/strsort.c
new file mode 100644
index 0000000..e7ab49a
--- /dev/null
+++ b/src/lib/libast/string/strsort.c
@@ -0,0 +1,57 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * strsort - sort an array pointers using fn
+ *
+ * fn follows strcmp(3) conventions
+ *
+ * David Korn
+ * AT&T Bell Laboratories
+ *
+ * derived from Bourne Shell
+ */
+
+#include <ast.h>
+
+void
+strsort(char** argv, int n, int(*fn)(const char*, const char*))
+{
+ register int i;
+ register int j;
+ register int m;
+ register char** ap;
+ char* s;
+ int k;
+
+ for (j = 1; j <= n; j *= 2);
+ for (m = 2 * j - 1; m /= 2;)
+ for (j = 0, k = n - m; j < k; j++)
+ for (i = j; i >= 0; i -= m)
+ {
+ ap = &argv[i];
+ if ((*fn)(ap[m], ap[0]) >= 0) break;
+ s = ap[m];
+ ap[m] = ap[0];
+ ap[0] = s;
+ }
+}
diff --git a/src/lib/libast/string/strtape.c b/src/lib/libast/string/strtape.c
new file mode 100644
index 0000000..e31f227
--- /dev/null
+++ b/src/lib/libast/string/strtape.c
@@ -0,0 +1,148 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * local device pathname for portable tape unit specification is returned
+ * if e is non-null then it is set to the next unused char in s
+ *
+ * <unit><density>[<no-rewind>]
+ * {0-7}[l,m,h,u,c][n]
+ */
+
+#include <ast.h>
+
+char*
+strtape(register const char* s, register char** e)
+{
+ int mtunit = '0';
+ int mtdensity = 0;
+ char mtrewind[2];
+ char mtbehavior[2];
+
+ static char tapefile[sizeof("/dev/Xrmt/123456789")];
+
+ mtrewind[0] = mtrewind[1] = mtbehavior[0] = mtbehavior[1] = 0;
+ for (;;)
+ {
+ switch (*s)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ mtunit = *s++;
+ continue;
+ case 'b':
+ case 'v':
+ mtbehavior[0] = *s++;
+ continue;
+ case 'l':
+ case 'm':
+ case 'h':
+ case 'u':
+ case 'c':
+ mtdensity = *s++;
+ continue;
+ case 'n':
+ mtrewind[0] = *s++;
+ continue;
+ }
+ break;
+ }
+ if (e) *e = (char*)s;
+ if (!access("/dev/rmt/.", F_OK))
+ {
+ /*
+ * system V
+ */
+
+ if (!mtdensity) mtdensity = 'm';
+ sfsprintf(tapefile, sizeof(tapefile), "/dev/rmt/ctape%c%s", mtunit, mtrewind);
+ if (!access(tapefile, F_OK)) return(tapefile);
+ for (;;)
+ {
+ sfsprintf(tapefile, sizeof(tapefile), "/dev/rmt/%c%c%s%s", mtunit, mtdensity, mtbehavior, mtrewind);
+ if (!access(tapefile, F_OK)) return(tapefile);
+ if (!mtbehavior[0]) break;
+ mtbehavior[0] = 0;
+ }
+ }
+ else if (!access("/dev/nst0", F_OK))
+ {
+ /*
+ * linux
+ */
+
+ sfsprintf(tapefile, sizeof(tapefile), "/dev/%sst%c", mtrewind, mtunit);
+ }
+ else if (!access("/dev/nrmt0", F_OK))
+ {
+ /*
+ * 9th edition
+ */
+
+ switch (mtdensity)
+ {
+ case 'l':
+ mtunit = '0';
+ break;
+ case 'm':
+ mtunit = '1';
+ break;
+ case 'h':
+ mtunit = '2';
+ break;
+ }
+ sfsprintf(tapefile, sizeof(tapefile), "/dev/%srmt%c", mtrewind, mtunit);
+ }
+ else
+ {
+ /*
+ * BSD
+ */
+
+ mtunit -= '0';
+ switch (mtdensity)
+ {
+ case 'l':
+ break;
+ case 'h':
+ mtunit |= 020;
+ break;
+ default:
+ mtunit |= 010;
+ break;
+ }
+ switch (mtrewind[0])
+ {
+ case 'n':
+ mtunit |= 040;
+ break;
+ }
+ sfsprintf(tapefile, sizeof(tapefile), "/dev/rmt%d", mtunit);
+ }
+ return(tapefile);
+}
diff --git a/src/lib/libast/string/strtoi.h b/src/lib/libast/string/strtoi.h
new file mode 100644
index 0000000..b1155a5
--- /dev/null
+++ b/src/lib/libast/string/strtoi.h
@@ -0,0 +1,640 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * AT&T Research
+ * Glenn Fowler
+ * Phong Vo
+ *
+ * common header and implementation for
+ *
+ * strtol strtoul strton
+ * strtoll strtoull strtonll
+ * strntol strntoul strnton
+ * strntoll strntoull strntonll
+ *
+ * define these macros to instantiate an implementation:
+ *
+ * S2I_function the function name
+ * S2I_number the signed number type
+ * S2I_unumber the unsigned number type
+ * S2I_unsigned 1 for unsigned, 0 for signed
+ * S2I_qualifier 1 for optional qualifier suffix, 0 otherwise
+ * S2I_multiplier 1 for optional multiplier suffix, 0 otherwise
+ * S2I_size the second argument is the input string size
+ *
+ * convert string to number
+ * errno=ERANGE on overflow (LONG_MAX) or underflow (LONG_MIN)
+ * if non-null e will point to first unrecognized char in s
+ * if basep!=0 it points to the default base on input and
+ * will point to the explicit base on return
+ * a default base of 0 will determine the base from the input
+ * a default base of 1 will determine the base from the input using bb#*
+ * a base prefix in the string overrides *b
+ * *b will not be set if the string has no base prefix
+ * if m>1 and no multipler was specified then the result is multiplied by m
+ * if m<0 then multipliers are not consumed
+ * if a base arg or prefix is specified then multiplier is not consumed
+ *
+ * integer numbers are of the form:
+ *
+ * [sign][base][number[qualifier]][multiplier]
+ *
+ * base: nnn# base nnn
+ * 0[xX] hex
+ * 0 octal
+ * [1-9] decimal
+ *
+ * number: [0-9a-zA-Z]*
+ *
+ * qualifier: [lL]
+ * [uU]
+ * [uU][lL]
+ * [lL][uU]
+ * [lL][lL][uU]
+ * [uU][lL][lL]
+ *
+ * multiplier: . pseudo-float if m>1
+ * [bB] block (512)
+ * [cC] char (1)
+ * [gG] giga (1000*1000*1000)
+ * [gG]i gibi (1024*1024*1024)
+ * [kK] kilo (1000)
+ * [kK]i kibi (1024)
+ * [mM] mega (1000*1000)
+ * [mM]i mibi (1024*1024)
+ */
+
+#include <ast.h>
+#include <ctype.h>
+
+#include "sfhdr.h"
+
+#if !__STD_C && !defined(const)
+#define const
+#endif
+
+#ifndef ERANGE
+#define ERANGE EINVAL
+#endif
+
+#define QL 01
+#define QU 02
+
+#define S2I_umax (~((S2I_unumber)0))
+
+#if S2I_unsigned
+#define S2I_type S2I_unumber
+#define S2I_min 0
+#define S2I_max S2I_umax
+#else
+#define S2I_type S2I_number
+#define S2I_min (-S2I_max-1)
+#define S2I_max (S2I_umax>>1)
+#endif
+
+#if S2I_size
+#define S2I_valid(s) ((s)<(z))
+#else
+#define S2I_valid(s) 1
+#endif
+
+#define ADDOVER(n,c,s) ((S2I_umax-(n))<((S2I_unumber)((c)+(s))))
+#define MPYOVER(n,c) (((S2I_unumber)(n))>(S2I_umax/(c)))
+
+static const S2I_unumber mm[] =
+{
+ 0,
+ S2I_umax / 1,
+ S2I_umax / 2,
+ S2I_umax / 3,
+ S2I_umax / 4,
+ S2I_umax / 5,
+ S2I_umax / 6,
+ S2I_umax / 7,
+ S2I_umax / 8,
+ S2I_umax / 9,
+ S2I_umax / 10,
+ S2I_umax / 11,
+ S2I_umax / 12,
+ S2I_umax / 13,
+ S2I_umax / 14,
+ S2I_umax / 15,
+ S2I_umax / 16,
+ S2I_umax / 17,
+ S2I_umax / 18,
+ S2I_umax / 19,
+ S2I_umax / 20,
+ S2I_umax / 21,
+ S2I_umax / 22,
+ S2I_umax / 23,
+ S2I_umax / 24,
+ S2I_umax / 25,
+ S2I_umax / 26,
+ S2I_umax / 27,
+ S2I_umax / 28,
+ S2I_umax / 29,
+ S2I_umax / 30,
+ S2I_umax / 31,
+ S2I_umax / 32,
+ S2I_umax / 33,
+ S2I_umax / 34,
+ S2I_umax / 35,
+ S2I_umax / 36,
+ S2I_umax / 37,
+ S2I_umax / 38,
+ S2I_umax / 39,
+ S2I_umax / 40,
+ S2I_umax / 41,
+ S2I_umax / 42,
+ S2I_umax / 43,
+ S2I_umax / 44,
+ S2I_umax / 45,
+ S2I_umax / 46,
+ S2I_umax / 47,
+ S2I_umax / 48,
+ S2I_umax / 49,
+ S2I_umax / 50,
+ S2I_umax / 51,
+ S2I_umax / 52,
+ S2I_umax / 53,
+ S2I_umax / 54,
+ S2I_umax / 55,
+ S2I_umax / 56,
+ S2I_umax / 57,
+ S2I_umax / 58,
+ S2I_umax / 59,
+ S2I_umax / 60,
+ S2I_umax / 61,
+ S2I_umax / 62,
+ S2I_umax / 63,
+ S2I_umax / 64,
+};
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+extern S2I_type
+#undef extern
+#if S2I_size
+#if S2I_multiplier
+#if __STD_C
+S2I_function(const char* a, size_t size, char** e, char* basep, int m)
+#else
+S2I_function(a, size, e, basep, m) const char* a; size_t size; char** e; char* basep; int m;
+#endif
+#else
+#if __STD_C
+S2I_function(const char* a, size_t size, char** e, int base)
+#else
+S2I_function(a, size, e, base) const char* a; size_t size; char** e; int base;
+#endif
+#endif
+#else
+#if S2I_multiplier
+#if __STD_C
+S2I_function(const char* a, char** e, char* basep, int m)
+#else
+S2I_function(a, e, basep, m) const char* a; char** e; char* basep; int m;
+#endif
+#else
+#if __STD_C
+S2I_function(const char* a, char** e, int base)
+#else
+S2I_function(a, e, base) const char* a; char** e; int base;
+#endif
+#endif
+#endif
+{
+ register unsigned char* s = (unsigned char*)a;
+#if S2I_size
+ register unsigned char* z = s + size;
+#endif
+ register S2I_unumber n;
+ register S2I_unumber x;
+ register int c;
+ register int shift;
+ register unsigned char* p;
+ register unsigned char* cv;
+ unsigned char* b;
+ unsigned char* k;
+ S2I_unumber v;
+#if S2I_multiplier
+ register int base;
+#endif
+ int negative;
+ int overflow = 0;
+ int decimal = 0;
+ int thousand = 0;
+#if !S2I_unsigned
+ int qualifier = 0;
+#endif
+
+#if S2I_multiplier
+ base = basep ? *((unsigned char*)basep) : 0;
+#else
+ if (base > 36 && base <= SF_RADIX)
+ {
+ static int conformance = -1;
+
+ if (conformance < 0)
+ conformance = !strcmp(astconf("CONFORMANCE", NiL, NiL), "standard");
+ if (conformance)
+ base = 1;
+ }
+#endif
+ if (base && (base < 2 || base > SF_RADIX))
+ {
+ errno = EINVAL;
+ return 0;
+ }
+ while (S2I_valid(s) && isspace(*s))
+ s++;
+ if ((negative = S2I_valid(s) && (*s == '-')) || S2I_valid(s) && *s == '+')
+ k = ++s;
+ else
+ k = 0;
+ p = s;
+ if (!base)
+ {
+ if (S2I_valid(p) && (c = *p++) >= '0' && c <= '9')
+ {
+ n = c - '0';
+ if (S2I_valid(p) && (c = *p) >= '0' && c <= '9')
+ {
+ n = (n << 3) + (n << 1) + c - '0';
+ p++;
+ }
+ if (S2I_valid(p) && *p == '#')
+ {
+ if (n >= 2 && n <= 64)
+ {
+ k = s = p + 1;
+ base = n;
+ }
+ }
+ else if (base)
+ base = 0;
+ else if (S2I_valid(s) && *s == '0' && S2I_valid(s + 1))
+ {
+ if ((c = *(s + 1)) == 'x' || c == 'X')
+ {
+ k = s += 2;
+ base = 16;
+ }
+ else if (c >= '0' && c <= '7')
+ {
+ s++;
+ base = 8;
+ }
+ }
+ }
+ if (!base)
+ base = 10;
+ else if (base < 2 || base > SF_RADIX)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+#if S2I_multiplier
+ else
+ {
+ if (basep)
+ *basep = base;
+ m = -1;
+ }
+#endif
+ }
+#if S2I_multiplier
+ else
+ m = -1;
+#endif
+
+ /*
+ * this part transcribed from sfvscanf()
+ */
+
+ SFSETLOCALE(&decimal, &thousand);
+ x = mm[base];
+ n = 0;
+ if (base == 10)
+ {
+ b = s;
+ p = 0;
+ for (;;)
+ {
+ if (S2I_valid(s) && (c = *s++) >= '0' && c <= '9')
+ {
+ if (n > x)
+ overflow = 1;
+ else
+ {
+ n = (n << 3) + (n << 1);
+ c -= '0';
+ if (ADDOVER(n, c, negative))
+ overflow = 1;
+ n += c;
+ }
+ }
+ else if (p && (s - p) != (3 + S2I_valid(s)))
+ {
+ s = p;
+ n = v;
+ c = 0;
+ break;
+ }
+ else if (!S2I_valid(s) || c != thousand)
+ break;
+ else if (!p && (s - b) > 4)
+ {
+ if (e)
+ *e = (char*)s - 1;
+ if (overflow)
+ {
+ errno = ERANGE;
+#if S2I_unsigned
+ n = S2I_max;
+#else
+ n = negative ? S2I_min : S2I_max;
+#endif
+ }
+ return n;
+ }
+ else
+ {
+ p = s;
+ v = n;
+ }
+ }
+ }
+ else
+ {
+ SFCVINIT();
+ cv = base <= 36 ? _Sfcv36 : _Sfcv64;
+ if ((base & ~(base - 1)) == base)
+ {
+#if !S2I_unsigned
+ qualifier |= QU;
+#endif
+ if (base < 8)
+ shift = base < 4 ? 1 : 2;
+ else if (base < 32)
+ shift = base < 16 ? 3 : 4;
+ else
+ shift = base < 64 ? 5 : 6;
+ while (S2I_valid(s) && (c = cv[*s++]) < base)
+ {
+ if (n > x)
+ overflow = 1;
+ else
+ {
+ n <<= shift;
+ if (ADDOVER(n, c, negative))
+ overflow = 1;
+ n += c;
+ }
+ }
+ }
+ else
+ while (S2I_valid(s) && (c = cv[*s++]) < base)
+ {
+ if (n > x)
+ overflow = 1;
+ else
+ {
+ n *= base;
+ if (ADDOVER(n, c, negative))
+ overflow = 1;
+ n += c;
+ }
+ }
+ c = *(s - 1);
+ }
+
+#if S2I_qualifier
+
+ /*
+ * optional qualifier suffix
+ */
+
+ if (S2I_valid(s) && s > (unsigned char*)(a + 1))
+ {
+ base = 0;
+ for (;;)
+ {
+ if (!(base & QL) && (c == 'l' || c == 'L'))
+ {
+ base |= QL;
+ if (!S2I_valid(s))
+ break;
+ c = *s++;
+ if (c == 'l' || c == 'L')
+ {
+ if (!S2I_valid(s))
+ break;
+ c = *s++;
+ }
+ }
+ else if (!(base & QU) && (c == 'u' || c == 'U'))
+ {
+ base |= QU;
+#if !S2I_unsigned
+ qualifier |= QU;
+#endif
+ if (!S2I_valid(s))
+ break;
+ c = *s++;
+ }
+ else
+ break;
+ }
+ }
+#endif
+ if (S2I_valid(s))
+ {
+#if S2I_multiplier
+ /*
+ * optional multiplier suffix
+ */
+
+ if (m < 0 || s == (unsigned char*)(a + 1))
+ s--;
+ else
+ {
+ x = m != 1;
+ switch (c)
+ {
+ case 'b':
+ case 'B':
+ shift = 9;
+ x = 0;
+ break;
+ case 'k':
+ case 'K':
+ shift = 10;
+ break;
+ case 'm':
+ case 'M':
+ shift = 20;
+ break;
+ case 'g':
+ case 'G':
+ shift = 30;
+ break;
+ case 't':
+ case 'T':
+ shift = 40;
+ break;
+ case 'p':
+ case 'P':
+ shift = 50;
+ break;
+ case 'e':
+ case 'E':
+ shift = 60;
+ break;
+ default:
+ if (m <= 1)
+ v = 0;
+ else if (c == decimal && S2I_valid(s))
+ {
+ if (MPYOVER(n, m))
+ overflow = 1;
+ n *= m;
+ v = 0;
+ while (S2I_valid(s) && (c = *s++) >= '0' && c <= '9')
+ v += (m /= 10) * (c - '0');
+ if (ADDOVER(n, v, negative))
+ overflow = 1;
+ n += v;
+ v = 0;
+ }
+ else
+ v = m;
+ s--;
+ shift = 0;
+ break;
+ }
+ if (shift)
+ {
+ if (S2I_valid(s))
+ switch (*s)
+ {
+ case 'i':
+ case 'I':
+ s++;
+ x = 0;
+ break;
+ }
+ if (S2I_valid(s))
+ switch (*s)
+ {
+ case 'b':
+ case 'B':
+ s++;
+ break;
+ }
+ if (x)
+ {
+ v = 1;
+ for (shift /= 10; shift; shift--)
+ {
+ if (v >= (S2I_max/1000))
+ {
+ v = 0;
+ overflow = 1;
+ }
+ v *= 1000;
+ }
+ }
+ else
+#if S2I_unsigned
+ if (shift >= (sizeof(S2I_type) * CHAR_BIT))
+#else
+ if (shift >= (sizeof(S2I_type) * CHAR_BIT - 1))
+#endif
+ {
+ v = 0;
+ overflow = 1;
+ }
+ else
+ v = ((S2I_unumber)1) << shift;
+ }
+ if (v)
+ {
+ if (MPYOVER(n, v))
+ overflow = 1;
+ n *= v;
+ }
+ }
+#else
+ s--;
+#endif
+ }
+ if (s == k)
+ {
+ s--;
+#if S2I_multiplier
+ if (basep)
+ *basep = 10;
+#endif
+ }
+#if !S2I_unsigned
+ else if (!(qualifier & QU))
+ {
+ if (negative)
+ {
+ if (!n)
+ {
+ b = k;
+ do
+ {
+ if (b >= s)
+ {
+ negative = 0;
+ break;
+ }
+ } while (*b++ == '0');
+ }
+ if (negative && (n - 1) > S2I_max)
+ overflow = 1;
+ }
+ else if (n > S2I_max)
+ overflow = 1;
+ }
+#endif
+ if (e)
+ *e = (char*)s;
+ if (overflow)
+ {
+#if !S2I_unsigned
+ if (negative)
+ {
+ if (x << 1)
+ errno = ERANGE;
+ return (S2I_type)S2I_min;
+ }
+#endif
+ errno = ERANGE;
+ return (S2I_type)S2I_max;
+ }
+ return negative ? -n : n;
+}
diff --git a/src/lib/libast/string/strtoip4.c b/src/lib/libast/string/strtoip4.c
new file mode 100644
index 0000000..6d4aed2
--- /dev/null
+++ b/src/lib/libast/string/strtoip4.c
@@ -0,0 +1,150 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+#include <ctype.h>
+
+/*
+ * convert string to 4 byte local byte order ip address
+ * with optional prefix bits
+ * pointer to first unused char placed in *e, even on error
+ * return 0:ok <0:error
+ *
+ * valid addresses match the egrep RE:
+ *
+ * [0-9]{1,3}(\.[0-9]{1,3})*|0[xX][0-9a-fA-Z]+
+ *
+ * valid bits/masks match the egrep RE:
+ *
+ * (/([0-9]+|[0-9]{1,3}(\.[0-9]{1,3})*))?
+ *
+ * if pbits!=0 and no bits/mask specified then trailing 0's in addr
+ * are used to compute the mask
+ */
+
+int
+strtoip4(register const char* s, char** e, uint32_t* paddr, unsigned char* pbits)
+{
+ register int c;
+ register unsigned int n;
+ register uint32_t addr;
+ register int part;
+ register unsigned char bits;
+ uint32_t z;
+ int old;
+ int r;
+ const char* b;
+
+ r = -1;
+ while (isspace(*s))
+ s++;
+ b = s;
+ addr = 0;
+ bits = 0;
+ part = 0;
+ do
+ {
+ n = 0;
+ while ((c = *s++) >= '0' && c <= '9')
+ n = n * 10 + (c - '0');
+ if ((c == 'x' || c == 'X') && !part)
+ {
+ addr = n;
+ for (;;)
+ {
+ if ((c = *s++) >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'a' && c <= 'f')
+ c -= 'a' - 10;
+ else if (c >= 'A' && c <= 'F')
+ c -= 'F' - 10;
+ else
+ break;
+ addr = addr * 16 + c;
+ }
+ part = 4;
+ break;
+ }
+ if (n > 0xff)
+ goto done;
+ addr = (addr << 8) | n;
+ part++;
+ } while (c == '.');
+ if ((s - b) == 1 && c != '/' || part > 4)
+ goto done;
+ if (old = part < 4)
+ while (part++ < 4)
+ addr <<= 8;
+ if (pbits)
+ {
+ if (c == '/')
+ {
+ part = 0;
+ z = 0;
+ for (;;)
+ {
+ n = 0;
+ while ((c = *s++) >= '0' && c <= '9')
+ n = n * 10 + (c - '0');
+ z = (z << 8) | n;
+ part++;
+ if (c != '.')
+ break;
+ old = 1;
+ }
+ if (part > 4)
+ goto done;
+ if (z <= 32 && (!old || part < 2))
+ bits = z;
+ else if (z)
+ {
+ if (part == 4 && (z & 0x8000001) == 1)
+ z = ~z;
+ while (!(z & 1))
+ z >>= 1;
+ while (z & 1)
+ {
+ z >>= 1;
+ bits++;
+ }
+ }
+ }
+ else if ((z = (addr >> 24)) < 128)
+ bits = 8;
+ else if (z < 192)
+ bits = 16;
+ else
+ bits = 24;
+ if (*pbits = bits)
+ addr &= ~((((uint32_t)1)<<(32-bits))-1);
+ else
+ addr = 0;
+ }
+ if (paddr)
+ *paddr = addr;
+ r = 0;
+ done:
+ if (e)
+ *e = (char*)(s - 1);
+ return r;
+}
diff --git a/src/lib/libast/string/strtoip6.c b/src/lib/libast/string/strtoip6.c
new file mode 100644
index 0000000..ff1c652
--- /dev/null
+++ b/src/lib/libast/string/strtoip6.c
@@ -0,0 +1,204 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#if _PACKAGE_ast
+#include <ast.h>
+#else
+#include <stdint.h>
+#endif
+
+#include <ctype.h>
+#include <ip6.h>
+
+/*
+ * convert string to ipv6 network byte order ip address
+ * with optional prefix bits
+ * pointer to first unused char placed in *e, even on error
+ * return 0:ok <0:error
+ */
+
+#define COL 16
+#define DOT 17
+#define END 18
+#define PFX 19
+
+int
+strtoip6(register const char* s, char** e, unsigned char* addr, unsigned char* bits)
+{
+ register unsigned char* b = addr;
+ register unsigned char* x = b + IP6ADDR;
+ register unsigned char* z;
+ register int c;
+ register uint32_t a;
+
+ static unsigned char lex[256];
+
+ if (!lex[0])
+ {
+ for (c = 0; c < sizeof(lex); ++c)
+ lex[c] = END;
+ lex['0'] = 0;
+ lex['1'] = 1;
+ lex['2'] = 2;
+ lex['3'] = 3;
+ lex['4'] = 4;
+ lex['5'] = 5;
+ lex['6'] = 6;
+ lex['7'] = 7;
+ lex['8'] = 8;
+ lex['9'] = 9;
+ lex['A'] = lex['a'] = 10;
+ lex['B'] = lex['b'] = 11;
+ lex['C'] = lex['c'] = 12;
+ lex['D'] = lex['d'] = 13;
+ lex['E'] = lex['e'] = 14;
+ lex['F'] = lex['f'] = 15;
+ lex[':'] = COL;
+ lex['.'] = DOT;
+ lex['/'] = PFX;
+ }
+ while (isspace(*s))
+ s++;
+ z = 0;
+ a = 0;
+ if (*s)
+ for (;;)
+ {
+ switch (c = lex[*((unsigned char*)s++)])
+ {
+ case END:
+ case PFX:
+ if ((x - b) < 2)
+ break;
+ *b++ = a>>8;
+ *b++ = a;
+ break;
+ case COL:
+ if ((x - b) < 2)
+ break;
+ *b++ = a>>8;
+ *b++ = a;
+ a = 0;
+ if (*s == ':')
+ {
+ if (z)
+ {
+ s--;
+ break;
+ }
+ z = b;
+ if ((c = lex[*((unsigned char*)++s)]) >= 16)
+ {
+ s++;
+ break;
+ }
+ }
+ continue;
+ case DOT:
+ if (b >= x)
+ {
+ s--;
+ break;
+ }
+ *b++ = ((a >> 8) & 0xf) * 100 + ((a >> 4) & 0xf) * 10 + (a & 0xf);
+ a = 0;
+ for (;;)
+ {
+ switch (c = lex[*((unsigned char*)s++)])
+ {
+ case COL:
+ case END:
+ case PFX:
+ if (b < x)
+ *b++ = a;
+ a = 0;
+ break;
+ case DOT:
+ if (b >= x)
+ break;
+ *b++ = a;
+ a = 0;
+ continue;
+ default:
+ a = (a * 10) + c;
+ continue;
+ }
+ break;
+ }
+ if (c == COL)
+ {
+ if (*s == ':')
+ {
+ if (z)
+ {
+ s--;
+ break;
+ }
+ z = b;
+ if ((c = lex[*((unsigned char*)++s)]) >= 16)
+ {
+ s++;
+ break;
+ }
+ }
+ if ((b - addr) == 6 && addr[0] == 0x20 && addr[1] == 0x02)
+ continue;
+ }
+ break;
+ default:
+ a = (a << 4) | c;
+ continue;
+ }
+ break;
+ }
+ if (b == addr)
+ c = END + 1;
+ else
+ {
+ if (z)
+ {
+ while (b > z)
+ *--x = *--b;
+ while (x > z)
+ *--x = 0;
+ }
+ else
+ while (b < x)
+ *b++ = 0;
+ if (bits)
+ {
+ if (c == PFX)
+ {
+ a = 0;
+ while ((c = lex[*((unsigned char*)s++)]) < 10)
+ a = a * 10 + c;
+ }
+ else
+ a = 0xff;
+ *bits = a;
+ }
+ }
+ if (e)
+ *e = (char*)(s - 1);
+ return c == END ? 0 : -1;
+}
diff --git a/src/lib/libast/string/strton.c b/src/lib/libast/string/strton.c
new file mode 100644
index 0000000..05fbd86
--- /dev/null
+++ b/src/lib/libast/string/strton.c
@@ -0,0 +1,31 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strton() implementation
+ */
+
+#define S2I_function strton
+#define S2I_number long
+#define S2I_unumber unsigned long
+#define S2I_multiplier 1
+
+#include "strtoi.h"
diff --git a/src/lib/libast/string/strtonll.c b/src/lib/libast/string/strtonll.c
new file mode 100644
index 0000000..22084dc
--- /dev/null
+++ b/src/lib/libast/string/strtonll.c
@@ -0,0 +1,31 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+/*
+ * strtonll() implementation
+ */
+
+#define S2I_function strtonll
+#define S2I_number intmax_t
+#define S2I_unumber uintmax_t
+#define S2I_multiplier 1
+
+#include "strtoi.h"
diff --git a/src/lib/libast/string/struid.c b/src/lib/libast/string/struid.c
new file mode 100644
index 0000000..9a26e8f
--- /dev/null
+++ b/src/lib/libast/string/struid.c
@@ -0,0 +1,109 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * uid name -> number
+ */
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide getpwnam getpwuid
+#else
+#define getpwnam ______getpwnam
+#define getpwuid ______getpwuid
+#endif
+
+#include <ast.h>
+#include <cdt.h>
+#include <pwd.h>
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide getpwnam getpwuid
+#else
+#undef getpwnam
+#undef getpwuid
+#endif
+
+extern struct passwd* getpwnam(const char*);
+extern struct passwd* getpwuid(uid_t);
+
+typedef struct Id_s
+{
+ Dtlink_t link;
+ int id;
+ char name[1];
+} Id_t;
+
+/*
+ * return uid number given uid name
+ * -1 on first error for a given name
+ * -2 on subsequent errors for a given name
+ */
+
+int
+struid(const char* name)
+{
+ register Id_t* ip;
+ register struct passwd* pw;
+ int id;
+ char* e;
+
+ static Dt_t* dict;
+ static Dtdisc_t disc;
+
+ if (!dict)
+ {
+ disc.key = offsetof(Id_t, name);
+ dict = dtopen(&disc, Dtset);
+ }
+ else if (ip = (Id_t*)dtmatch(dict, name))
+ return ip->id;
+ if (pw = getpwnam(name))
+ id = pw->pw_uid;
+ else
+ {
+ id = strtol(name, &e, 0);
+#if _WINIX
+ if (!*e)
+ {
+ if (!getpwuid(id))
+ id = -1;
+ }
+ else if (streq(name, "root") && (pw = getpwnam("Administrator")))
+ id = pw->pw_uid;
+ else
+ id = -1;
+#else
+ if (*e || !getpwuid(id))
+ id = -1;
+#endif
+ }
+ if (dict && (ip = newof(0, Id_t, 1, strlen(name))))
+ {
+ strcpy(ip->name, name);
+ ip->id = id >= 0 ? id : -2;
+ dtinsert(dict, ip);
+ }
+ return id;
+}
diff --git a/src/lib/libast/string/struniq.c b/src/lib/libast/string/struniq.c
new file mode 100644
index 0000000..498fd4e
--- /dev/null
+++ b/src/lib/libast/string/struniq.c
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * struniq - uniq a sorted argv
+ * 0 sentinel is neither expected nor restored
+ *
+ * Glenn Fowler
+ * David Korn
+ * AT&T Research
+ */
+
+#include <ast.h>
+
+int
+struniq(char** argv, int n)
+{
+ register char** ao;
+ register char** an;
+ register char** ae;
+
+ ao = an = argv;
+ ae = ao + n;
+ while (++an < ae)
+ {
+ while (streq(*ao, *an))
+ if (++an >= ae)
+ return ao - argv + 1;
+ *++ao = *an;
+ }
+ return ao - argv + 1;
+}
diff --git a/src/lib/libast/string/strvcmp.c b/src/lib/libast/string/strvcmp.c
new file mode 100644
index 0000000..036460d
--- /dev/null
+++ b/src/lib/libast/string/strvcmp.c
@@ -0,0 +1,74 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <ast.h>
+#include <ctype.h>
+
+/*
+ * version strcmp(3)
+ */
+
+int
+strvcmp(register const char* a, register const char* b)
+{
+ register unsigned long na;
+ register unsigned long nb;
+
+ for (;;)
+ {
+ if (isdigit(*a) && isdigit(*b))
+ {
+ na = nb = 0;
+ while (isdigit(*a))
+ na = na * 10 + *a++ - '0';
+ while (isdigit(*b))
+ nb = nb * 10 + *b++ - '0';
+ if (na < nb)
+ return -1;
+ if (na > nb)
+ return 1;
+ }
+ else if (*a != *b)
+ break;
+ else if (!*a)
+ return 0;
+ else
+ {
+ a++;
+ b++;
+ }
+ }
+ if (*a == 0)
+ return -1;
+ if (*b == 0)
+ return 1;
+ if (*a == '.')
+ return -1;
+ if (*b == '.')
+ return 1;
+ if (*a == '-')
+ return -1;
+ if (*b == '-')
+ return 1;
+ return *a < *b ? -1 : 1;
+}
diff --git a/src/lib/libast/string/swapget.c b/src/lib/libast/string/swapget.c
new file mode 100644
index 0000000..b032bfc
--- /dev/null
+++ b/src/lib/libast/string/swapget.c
@@ -0,0 +1,57 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * internal representation conversion support
+ */
+
+#include <ast.h>
+#include <swap.h>
+
+/*
+ * get int_n from b according to op
+ */
+
+intmax_t
+swapget(int op, const void* b, int n)
+{
+ register unsigned char* p;
+ register unsigned char* d;
+ intmax_t v;
+ unsigned char tmp[sizeof(intmax_t)];
+
+ if (n > sizeof(intmax_t))
+ n = sizeof(intmax_t);
+ if (op) swapmem(op, b, d = tmp, n);
+ else d = (unsigned char*)b;
+ p = d + n;
+ v = 0;
+ while (d < p)
+ {
+ v <<= CHAR_BIT;
+ v |= *d++;
+ }
+ return v;
+}
diff --git a/src/lib/libast/string/swapmem.c b/src/lib/libast/string/swapmem.c
new file mode 100644
index 0000000..7a96bf0
--- /dev/null
+++ b/src/lib/libast/string/swapmem.c
@@ -0,0 +1,109 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * internal representation conversion support
+ */
+
+#include <ast.h>
+#include <swap.h>
+
+/*
+ * swap n bytes according to op
+ * from==to is ok
+ */
+
+void*
+swapmem(int op, const void* from, void* to, register size_t n)
+{
+ register char* f = (char*)from;
+ register char* t = (char*)to;
+ register int c;
+
+ switch (op & (n - 1))
+ {
+ case 0:
+ if (t != f)
+ memcpy(t, f, n);
+ break;
+ case 1:
+ for (n >>= 1; n--; f += 2, t += 2)
+ {
+ c = f[0]; t[0] = f[1]; t[1] = c;
+ }
+ break;
+ case 2:
+ for (n >>= 2; n--; f += 4, t += 4)
+ {
+ c = f[0]; t[0] = f[2]; t[2] = c;
+ c = f[1]; t[1] = f[3]; t[3] = c;
+ }
+ break;
+ case 3:
+ for (n >>= 2; n--; f += 4, t += 4)
+ {
+ c = f[0]; t[0] = f[3]; t[3] = c;
+ c = f[1]; t[1] = f[2]; t[2] = c;
+ }
+ break;
+ case 4:
+ for (n >>= 3; n--; f += 8, t += 8)
+ {
+ c = f[0]; t[0] = f[4]; t[4] = c;
+ c = f[1]; t[1] = f[5]; t[5] = c;
+ c = f[2]; t[2] = f[6]; t[6] = c;
+ c = f[3]; t[3] = f[7]; t[7] = c;
+ }
+ break;
+ case 5:
+ for (n >>= 3; n--; f += 8, t += 8)
+ {
+ c = f[0]; t[0] = f[5]; t[5] = c;
+ c = f[1]; t[1] = f[4]; t[4] = c;
+ c = f[2]; t[2] = f[7]; t[7] = c;
+ c = f[3]; t[3] = f[6]; t[6] = c;
+ }
+ break;
+ case 6:
+ for (n >>= 3; n--; f += 8, t += 8)
+ {
+ c = f[0]; t[0] = f[6]; t[6] = c;
+ c = f[1]; t[1] = f[7]; t[7] = c;
+ c = f[2]; t[2] = f[4]; t[4] = c;
+ c = f[3]; t[3] = f[5]; t[5] = c;
+ }
+ break;
+ case 7:
+ for (n >>= 3; n--; f += 8, t += 8)
+ {
+ c = f[0]; t[0] = f[7]; t[7] = c;
+ c = f[1]; t[1] = f[6]; t[6] = c;
+ c = f[2]; t[2] = f[5]; t[5] = c;
+ c = f[3]; t[3] = f[4]; t[4] = c;
+ }
+ break;
+ }
+ return to;
+}
diff --git a/src/lib/libast/string/swapop.c b/src/lib/libast/string/swapop.c
new file mode 100644
index 0000000..aefe687
--- /dev/null
+++ b/src/lib/libast/string/swapop.c
@@ -0,0 +1,59 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * internal representation conversion support
+ */
+
+#include <ast.h>
+#include <swap.h>
+
+/*
+ * return the swap operation for external to internal conversion
+ * if size<0 then (-size) used and (-size==4)&&(op==3) => op=7
+ * this is a workaround for 4 byte magic predicting 8 byte swap
+ */
+
+int
+swapop(const void* internal, const void* external, int size)
+{
+ register int op;
+ register int z;
+ char tmp[sizeof(intmax_t)];
+
+ if ((z = size) < 0)
+ z = -z;
+ if (z <= 1)
+ return 0;
+ if (z <= sizeof(intmax_t))
+ for (op = 0; op < z; op++)
+ if (!memcmp(internal, swapmem(op, external, tmp, z), z))
+ {
+ if (size < 0 && z == 4 && op == 3)
+ op = 7;
+ return op;
+ }
+ return -1;
+}
diff --git a/src/lib/libast/string/swapput.c b/src/lib/libast/string/swapput.c
new file mode 100644
index 0000000..66373ae
--- /dev/null
+++ b/src/lib/libast/string/swapput.c
@@ -0,0 +1,50 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * internal representation conversion support
+ */
+
+#include <ast.h>
+#include <swap.h>
+
+/*
+ * put v of n chars into b according to op
+ */
+
+void*
+swapput(int op, void* b, int n, intmax_t v)
+{
+ register char* p = (char*)b + n;
+
+ while (p > (char*)b)
+ {
+ *--p = v;
+ v >>= CHAR_BIT;
+ }
+ if (op)
+ swapmem(op, p, p, n);
+ return b;
+}
diff --git a/src/lib/libast/string/tok.c b/src/lib/libast/string/tok.c
new file mode 100644
index 0000000..c781fb7
--- /dev/null
+++ b/src/lib/libast/string/tok.c
@@ -0,0 +1,190 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * token stream routines
+ */
+
+#include <ast.h>
+#include <tok.h>
+
+#define FLG_RESTORE 01 /* restore string on close */
+#define FLG_NEWLINE 02 /* return newline token next */
+
+typedef struct Tok_s /* token stream state */
+{
+ union
+ {
+ char* end; /* end ('\0') of last token */
+ struct Tok_s* nxt; /* next in free list */
+ } ptr;
+ char chr; /* replace *end with this */
+ char flg; /* FLG_* */
+} Tok_t;
+
+static Tok_t* freelist;
+
+/*
+ * open a new token stream on s
+ * if f==0 then string is not restored
+ */
+
+char*
+tokopen(register char* s, int f)
+{
+ register Tok_t* p;
+
+ if (p = freelist)
+ freelist = freelist->ptr.nxt;
+ else if (!(p = newof(0, Tok_t, 1, 0)))
+ return 0;
+ p->chr = *(p->ptr.end = s);
+ p->flg = f ? FLG_RESTORE : 0;
+ return (char*)p;
+}
+
+/*
+ * close a token stream
+ * restore the string to its original state
+ */
+
+void
+tokclose(char* u)
+{
+ register Tok_t* p = (Tok_t*)u;
+
+ if (p->flg == FLG_RESTORE && *p->ptr.end != p->chr)
+ *p->ptr.end = p->chr;
+ p->ptr.nxt = freelist;
+ freelist = p;
+}
+
+/*
+ * return next space separated token
+ * "\n" is returned as a token
+ * 0 returned when no tokens remain
+ * "..." and '...' quotes are honored with \ escapes
+ */
+
+char*
+tokread(char* u)
+{
+ register Tok_t* p = (Tok_t*)u;
+ register char* s;
+ register char* r;
+ register int q;
+ register int c;
+
+ /*
+ * restore string on each call
+ */
+
+ if (!p->chr)
+ return 0;
+ s = p->ptr.end;
+ switch (p->flg)
+ {
+ case FLG_NEWLINE:
+ p->flg = 0;
+ return "\n";
+ case FLG_RESTORE:
+ if (*s != p->chr)
+ *s = p->chr;
+ break;
+ default:
+ if (!*s)
+ s++;
+ break;
+ }
+
+ /*
+ * skip leading space
+ */
+
+ while (*s == ' ' || *s == '\t')
+ s++;
+ if (!*s)
+ {
+ p->ptr.end = s;
+ p->chr = 0;
+ return 0;
+ }
+
+ /*
+ * find the end of this token
+ */
+
+ r = s;
+ q = 0;
+ for (;;)
+ switch (c = *r++)
+ {
+ case '\n':
+ if (!q)
+ {
+ if (s == (r - 1))
+ {
+ if (!p->flg)
+ {
+ p->ptr.end = r;
+ return "\n";
+ }
+ r++;
+ }
+ else if (!p->flg)
+ p->flg = FLG_NEWLINE;
+ }
+ /*FALLTHROUGH*/
+ case ' ':
+ case '\t':
+ if (q)
+ break;
+ /*FALLTHROUGH*/
+ case 0:
+ if (s == --r)
+ {
+ p->ptr.end = r;
+ p->chr = 0;
+ }
+ else
+ {
+ p->chr = *(p->ptr.end = r);
+ if (*r)
+ *r = 0;
+ }
+ return s;
+ case '\\':
+ if (*r)
+ r++;
+ break;
+ case '"':
+ case '\'':
+ if (c == q)
+ q = 0;
+ else if (!q)
+ q = c;
+ break;
+ }
+}
diff --git a/src/lib/libast/string/tokline.c b/src/lib/libast/string/tokline.c
new file mode 100644
index 0000000..b572651
--- /dev/null
+++ b/src/lib/libast/string/tokline.c
@@ -0,0 +1,193 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * return an Sfio_t* to a file or string that
+ *
+ * splices \\n to single lines
+ * checks for "..." and '...' spanning newlines
+ * drops #...\n comments
+ *
+ * if <arg> is a file and first line matches
+ * #!!! <level> <message> !!!
+ * then error(<lev>,"%s: %s",<arg>,<msg>) called
+ *
+ * NOTE: seek disabled and string disciplines cannot be composed
+ * quoted \n translated to \r
+ */
+
+#include <ast.h>
+#include <error.h>
+#include <tok.h>
+
+typedef struct
+{
+ Sfdisc_t disc;
+ Sfio_t* sp;
+ int quote;
+ int* line;
+} Splice_t;
+
+/*
+ * the splicer
+ */
+
+static int
+spliceline(Sfio_t* s, int op, void* val, Sfdisc_t* ad)
+{
+ Splice_t* d = (Splice_t*)ad;
+ register char* b;
+ register int c;
+ register int n;
+ register int q;
+ register int j;
+ register char* e;
+ char* buf;
+
+ NoP(val);
+ switch (op)
+ {
+ case SF_CLOSING:
+ sfclose(d->sp);
+ return 0;
+ case SF_DPOP:
+ free(d);
+ return 0;
+ case SF_READ:
+ do
+ {
+ if (!(buf = sfgetr(d->sp, '\n', 0)) && !(buf = sfgetr(d->sp, '\n', -1)))
+ return 0;
+ n = sfvalue(d->sp);
+ q = d->quote;
+ j = 0;
+ (*d->line)++;
+ if (n > 1 && buf[n - 2] == '\\')
+ {
+ j = 1;
+ n -= 2;
+ if (q == '#')
+ {
+ n = 0;
+ continue;
+ }
+ }
+ else if (q == '#')
+ {
+ q = 0;
+ n = 0;
+ continue;
+ }
+ if (n > 0)
+ {
+ e = (b = buf) + n;
+ while (b < e)
+ {
+ if ((c = *b++) == '\\')
+ b++;
+ else if (c == q)
+ q = 0;
+ else if (!q)
+ {
+ if (c == '\'' || c == '"')
+ q = c;
+ else if (c == '#' && (b == (buf + 1) || (c = *(b - 2)) == ' ' || c == '\t'))
+ {
+ if (buf[n - 1] != '\n')
+ {
+ q = '#';
+ n = b - buf - 2;
+ }
+ else if (n = b - buf - 1)
+ buf[n - 1] = '\n';
+ break;
+ }
+ }
+ }
+ if (n > 0)
+ {
+ if (!j && buf[n - 1] != '\n' && (s->_flags & SF_STRING))
+ buf[n++] = '\n';
+ if (q && buf[n - 1] == '\n')
+ buf[n - 1] = '\r';
+ }
+ }
+ } while (n <= 0);
+ sfsetbuf(s, buf, n);
+ d->quote = q;
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/*
+ * open a stream to parse lines
+ *
+ * flags: 0 arg: open Sfio_t*
+ * flags: SF_READ arg: file name
+ * flags: SF_STRING arg: null terminated char*
+ *
+ * if line!=0 then it points to a line count that starts at 0
+ * and is incremented for each input line
+ */
+
+Sfio_t*
+tokline(const char* arg, int flags, int* line)
+{
+ Sfio_t* f;
+ Sfio_t* s;
+ Splice_t* d;
+ char* p;
+ char* e;
+
+ static int hidden;
+
+ if (!(d = newof(0, Splice_t, 1, 0)))
+ return 0;
+ if (!(s = sfopen(NiL, NiL, "s")))
+ {
+ free(d);
+ return 0;
+ }
+ if (!(flags & (SF_STRING|SF_READ)))
+ f = (Sfio_t*)arg;
+ else if (!(f = sfopen(NiL, arg, (flags & SF_STRING) ? "s" : "r")))
+ {
+ free(d);
+ sfclose(s);
+ return 0;
+ }
+ else if ((p = sfreserve(f, 0, 0)) && sfvalue(f) > 11 && strmatch(p, "#!!! +([-0-9]) *([!\n]) !!!\n*") && (e = strchr(p, '\n')))
+ {
+ flags = strtol(p + 5, &p, 10);
+ error(flags, "%s:%-.*s", arg, e - p - 4, p);
+ }
+ d->disc.exceptf = spliceline;
+ d->sp = f;
+ *(d->line = line ? line : &hidden) = 0;
+ sfdisc(s, (Sfdisc_t*)d);
+ return s;
+}
diff --git a/src/lib/libast/string/tokscan.c b/src/lib/libast/string/tokscan.c
new file mode 100644
index 0000000..34f6dfc
--- /dev/null
+++ b/src/lib/libast/string/tokscan.c
@@ -0,0 +1,360 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * scan s for tokens in fmt
+ * s modified in place and not restored
+ * if nxt!=0 then it will point to the first unread char in s
+ * the number of scanned tokens is returned
+ * -1 returned if s was not empty and fmt failed to match
+ *
+ * ' ' in fmt matches 0 or more {space,tab}
+ * '\n' in fmt eats remainder of current line
+ * "..." and '...' quotes interpreted
+ * newline is equivalent to end of buf except when quoted
+ * \\ quotes following char
+ *
+ * message support for %s and %v data
+ *
+ * (5:12345) fixed length strings, ) may be \t
+ * (null) NiL
+ *
+ * "..." and '...' may span \n, and \\n is the line splice
+ * quoted '\r' translated to '\n'
+ * otherwise tokenizing is unconditionally terminated by '\n'
+ *
+ * a null arg pointer skips that arg
+ *
+ * %c char
+ * %[hl]d [short|int|long] base 10
+ * %f double
+ * %g double
+ * %[hl]n [short|int|long] C-style base
+ * %[hl]o [short|int|long] base 8
+ * %s string
+ * %[hl]u same as %[hl]n
+ * %v argv, elements
+ * %[hl]x [short|int|long] base 16
+ *
+ * unmatched char args are set to "", int args to 0
+ */
+
+#include <ast.h>
+#include <tok.h>
+
+static char empty[1];
+
+/*
+ * get one string token into p
+ */
+
+static char*
+lextok(register char* s, register int c, char** p, int* n)
+{
+ register char* t;
+ register int q;
+ char* b;
+ char* u;
+
+ if (*s == '(' && (!c || c == ' ' || c == '\n'))
+ {
+ q = strtol(s + 1, &b, 10);
+ if (*b == ':')
+ {
+ if (*(t = ++b + q) == ')' || *t == '\t')
+ {
+ s = t;
+ *s++ = 0;
+ goto end;
+ }
+ }
+ else if (strneq(b, "null)", 5))
+ {
+ s = b + 5;
+ b = 0;
+ goto end;
+ }
+ }
+ b = s;
+ q = 0;
+ t = 0;
+ for (;;)
+ {
+ if (!*s || !q && *s == '\n')
+ {
+ if (!q)
+ {
+ if (!c || c == ' ' || c == '\n') (*n)++;
+ else
+ {
+ s = b;
+ b = empty;
+ break;
+ }
+ }
+ if (t) *t = 0;
+ break;
+ }
+ else if (*s == '\\')
+ {
+ u = s;
+ if (!*++s || *s == '\n' && (!*++s || *s == '\n')) continue;
+ if (p)
+ {
+ if (b == u) b = s;
+ else if (!t) t = u;
+ }
+ }
+ else if (q)
+ {
+ if (*s == q)
+ {
+ q = 0;
+ if (!t) t = s;
+ s++;
+ continue;
+ }
+ else if (*s == '\r') *s = '\n';
+ }
+ else if (*s == '"' || *s == '\'')
+ {
+ q = *s++;
+ if (p)
+ {
+ if (b == (s - 1)) b = s;
+ else if (!t) t = s - 1;
+ }
+ continue;
+ }
+ else if (*s == c || c == ' ' && *s == '\t')
+ {
+ *s++ = 0;
+ if (t) *t = 0;
+ end:
+ if (c == ' ') while (*s == ' ' || *s == '\t') s++;
+ (*n)++;
+ break;
+ }
+ if (t) *t++ = *s;
+ s++;
+ }
+ if (p) *p = b;
+ return(s);
+}
+
+/*
+ * scan entry
+ */
+
+int
+tokscan(register char* s, char** nxt, const char* fmt, ...)
+{
+ register int c;
+ register char* f;
+ int num = 0;
+ char* skip = 0;
+ int q;
+ int onum;
+ long val;
+ double dval;
+ va_list ap;
+ char* p_char;
+ double* p_double;
+ int* p_int;
+ long* p_long;
+ short* p_short;
+ char** p_string;
+ char* prv_f = 0;
+ va_list prv_ap;
+
+ va_start(ap, fmt);
+ if (!*s || *s == '\n')
+ {
+ skip = s;
+ s = empty;
+ }
+ f = (char*)fmt;
+ for (;;) switch (c = *f++)
+ {
+ case 0:
+ if (f = prv_f)
+ {
+ prv_f = 0;
+ /* prv_ap value is guarded by prv_f */
+ va_copy(ap, prv_ap);
+ continue;
+ }
+ goto done;
+ case ' ':
+ while (*s == ' ' || *s == '\t') s++;
+ break;
+ case '%':
+ onum = num;
+ switch (c = *f++)
+ {
+ case 'h':
+ case 'l':
+ q = c;
+ c = *f++;
+ break;
+ default:
+ q = 0;
+ break;
+ }
+ switch (c)
+ {
+ case 0:
+ case '%':
+ f--;
+ continue;
+ case ':':
+ prv_f = f;
+ f = va_arg(ap, char*);
+ va_copy(prv_ap, ap);
+ va_copy(ap, va_listval(va_arg(ap, va_listarg)));
+ continue;
+ case 'c':
+ p_char = va_arg(ap, char*);
+ if (!(c = *s) || c == '\n')
+ {
+ if (p_char) *p_char = 0;
+ }
+ else
+ {
+ if (p_char) *p_char = c;
+ s++;
+ num++;
+ }
+ break;
+ case 'd':
+ case 'n':
+ case 'o':
+ case 'u':
+ case 'x':
+ switch (c)
+ {
+ case 'd':
+ c = 10;
+ break;
+ case 'n':
+ case 'u':
+ c = 0;
+ break;
+ case 'o':
+ c = 8;
+ break;
+ case 'x':
+ c = 16;
+ break;
+ }
+ if (!*s || *s == '\n')
+ {
+ val = 0;
+ p_char = s;
+ }
+ else val = strtol(s, &p_char, c);
+ switch (q)
+ {
+ case 'h':
+ if (p_short = va_arg(ap, short*)) *p_short = (short)val;
+ break;
+ case 'l':
+ if (p_long = va_arg(ap, long*)) *p_long = val;
+ break;
+ default:
+ if (p_int = va_arg(ap, int*)) *p_int = (int)val;
+ break;
+ }
+ if (s != p_char)
+ {
+ s = p_char;
+ num++;
+ }
+ break;
+ case 'f':
+ case 'g':
+ if (!*s || *s == '\n')
+ {
+ dval = 0;
+ p_char = s;
+ }
+ else dval = strtod(s, &p_char);
+ if (p_double = va_arg(ap, double*)) *p_double = dval;
+ if (s != p_char)
+ {
+ s = p_char;
+ num++;
+ }
+ break;
+ case 's':
+ p_string = va_arg(ap, char**);
+ if (q = *f) f++;
+ if (!*s || *s == '\n')
+ {
+ if (p_string) *p_string = s;
+ }
+ else s = lextok(s, q, p_string, &num);
+ break;
+ case 'v':
+ p_string = va_arg(ap, char**);
+ c = va_arg(ap, int);
+ if (q = *f) f++;
+ if ((!*s || *s == '\n') && p_string)
+ {
+ *p_string = 0;
+ p_string = 0;
+ }
+ while (*s && *s != '\n' && --c > 0)
+ {
+ s = lextok(s, q, p_string, &num);
+ if (p_string) p_string++;
+ }
+ if (p_string) *p_string = 0;
+ break;
+ }
+ if (skip) num = onum;
+ else if (num == onum)
+ {
+ if (!num) num = -1;
+ skip = s;
+ s = empty;
+ }
+ break;
+ case '\n':
+ goto done;
+ default:
+ if ((*s++ != c) && !skip)
+ {
+ skip = s - 1;
+ s = empty;
+ }
+ break;
+ }
+ done:
+ va_end(ap);
+ if (*s == '\n') *s++ = 0;
+ if (nxt) *nxt = skip ? skip : s;
+ return(num);
+}
diff --git a/src/lib/libast/string/wc2utf8.c b/src/lib/libast/string/wc2utf8.c
new file mode 100644
index 0000000..3b70391
--- /dev/null
+++ b/src/lib/libast/string/wc2utf8.c
@@ -0,0 +1,74 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * convert wide character to utf8 in s
+ * s must have room for at least 6 bytes
+ * number of chars in placed in s returned
+ * thanks Tom Duff
+ */
+
+#include <ast.h>
+
+typedef struct Utf8_s
+{
+ uint32_t range;
+ unsigned short prefix;
+ unsigned short shift;
+} Utf8_t;
+
+static const Utf8_t ops[] =
+{
+ { 0x00000080, 0x00, 0 },
+ { 0x00000800, 0xc0, 6 },
+ { 0x00010000, 0xe0, 12 },
+ { 0x00200000, 0xf0, 18 },
+ { 0x04000000, 0xf8, 24 },
+ { 0x80000000, 0xfc, 30 }
+};
+
+int
+wc2utf8(register char* s, register uint32_t w)
+{
+ register int i;
+ char* b;
+
+ for (i = 0; i < elementsof(ops); i++)
+ if (w < ops[i].range)
+ {
+ b = s;
+ *s++ = ops[i].prefix | (w >> ops[i].shift);
+ switch (ops[i].shift)
+ {
+ case 30: *s++ = 0x80 | ((w >> 24) & 0x3f);
+ case 24: *s++ = 0x80 | ((w >> 18) & 0x3f);
+ case 18: *s++ = 0x80 | ((w >> 12) & 0x3f);
+ case 12: *s++ = 0x80 | ((w >> 6) & 0x3f);
+ case 6: *s++ = 0x80 | (w & 0x3f);
+ }
+ return s - b;
+ }
+ return 0;
+}
diff --git a/src/lib/libast/tm/tmdata.c b/src/lib/libast/tm/tmdata.c
new file mode 100644
index 0000000..1cdaf24
--- /dev/null
+++ b/src/lib/libast/tm/tmdata.c
@@ -0,0 +1,288 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * time conversion support readonly data
+ */
+
+#include <ast.h>
+#include <tm.h>
+
+/*
+ * default format strings -- must agree with TM_* indices
+ */
+
+static char* format[] =
+{
+ "Jan", "Feb", "Mar", "Apr",
+ "May", "Jun", "Jul", "Aug",
+ "Sep", "Oct", "Nov", "Dec",
+
+ "January", "February", "March", "April",
+ "May", "June", "July", "August",
+ "September", "October", "November", "December",
+
+ "Sun", "Mon", "Tue", "Wed",
+ "Thu", "Fri", "Sat",
+
+ "Sunday", "Monday", "Tuesday", "Wednesday",
+ "Thursday", "Friday", "Saturday",
+
+ "%H:%M:%S", "%m/%d/%y", "%a %b %e %T %Z %Y",
+
+ "AM", "PM",
+
+ "GMT", "UTC", "UCT", "CUT",
+
+ "DST", "", "", "",
+
+ "s", "es", "", "",
+
+ "second", "minute", "hour", "day",
+ "week", "month", "year",
+
+ "midnight", "morning", "noon", "evening",
+
+ "yesterday", "today", "tomorrow",
+
+ "last", "ago", "past",
+ "this", "now", "current",
+ "in", "next", "hence",
+ "exactly", "", "",
+
+ "at", "on", "", "",
+
+ "st", "nd", "rd", "th", "th",
+ "th", "th", "th", "th", "th",
+
+ "", "", "", "", "",
+ "", "", "", "", "",
+
+ "%a %b %e %T %Y",
+ "%a %b %e %T %Z %Y",
+ "%a %b %e %T %z %Z %Y",
+ "%b %e %H:%M",
+ "%b %e %Y",
+ "%I:%M:%S %p",
+
+ "", "", "", "", "",
+
+ "first", "", "third", "fourth", "fifth",
+ "sixth", "seventh", "eighth", "ninth", "tenth",
+
+ "final", "ending", "nth",
+
+ "work", "working", "workday",
+};
+
+/*
+ * format[] lex type classes
+ */
+
+static unsigned char lex[] =
+{
+ TM_MONTH_ABBREV,TM_MONTH_ABBREV,TM_MONTH_ABBREV,TM_MONTH_ABBREV,
+ TM_MONTH_ABBREV,TM_MONTH_ABBREV,TM_MONTH_ABBREV,TM_MONTH_ABBREV,
+ TM_MONTH_ABBREV,TM_MONTH_ABBREV,TM_MONTH_ABBREV,TM_MONTH_ABBREV,
+
+ TM_MONTH, TM_MONTH, TM_MONTH, TM_MONTH,
+ TM_MONTH, TM_MONTH, TM_MONTH, TM_MONTH,
+ TM_MONTH, TM_MONTH, TM_MONTH, TM_MONTH,
+
+ TM_DAY_ABBREV, TM_DAY_ABBREV, TM_DAY_ABBREV, TM_DAY_ABBREV,
+ TM_DAY_ABBREV, TM_DAY_ABBREV, TM_DAY_ABBREV,
+
+ TM_DAY, TM_DAY, TM_DAY, TM_DAY,
+ TM_DAY, TM_DAY, TM_DAY,
+
+ 0, 0, 0,
+
+ TM_MERIDIAN, TM_MERIDIAN,
+
+ TM_UT, TM_UT, TM_UT, TM_UT,
+ TM_DT, TM_DT, TM_DT, TM_DT,
+
+ TM_SUFFIXES, TM_SUFFIXES, TM_SUFFIXES, TM_SUFFIXES,
+
+ TM_PARTS, TM_PARTS, TM_PARTS, TM_PARTS,
+ TM_PARTS, TM_PARTS, TM_PARTS,
+
+ TM_HOURS, TM_HOURS, TM_HOURS, TM_HOURS,
+
+ TM_DAYS, TM_DAYS, TM_DAYS,
+
+ TM_LAST, TM_LAST, TM_LAST,
+ TM_THIS, TM_THIS, TM_THIS,
+ TM_NEXT, TM_NEXT, TM_NEXT,
+ TM_EXACT, TM_EXACT, TM_EXACT,
+
+ TM_NOISE, TM_NOISE, TM_NOISE, TM_NOISE,
+
+ TM_ORDINAL, TM_ORDINAL, TM_ORDINAL, TM_ORDINAL, TM_ORDINAL,
+ TM_ORDINAL, TM_ORDINAL, TM_ORDINAL, TM_ORDINAL, TM_ORDINAL,
+
+ 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+
+ 0, 0, 0,
+ 0, 0, 0,
+
+ 0, 0, 0, 0, 0,
+
+ TM_ORDINALS, TM_ORDINALS, TM_ORDINALS, TM_ORDINALS, TM_ORDINALS,
+ TM_ORDINALS, TM_ORDINALS, TM_ORDINALS, TM_ORDINALS, TM_ORDINALS,
+
+ TM_FINAL, TM_FINAL, TM_FINAL,
+
+ TM_WORK, TM_WORK, TM_WORK,
+};
+
+/*
+ * output format digits
+ */
+
+static char digit[] = "0123456789";
+
+/*
+ * number of days in month i
+ */
+
+static short days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+/*
+ * sum of days in months before month i
+ */
+
+static short sum[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
+
+/*
+ * leap second time_t and accumulated adjustments
+ * (reverse order -- biased for recent dates)
+ *
+ * tl.time is the seconds since the epoch for the leap event
+ *
+ * adding: the first additional second
+ * subtracting: the first dissappearing second
+ */
+
+static Tm_leap_t leap[] =
+{
+ 1230768023, 24, /* 2008-12-31+23:59:60-0000 */
+ 1136073622, 23, /* 2005-12-31+23:59:60-0000 */
+ 915148821, 22, /* 1998-12-31+23:59:60-0000 */
+ 867715220, 21, /* 1997-06-30+23:59:60-0000 */
+ 820454419, 20, /* 1995-12-31+23:59:60-0000 */
+ 773020818, 19, /* 1994-06-30+23:59:60-0000 */
+ 741484817, 18, /* 1993-06-30+23:59:60-0000 */
+ 709948816, 17, /* 1992-06-30+23:59:60-0000 */
+ 662688015, 16, /* 1990-12-31+23:59:60-0000 */
+ 631152014, 15, /* 1989-12-31+23:59:60-0000 */
+ 567993613, 14, /* 1987-12-31+23:59:60-0000 */
+ 489024012, 13, /* 1985-06-30+23:59:60-0000 */
+ 425865611, 12, /* 1983-06-30+23:59:60-0000 */
+ 394329610, 11, /* 1982-06-30+23:59:60-0000 */
+ 362793609, 10, /* 1981-06-30+23:59:60-0000 */
+ 315532808, 9, /* 1979-12-31+23:59:60-0000 */
+ 283996807, 8, /* 1978-12-31+23:59:60-0000 */
+ 252460806, 7, /* 1977-12-31+23:59:60-0000 */
+ 220924805, 6, /* 1976-12-31+23:59:60-0000 */
+ 189302404, 5, /* 1975-12-31+23:59:60-0000 */
+ 157766403, 4, /* 1974-12-31+23:59:60-0000 */
+ 126230402, 3, /* 1973-12-31+23:59:60-0000 */
+ 94694401, 2, /* 1972-12-31+23:59:60-0000 */
+ 78796800, 1, /* 1972-06-30+23:59:60-0000 */
+ 0, 0, /* can reference (tl+1) */
+ 0, 0
+};
+
+/*
+ * time zones
+ *
+ * the UTC entries must be first
+ *
+ * zones with the same type are contiguous with all but the
+ * first entry for the type having a null type
+ *
+ * tz.standard is the sentinel
+ */
+
+static Tm_zone_t zone[] =
+{
+ 0, "GMT", 0, ( 0 * 60), 0, /* UTC */
+ 0, "UCT", 0, ( 0 * 60), 0, /* UTC */
+ 0, "UTC", 0, ( 0 * 60), 0, /* UTC */
+ 0, "CUT", 0, ( 0 * 60), 0, /* UTC */
+ 0, "Z", 0, ( 0 * 60), 0, /* UTC */
+ "USA", "HST", 0, (10 * 60), 0, /* Hawaii */
+ 0, "YST", "YDT", ( 9 * 60), TM_DST, /* Yukon */
+ 0, "PST", "PDT", ( 8 * 60), TM_DST, /* Pacific */
+ 0, "PST", "PPET", ( 8 * 60), TM_DST, /* Pacific pres elect */
+ 0, "MST", "MDT", ( 7 * 60), TM_DST, /* Mountain */
+ 0, "CST", "CDT", ( 6 * 60), TM_DST, /* Central */
+ 0, "EST", "EDT", ( 5 * 60), TM_DST, /* Eastern */
+ "CAN", "AST", "ADT", ( 4 * 60), TM_DST, /* Atlantic */
+ 0, "NST", 0, ( 3 * 60 + 30), 0, /* Newfoundland */
+ "GBR", "", "BST", ( 0 * 60), TM_DST, /* British Summer */
+ "EUR", "WET", "WEST", ( 0 * 60), TM_DST, /* Western Eurpoean */
+ 0, "CET", "CEST", -( 1 * 60), TM_DST, /* Central European */
+ 0, "MET", "MEST", -( 1 * 60), TM_DST, /* Middle European */
+ 0, "EET", "EEST", -( 2 * 60), TM_DST, /* Eastern Eurpoean */
+ "ISR", "IST", "IDT", -( 3 * 60), TM_DST, /* Israel */
+ "IND", "IST", 0, -( 5 * 60 + 30 ), 0, /* India */
+ "CHN", "HKT", 0, -( 8 * 60), 0, /* Hong Kong */
+ "KOR", "KST", "KDT", -( 8 * 60), TM_DST, /* Korea */
+ "SNG", "SST", 0, -( 8 * 60), 0, /* Singapore */
+ "JPN", "JST", 0, -( 9 * 60), 0, /* Japan */
+ "AUS", "AWST", 0, -( 8 * 60), 0, /* Australia Western */
+ 0, "WST", 0, -( 8 * 60), 0, /* Australia Western */
+ 0, "ACST", 0, -( 9 * 60 + 30),TM_DST, /* Australia Central */
+ 0, "CST", 0, -( 9 * 60 + 30),TM_DST, /* Australia Central */
+ 0, "AEST", 0, -(10 * 60), TM_DST, /* Australia Eastern */
+ 0, "EST", 0, -(10 * 60), TM_DST, /* Australia Eastern */
+ "NZL", "NZST", "NZDT", -(12 * 60), TM_DST, /* New Zealand */
+ 0, 0, 0, 0, 0
+};
+
+/*
+ * 2007-03-19 move tm_data from _tm_data_ to (*_tm_datap_)
+ * to allow future Tm_data_t growth
+ * by 2009 _tm_data_ can be static
+ */
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+
+extern Tm_data_t _tm_data_;
+
+#undef extern
+
+Tm_data_t _tm_data_ = { format, lex, digit, days, sum, leap, zone };
+
+__EXTERN__(Tm_data_t, _tm_data_);
+
+__EXTERN__(Tm_data_t*, _tm_datap_);
+
+Tm_data_t* _tm_datap_ = &_tm_data_;
diff --git a/src/lib/libast/tm/tmdate.c b/src/lib/libast/tm/tmdate.c
new file mode 100644
index 0000000..e7ffb79
--- /dev/null
+++ b/src/lib/libast/tm/tmdate.c
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * time conversion support
+ */
+
+#include <tmx.h>
+
+/*
+ * parse date expression in s and return time_t value
+ * see tmxdate() for details
+ */
+
+time_t
+tmdate(const char* s, char** e, time_t* clock)
+{
+ return tmxsec(tmxdate(s, e, tmxclock(clock)));
+}
diff --git a/src/lib/libast/tm/tmequiv.c b/src/lib/libast/tm/tmequiv.c
new file mode 100644
index 0000000..4ab07c9
--- /dev/null
+++ b/src/lib/libast/tm/tmequiv.c
@@ -0,0 +1,57 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * time_t conversion support
+ */
+
+#include <tm.h>
+
+/*
+ * use one of the 14 equivalent calendar years to determine
+ * daylight savings time for future years beyond the range
+ * of the local system (via tmxtm())
+ */
+
+static const short equiv[] =
+{
+ 2006, 2012,
+ 2001, 2024,
+ 2002, 2008,
+ 2003, 2020,
+ 2009, 2004,
+ 2010, 2016,
+ 2005, 2000,
+};
+
+/*
+ * return the circa 2000 equivalent calendar year for tm
+ */
+
+int
+tmequiv(Tm_t* tm)
+{
+ return tm->tm_year < (2038 - 1900) ? (tm->tm_year + 1900) : equiv[tm->tm_wday + tmisleapyear(tm->tm_year)];
+}
diff --git a/src/lib/libast/tm/tmfix.c b/src/lib/libast/tm/tmfix.c
new file mode 100644
index 0000000..5425a8b
--- /dev/null
+++ b/src/lib/libast/tm/tmfix.c
@@ -0,0 +1,173 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * time conversion support
+ */
+
+#include <ast.h>
+#include <tmx.h>
+
+#define DAYS(p) (tm_data.days[(p)->tm_mon]+((p)->tm_mon==1&&LEAP(p)))
+#define LEAP(p) (tmisleapyear((p)->tm_year))
+
+/*
+ * correct out of bounds fields in tm
+ *
+ * tm_isdst is not changed -- call tmxtm() to get that
+ *
+ * tm is the return value
+ */
+
+Tm_t*
+tmfix(register Tm_t* tm)
+{
+ register int n;
+ register int w;
+ Tm_t* p;
+ time_t t;
+
+ /*
+ * check for special case that adjusts tm_wday at the end
+ * this happens during
+ * nl_langinfo() => strftime() => tmfmt()
+ */
+
+ if (w = !tm->tm_sec && !tm->tm_min && !tm->tm_mday && !tm->tm_year && !tm->tm_yday && !tm->tm_isdst)
+ {
+ tm->tm_year = 99;
+ tm->tm_mday = 2;
+ }
+
+ /*
+ * adjust from shortest to longest units
+ */
+
+ if ((n = tm->tm_nsec) < 0)
+ {
+ tm->tm_sec -= (TMX_RESOLUTION - n) / TMX_RESOLUTION;
+ tm->tm_nsec = TMX_RESOLUTION - (-n) % TMX_RESOLUTION;
+ }
+ else if (n >= TMX_RESOLUTION)
+ {
+ tm->tm_sec += n / TMX_RESOLUTION;
+ tm->tm_nsec %= TMX_RESOLUTION;
+ }
+ if ((n = tm->tm_sec) < 0)
+ {
+ tm->tm_min -= (60 - n) / 60;
+ tm->tm_sec = 60 - (-n) % 60;
+ }
+ else if (n > (59 + TM_MAXLEAP))
+ {
+ tm->tm_min += n / 60;
+ tm->tm_sec %= 60;
+ }
+ if ((n = tm->tm_min) < 0)
+ {
+ tm->tm_hour -= (60 - n) / 60;
+ n = tm->tm_min = 60 - (-n) % 60;
+ }
+ if (n > 59)
+ {
+ tm->tm_hour += n / 60;
+ tm->tm_min %= 60;
+ }
+ if ((n = tm->tm_hour) < 0)
+ {
+ tm->tm_mday -= (23 - n) / 24;
+ tm->tm_hour = 24 - (-n) % 24;
+ }
+ else if (n >= 24)
+ {
+ tm->tm_mday += n / 24;
+ tm->tm_hour %= 24;
+ }
+ if (tm->tm_mon >= 12)
+ {
+ tm->tm_year += tm->tm_mon / 12;
+ tm->tm_mon %= 12;
+ }
+ else if (tm->tm_mon < 0)
+ {
+ tm->tm_year--;
+ if ((tm->tm_mon += 12) < 0)
+ {
+ tm->tm_year += tm->tm_mon / 12;
+ tm->tm_mon = (-tm->tm_mon) % 12;
+ }
+ }
+ while (tm->tm_mday < -365)
+ {
+ tm->tm_year--;
+ tm->tm_mday += 365 + LEAP(tm);
+ }
+ while (tm->tm_mday > 365)
+ {
+ tm->tm_mday -= 365 + LEAP(tm);
+ tm->tm_year++;
+ }
+ while (tm->tm_mday < 1)
+ {
+ if (--tm->tm_mon < 0)
+ {
+ tm->tm_mon = 11;
+ tm->tm_year--;
+ }
+ tm->tm_mday += DAYS(tm);
+ }
+ while (tm->tm_mday > (n = DAYS(tm)))
+ {
+ tm->tm_mday -= n;
+ if (++tm->tm_mon > 11)
+ {
+ tm->tm_mon = 0;
+ tm->tm_year++;
+ }
+ }
+ if (w)
+ {
+ w = tm->tm_wday;
+ t = tmtime(tm, TM_LOCALZONE);
+ p = tmmake(&t);
+ if (w = (w - p->tm_wday))
+ {
+ if (w < 0)
+ w += 7;
+ tm->tm_wday += w;
+ if ((tm->tm_mday += w) > DAYS(tm))
+ tm->tm_mday -= 7;
+ }
+ }
+ tm->tm_yday = tm_data.sum[tm->tm_mon] + (tm->tm_mon > 1 && LEAP(tm)) + tm->tm_mday - 1;
+ n = tm->tm_year + 1900 - 1;
+ tm->tm_wday = (n + n / 4 - n / 100 + n / 400 + tm->tm_yday + 1) % 7;
+
+ /*
+ * tm_isdst is adjusted by tmtime()
+ */
+
+ return tm;
+}
diff --git a/src/lib/libast/tm/tmfmt.c b/src/lib/libast/tm/tmfmt.c
new file mode 100644
index 0000000..dda0ed0
--- /dev/null
+++ b/src/lib/libast/tm/tmfmt.c
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * time conversion support
+ */
+
+#include <tmx.h>
+
+/*
+ * format date given clock into buf of length len
+ * see tmxfmt() for details
+ */
+
+char*
+tmfmt(char* buf, size_t len, const char* format, time_t* clock)
+{
+ return tmxfmt(buf, len, format, tmxclock(clock));
+}
diff --git a/src/lib/libast/tm/tmform.c b/src/lib/libast/tm/tmform.c
new file mode 100644
index 0000000..4b608c8
--- /dev/null
+++ b/src/lib/libast/tm/tmform.c
@@ -0,0 +1,44 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * OBSOLETE: use tmfmt() instead
+ *
+ * time conversion support
+ */
+
+#include <ast.h>
+#include <tm.h>
+
+/*
+ * format date given clock
+ * end of buf is returned
+ */
+
+char*
+tmform(char* buf, const char* format, time_t* clock)
+{
+ return tmfmt(buf, 256, format, clock);
+}
diff --git a/src/lib/libast/tm/tmgoff.c b/src/lib/libast/tm/tmgoff.c
new file mode 100644
index 0000000..c8c8d57
--- /dev/null
+++ b/src/lib/libast/tm/tmgoff.c
@@ -0,0 +1,77 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * time conversion support
+ */
+
+#include <ast.h>
+#include <tm.h>
+#include <ctype.h>
+
+/*
+ * return minutes offset from absolute timezone expression
+ *
+ * [[-+]hh[:mm[:ss]]]
+ * [-+]hhmm
+ *
+ * if e is non-null then it points to the first unrecognized char in s
+ * d returned if no offset in s
+ */
+
+int
+tmgoff(register const char* s, char** e, int d)
+{
+ register int n = d;
+ int east;
+ const char* t = s;
+
+ if ((east = *s == '+') || *s == '-')
+ {
+ s++;
+ if (isdigit(*s) && isdigit(*(s + 1)))
+ {
+ n = ((*s - '0') * 10 + (*(s + 1) - '0')) * 60;
+ s += 2;
+ if (*s == ':')
+ s++;
+ if (isdigit(*s) && isdigit(*(s + 1)))
+ {
+ n += ((*s - '0') * 10 + (*(s + 1) - '0'));
+ s += 2;
+ if (*s == ':')
+ s++;
+ if (isdigit(*s) && isdigit(*(s + 1)))
+ s += 2;
+ }
+ if (east)
+ n = -n;
+ t = s;
+ }
+ }
+ if (e)
+ *e = (char*)t;
+ return n;
+}
diff --git a/src/lib/libast/tm/tminit.c b/src/lib/libast/tm/tminit.c
new file mode 100644
index 0000000..1918861
--- /dev/null
+++ b/src/lib/libast/tm/tminit.c
@@ -0,0 +1,460 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * time conversion support
+ */
+
+#include <tm.h>
+#include <ctype.h>
+#include <namval.h>
+
+#include "FEATURE/tmlib"
+
+#ifndef tzname
+# if defined(__DYNAMIC__)
+# undef _dat_tzname
+# define tzname __DYNAMIC__(tzname)
+# else
+# if !_dat_tzname
+# if _dat__tzname
+# undef _dat_tzname
+# define _dat_tzname 1
+# define tzname _tzname
+# endif
+# endif
+# endif
+# if _dat_tzname && !defined(tzname)
+ extern char* tzname[];
+# endif
+#endif
+
+#define TM_type (-1)
+
+static const Namval_t options[] =
+{
+ "adjust", TM_ADJUST,
+ "format", TM_DEFAULT,
+ "leap", TM_LEAP,
+ "subsecond", TM_SUBSECOND,
+ "type", TM_type,
+ "utc", TM_UTC,
+ 0, 0
+};
+
+/*
+ * 2007-03-19 move tm_info from _tm_info_ to (*_tm_infop_)
+ * to allow future Tm_info_t growth
+ * by 2009 _tm_info_ can be static
+ */
+
+#if _BLD_ast && defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+
+extern Tm_info_t _tm_info_;
+
+#undef extern
+
+Tm_info_t _tm_info_ = { 0 };
+
+__EXTERN__(Tm_info_t, _tm_info_);
+
+__EXTERN__(Tm_info_t*, _tm_infop_);
+
+Tm_info_t* _tm_infop_ = &_tm_info_;
+
+#if _tzset_environ
+
+static char TZ[256];
+static char* TE[2];
+
+struct tm*
+_tm_localtime(const time_t* t)
+{
+ struct tm* r;
+ char* e;
+ char** v = environ;
+
+ if (TZ[0])
+ {
+ if (!environ || !*environ)
+ environ = TE;
+ else
+ e = environ[0];
+ environ[0] = TZ;
+ }
+ r = localtime(t);
+ if (TZ[0])
+ {
+ if (environ != v)
+ environ = v;
+ else
+ environ[0] = e;
+ }
+ return r;
+}
+
+#endif
+
+/*
+ * return minutes west of GMT for local time clock
+ *
+ * isdst will point to non-zero if DST is in effect
+ * this routine also kicks in the local initialization
+ */
+
+static int
+tzwest(time_t* clock, int* isdst)
+{
+ register struct tm* tp;
+ register int n;
+ register int m;
+ int h;
+ time_t epoch;
+
+ /*
+ * convert to GMT assuming local time
+ */
+
+ if (!(tp = gmtime(clock)))
+ {
+ /*
+ * some systems return 0 for negative time_t
+ */
+
+ epoch = 0;
+ clock = &epoch;
+ tp = gmtime(clock);
+ }
+ n = tp->tm_yday;
+ h = tp->tm_hour;
+ m = tp->tm_min;
+
+ /*
+ * tmlocaltime() handles DST and GMT offset
+ */
+
+ tp = tmlocaltime(clock);
+ if (n = tp->tm_yday - n)
+ {
+ if (n > 1)
+ n = -1;
+ else if (n < -1)
+ n = 1;
+ }
+ *isdst = tp->tm_isdst;
+ return (h - tp->tm_hour - n * 24) * 60 + m - tp->tm_min;
+}
+
+/*
+ * stropt() option handler
+ */
+
+static int
+tmopt(void* a, const void* p, int n, const char* v)
+{
+ Tm_zone_t* zp;
+
+ NoP(a);
+ if (p)
+ switch (((Namval_t*)p)->value)
+ {
+ case TM_DEFAULT:
+ tm_info.deformat = (n && (n = strlen(v)) > 0 && (n < 2 || v[n-2] != '%' || v[n-1] != '?')) ? strdup(v) : tm_info.format[TM_DEFAULT];
+ break;
+ case TM_type:
+ tm_info.local->type = (n && *v) ? ((zp = tmtype(v, NiL)) ? zp->type : strdup(v)) : 0;
+ break;
+ default:
+ if (n)
+ tm_info.flags |= ((Namval_t*)p)->value;
+ else
+ tm_info.flags &= ~((Namval_t*)p)->value;
+ break;
+ }
+ return 0;
+}
+
+/*
+ * initialize the local timezone
+ */
+
+static void
+tmlocal(void)
+{
+ register Tm_zone_t* zp;
+ register int n;
+ register char* s;
+ register char* e;
+ int i;
+ int m;
+ int isdst;
+ char* t;
+ struct tm* tp;
+ time_t now;
+ char buf[16];
+
+ static Tm_zone_t local;
+
+#if _tzset_environ
+ {
+ char** v = environ;
+
+ if (s = getenv("TZ"))
+ {
+ sfsprintf(TZ, sizeof(TZ), "TZ=%s", s);
+ if (!environ || !*environ)
+ environ = TE;
+ else
+ e = environ[0];
+ environ[0] = TZ;
+ }
+ else
+ {
+ TZ[0] = 0;
+ e = 0;
+ }
+#endif
+#if _lib_tzset
+ tzset();
+#endif
+#if _tzset_environ
+ if (environ != v)
+ environ = v;
+ else if (e)
+ environ[0] = e;
+ }
+#endif
+#if _dat_tzname
+ local.standard = strdup(tzname[0]);
+ local.daylight = strdup(tzname[1]);
+#endif
+ tmlocale();
+
+ /*
+ * tm_info.local
+ */
+
+ tm_info.zone = tm_info.local = &local;
+ time(&now);
+ n = tzwest(&now, &isdst);
+
+ /*
+ * compute local DST offset by roaming
+ * through the last 12 months until tzwest() changes
+ */
+
+ for (i = 0; i < 12; i++)
+ {
+ now -= 31 * 24 * 60 * 60;
+ if ((m = tzwest(&now, &isdst)) != n)
+ {
+ if (!isdst)
+ {
+ isdst = n;
+ n = m;
+ m = isdst;
+ }
+ m -= n;
+ break;
+ }
+ }
+ local.west = n;
+ local.dst = m;
+
+ /*
+ * now get the time zone names
+ */
+
+#if _dat_tzname
+ if (tzname[0])
+ {
+ /*
+ * POSIX
+ */
+
+ if (!local.standard)
+ local.standard = strdup(tzname[0]);
+ if (!local.daylight)
+ local.daylight = strdup(tzname[1]);
+ }
+ else
+#endif
+ if ((s = getenv("TZNAME")) && *s && (s = strdup(s)))
+ {
+ /*
+ * BSD
+ */
+
+ local.standard = s;
+ if (s = strchr(s, ','))
+ *s++ = 0;
+ else
+ s = "";
+ local.daylight = s;
+ }
+ else if ((s = getenv("TZ")) && *s && *s != ':' && (s = strdup(s)))
+ {
+ /*
+ * POSIX style but skipped by tmlocaltime()
+ */
+
+ local.standard = s;
+ if (*++s && *++s && *++s)
+ {
+ *s++ = 0;
+ tmgoff(s, &t, 0);
+ for (s = t; isalpha(*t); t++);
+ *t = 0;
+ }
+ else
+ s = "";
+ local.daylight = s;
+ }
+ else
+ {
+ /*
+ * tm_data.zone table lookup
+ */
+
+ t = 0;
+ for (zp = tm_data.zone; zp->standard; zp++)
+ {
+ if (zp->type)
+ t = zp->type;
+ if (zp->west == n && zp->dst == m)
+ {
+ local.type = t;
+ local.standard = zp->standard;
+ if (!(s = zp->daylight))
+ {
+ e = (s = buf) + sizeof(buf);
+ s = tmpoff(s, e - s, zp->standard, 0, 0);
+ if (s < e - 1)
+ {
+ *s++ = ' ';
+ tmpoff(s, e - s, tm_info.format[TM_DT], m, TM_DST);
+ }
+ s = strdup(buf);
+ }
+ local.daylight = s;
+ break;
+ }
+ }
+ if (!zp->standard)
+ {
+ /*
+ * not in the table
+ */
+
+ e = (s = buf) + sizeof(buf);
+ s = tmpoff(s, e - s, tm_info.format[TM_UT], n, 0);
+ local.standard = strdup(buf);
+ if (s < e - 1)
+ {
+ *s++ = ' ';
+ tmpoff(s, e - s, tm_info.format[TM_UT], m, TM_DST);
+ local.daylight = strdup(buf);
+ }
+ }
+ }
+
+ /*
+ * set the options
+ */
+
+ stropt(getenv("TM_OPTIONS"), options, sizeof(*options), tmopt, NiL);
+
+ /*
+ * the time zone type is probably related to the locale
+ */
+
+ if (!local.type)
+ {
+ s = local.standard;
+ t = 0;
+ for (zp = tm_data.zone; zp->standard; zp++)
+ {
+ if (zp->type)
+ t = zp->type;
+ if (tmword(s, NiL, zp->standard, NiL, 0))
+ {
+ local.type = t;
+ break;
+ }
+ }
+ }
+
+ /*
+ * tm_info.flags
+ */
+
+ if (!(tm_info.flags & TM_ADJUST))
+ {
+ now = (time_t)78811200; /* Jun 30 1972 23:59:60 */
+ tp = tmlocaltime(&now);
+ if (tp->tm_sec != 60)
+ tm_info.flags |= TM_ADJUST;
+ }
+ if (!(tm_info.flags & TM_UTC))
+ {
+ s = local.standard;
+ zp = tm_data.zone;
+ if (local.daylight)
+ zp++;
+ for (; !zp->type && zp->standard; zp++)
+ if (tmword(s, NiL, zp->standard, NiL, 0))
+ {
+ tm_info.flags |= TM_UTC;
+ break;
+ }
+ }
+}
+
+/*
+ * initialize tm data
+ */
+
+void
+tminit(register Tm_zone_t* zp)
+{
+ static uint32_t serial = ~(uint32_t)0;
+
+ if (serial != ast.env_serial)
+ {
+ serial = ast.env_serial;
+ if (tm_info.local)
+ {
+ memset(tm_info.local, 0, sizeof(*tm_info.local));
+ tm_info.local = 0;
+ }
+ }
+ if (!tm_info.local)
+ tmlocal();
+ if (!zp)
+ zp = tm_info.local;
+ tm_info.zone = zp;
+}
diff --git a/src/lib/libast/tm/tmleap.c b/src/lib/libast/tm/tmleap.c
new file mode 100644
index 0000000..87c2f04
--- /dev/null
+++ b/src/lib/libast/tm/tmleap.c
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * time conversion support
+ */
+
+#include <tmx.h>
+
+/*
+ * return clock with leap seconds adjusted
+ * see tmxleap() for details
+ */
+
+time_t
+tmleap(register time_t* clock)
+{
+ return tmxsec(tmxleap(tmxclock(clock)));
+}
diff --git a/src/lib/libast/tm/tmlex.c b/src/lib/libast/tm/tmlex.c
new file mode 100644
index 0000000..4bcd864
--- /dev/null
+++ b/src/lib/libast/tm/tmlex.c
@@ -0,0 +1,67 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * time conversion support
+ */
+
+#include <ast.h>
+#include <tm.h>
+#include <ctype.h>
+
+/*
+ * return the tab table index that matches s ignoring case and .'s
+ * tm_data.format checked if tminfo.format!=tm_data.format
+ *
+ * ntab and nsuf are the number of elements in tab and suf,
+ * -1 for 0 sentinel
+ *
+ * all isalpha() chars in str must match
+ * suf is a table of nsuf valid str suffixes
+ * if e is non-null then it will point to first unmatched char in str
+ * which will always be non-isalpha()
+ */
+
+int
+tmlex(register const char* s, char** e, char** tab, int ntab, char** suf, int nsuf)
+{
+ register char** p;
+ register char* x;
+ register int n;
+
+ for (p = tab, n = ntab; n-- && (x = *p); p++)
+ if (*x && *x != '%' && tmword(s, e, x, suf, nsuf))
+ return p - tab;
+ if (tm_info.format != tm_data.format && tab >= tm_info.format && tab < tm_info.format + TM_NFORM)
+ {
+ tab = tm_data.format + (tab - tm_info.format);
+ if (suf && tab >= tm_info.format && tab < tm_info.format + TM_NFORM)
+ suf = tm_data.format + (suf - tm_info.format);
+ for (p = tab, n = ntab; n-- && (x = *p); p++)
+ if (*x && *x != '%' && tmword(s, e, x, suf, nsuf))
+ return p - tab;
+ }
+ return -1;
+}
diff --git a/src/lib/libast/tm/tmlocale.c b/src/lib/libast/tm/tmlocale.c
new file mode 100644
index 0000000..98dafdb
--- /dev/null
+++ b/src/lib/libast/tm/tmlocale.c
@@ -0,0 +1,644 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * time conversion translation support
+ */
+
+#include <ast.h>
+#include <cdt.h>
+#include <iconv.h>
+#include <mc.h>
+#include <tm.h>
+#include <ast_nl_types.h>
+
+#include "lclib.h"
+
+static struct
+{
+ char* format;
+ Lc_info_t* locale;
+ char null[1];
+} state;
+
+/*
+ * this is unix dadgummit
+ */
+
+static int
+standardized(Lc_info_t* li, register char** b)
+{
+ if ((li->lc->language->flags & (LC_debug|LC_default)) || streq(li->lc->language->code, "en"))
+ {
+ b[TM_TIME] = "%H:%M:%S";
+ b[TM_DATE] = "%m/%d/%y";
+ b[TM_DEFAULT] = "%a %b %e %T %Z %Y";
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * fix up LC_TIME data after loading
+ */
+
+static void
+fixup(Lc_info_t* li, register char** b)
+{
+ register char** v;
+ register char** e;
+ register int n;
+
+ static int must[] =
+ {
+ TM_TIME,
+ TM_DATE,
+ TM_DEFAULT,
+ TM_MERIDIAN,
+ TM_UT,
+ TM_DT,
+ TM_SUFFIXES,
+ TM_PARTS,
+ TM_HOURS,
+ TM_DAYS,
+ TM_LAST,
+ TM_THIS,
+ TM_NEXT,
+ TM_EXACT,
+ TM_NOISE,
+ TM_ORDINAL,
+ TM_CTIME,
+ TM_DATE_1,
+ TM_INTERNATIONAL,
+ TM_RECENT,
+ TM_DISTANT,
+ TM_MERIDIAN_TIME,
+ TM_ORDINALS,
+ TM_FINAL,
+ TM_WORK,
+ };
+
+ standardized(li, b);
+ for (v = b, e = b + TM_NFORM; v < e; v++)
+ if (!*v)
+ *v = state.null;
+ for (n = 0; n < elementsof(must); n++)
+ if (!*b[must[n]])
+ b[must[n]] = tm_data.format[must[n]];
+ if (li->lc->flags & LC_default)
+ for (n = 0; n < TM_NFORM; n++)
+ if (!*b[n])
+ b[n] = tm_data.format[n];
+ if (strchr(b[TM_UT], '%'))
+ {
+ tm_info.deformat = b[TM_UT];
+ for (n = TM_UT; n < TM_DT; n++)
+ b[n] = state.null;
+ }
+ else
+ tm_info.deformat = b[TM_DEFAULT];
+ tm_info.format = b;
+ if (!(tm_info.deformat = state.format))
+ tm_info.deformat = tm_info.format[TM_DEFAULT];
+ li->data = (void*)b;
+}
+
+#if _WINIX
+
+#include <ast_windows.h>
+
+typedef struct Map_s
+{
+ LCID native;
+ int local;
+} Map_t;
+
+static const Map_t map[] =
+{
+ LOCALE_S1159, (TM_MERIDIAN+0),
+ LOCALE_S2359, (TM_MERIDIAN+1),
+ LOCALE_SABBREVDAYNAME1, (TM_DAY_ABBREV+1),
+ LOCALE_SABBREVDAYNAME2, (TM_DAY_ABBREV+2),
+ LOCALE_SABBREVDAYNAME3, (TM_DAY_ABBREV+3),
+ LOCALE_SABBREVDAYNAME4, (TM_DAY_ABBREV+4),
+ LOCALE_SABBREVDAYNAME5, (TM_DAY_ABBREV+5),
+ LOCALE_SABBREVDAYNAME6, (TM_DAY_ABBREV+6),
+ LOCALE_SABBREVDAYNAME7, (TM_DAY_ABBREV+0),
+ LOCALE_SABBREVMONTHNAME1, (TM_MONTH_ABBREV+0),
+ LOCALE_SABBREVMONTHNAME2, (TM_MONTH_ABBREV+1),
+ LOCALE_SABBREVMONTHNAME3, (TM_MONTH_ABBREV+2),
+ LOCALE_SABBREVMONTHNAME4, (TM_MONTH_ABBREV+3),
+ LOCALE_SABBREVMONTHNAME5, (TM_MONTH_ABBREV+4),
+ LOCALE_SABBREVMONTHNAME6, (TM_MONTH_ABBREV+5),
+ LOCALE_SABBREVMONTHNAME7, (TM_MONTH_ABBREV+6),
+ LOCALE_SABBREVMONTHNAME8, (TM_MONTH_ABBREV+7),
+ LOCALE_SABBREVMONTHNAME9, (TM_MONTH_ABBREV+8),
+ LOCALE_SABBREVMONTHNAME10, (TM_MONTH_ABBREV+9),
+ LOCALE_SABBREVMONTHNAME11, (TM_MONTH_ABBREV+10),
+ LOCALE_SABBREVMONTHNAME12, (TM_MONTH_ABBREV+11),
+ LOCALE_SDAYNAME1, (TM_DAY+1),
+ LOCALE_SDAYNAME2, (TM_DAY+2),
+ LOCALE_SDAYNAME3, (TM_DAY+3),
+ LOCALE_SDAYNAME4, (TM_DAY+4),
+ LOCALE_SDAYNAME5, (TM_DAY+5),
+ LOCALE_SDAYNAME6, (TM_DAY+6),
+ LOCALE_SDAYNAME7, (TM_DAY+0),
+ LOCALE_SMONTHNAME1, (TM_MONTH+0),
+ LOCALE_SMONTHNAME2, (TM_MONTH+1),
+ LOCALE_SMONTHNAME3, (TM_MONTH+2),
+ LOCALE_SMONTHNAME4, (TM_MONTH+3),
+ LOCALE_SMONTHNAME5, (TM_MONTH+4),
+ LOCALE_SMONTHNAME6, (TM_MONTH+5),
+ LOCALE_SMONTHNAME7, (TM_MONTH+6),
+ LOCALE_SMONTHNAME8, (TM_MONTH+7),
+ LOCALE_SMONTHNAME9, (TM_MONTH+8),
+ LOCALE_SMONTHNAME10, (TM_MONTH+9),
+ LOCALE_SMONTHNAME11, (TM_MONTH+10),
+ LOCALE_SMONTHNAME12, (TM_MONTH+11),
+};
+
+#undef extern
+
+/*
+ * convert ms word date spec w to posix strftime format f
+ * next char after f returned
+ * the caller already made sure f is big enough
+ */
+
+static char*
+word2posix(register char* f, register char* w, int alternate)
+{
+ register char* r;
+ register int c;
+ register int p;
+ register int n;
+
+ while (*w)
+ {
+ p = 0;
+ r = w;
+ while (*++w == *r);
+ if ((n = w - r) > 3 && alternate)
+ n--;
+ switch (*r)
+ {
+ case 'a':
+ case 'A':
+ if (!strncasecmp(w, "am/pm", 5))
+ w += 5;
+ else if (!strncasecmp(w, "a/p", 3))
+ w += 3;
+ c = 'p';
+ break;
+ case 'd':
+ switch (n)
+ {
+ case 1:
+ p = '-';
+ /*FALLTHROUGH*/
+ case 2:
+ c = 'd';
+ break;
+ case 3:
+ c = 'a';
+ break;
+ default:
+ c = 'A';
+ break;
+ }
+ break;
+ case 'h':
+ switch (n)
+ {
+ case 1:
+ p = '-';
+ /*FALLTHROUGH*/
+ default:
+ c = 'I';
+ break;
+ }
+ break;
+ case 'H':
+ switch (n)
+ {
+ case 1:
+ p = '-';
+ /*FALLTHROUGH*/
+ default:
+ c = 'H';
+ break;
+ }
+ break;
+ case 'M':
+ switch (n)
+ {
+ case 1:
+ p = '-';
+ /*FALLTHROUGH*/
+ case 2:
+ c = 'm';
+ break;
+ case 3:
+ c = 'b';
+ break;
+ default:
+ c = 'B';
+ break;
+ }
+ break;
+ case 'm':
+ switch (n)
+ {
+ case 1:
+ p = '-';
+ /*FALLTHROUGH*/
+ default:
+ c = 'M';
+ break;
+ }
+ break;
+ case 's':
+ switch (n)
+ {
+ case 1:
+ p = '-';
+ /*FALLTHROUGH*/
+ default:
+ c = 'S';
+ break;
+ }
+ break;
+ case 'y':
+ switch (n)
+ {
+ case 1:
+ p = '-';
+ /*FALLTHROUGH*/
+ case 2:
+ c = 'y';
+ break;
+ default:
+ c = 'Y';
+ break;
+ }
+ break;
+ case '\'':
+ if (n & 1)
+ for (w = r + 1; *w; *f++ = *w++)
+ if (*w == '\'')
+ {
+ w++;
+ break;
+ }
+ continue;
+ case '%':
+ while (r < w)
+ {
+ *f++ = *r++;
+ *f++ = *r++;
+ }
+ continue;
+ default:
+ while (r < w)
+ *f++ = *r++;
+ continue;
+ }
+ *f++ = '%';
+ if (p)
+ *f++ = '-';
+ *f++ = c;
+ }
+ *f++ = 0;
+ return f;
+}
+
+/*
+ * load the native LC_TIME data for the current locale
+ */
+
+static void
+native_lc_time(Lc_info_t* li)
+{
+ register char* s;
+ register char* t;
+ register char** b;
+ register int n;
+ register int m;
+ register int i;
+ LCID lcid;
+ int nt;
+ int ns;
+ int nl;
+ int clock_24;
+ int leading_0;
+ char buf[256];
+
+ lcid = li->lc->index;
+ nt = 2 * GetLocaleInfo(lcid, LOCALE_STIME, 0, 0) + 7; /* HH:MM:SS */
+ ns = 3 * GetLocaleInfo(lcid, LOCALE_SSHORTDATE, 0, 0);
+ nl = 3 * GetLocaleInfo(lcid, LOCALE_SLONGDATE, 0, 0);
+ n = nt + ns + nl;
+ for (i = 0; i < elementsof(map); i++)
+ n += GetLocaleInfo(lcid, map[i].native, 0, 0);
+ if (!(b = newof(0, char*, TM_NFORM, n)))
+ return;
+ s = (char*)(b + TM_NFORM);
+ for (i = 0; i < elementsof(map); i++)
+ {
+ if (!(m = GetLocaleInfo(lcid, map[i].native, s, n)))
+ goto bad;
+ b[map[i].local] = s;
+ s += m;
+ }
+ if (!standardized(li, b))
+ {
+ /*
+ * synthesize TM_TIME format from the ms word template
+ */
+
+ if (!GetLocaleInfo(lcid, LOCALE_ITIME, buf, sizeof(buf)))
+ goto bad;
+ clock_24 = atoi(buf);
+ if (!GetLocaleInfo(lcid, LOCALE_ITLZERO, buf, sizeof(buf)))
+ goto bad;
+ leading_0 = atoi(buf);
+ if (!GetLocaleInfo(lcid, LOCALE_STIME, buf, sizeof(buf)))
+ goto bad;
+ b[TM_TIME] = s;
+ *s++ = '%';
+ if (!leading_0)
+ *s++ = '-';
+ *s++ = clock_24 ? 'H' : 'I';
+ for (t = buf; *s = *t++; s++);
+ *s++ = '%';
+ if (!leading_0)
+ *s++ = '-';
+ *s++ = 'M';
+ for (t = buf; *s = *t++; s++);
+ *s++ = '%';
+ if (!leading_0)
+ *s++ = '-';
+ *s++ = 'S';
+ *s++ = 0;
+
+ /*
+ * synthesize TM_DATE format
+ */
+
+ if (!GetLocaleInfo(lcid, LOCALE_SSHORTDATE, buf, sizeof(buf)))
+ goto bad;
+ b[TM_DATE] = s;
+ s = word2posix(s, buf, 1);
+
+ /*
+ * synthesize TM_DEFAULT format
+ */
+
+ if (!GetLocaleInfo(lcid, LOCALE_SLONGDATE, buf, sizeof(buf)))
+ goto bad;
+ b[TM_DEFAULT] = s;
+ s = word2posix(s, buf, 1);
+ strcpy(s - 1, " %X");
+ }
+
+ /*
+ * done
+ */
+
+ fixup(li, b);
+ return;
+ bad:
+ free(b);
+}
+
+#else
+
+#if _lib_nl_langinfo && _hdr_langinfo
+
+#if _hdr_nl_types
+#include <nl_types.h>
+#endif
+
+#include <langinfo.h>
+
+typedef struct Map_s
+{
+ int native;
+ int local;
+} Map_t;
+
+static const Map_t map[] =
+{
+ AM_STR, (TM_MERIDIAN+0),
+ PM_STR, (TM_MERIDIAN+1),
+ ABDAY_1, (TM_DAY_ABBREV+0),
+ ABDAY_2, (TM_DAY_ABBREV+1),
+ ABDAY_3, (TM_DAY_ABBREV+2),
+ ABDAY_4, (TM_DAY_ABBREV+3),
+ ABDAY_5, (TM_DAY_ABBREV+4),
+ ABDAY_6, (TM_DAY_ABBREV+5),
+ ABDAY_7, (TM_DAY_ABBREV+6),
+ ABMON_1, (TM_MONTH_ABBREV+0),
+ ABMON_2, (TM_MONTH_ABBREV+1),
+ ABMON_3, (TM_MONTH_ABBREV+2),
+ ABMON_4, (TM_MONTH_ABBREV+3),
+ ABMON_5, (TM_MONTH_ABBREV+4),
+ ABMON_6, (TM_MONTH_ABBREV+5),
+ ABMON_7, (TM_MONTH_ABBREV+6),
+ ABMON_8, (TM_MONTH_ABBREV+7),
+ ABMON_9, (TM_MONTH_ABBREV+8),
+ ABMON_10, (TM_MONTH_ABBREV+9),
+ ABMON_11, (TM_MONTH_ABBREV+10),
+ ABMON_12, (TM_MONTH_ABBREV+11),
+ DAY_1, (TM_DAY+0),
+ DAY_2, (TM_DAY+1),
+ DAY_3, (TM_DAY+2),
+ DAY_4, (TM_DAY+3),
+ DAY_5, (TM_DAY+4),
+ DAY_6, (TM_DAY+5),
+ DAY_7, (TM_DAY+6),
+ MON_1, (TM_MONTH+0),
+ MON_2, (TM_MONTH+1),
+ MON_3, (TM_MONTH+2),
+ MON_4, (TM_MONTH+3),
+ MON_5, (TM_MONTH+4),
+ MON_6, (TM_MONTH+5),
+ MON_7, (TM_MONTH+6),
+ MON_8, (TM_MONTH+7),
+ MON_9, (TM_MONTH+8),
+ MON_10, (TM_MONTH+9),
+ MON_11, (TM_MONTH+10),
+ MON_12, (TM_MONTH+11),
+#ifdef _DATE_FMT
+ _DATE_FMT, TM_DEFAULT,
+#else
+ D_T_FMT, TM_DEFAULT,
+#endif
+ D_FMT, TM_DATE,
+ T_FMT, TM_TIME,
+#ifdef ERA
+ ERA, TM_ERA,
+ ERA_D_T_FMT, TM_ERA_DEFAULT,
+ ERA_D_FMT, TM_ERA_DATE,
+ ERA_T_FMT, TM_ERA_TIME,
+#endif
+#ifdef ALT_DIGITS
+ ALT_DIGITS, TM_DIGITS,
+#endif
+};
+
+static void
+native_lc_time(Lc_info_t* li)
+{
+ register char* s;
+ register char* t;
+ register char** b;
+ register int n;
+ register int i;
+
+ n = 0;
+ for (i = 0; i < elementsof(map); i++)
+ {
+ if (!(t = nl_langinfo(map[i].native)))
+ t = tm_data.format[map[i].local];
+ n += strlen(t) + 1;
+ }
+ if (!(b = newof(0, char*, TM_NFORM, n)))
+ return;
+ s = (char*)(b + TM_NFORM);
+ for (i = 0; i < elementsof(map); i++)
+ {
+ b[map[i].local] = s;
+ if (!(t = nl_langinfo(map[i].native)))
+ t = tm_data.format[map[i].local];
+ while (*s++ = *t++);
+ }
+ fixup(li, b);
+}
+
+#else
+
+#define native_lc_time(li) ((li->data=(void*)(tm_info.format=tm_data.format)),(tm_info.deformat=tm_info.format[TM_DEFAULT]))
+
+#endif
+
+#endif
+
+/*
+ * load the LC_TIME data for the current locale
+ */
+
+static void
+load(Lc_info_t* li)
+{
+ register char* s;
+ register char** b;
+ register char** v;
+ register char** e;
+ unsigned char* u;
+ ssize_t n;
+ iconv_t cvt;
+ Sfio_t* sp;
+ Sfio_t* tp;
+ char path[PATH_MAX];
+
+ if (b = (char**)li->data)
+ {
+ tm_info.format = b;
+ if (!(tm_info.deformat = state.format))
+ tm_info.deformat = tm_info.format[TM_DEFAULT];
+ return;
+ }
+ tm_info.format = tm_data.format;
+ if (!(tm_info.deformat = state.format))
+ tm_info.deformat = tm_info.format[TM_DEFAULT];
+ if (mcfind(NiL, NiL, LC_TIME, 0, path, sizeof(path)) && (sp = sfopen(NiL, path, "r")))
+ {
+ n = sfsize(sp);
+ tp = 0;
+ if (u = (unsigned char*)sfreserve(sp, 3, 1))
+ {
+ if (u[0] == 0xef && u[1] == 0xbb && u[2] == 0xbf && (cvt = iconv_open("", "utf")) != (iconv_t)(-1))
+ {
+ if (tp = sfstropen())
+ {
+ sfread(sp, u, 3);
+ n = iconv_move(cvt, sp, tp, SF_UNBOUND, NiL);
+ }
+ iconv_close(cvt);
+ }
+ if (!tp)
+ sfread(sp, u, 0);
+ }
+ if (b = newof(0, char*, TM_NFORM, n + 2))
+ {
+ v = b;
+ e = b + TM_NFORM;
+ s = (char*)e;
+ if (tp && memcpy(s, sfstrbase(tp), n) || !tp && sfread(sp, s, n) == n)
+ {
+ s[n] = '\n';
+ while (v < e)
+ {
+ *v++ = s;
+ if (!(s = strchr(s, '\n')))
+ break;
+ *s++ = 0;
+ }
+ fixup(li, b);
+ }
+ else
+ free(b);
+ }
+ if (tp)
+ sfclose(tp);
+ sfclose(sp);
+ }
+ else
+ native_lc_time(li);
+}
+
+/*
+ * check that tm_info.format matches the current locale
+ */
+
+char**
+tmlocale(void)
+{
+ Lc_info_t* li;
+
+ if (!tm_info.format)
+ {
+ tm_info.format = tm_data.format;
+ if (!tm_info.deformat)
+ tm_info.deformat = tm_info.format[TM_DEFAULT];
+ else if (tm_info.deformat != tm_info.format[TM_DEFAULT])
+ state.format = tm_info.deformat;
+ }
+ li = LCINFO(AST_LC_TIME);
+ if (!li->data)
+ load(li);
+ return tm_info.format;
+}
diff --git a/src/lib/libast/tm/tmmake.c b/src/lib/libast/tm/tmmake.c
new file mode 100644
index 0000000..04e0bed
--- /dev/null
+++ b/src/lib/libast/tm/tmmake.c
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * time conversion support
+ */
+
+#include <tmx.h>
+
+/*
+ * return Tm_t for clock
+ * see tmxmake() for details
+ */
+
+Tm_t*
+tmmake(time_t* clock)
+{
+ return tmxmake(tmxclock(clock));
+}
diff --git a/src/lib/libast/tm/tmpoff.c b/src/lib/libast/tm/tmpoff.c
new file mode 100644
index 0000000..0a25704
--- /dev/null
+++ b/src/lib/libast/tm/tmpoff.c
@@ -0,0 +1,62 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * time conversion support
+ */
+
+#include <ast.h>
+#include <tm.h>
+
+/*
+ * n is minutes west of UTC
+ *
+ * append p and SHHMM part of n to s
+ * where S is + or -
+ *
+ * n ignored if n==d
+ * end of s is returned
+ */
+
+char*
+tmpoff(register char* s, size_t z, register const char* p, register int n, int d)
+{
+ register char* e = s + z;
+
+ while (s < e && (*s = *p++))
+ s++;
+ if (n != d && s < e)
+ {
+ if (n < 0)
+ {
+ n = -n;
+ *s++ = '+';
+ }
+ else
+ *s++ = '-';
+ s += sfsprintf(s, e - s, "%02d%s%02d", n / 60, d == -24*60 ? ":" : "", n % 60);
+ }
+ return s;
+}
diff --git a/src/lib/libast/tm/tmscan.c b/src/lib/libast/tm/tmscan.c
new file mode 100644
index 0000000..c2cda80
--- /dev/null
+++ b/src/lib/libast/tm/tmscan.c
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * time conversion support
+ */
+
+#include <tmx.h>
+
+/*
+ * scan date expression in s using format
+ * see tmxscan() for details
+ */
+
+time_t
+tmscan(const char* s, char** e, const char* format, char** f, time_t* clock, long flags)
+{
+ return tmxsec(tmxscan(s, e, format, f, tmxclock(clock), flags));
+}
diff --git a/src/lib/libast/tm/tmsleep.c b/src/lib/libast/tm/tmsleep.c
new file mode 100644
index 0000000..3e4f84e
--- /dev/null
+++ b/src/lib/libast/tm/tmsleep.c
@@ -0,0 +1,42 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * nanosecond resolution sleep
+ */
+
+#include <ast.h>
+#include <tm.h>
+#include <tv.h>
+
+int
+tmsleep(time_t sec, time_t nsec)
+{
+ Tv_t tv;
+
+ tv.tv_sec = sec;
+ tv.tv_nsec = nsec;
+ return tvsleep(&tv, NiL);
+}
diff --git a/src/lib/libast/tm/tmtime.c b/src/lib/libast/tm/tmtime.c
new file mode 100644
index 0000000..086dd5a
--- /dev/null
+++ b/src/lib/libast/tm/tmtime.c
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * time conversion support
+ */
+
+#include <tmx.h>
+
+/*
+ * convert Tm_t to time_t
+ * see tmxtime() for details
+ */
+
+time_t
+tmtime(register Tm_t* tm, int west)
+{
+ return tmxsec(tmxtime(tm, west));
+}
diff --git a/src/lib/libast/tm/tmtype.c b/src/lib/libast/tm/tmtype.c
new file mode 100644
index 0000000..ec45f52
--- /dev/null
+++ b/src/lib/libast/tm/tmtype.c
@@ -0,0 +1,57 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * time conversion support
+ */
+
+#include <ast.h>
+#include <tm.h>
+
+/*
+ * return the tm_data.zone[] time zone entry for type s
+ *
+ * if e is non-null then it will point to the first
+ * unmatched char in s
+ *
+ * 0 returned for no match
+ */
+
+Tm_zone_t*
+tmtype(register const char* s, char** e)
+{
+ register Tm_zone_t* zp;
+ register char* t;
+
+ tmset(tm_info.zone);
+ zp = tm_info.local;
+ do
+ {
+ if ((t = zp->type) && tmword(s, e, t, NiL, 0)) return(zp);
+ if (zp == tm_info.local) zp = tm_data.zone;
+ else zp++;
+ } while (zp->standard);
+ return(0);
+}
diff --git a/src/lib/libast/tm/tmweek.c b/src/lib/libast/tm/tmweek.c
new file mode 100644
index 0000000..78ca98c
--- /dev/null
+++ b/src/lib/libast/tm/tmweek.c
@@ -0,0 +1,87 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * Time_t conversion support
+ */
+
+#include <tmx.h>
+
+static unsigned char offset[7][3] =
+{
+ { 7, 6, 6 },
+ { 1, 7, 7 },
+ { 2, 1, 8 },
+ { 3, 2, 9 },
+ { 4, 3, 10},
+ { 5, 4, 4 },
+ { 6, 5, 5 },
+};
+
+/*
+ * type is week type
+ * 0 sunday first day of week
+ * 1 monday first day of week
+ * 2 monday first day of iso week
+ * if week<0 then return week for tm
+ * if day<0 then set tm to first day of week
+ * otherwise set tm to day in week
+ * and return tm->tm_yday
+ */
+
+int
+tmweek(Tm_t* tm, int type, int week, int day)
+{
+ int d;
+
+ if (week < 0)
+ {
+ if ((day = tm->tm_wday - tm->tm_yday % 7) < 0)
+ day += 7;
+ week = (tm->tm_yday + offset[day][type]) / 7;
+ if (type == 2)
+ {
+ if (!week)
+ week = (day > 0 && day < 6 || tmisleapyear(tm->tm_year - 1)) ? 53 : 52;
+ else if (week == 53 && (tm->tm_wday + (31 - tm->tm_mday)) < 4)
+ week = 1;
+ }
+ return week;
+ }
+ if (day < 0)
+ day = type != 0;
+ tm->tm_mon = 0;
+ tm->tm_mday = 1;
+ tmfix(tm);
+ d = tm->tm_wday;
+ tm->tm_mday = week * 7 - offset[d][type] + ((day || type != 2) ? day : 7);
+ tmfix(tm);
+ if (d = tm->tm_wday - day)
+ {
+ tm->tm_mday -= d;
+ tmfix(tm);
+ }
+ return tm->tm_yday;
+}
diff --git a/src/lib/libast/tm/tmword.c b/src/lib/libast/tm/tmword.c
new file mode 100644
index 0000000..33ce66d
--- /dev/null
+++ b/src/lib/libast/tm/tmword.c
@@ -0,0 +1,89 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * time conversion support
+ */
+
+#include <ast.h>
+#include <tm.h>
+#include <ctype.h>
+
+/*
+ * match s against t ignoring case and .'s
+ *
+ * suf is an n element table of suffixes that may trail s
+ * if all isalpha() chars in s match then 1 is returned
+ * and if e is non-null it will point to the first unmatched
+ * char in s, otherwise 0 is returned
+ */
+
+int
+tmword(register const char* s, char** e, register const char* t, char** suf, int n)
+{
+ register int c;
+ const char* b;
+
+ if (*s && *t)
+ {
+ b = s;
+ while (c = *s++)
+ {
+ if (c != '.')
+ {
+ if (!isalpha(c) || c != *t && (islower(c) ? toupper(c) : tolower(c)) != *t)
+ break;
+ t++;
+ }
+ }
+ s--;
+ if (!isalpha(c))
+ {
+ if (c == '_')
+ s++;
+ if (e)
+ *e = (char*)s;
+ return s > b;
+ }
+ if (!*t && s > (b + 1))
+ {
+ b = s;
+ while (n-- && (t = *suf++))
+ {
+ s = b;
+ while (isalpha(c = *s++) && (c == *t || (islower(c) ? toupper(c) : tolower(c)) == *t)) t++;
+ if (!*t && !isalpha(c))
+ {
+ if (c != '_')
+ s--;
+ if (e)
+ *e = (char*)s;
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
diff --git a/src/lib/libast/tm/tmxdate.c b/src/lib/libast/tm/tmxdate.c
new file mode 100644
index 0000000..8048f7f
--- /dev/null
+++ b/src/lib/libast/tm/tmxdate.c
@@ -0,0 +1,1745 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * Time_t conversion support
+ *
+ * relative times inspired by Steve Bellovin's netnews getdate(3)
+ */
+
+#include <tmx.h>
+#include <ctype.h>
+#include <debug.h>
+
+#define dig1(s,n) ((n)=((*(s)++)-'0'))
+#define dig2(s,n) ((n)=((*(s)++)-'0')*10,(n)+=(*(s)++)-'0')
+#define dig3(s,n) ((n)=((*(s)++)-'0')*100,(n)+=((*(s)++)-'0')*10,(n)+=(*(s)++)-'0')
+#define dig4(s,n) ((n)=((*(s)++)-'0')*1000,(n)+=((*(s)++)-'0')*100,(n)+=((*(s)++)-'0')*10,(n)+=(*(s)++)-'0')
+
+#undef BREAK
+
+#define BREAK (1<<0)
+#define CCYYMMDDHHMMSS (1<<1)
+#define CRON (1<<2)
+#define DAY (1<<3)
+#define EXACT (1<<4)
+#define FINAL (1<<5)
+#define HOLD (1<<6)
+#define HOUR (1<<7)
+#define LAST (1<<8)
+#define MDAY (1<<9)
+#define MINUTE (1<<10)
+#define MONTH (1<<11)
+#define NEXT (1<<12)
+#define NSEC (1<<13)
+#define ORDINAL (1<<14)
+#define SECOND (1<<15)
+#define THIS (1L<<16)
+#define WDAY (1L<<17)
+#define WORK (1L<<18)
+#define YEAR (1L<<19)
+#define ZONE (1L<<20)
+
+#define FFMT "%s%s%s%s%s%s%s|"
+#define FLAGS(f) (f&EXACT)?"|EXACT":"",(f&LAST)?"|LAST":"",(f&THIS)?"|THIS":"",(f&NEXT)?"|NEXT":"",(f&ORDINAL)?"|ORDINAL":"",(f&FINAL)?"|FINAL":"",(f&WORK)?"|WORK":""
+/*
+ * parse cron range into set
+ * return: -1:error 0:* 1:some
+ */
+
+static int
+range(register char* s, char** e, char* set, int lo, int hi)
+{
+ int n;
+ int m;
+ int i;
+ char* t;
+
+ while (isspace(*s) || *s == '_')
+ s++;
+ if (*s == '*')
+ {
+ *e = s + 1;
+ return 0;
+ }
+ memset(set, 0, hi + 1);
+ for (;;)
+ {
+ n = strtol(s, &t, 10);
+ if (s == t || n < lo || n > hi)
+ return -1;
+ i = 1;
+ if (*(s = t) == '-')
+ {
+ m = strtol(++s, &t, 10);
+ if (s == t || m < n || m > hi)
+ return -1;
+ if (*(s = t) == '/')
+ {
+ i = strtol(++s, &t, 10);
+ if (s == t || i < 1)
+ return -1;
+ s = t;
+ }
+ }
+ else
+ m = n;
+ for (; n <= m; n += i)
+ set[n] = 1;
+ if (*s != ',')
+ break;
+ s++;
+ }
+ *e = s;
+ return 1;
+}
+
+/*
+ * normalize <p,q> to power of 10 u in tm
+ */
+
+static void
+powerize(Tm_t* tm, unsigned long p, unsigned long q, unsigned long u)
+{
+ Time_t t = p;
+
+ while (q > u)
+ {
+ q /= 10;
+ t /= 10;
+ }
+ while (q < u)
+ {
+ q *= 10;
+ t *= 10;
+ }
+ tm->tm_nsec += (int)(t % TMX_RESOLUTION);
+ tm->tm_sec += (int)(t / TMX_RESOLUTION);
+}
+
+#define K1(c1) (c1)
+#define K2(c1,c2) (((c1)<<8)|(c2))
+#define K3(c1,c2,c3) (((c1)<<16)|((c2)<<8)|(c3))
+#define K4(c1,c2,c3,c4) (((c1)<<24)|((c2)<<16)|((c3)<<8)|(c4))
+
+#define P_INIT(n) w = n; p = q = 0; u = (char*)s + 1
+
+/*
+ * parse date expression in s and return Time_t value
+ *
+ * if non-null, e points to the first invalid sequence in s
+ * now provides default values
+ */
+
+Time_t
+tmxdate(register const char* s, char** e, Time_t now)
+{
+ register Tm_t* tm;
+ register long n;
+ register int w;
+ unsigned long set;
+ unsigned long state;
+ unsigned long flags;
+ Time_t fix;
+ char* t;
+ char* u;
+ const char* o;
+ const char* x;
+ char* last;
+ char* type;
+ int day;
+ int dir;
+ int dst;
+ int zone;
+ int c;
+ int f;
+ int i;
+ int j;
+ int k;
+ int l;
+ long m;
+ unsigned long p;
+ unsigned long q;
+ Tm_zone_t* zp;
+ Tm_t ts;
+ char skip[UCHAR_MAX + 1];
+
+ /*
+ * check DATEMSK first
+ */
+
+ debug((error(-1, "AHA tmxdate 2009-03-06")));
+ fix = tmxscan(s, &last, NiL, &t, now, 0);
+ if (t && !*last)
+ {
+ if (e)
+ *e = last;
+ return fix;
+ }
+ o = s;
+
+ reset:
+
+ /*
+ * use now for defaults
+ */
+
+ tm = tmxtm(&ts, now, NiL);
+ tm_info.date = tm->tm_zone;
+ day = -1;
+ dir = 0;
+ dst = TM_DST;
+ set = state = 0;
+ type = 0;
+ zone = TM_LOCALZONE;
+ skip[0] = 0;
+ for (n = 1; n <= UCHAR_MAX; n++)
+ skip[n] = isspace(n) || strchr("_,;@=|!^()[]{}", n);
+
+ /*
+ * get <weekday year month day hour minutes seconds ?[ds]t [ap]m>
+ */
+
+ again:
+ for (;;)
+ {
+ state &= (state & HOLD) ? ~(HOLD) : ~(EXACT|LAST|NEXT|THIS);
+ if ((set|state) & (YEAR|MONTH|DAY))
+ skip['/'] = 1;
+ message((-1, "AHA#%d state=" FFMT " set=" FFMT, __LINE__, FLAGS(state), FLAGS(set)));
+ for (;;)
+ {
+ if (*s == '.' || *s == '-' || *s == '+')
+ {
+ if (((set|state) & (YEAR|MONTH|HOUR|MINUTE|ZONE)) == (YEAR|MONTH|HOUR|MINUTE) && (i = tmgoff(s, &t, TM_LOCALZONE)) != TM_LOCALZONE)
+ {
+ zone = i;
+ state |= ZONE;
+ if (!*(s = t))
+ break;
+ }
+ else if (*s == '+')
+ break;
+ }
+ else if (!skip[*s])
+ break;
+ s++;
+ }
+ if (!*(last = (char*)s))
+ break;
+ if (*s == '#')
+ {
+ if (isdigit(*++s))
+ {
+ now = strtoull(s, &t, 0);
+ sns:
+ if (*(s = t) == '.')
+ {
+ fix = 0;
+ m = 1000000000;
+ while (isdigit(*++s))
+ fix += (*s - '0') * (m /= 10);
+ now = tmxsns(now, fix);
+ }
+ else if (now <= 0x7fffffff)
+ now = tmxsns(now, 0);
+ goto reset;
+ }
+ else if (*s++ == '#')
+ {
+ now = tmxtime(tm, zone);
+ goto reset;
+ }
+ break;
+ }
+ if ((*s == 'P' || *s == 'p') && (!isalpha(*(s + 1)) || (*(s + 1) == 'T' || *(s + 1) == 't') && !isalpha(*(s + 2))))
+ {
+ Tm_t otm;
+
+ /*
+ * iso duration
+ */
+
+ otm = *tm;
+ t = (char*)s;
+ m = 0;
+ P_INIT('Y');
+ do
+ {
+ c = *++s;
+ duration_next:
+ switch (c)
+ {
+ case 0:
+ m++;
+ if ((char*)s > u)
+ {
+ s--;
+ c = '_';
+ goto duration_next;
+ }
+ break;
+ case 'T':
+ case 't':
+ m++;
+ if ((char*)s > u)
+ {
+ s++;
+ c = 'D';
+ goto duration_next;
+ }
+ continue;
+ case 'Y':
+ case 'y':
+ m = 0;
+ if (q > 1)
+ tm->tm_sec += (365L*24L*60L*60L) * p / q;
+ else
+ tm->tm_year += p;
+ P_INIT('M');
+ continue;
+ case 'm':
+ if (!m)
+ m = 1;
+ /*FALLTHROUGH*/
+ case 'M':
+ switch (*(s + 1))
+ {
+ case 'I':
+ case 'i':
+ s++;
+ m = 1;
+ w = 'S';
+ break;
+ case 'O':
+ case 'o':
+ s++;
+ m = 0;
+ w = 'H';
+ break;
+ case 'S':
+ case 's':
+ s++;
+ m = 2;
+ w = 's';
+ break;
+ }
+ switch (m)
+ {
+ case 0:
+ m = 1;
+ if (q > 1)
+ tm->tm_sec += (3042L*24L*60L*60L) * p / q / 100L;
+ else
+ tm->tm_mon += p;
+ break;
+ case 1:
+ m = 2;
+ if (q > 1)
+ tm->tm_sec += (60L) * p / q;
+ else
+ tm->tm_min += p;
+ break;
+ default:
+ if (q > 1)
+ powerize(tm, p, q, 1000UL);
+ else
+ tm->tm_nsec += p * 1000000L;
+ break;
+ }
+ P_INIT(w);
+ continue;
+ case 'W':
+ case 'w':
+ m = 0;
+ if (q > 1)
+ tm->tm_sec += (7L*24L*60L*60L) * p / q;
+ else
+ tm->tm_mday += 7 * p;
+ P_INIT('D');
+ continue;
+ case 'D':
+ case 'd':
+ m = 0;
+ if (q > 1)
+ tm->tm_sec += (24L*60L*60L) * p / q;
+ else
+ tm->tm_mday += p;
+ P_INIT('H');
+ continue;
+ case 'H':
+ case 'h':
+ m = 1;
+ if (q > 1)
+ tm->tm_sec += (60L*60L) * p / q;
+ else
+ tm->tm_hour += p;
+ P_INIT('m');
+ continue;
+ case 'S':
+ case 's':
+ m = 2;
+ /*FALLTHROUGH*/
+ case ' ':
+ case '_':
+ case '\n':
+ case '\r':
+ case '\t':
+ case '\v':
+ if (q > 1)
+ powerize(tm, p, q, 1000000000UL);
+ else
+ tm->tm_sec += p;
+ P_INIT('U');
+ continue;
+ case 'U':
+ case 'u':
+ switch (*(s + 1))
+ {
+ case 'S':
+ case 's':
+ s++;
+ break;
+ }
+ m = 0;
+ if (q > 1)
+ powerize(tm, p, q, 1000000UL);
+ else
+ tm->tm_nsec += p * 1000L;
+ P_INIT('N');
+ continue;
+ case 'N':
+ case 'n':
+ switch (*(s + 1))
+ {
+ case 'S':
+ case 's':
+ s++;
+ break;
+ }
+ m = 0;
+ if (q > 1)
+ powerize(tm, p, q, 1000000000UL);
+ else
+ tm->tm_nsec += p;
+ P_INIT('Y');
+ continue;
+ case '.':
+ if (q)
+ goto exact;
+ q = 1;
+ continue;
+ case '-':
+ c = 'M';
+ u = (char*)s++;
+ while (*++u && *u != ':')
+ if (*u == '-')
+ {
+ c = 'Y';
+ break;
+ }
+ goto duration_next;
+ case ':':
+ c = 'm';
+ u = (char*)s++;
+ while (*++u)
+ if (*u == ':')
+ {
+ c = 'H';
+ break;
+ }
+ goto duration_next;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ q *= 10;
+ p = p * 10 + (c - '0');
+ continue;
+ default:
+ exact:
+ *tm = otm;
+ s = (const char*)t + 1;
+ if (*t == 'p')
+ {
+ state |= HOLD|EXACT;
+ set &= ~(EXACT|LAST|NEXT|THIS);
+ set |= state & (EXACT|LAST|NEXT|THIS);
+ }
+ goto again;
+ }
+ break;
+ } while (c);
+ continue;
+ }
+ f = -1;
+ if (*s == '+')
+ {
+ while (isspace(*++s) || *s == '_');
+ n = strtol(s, &t, 0);
+ if (w = t - s)
+ {
+ for (s = t; skip[*s]; s++);
+ state |= (f = n) ? NEXT : THIS;
+ set &= ~(EXACT|LAST|NEXT|THIS);
+ set |= state & (EXACT|LAST|NEXT|THIS);
+ }
+ else
+ s = last;
+ }
+ if (!(state & CRON))
+ {
+ /*
+ * check for cron date
+ *
+ * min hour day-of-month month day-of-week
+ *
+ * if it's cron then determine the next time
+ * that satisfies the specification
+ *
+ * NOTE: the only spacing is ' '||'_'||';'
+ */
+
+ i = 0;
+ n = *(t = (char*)s);
+ for (;;)
+ {
+ if (n == '*')
+ n = *++s;
+ else if (!isdigit(n))
+ break;
+ else
+ while ((n = *++s) == ',' || n == '-' || n == '/' || isdigit(n));
+ if (n != ' ' && n != '_' && n != ';')
+ {
+ if (!n)
+ i++;
+ break;
+ }
+ i++;
+ while ((n = *++s) == ' ' || n == '_');
+ }
+ if (i == 5)
+ {
+ Time_t tt;
+ char hit[60];
+ char mon[13];
+ char day[7];
+
+ state |= CRON;
+ flags = 0;
+ tm->tm_sec = 0;
+ tm->tm_min++;
+ tmfix(tm);
+
+ /*
+ * minute
+ */
+
+ if ((k = range(t, &t, hit, 0, 59)) < 0)
+ break;
+ if (k && !hit[i = tm->tm_min])
+ {
+ hit[i] = 1;
+ do if (++i > 59)
+ {
+ i = 0;
+ if (++tm->tm_hour > 59)
+ {
+ tm->tm_min = i;
+ tmfix(tm);
+ }
+ } while (!hit[i]);
+ tm->tm_min = i;
+ }
+
+ /*
+ * hour
+ */
+
+ if ((k = range(t, &t, hit, 0, 23)) < 0)
+ break;
+ if (k && !hit[i = tm->tm_hour])
+ {
+ hit[i] = 1;
+ do if (++i > 23)
+ {
+ i = 0;
+ if (++tm->tm_mday > 28)
+ {
+ tm->tm_hour = i;
+ tmfix(tm);
+ }
+ } while (!hit[i]);
+ tm->tm_hour = i;
+ }
+
+ /*
+ * day of month
+ */
+
+ if ((k = range(t, &t, hit, 1, 31)) < 0)
+ break;
+ if (k)
+ flags |= DAY|MDAY;
+
+ /*
+ * month
+ */
+
+ if ((k = range(t, &t, mon, 1, 12)) < 0)
+ break;
+ if (k)
+ flags |= MONTH;
+ else
+ for (i = 1; i <= 12; i++)
+ mon[i] = 1;
+
+ /*
+ * day of week
+ */
+
+ if ((k = range(t, &t, day, 0, 6)) < 0)
+ break;
+ if (k)
+ flags |= WDAY;
+ s = t;
+ if (flags & (MONTH|MDAY|WDAY))
+ {
+ fix = tmxtime(tm, zone);
+ tm = tmxtm(tm, fix, tm->tm_zone);
+ i = tm->tm_mon + 1;
+ j = tm->tm_mday;
+ k = tm->tm_wday;
+ for (;;)
+ {
+ if (!mon[i])
+ {
+ if (++i > 12)
+ {
+ i = 1;
+ tm->tm_year++;
+ }
+ tm->tm_mon = i - 1;
+ tm->tm_mday = 1;
+ tt = tmxtime(tm, zone);
+ if (tt < fix)
+ goto done;
+ tm = tmxtm(tm, tt, tm->tm_zone);
+ i = tm->tm_mon + 1;
+ j = tm->tm_mday;
+ k = tm->tm_wday;
+ continue;
+ }
+ if (flags & (MDAY|WDAY))
+ {
+ if ((flags & (MDAY|WDAY)) == (MDAY|WDAY))
+ {
+ if (hit[j] && day[k])
+ break;
+ }
+ else if ((flags & MDAY) && hit[j])
+ break;
+ else if ((flags & WDAY) && day[k])
+ break;
+ if (++j > 28)
+ {
+ tm->tm_mon = i - 1;
+ tm->tm_mday = j;
+ tm = tmxtm(tm, tmxtime(tm, zone), tm->tm_zone);
+ i = tm->tm_mon + 1;
+ j = tm->tm_mday;
+ k = tm->tm_wday;
+ }
+ else if ((flags & WDAY) && ++k > 6)
+ k = 0;
+ }
+ else if (flags & MONTH)
+ break;
+ }
+ tm->tm_mon = i - 1;
+ tm->tm_mday = j;
+ tm->tm_wday = k;
+ }
+ continue;
+ }
+ s = t;
+ }
+ n = -1;
+ if (isdigit(*s))
+ {
+ n = strtol(s, &t, 10);
+ if ((w = t - s) && *t == '.' && isdigit(*(t + 1)) && isdigit(*(t + 2)) && isdigit(*(t + 3)))
+ {
+ now = n;
+ goto sns;
+ }
+ if ((*t == 'T' || *t == 't') && ((set|state) & (YEAR|MONTH|DAY)) == (YEAR|MONTH) && isdigit(*(t + 1)))
+ t++;
+ u = t + (*t == '-');
+ message((-1, "AHA#%d n=%d w=%d u='%c' f=%d t=\"%s\"", __LINE__, n, w, *u, f, t));
+ if ((w == 2 || w == 4) && (*u == 'W' || *u == 'w') && isdigit(*(u + 1)))
+ {
+ if (w == 4)
+ {
+ if ((n -= 1900) < TM_WINDOW)
+ break;
+ }
+ else if (n < TM_WINDOW)
+ n += 100;
+ m = n;
+ n = strtol(++u, &t, 10);
+ if ((i = (t - u)) < 2 || i > 3)
+ break;
+ if (i == 3)
+ {
+ k = n % 10;
+ n /= 10;
+ }
+ else if (*t != '-')
+ k = 1;
+ else if (*++t && dig1(t, k) < 1 || k > 7)
+ break;
+ if (n < 0 || n > 53)
+ break;
+ if (k == 7)
+ k = 0;
+ tm->tm_year = m;
+ tmweek(tm, 2, n, k);
+ set |= YEAR|MONTH|DAY;
+ s = t;
+ continue;
+ }
+ else if (w == 6 || w == 8 && (n / 1000000) > 12)
+ {
+ t = (char*)s;
+ flags = 0;
+ if (w == 8 || w == 6 && *u != 'T' && *u != 't')
+ {
+ dig4(t, m);
+ if ((m -= 1900) < TM_WINDOW)
+ break;
+ }
+ else
+ {
+ dig2(t, m);
+ if (m < TM_WINDOW)
+ m += 100;
+ }
+ flags |= YEAR;
+ if (dig2(t, l) <= 0 || l > 12)
+ break;
+ flags |= MONTH;
+ if (*t != 'T' && *t != 't' || !isdigit(*++t))
+ {
+ if (w == 6)
+ goto save_yymm;
+ if (dig2(t, k) < 1 || k > 31)
+ break;
+ flags |= DAY;
+ goto save_yymmdd;
+ }
+ n = strtol(s = t, &t, 0);
+ if ((t - s) < 2)
+ break;
+ if (dig2(s, j) > 24)
+ break;
+ if ((t - s) < 2)
+ {
+ if ((t - s) == 1 || *t++ != '-')
+ break;
+ n = strtol(s = t, &t, 0);
+ if ((t - s) < 2)
+ break;
+ }
+ if (dig2(s, i) > 59)
+ break;
+ flags |= HOUR|MINUTE;
+ if ((t - s) == 2)
+ {
+ if (dig2(s, n) > (59 + TM_MAXLEAP))
+ break;
+ flags |= SECOND;
+ }
+ else if (t - s)
+ break;
+ else
+ n = 0;
+ p = 0;
+ if (*t == '.')
+ {
+ q = 1000000000;
+ while (isdigit(*++t))
+ p += (*t - '0') * (q /= 10);
+ set |= NSEC;
+ }
+ if (n > (59 + TM_MAXLEAP))
+ break;
+ goto save;
+ }
+ else if (f == -1 && isalpha(*t) && tmlex(t, &t, tm_info.format + TM_ORDINAL, TM_ORDINALS - TM_ORDINAL, NiL, 0) >= 0)
+ {
+ message((-1, "AHA#%d n=%d", __LINE__, n));
+ ordinal:
+ if (n)
+ n--;
+ message((-1, "AHA#%d n=%d", __LINE__, n));
+ state |= ((f = n) ? NEXT : THIS)|ORDINAL;
+ set &= ~(EXACT|LAST|NEXT|THIS);
+ set |= state & (EXACT|LAST|NEXT|THIS);
+ for (s = t; skip[*s]; s++);
+ if (isdigit(*s))
+ {
+ if (n = strtol(s, &t, 10))
+ n--;
+ s = t;
+ if (*s == '_')
+ s++;
+ }
+ else
+ n = -1;
+ dir = f;
+ message((-1, "AHA#%d f=%d n=%d state=" FFMT, __LINE__, f, n, FLAGS(state)));
+ }
+ else
+ {
+ for (u = t; isspace(*u); u++);
+ message((-1, "AHA#%d n=%d u=\"%s\"", __LINE__, n, u));
+ if ((j = tmlex(u, NiL, tm_info.format, TM_NFORM, tm_info.format + TM_SUFFIXES, TM_PARTS - TM_SUFFIXES)) >= 0 && tm_data.lex[j] == TM_PARTS)
+ s = u;
+ else
+ {
+ message((-1, "AHA#%d t=\"%s\"", __LINE__, t));
+ if (!(state & (LAST|NEXT|THIS)) && ((i = t - s) == 4 && (*t == '.' && isdigit(*(t + 1)) && isdigit(*(t + 2)) && *(t + 3) != '.' || (!*t || isspace(*t) || *t == '_' || isalnum(*t)) && n >= 0 && (n % 100) < 60 && ((m = (n / 100)) < 20 || m < 24 && !((set|state) & (YEAR|MONTH|HOUR|MINUTE)))) || i > 4 && i <= 12))
+ {
+ /*
+ * various { date(1) touch(1) } formats
+ *
+ * [[cc]yy[mm]]ddhhmm[.ss[.nn...]]
+ * [cc]yyjjj
+ * hhmm[.ss[.nn...]]
+ */
+
+ message((-1, "AHA#%d t=\"%s\"", __LINE__, t));
+ flags = 0;
+ if (state & CCYYMMDDHHMMSS)
+ break;
+ state |= CCYYMMDDHHMMSS;
+ p = 0;
+ if ((i == 7 || i == 5) && (!*t || *t == 'Z' || *t == 'z'))
+ {
+ if (i == 7)
+ {
+ dig4(s, m);
+ if ((m -= 1900) < TM_WINDOW)
+ break;
+ }
+ else if (dig2(s, m) < TM_WINDOW)
+ m += 100;
+ dig3(s, k);
+ l = 1;
+ j = 0;
+ i = 0;
+ n = 0;
+ flags |= MONTH;
+ }
+ else if (i & 1)
+ break;
+ else
+ {
+ u = t;
+ if (i == 12)
+ {
+ x = s;
+ dig2(x, m);
+ if (m <= 12)
+ {
+ u -= 4;
+ i -= 4;
+ x = s + 8;
+ dig4(x, m);
+ }
+ else
+ dig4(s, m);
+ if (m < 1969 || m >= 3000)
+ break;
+ m -= 1900;
+ }
+ else if (i == 10)
+ {
+ x = s;
+ if (!dig2(x, m) || m > 12 || !dig2(x, m) || m > 31 || dig2(x, m) > 24 || dig2(x, m) > 60 || dig2(x, m) <= 60 && !(tm_info.flags & TM_DATESTYLE))
+ dig2(s, m);
+ else
+ {
+ u -= 2;
+ i -= 2;
+ x = s + 8;
+ dig2(x, m);
+ }
+ if (m < TM_WINDOW)
+ m += 100;
+ }
+ else
+ m = tm->tm_year;
+ if ((u - s) < 8)
+ l = tm->tm_mon + 1;
+ else if (dig2(s, l) <= 0 || l > 12)
+ break;
+ else
+ flags |= MONTH;
+ if ((u - s) < 6)
+ k = tm->tm_mday;
+ else if (dig2(s, k) < 1 || k > 31)
+ break;
+ else
+ flags |= DAY;
+ if ((u - s) < 4)
+ break;
+ if (dig2(s, j) > 24)
+ break;
+ if (dig2(s, i) > 59)
+ break;
+ flags |= HOUR|MINUTE;
+ if ((u - s) == 2)
+ {
+ dig2(s, n);
+ flags |= SECOND;
+ }
+ else if (u - s)
+ break;
+ else if (*t != '.')
+ n = 0;
+ else
+ {
+ n = strtol(t + 1, &t, 10);
+ flags |= SECOND;
+ if (*t == '.')
+ {
+ q = 1000000000;
+ while (isdigit(*++t))
+ p += (*t - '0') * (q /= 10);
+ set |= NSEC;
+ }
+ }
+ if (n > (59 + TM_MAXLEAP))
+ break;
+ }
+ save:
+ tm->tm_hour = j;
+ tm->tm_min = i;
+ tm->tm_sec = n;
+ tm->tm_nsec = p;
+ save_yymmdd:
+ tm->tm_mday = k;
+ save_yymm:
+ tm->tm_mon = l - 1;
+ tm->tm_year = m;
+ s = t;
+ set |= flags;
+ continue;
+ }
+ for (s = t; skip[*s]; s++);
+ message((-1, "AHA#%d s=\"%s\"", __LINE__, s));
+ if (*s == ':' || *s == '.' && ((set|state) & (YEAR|MONTH|DAY|HOUR)) == (YEAR|MONTH|DAY))
+ {
+ c = *s;
+ if ((state & HOUR) || n > 24)
+ break;
+ while (isspace(*++s) || *s == '_');
+ if (!isdigit(*s))
+ break;
+ i = n;
+ n = strtol(s, &t, 10);
+ for (s = t; isspace(*s) || *s == '_'; s++);
+ if (n > 59)
+ break;
+ j = n;
+ m = 0;
+ if (*s == c)
+ {
+ while (isspace(*++s) || *s == '_');
+ if (!isdigit(*s))
+ break;
+ n = strtol(s, &t, 10);
+ s = t;
+ if (n > (59 + TM_MAXLEAP))
+ break;
+ set |= SECOND;
+ while (isspace(*s))
+ s++;
+ if (*s == '.')
+ {
+ q = 1000000000;
+ while (isdigit(*++s))
+ m += (*s - '0') * (q /= 10);
+ set |= NSEC;
+ }
+ }
+ else
+ n = 0;
+ set |= HOUR|MINUTE;
+ skip[':'] = 1;
+ k = tm->tm_hour;
+ tm->tm_hour = i;
+ l = tm->tm_min;
+ tm->tm_min = j;
+ tm->tm_sec = n;
+ tm->tm_nsec = m;
+ while (isspace(*s))
+ s++;
+ switch (tmlex(s, &t, tm_info.format, TM_NFORM, tm_info.format + TM_MERIDIAN, 2))
+ {
+ case TM_MERIDIAN:
+ s = t;
+ if (i == 12)
+ tm->tm_hour = i = 0;
+ break;
+ case TM_MERIDIAN+1:
+ if (i < 12)
+ tm->tm_hour = i += 12;
+ break;
+ }
+ if (f >= 0 || (state & (LAST|NEXT)))
+ {
+ message((-1, "AHA#%d f=%d i=%d j=%d k=%d l=%d", __LINE__, f, i, j, k, l));
+ state &= ~HOLD;
+ if (f < 0)
+ {
+ if (state & LAST)
+ f = -1;
+ else if (state & NEXT)
+ f = 1;
+ else
+ f = 0;
+ }
+ if (f > 0)
+ {
+ if (i > k || i == k && j > l)
+ f--;
+ }
+ else if (i < k || i == k && j < l)
+ f++;
+ if (f > 0)
+ {
+ tm->tm_hour += f * 24;
+ while (tm->tm_hour >= 24)
+ {
+ tm->tm_hour -= 24;
+ tm->tm_mday++;
+ }
+ }
+ else if (f < 0)
+ {
+ tm->tm_hour += f * 24;
+ while (tm->tm_hour < 24)
+ {
+ tm->tm_hour += 24;
+ tm->tm_mday--;
+ }
+ }
+ }
+ continue;
+ }
+ }
+ }
+ }
+ for (;;)
+ {
+ message((-1, "AHA#%d s=\"%s\"", __LINE__, s));
+ if (*s == '-' || *s == '+')
+ {
+ if (((set|state) & (MONTH|DAY|HOUR|MINUTE)) == (MONTH|DAY|HOUR|MINUTE) || *s == '+' && (!isdigit(s[1]) || !isdigit(s[2]) || s[3] != ':' && (s[3] != '.' || ((set|state) & (YEAR|MONTH)) != (YEAR|MONTH))))
+ break;
+ s++;
+ }
+ else if (skip[*s])
+ s++;
+ else
+ break;
+ }
+ if (isalpha(*s))
+ {
+ if (n > 0)
+ {
+ x = s;
+ q = *s++;
+ message((-1, "AHA#%d n=%d q='%c'", __LINE__, n, q));
+ if (isalpha(*s))
+ {
+ q <<= 8;
+ q |= *s++;
+ if (isalpha(*s))
+ {
+ if (tmlex(s, &t, tm_info.format + TM_SUFFIXES, TM_PARTS - TM_SUFFIXES, NiL, 0) >= 0)
+ s = t;
+ if (isalpha(*s))
+ {
+ q <<= 8;
+ q |= *s++;
+ if (isalpha(*s))
+ {
+ q <<= 8;
+ q |= *s++;
+ if (isalpha(*s))
+ q = 0;
+ }
+ }
+ }
+ }
+ switch (q)
+ {
+ case K1('y'):
+ case K1('Y'):
+ case K2('y','r'):
+ case K2('Y','R'):
+ tm->tm_year += n;
+ set |= YEAR;
+ continue;
+ case K1('M'):
+ case K2('m','o'):
+ case K2('M','O'):
+ tm->tm_mon += n;
+ set |= MONTH;
+ continue;
+ case K1('w'):
+ case K1('W'):
+ case K2('w','k'):
+ case K2('W','K'):
+ tm->tm_mday += n * 7;
+ set |= DAY;
+ continue;
+ case K1('d'):
+ case K1('D'):
+ case K2('d','a'):
+ case K2('d','y'):
+ case K2('D','A'):
+ case K2('D','Y'):
+ tm->tm_mday += n;
+ set |= DAY;
+ continue;
+ case K1('h'):
+ case K1('H'):
+ case K2('h','r'):
+ case K2('H','R'):
+ tm->tm_hour += n;
+ set |= HOUR;
+ continue;
+ case K1('m'):
+ case K2('m','n'):
+ case K2('M','N'):
+ tm->tm_min += n;
+ set |= MINUTE;
+ continue;
+ case K1('s'):
+ case K2('s','c'):
+ case K1('S'):
+ case K2('S','C'):
+ tm->tm_sec += n;
+ set |= SECOND;
+ continue;
+ case K2('m','s'):
+ case K3('m','s','c'):
+ case K4('m','s','e','c'):
+ case K2('M','S'):
+ case K3('M','S','C'):
+ case K4('M','S','E','C'):
+ tm->tm_nsec += n * 1000000L;
+ continue;
+ case K1('u'):
+ case K2('u','s'):
+ case K3('u','s','c'):
+ case K4('u','s','e','c'):
+ case K1('U'):
+ case K2('U','S'):
+ case K3('U','S','C'):
+ case K4('U','S','E','C'):
+ tm->tm_nsec += n * 1000L;
+ continue;
+ case K2('n','s'):
+ case K3('n','s','c'):
+ case K4('n','s','e','c'):
+ case K2('N','S'):
+ case K3('N','S','C'):
+ case K4('N','S','E','C'):
+ tm->tm_nsec += n;
+ continue;
+ }
+ s = x;
+ }
+ if ((j = tmlex(s, &t, tm_info.format, TM_NFORM, tm_info.format + TM_SUFFIXES, TM_PARTS - TM_SUFFIXES)) >= 0)
+ {
+ if (tm_data.lex[j] == TM_PARTS || n < 1000)
+ {
+ s = t;
+ switch (tm_data.lex[j])
+ {
+ case TM_EXACT:
+ state |= HOLD|EXACT;
+ set &= ~(EXACT|LAST|NEXT|THIS);
+ set |= state & (EXACT|LAST|NEXT|THIS);
+ continue;
+ case TM_LAST:
+ state |= HOLD|LAST;
+ set &= ~(EXACT|LAST|NEXT|THIS);
+ set |= state & (EXACT|LAST|NEXT|THIS);
+ continue;
+ case TM_THIS:
+ state |= HOLD|THIS;
+ set &= ~(EXACT|LAST|NEXT|THIS);
+ set |= state & (EXACT|LAST|NEXT|THIS);
+ n = 0;
+ continue;
+ case TM_NEXT:
+ /*
+ * disambiguate english "last ... in"
+ */
+
+ if (!((state|set) & LAST))
+ {
+ state |= HOLD|NEXT;
+ set &= ~(EXACT|LAST|NEXT|THIS);
+ set |= state & (EXACT|LAST|NEXT|THIS);
+ continue;
+ }
+ /*FALLTHROUGH*/
+ case TM_FINAL:
+ state |= HOLD|THIS|FINAL;
+ set &= ~(EXACT|LAST|NEXT|THIS);
+ set |= state & (EXACT|LAST|NEXT|THIS|FINAL);
+ continue;
+ case TM_WORK:
+ message((-1, "AHA#%d WORK", __LINE__));
+ state |= WORK;
+ set |= DAY;
+ if (state & LAST)
+ {
+ state &= ~LAST;
+ set &= ~LAST;
+ state |= FINAL;
+ set |= FINAL;
+ }
+ goto clear_hour;
+ case TM_ORDINAL:
+ j += TM_ORDINALS - TM_ORDINAL;
+ message((-1, "AHA#%d j=%d", __LINE__, j));
+ /*FALLTHROUGH*/
+ case TM_ORDINALS:
+ n = j - TM_ORDINALS + 1;
+ message((-1, "AHA#%d n=%d", __LINE__, n));
+ goto ordinal;
+ case TM_MERIDIAN:
+ if (f >= 0)
+ f++;
+ else if (state & LAST)
+ f = -1;
+ else if (state & THIS)
+ f = 1;
+ else if (state & NEXT)
+ f = 2;
+ else
+ f = 0;
+ if (n > 0)
+ {
+ if (n > 24)
+ goto done;
+ tm->tm_hour = n;
+ }
+ for (k = tm->tm_hour; k < 0; k += 24);
+ k %= 24;
+ if (j == TM_MERIDIAN)
+ {
+ if (k == 12)
+ tm->tm_hour -= 12;
+ }
+ else if (k < 12)
+ tm->tm_hour += 12;
+ if (n > 0)
+ goto clear_min;
+ continue;
+ case TM_DAY_ABBREV:
+ j += TM_DAY - TM_DAY_ABBREV;
+ /*FALLTHROUGH*/
+ case TM_DAY:
+ case TM_PARTS:
+ case TM_HOURS:
+ state |= set & (EXACT|LAST|NEXT|THIS);
+ if (!(state & (LAST|NEXT|THIS)))
+ for (;;)
+ {
+ while (skip[*s])
+ s++;
+ if ((k = tmlex(s, &t, tm_info.format + TM_LAST, TM_NOISE - TM_LAST, NiL, 0)) >= 0)
+ {
+ s = t;
+ if (k <= 2)
+ state |= LAST;
+ else if (k <= 5)
+ state |= THIS;
+ else if (k <= 8)
+ state |= NEXT;
+ else
+ state |= EXACT;
+ }
+ else
+ {
+ state |= (n > 0) ? NEXT : THIS;
+ break;
+ }
+ set &= ~(EXACT|LAST|NEXT|THIS);
+ set |= state & (EXACT|LAST|NEXT|THIS);
+ }
+ /*FALLTHROUGH*/
+ case TM_DAYS:
+ message((-1, "AHA#%d n=%d j=%d f=%d state=" FFMT, __LINE__, n, j, f, FLAGS(state)));
+ if (n == -1)
+ {
+ /*
+ * disambiguate english "second"
+ */
+
+ if (j == TM_PARTS && f == -1)
+ {
+ state &= ~(LAST|NEXT|THIS|ORDINAL); /*AHA*/
+ n = 2;
+ goto ordinal;
+ }
+ n = 1;
+ }
+
+ /*
+ * disambiguate "last" vs. { "previous" "final" }
+ */
+
+ while (isspace(*s))
+ s++;
+ message((-1, "AHA#%d disambiguate LAST s='%s'", __LINE__, s));
+ if ((k = tmlex(s, &t, tm_info.format + TM_NEXT, TM_EXACT - TM_NEXT, NiL, 0)) >= 0 || (k = tmlex(s, &t, tm_info.format + TM_PARTS + 3, 1, NiL, 0)) >= 0)
+ {
+ s = t;
+ if (state & LAST)
+ {
+ state &= ~LAST;
+ set &= ~LAST;
+ state |= FINAL;
+ set |= FINAL;
+ message((-1, "AHA#%d LAST => FINAL", __LINE__));
+ }
+ else
+ state &= ~(THIS|NEXT);
+ }
+ message((-1, "AHA#%d disambiguate LAST k=%d", __LINE__, k));
+ if (state & LAST)
+ n = -n;
+ else if (!(state & NEXT))
+ n--;
+ m = (f > 0) ? f * n : n;
+ message((-1, "AHA#%d f=%d n=%d i=%d j=%d k=%d l=%d m=%d state=" FFMT, __LINE__, f, n, i, j, k, l, m, FLAGS(state)));
+ switch (j)
+ {
+ case TM_DAYS+0:
+ tm->tm_mday--;
+ set |= DAY;
+ goto clear_hour;
+ case TM_DAYS+1:
+ set |= DAY;
+ goto clear_hour;
+ case TM_DAYS+2:
+ tm->tm_mday++;
+ set |= DAY;
+ goto clear_hour;
+ case TM_PARTS+0:
+ set |= SECOND;
+ if ((m < 0 ? -m : m) > (365L*24L*60L*60L))
+ {
+ now = tmxtime(tm, zone) + tmxsns(m, 0);
+ goto reset;
+ }
+ tm->tm_sec += m;
+ goto clear_nsec;
+ case TM_PARTS+1:
+ tm->tm_min += m;
+ set |= MINUTE;
+ goto clear_sec;
+ case TM_PARTS+2:
+ tm->tm_hour += m;
+ set |= MINUTE;
+ goto clear_min;
+ case TM_PARTS+3:
+ message((-1, "AHA#%d DAY m=%d n=%d%s", __LINE__, m, n, (state & LAST) ? " LAST" : ""));
+ if ((state & (LAST|NEXT|THIS)) == LAST)
+ tm->tm_mday = tm_data.days[tm->tm_mon] + (tm->tm_mon == 1 && tmisleapyear(tm->tm_year));
+ else if (state & ORDINAL)
+ tm->tm_mday = m + 1;
+ else
+ tm->tm_mday += m;
+ if (!(set & (FINAL|WORK)))
+ set |= HOUR;
+ goto clear_hour;
+ case TM_PARTS+4:
+ tm = tmxtm(tm, tmxtime(tm, zone), tm->tm_zone);
+ tm->tm_mday += 7 * m - tm->tm_wday + 1;
+ set |= DAY;
+ goto clear_hour;
+ case TM_PARTS+5:
+ tm->tm_mon += m;
+ set |= MONTH;
+ goto clear_mday;
+ case TM_PARTS+6:
+ tm->tm_year += m;
+ goto clear_mon;
+ case TM_HOURS+0:
+ tm->tm_mday += m;
+ set |= DAY;
+ goto clear_hour;
+ case TM_HOURS+1:
+ tm->tm_mday += m;
+ tm->tm_hour = 6;
+ set |= HOUR;
+ goto clear_min;
+ case TM_HOURS+2:
+ tm->tm_mday += m;
+ tm->tm_hour = 12;
+ set |= HOUR;
+ goto clear_min;
+ case TM_HOURS+3:
+ tm->tm_mday += m;
+ tm->tm_hour = 18;
+ set |= HOUR;
+ goto clear_min;
+ }
+ if (m >= 0 && (state & ORDINAL))
+ tm->tm_mday = 1;
+ tm = tmxtm(tm, tmxtime(tm, zone), tm->tm_zone);
+ day = j -= TM_DAY;
+ if (!dir)
+ dir = m;
+ message((-1, "AHA#%d j=%d m=%d", __LINE__, j, m));
+ j -= tm->tm_wday;
+ message((-1, "AHA#%d mday=%d wday=%d day=%d dir=%d f=%d i=%d j=%d l=%d m=%d", __LINE__, tm->tm_mday, tm->tm_wday, day, dir, f, i, j, l, m));
+ if (state & (LAST|NEXT|THIS))
+ {
+ if (state & ORDINAL)
+ {
+ while (isspace(*s))
+ s++;
+ if (isdigit(*s) || tmlex(s, &t, tm_info.format, TM_DAY_ABBREV, NiL, 0) >= 0)
+ {
+ state &= ~(LAST|NEXT|THIS);
+ goto clear_hour;
+ }
+ }
+ if (j < 0)
+ j += 7;
+ }
+ else if (j > 0)
+ j -= 7;
+ message((-1, "AHA#%d day=%d mday=%d f=%d m=%d j=%d state=" FFMT, __LINE__, day, tm->tm_mday, f, m, j, FLAGS(state)));
+ set |= DAY;
+ if (set & (FINAL|WORK))
+ goto clear_hour;
+ else if (state & (LAST|NEXT|THIS))
+ {
+ if (f >= 0)
+ day = -1;
+ else if (m > 0 && (state & (NEXT|YEAR|MONTH)) == NEXT && j >= 0)
+ m--;
+ tm->tm_mday += j + m * 7;
+ set &= ~(LAST|NEXT|THIS|ORDINAL); /*AHA*/
+ state &= ~(LAST|NEXT|THIS|ORDINAL); /*AHA*/
+ if (!(state & EXACT))
+ goto clear_hour;
+ }
+ continue;
+ case TM_MONTH_ABBREV:
+ j += TM_MONTH - TM_MONTH_ABBREV;
+ /*FALLTHROUGH*/
+ case TM_MONTH:
+ if (state & MONTH)
+ goto done;
+ state |= MONTH;
+ i = tm->tm_mon;
+ tm->tm_mon = j - TM_MONTH;
+ if (n < 0)
+ {
+ while (skip[*s])
+ s++;
+ if (isdigit(*s))
+ {
+ n = strtol(s, &t, 10);
+ if (n <= 31 && *t != ':')
+ s = t;
+ else
+ n = -1;
+ }
+ }
+ if (n >= 0)
+ {
+ if (n > 31)
+ goto done;
+ state |= DAY|MDAY;
+ tm->tm_mday = n;
+ if (f > 0)
+ tm->tm_year += f;
+ }
+ if (state & (LAST|NEXT|THIS))
+ {
+ n = i;
+ goto rel_month;
+ }
+ continue;
+ case TM_UT:
+ if (state & ZONE)
+ goto done;
+ state |= ZONE;
+ zone = tmgoff(s, &t, 0);
+ s = t;
+ continue;
+ case TM_DT:
+ if (!dst)
+ goto done;
+ if (!(state & ZONE))
+ {
+ dst = tm->tm_zone->dst;
+ zone = tm->tm_zone->west;
+ }
+ zone += tmgoff(s, &t, dst);
+ s = t;
+ dst = 0;
+ state |= ZONE;
+ continue;
+ case TM_NOISE:
+ continue;
+ }
+ }
+ }
+ if (n < 1000)
+ {
+ if (!(state & ZONE) && (zp = tmzone(s, &t, type, &dst)))
+ {
+ s = t;
+ zone = zp->west + dst;
+ tm_info.date = zp;
+ state |= ZONE;
+ if (n < 0)
+ continue;
+ }
+ else if (!type && (zp = tmtype(s, &t)))
+ {
+ s = t;
+ type = zp->type;
+ if (n < 0)
+ continue;
+ }
+ state |= BREAK;
+ }
+ }
+ else if (*s == '/')
+ {
+ if (!(state & (YEAR|MONTH)) && n >= 1969 && n < 3000 && (i = strtol(s + 1, &t, 10)) > 0 && i <= 12)
+ {
+ state |= YEAR;
+ tm->tm_year = n - 1900;
+ s = t;
+ i--;
+ }
+ else
+ {
+ if ((state & MONTH) || n <= 0 || n > 31)
+ break;
+ if (isalpha(*++s))
+ {
+ if ((i = tmlex(s, &t, tm_info.format, TM_DAY_ABBREV, NiL, 0)) < 0)
+ break;
+ if (i >= TM_MONTH)
+ i -= TM_MONTH;
+ s = t;
+ }
+ else
+ {
+ i = n - 1;
+ n = strtol(s, &t, 10);
+ s = t;
+ if (n <= 0 || n > 31)
+ break;
+ if (*s == '/' && !isdigit(*(s + 1)))
+ break;
+ }
+ state |= DAY;
+ tm->tm_mday = n;
+ }
+ state |= MONTH;
+ n = tm->tm_mon;
+ tm->tm_mon = i;
+ if (*s == '/')
+ {
+ n = strtol(++s, &t, 10);
+ w = t - s;
+ s = t;
+ if (*s == '/' || *s == ':' || *s == '-' || *s == '_')
+ s++;
+ }
+ else
+ {
+ if (state & (LAST|NEXT|THIS))
+ {
+ rel_month:
+ if (state & LAST)
+ tm->tm_year -= (tm->tm_mon < n) ? 0 : 1;
+ else
+ tm->tm_year += ((state & NEXT) ? 1 : 0) + ((tm->tm_mon < n) ? 1 : 0);
+ if (state & MDAY)
+ goto clear_hour;
+ set &= ~(LAST|NEXT|THIS); /*AHA*/
+ state &= ~(LAST|NEXT|THIS); /*AHA*/
+ goto clear_mday;
+ }
+ continue;
+ }
+ }
+ if (n < 0 || w > 4)
+ break;
+ if (w == 4)
+ {
+ if ((state & YEAR) || n < 1969 || n >= 3000)
+ break;
+ state |= YEAR;
+ tm->tm_year = n - 1900;
+ }
+ else if (w == 3)
+ {
+ if (state & (MONTH|MDAY|WDAY))
+ break;
+ state |= MONTH|DAY|MDAY;
+ tm->tm_mon = 0;
+ tm->tm_mday = n;
+ }
+ else if (w == 2 && !(state & YEAR))
+ {
+ state |= YEAR;
+ if (n < TM_WINDOW)
+ n += 100;
+ tm->tm_year = n;
+ }
+ else if (!(state & MONTH) && n >= 1 && n <= 12)
+ {
+ state |= MONTH;
+ tm->tm_mon = n - 1;
+ }
+ else if (!(state & (MDAY|WDAY)) && n >= 1 && n <= 31)
+ {
+ state |= DAY|MDAY|WDAY;
+ tm->tm_mday = n;
+ }
+ else
+ break;
+ if (state & BREAK)
+ {
+ last = t;
+ break;
+ }
+ continue;
+ clear_mon:
+ if ((set|state) & (EXACT|MONTH))
+ continue;
+ tm->tm_mon = 0;
+ clear_mday:
+ set |= MONTH;
+ if ((set|state) & (EXACT|DAY|HOUR))
+ continue;
+ tm->tm_mday = 1;
+ clear_hour:
+ message((-1, "AHA#%d DAY", __LINE__));
+ set |= DAY;
+ if ((set|state) & (EXACT|HOUR))
+ continue;
+ tm->tm_hour = 0;
+ clear_min:
+ set |= HOUR;
+ if ((set|state) & (EXACT|MINUTE))
+ continue;
+ tm->tm_min = 0;
+ clear_sec:
+ set |= MINUTE;
+ if ((set|state) & (EXACT|SECOND))
+ continue;
+ tm->tm_sec = 0;
+ clear_nsec:
+ set |= SECOND;
+ if ((set|state) & (EXACT|NSEC))
+ continue;
+ tm->tm_nsec = 0;
+ }
+ done:
+ if (day >= 0 && !(state & (MDAY|WDAY)))
+ {
+ message((-1, "AHA#%d day=%d dir=%d state=" FFMT, __LINE__, day, dir, FLAGS(state)));
+ tmfix(tm);
+ m = dir;
+ if (state & MONTH)
+ tm->tm_mday = 1;
+ else if (m < 0)
+ m++;
+ tm = tmxtm(tm, tmxtime(tm, zone), tm->tm_zone);
+ j = day - tm->tm_wday;
+ if (j < 0)
+ j += 7;
+ tm->tm_mday += j + m * 7;
+ if (state & FINAL)
+ for (n = tm_data.days[tm->tm_mon] + (tm->tm_mon == 1 && tmisleapyear(tm->tm_year)); (tm->tm_mday + 7) <= n; tm->tm_mday += 7);
+ }
+ else if (day < 0 && (state & FINAL) && (set & DAY))
+ {
+ tmfix(tm);
+ tm->tm_mday = tm_data.days[tm->tm_mon] + (tm->tm_mon == 1 && tmisleapyear(tm->tm_year));
+ }
+ if (state & WORK)
+ {
+ tm->tm_mday = (set & FINAL) ? (tm_data.days[tm->tm_mon] + (tm->tm_mon == 1 && tmisleapyear(tm->tm_year))) : 1;
+ tmfix(tm);
+ message((-1, "AHA#%d WORK mday=%d wday=%d", __LINE__, tm->tm_mday, tm->tm_wday));
+ if (tm->tm_wday == 0 && (j = 1) || tm->tm_wday == 6 && (j = 2))
+ {
+ if ((tm->tm_mday + j) > (tm_data.days[tm->tm_mon] + (tm->tm_mon == 1 && tmisleapyear(tm->tm_year))))
+ j -= 3;
+ tm->tm_mday += j;
+ }
+ }
+ now = tmxtime(tm, zone);
+ if (tm->tm_year <= 70 && tmxsec(now) > 31536000)
+ {
+ now = 0;
+ last = (char*)o;
+ }
+ if (e)
+ *e = last;
+ return now;
+}
diff --git a/src/lib/libast/tm/tmxduration.c b/src/lib/libast/tm/tmxduration.c
new file mode 100644
index 0000000..eb456a9
--- /dev/null
+++ b/src/lib/libast/tm/tmxduration.c
@@ -0,0 +1,80 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <tmx.h>
+#include <ctype.h>
+
+/*
+ * parse duration expression in s and return Time_t value
+ * if non-null, e points to the first unused char in s
+ * returns 0 with *e==s on error
+ */
+
+Time_t
+tmxduration(const char* s, char** e)
+{
+ Time_t ns;
+ Time_t ts;
+ Time_t now;
+ char* last;
+ char* t;
+ char* x;
+ Sfio_t* f;
+ int i;
+
+ now = TMX_NOW;
+ while (isspace(*s))
+ s++;
+ if (*s == 'P' || *s == 'p')
+ ns = tmxdate(s, &last, now) - now;
+ else
+ {
+ ns = strtod(s, &last) * TMX_RESOLUTION;
+ if (*last && (f = sfstropen()))
+ {
+ sfprintf(f, "exact %s", s);
+ t = sfstruse(f);
+ ts = tmxdate(t, &x, now);
+ if ((i = x - t - 6) > (last - s))
+ {
+ last = (char*)s + i;
+ ns = ts - now;
+ }
+ else
+ {
+ sfprintf(f, "p%s", s);
+ t = sfstruse(f);
+ ts = tmxdate(t, &x, now);
+ if ((i = x - t - 1) > (last - s))
+ {
+ last = (char*)s + i;
+ ns = ts - now;
+ }
+ }
+ sfstrclose(f);
+ }
+ }
+ if (e)
+ *e = last;
+ return ns;
+}
diff --git a/src/lib/libast/tm/tmxfmt.c b/src/lib/libast/tm/tmxfmt.c
new file mode 100644
index 0000000..2010c08
--- /dev/null
+++ b/src/lib/libast/tm/tmxfmt.c
@@ -0,0 +1,703 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * Time_t conversion support
+ */
+
+#include <tmx.h>
+#include <ctype.h>
+
+#define warped(t,n) ((t)<((n)-tmxsns(6L*30L*24L*60L*60L,0))||(t)>((n)+tmxsns(24L*60L*60L,0)))
+
+/*
+ * format n with padding p into s
+ * return end of s
+ *
+ * p: <0 blank padding
+ * 0 no padding
+ * >0 0 padding
+ */
+
+static char*
+number(register char* s, register char* e, register long n, register int p, int w, int pad)
+{
+ char* b;
+
+ if (w)
+ {
+ if (p > 0 && (pad == 0 || pad == '0'))
+ while (w > p)
+ {
+ p++;
+ n *= 10;
+ }
+ else if (w > p)
+ p = w;
+ }
+ switch (pad)
+ {
+ case '-':
+ p = 0;
+ break;
+ case '_':
+ if (p > 0)
+ p = -p;
+ break;
+ case '0':
+ if (p < 0)
+ p = -p;
+ break;
+ }
+ b = s;
+ if (p > 0)
+ s += sfsprintf(s, e - s, "%0*lu", p, n);
+ else if (p < 0)
+ s += sfsprintf(s, e - s, "%*lu", -p, n);
+ else
+ s += sfsprintf(s, e - s, "%lu", n);
+ if (w && (s - b) > w)
+ *(s = b + w) = 0;
+ return s;
+}
+
+typedef struct Stack_s
+{
+ char* format;
+ int delimiter;
+} Stack_t;
+
+/*
+ * format t into buf of length len
+ * end of buf is returned
+ */
+
+char*
+tmxfmt(char* buf, size_t len, const char* format, Time_t t)
+{
+ register char* cp;
+ register char* ep;
+ register char* p;
+ register int n;
+ int c;
+ int i;
+ int flags;
+ int alt;
+ int pad;
+ int delimiter;
+ int width;
+ int prec;
+ int parts;
+ char* arg;
+ char* f;
+ const char* oformat;
+ Tm_t* tm;
+ Tm_zone_t* zp;
+ Time_t now;
+ Stack_t* sp;
+ Stack_t stack[8];
+ Tm_t ts;
+ char argbuf[256];
+ char fmt[32];
+
+ tmlocale();
+ tm = tmxtm(&ts, t, NiL);
+ if (!format || !*format)
+ format = tm_info.deformat;
+ oformat = format;
+ flags = tm_info.flags;
+ sp = &stack[0];
+ cp = buf;
+ ep = buf + len;
+ delimiter = 0;
+ for (;;)
+ {
+ if ((c = *format++) == delimiter)
+ {
+ delimiter = 0;
+ if (sp <= &stack[0])
+ break;
+ sp--;
+ format = sp->format;
+ delimiter = sp->delimiter;
+ continue;
+ }
+ if (c != '%')
+ {
+ if (cp < ep)
+ *cp++ = c;
+ continue;
+ }
+ alt = 0;
+ arg = 0;
+ pad = 0;
+ width = 0;
+ prec = 0;
+ parts = 0;
+ for (;;)
+ {
+ switch (c = *format++)
+ {
+ case '_':
+ case '-':
+ pad = c;
+ continue;
+ case 'E':
+ case 'O':
+ if (!isalpha(*format))
+ break;
+ alt = c;
+ continue;
+ case '0':
+ if (!parts)
+ {
+ pad = c;
+ continue;
+ }
+ /*FALLTHROUGH*/
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ switch (parts)
+ {
+ case 0:
+ parts++;
+ /*FALLTHROUGH*/
+ case 1:
+ width = width * 10 + (c - '0');
+ break;
+ case 2:
+ prec = prec * 10 + (c - '0');
+ break;
+ }
+ continue;
+ case '.':
+ if (!parts++)
+ parts++;
+ continue;
+ case '(':
+ i = 1;
+ arg = argbuf;
+ for (;;)
+ {
+ if (!(c = *format++))
+ {
+ format--;
+ break;
+ }
+ else if (c == '(')
+ i++;
+ else if (c == ')' && !--i)
+ break;
+ else if (arg < &argbuf[sizeof(argbuf) - 1])
+ *arg++ = c;
+ }
+ *arg = 0;
+ arg = argbuf;
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+ switch (c)
+ {
+ case 0:
+ format--;
+ continue;
+ case '%':
+ if (cp < ep)
+ *cp++ = '%';
+ continue;
+ case '?':
+ if (tm_info.deformat != tm_info.format[TM_DEFAULT])
+ format = tm_info.deformat;
+ else if (!*format)
+ format = tm_info.format[TM_DEFAULT];
+ continue;
+ case 'a': /* abbreviated day of week name */
+ n = TM_DAY_ABBREV + tm->tm_wday;
+ goto index;
+ case 'A': /* day of week name */
+ n = TM_DAY + tm->tm_wday;
+ goto index;
+ case 'b': /* abbreviated month name */
+ case 'h':
+ n = TM_MONTH_ABBREV + tm->tm_mon;
+ goto index;
+ case 'B': /* month name */
+ n = TM_MONTH + tm->tm_mon;
+ goto index;
+ case 'c': /* `ctime(3)' date sans newline */
+ p = tm_info.format[TM_CTIME];
+ goto push;
+ case 'C': /* 2 digit century */
+ cp = number(cp, ep, (long)(1900 + tm->tm_year) / 100, 2, width, pad);
+ continue;
+ case 'd': /* day of month */
+ cp = number(cp, ep, (long)tm->tm_mday, 2, width, pad);
+ continue;
+ case 'D': /* date */
+ p = tm_info.format[TM_DATE];
+ goto push;
+ case 'e': /* blank padded day of month */
+ cp = number(cp, ep, (long)tm->tm_mday, -2, width, pad);
+ continue;
+ case 'f': /* (AST) OBSOLETE use %Qf */
+ p = "%Qf";
+ goto push;
+ case 'F': /* ISO 8601:2000 standard date format */
+ p = "%Y-%m-%d";
+ goto push;
+ case 'g': /* %V 2 digit year */
+ case 'G': /* %V 4 digit year */
+ n = tm->tm_year + 1900;
+ if (tm->tm_yday < 7)
+ {
+ if (tmweek(tm, 2, -1, -1) >= 52)
+ n--;
+ }
+ else if (tm->tm_yday > 358)
+ {
+ if (tmweek(tm, 2, -1, -1) <= 1)
+ n++;
+ }
+ if (c == 'g')
+ {
+ n %= 100;
+ c = 2;
+ }
+ else
+ c = 4;
+ cp = number(cp, ep, (long)n, c, width, pad);
+ continue;
+ case 'H': /* hour (0 - 23) */
+ cp = number(cp, ep, (long)tm->tm_hour, 2, width, pad);
+ continue;
+ case 'i': /* (AST) OBSOLETE use %QI */
+ p = "%QI";
+ goto push;
+ case 'I': /* hour (0 - 12) */
+ if ((n = tm->tm_hour) > 12) n -= 12;
+ else if (n == 0) n = 12;
+ cp = number(cp, ep, (long)n, 2, width, pad);
+ continue;
+ case 'j': /* Julian date (1 offset) */
+ cp = number(cp, ep, (long)(tm->tm_yday + 1), 3, width, pad);
+ continue;
+ case 'J': /* Julian date (0 offset) */
+ cp = number(cp, ep, (long)tm->tm_yday, 3, width, pad);
+ continue;
+ case 'k': /* (AST) OBSOLETE use %QD */
+ p = "%QD";
+ goto push;
+ case 'K': /* (AST) largest to smallest */
+ switch (alt)
+ {
+ case 'E':
+ p = (pad == '_') ? "%Y-%m-%d %H:%M:%S.%N %z" : "%Y-%m-%d+%H:%M:%S.%N%z";
+ break;
+ case 'O':
+ p = (pad == '_') ? "%Y-%m-%d %H:%M:%S.%N" : "%Y-%m-%d+%H:%M:%S.%N";
+ break;
+ default:
+ p = (pad == '_') ? "%Y-%m-%d %H:%M:%S" : "%Y-%m-%d+%H:%M:%S";
+ break;
+ }
+ goto push;
+ case 'l': /* (AST) OBSOLETE use %QL */
+ p = "%QL";
+ goto push;
+ case 'L': /* (AST) OBSOLETE use %Ql */
+ p = "%Ql";
+ goto push;
+ case 'm': /* month number */
+ cp = number(cp, ep, (long)(tm->tm_mon + 1), 2, width, pad);
+ continue;
+ case 'M': /* minutes */
+ cp = number(cp, ep, (long)tm->tm_min, 2, width, pad);
+ continue;
+ case 'n':
+ if (cp < ep)
+ *cp++ = '\n';
+ continue;
+ case 'N': /* (AST|GNU) nanosecond part */
+ cp = number(cp, ep, (long)tm->tm_nsec, 9, width, pad);
+ continue;
+#if 0
+ case 'o': /* (UNUSED) */
+ continue;
+#endif
+ case 'p': /* meridian */
+ n = TM_MERIDIAN + (tm->tm_hour >= 12);
+ goto index;
+ case 'P': /* (AST|GNU) lower case meridian */
+ p = tm_info.format[TM_MERIDIAN + (tm->tm_hour >= 12)];
+ while (cp < ep && (n = *p++))
+ *cp++ = isupper(n) ? tolower(n) : n;
+ continue;
+ case 'q': /* (AST) OBSOLETE use %Qz */
+ p = "%Qz";
+ goto push;
+ case 'Q': /* (AST) %Q<alpha> or %Q<delim>recent<delim>distant<delim> */
+ if (c = *format)
+ {
+ format++;
+ if (isalpha(c))
+ {
+ switch (c)
+ {
+ case 'd': /* `ls -l' distant date */
+ p = tm_info.format[TM_DISTANT];
+ goto push;
+ case 'D': /* `date(1)' date */
+ p = tm_info.format[TM_DATE_1];
+ goto push;
+ case 'f': /* TM_DEFAULT override */
+ p = tm_info.deformat;
+ goto push;
+ case 'I': /* international `date(1)' date */
+ p = tm_info.format[TM_INTERNATIONAL];
+ goto push;
+ case 'l': /* TM_DEFAULT */
+ p = tm_info.format[TM_DEFAULT];
+ goto push;
+ case 'L': /* `ls -l' date */
+ if (t)
+ {
+ now = tmxgettime();
+ if (warped(t, now))
+ {
+ p = tm_info.format[TM_DISTANT];
+ goto push;
+ }
+ }
+ p = tm_info.format[TM_RECENT];
+ goto push;
+ case 'o': /* set options ( %([+-]flag...)o ) */
+ if (arg)
+ {
+ c = '+';
+ i = 0;
+ for (;;)
+ {
+ switch (*arg++)
+ {
+ case 0:
+ n = 0;
+ break;
+ case '=':
+ i = !i;
+ continue;
+ case '+':
+ case '-':
+ case '!':
+ c = *(arg - 1);
+ continue;
+ case 'l':
+ n = TM_LEAP;
+ break;
+ case 'n':
+ case 's':
+ n = TM_SUBSECOND;
+ break;
+ case 'u':
+ n = TM_UTC;
+ break;
+ default:
+ continue;
+ }
+ if (!n)
+ break;
+
+ /*
+ * right, the global state stinks
+ * but we respect its locale-like status
+ */
+
+ if (c == '+')
+ {
+ if (!(flags & n))
+ {
+ flags |= n;
+ tm_info.flags |= n;
+ tm = tmxtm(tm, t, (flags & TM_UTC) ? &tm_data.zone[2] : tm->tm_zone);
+ if (!i)
+ tm_info.flags &= ~n;
+ }
+ }
+ else if (flags & n)
+ {
+ flags &= ~n;
+ tm_info.flags &= ~n;
+ tm = tmxtm(tm, t, (flags & TM_UTC) ? &tm_data.zone[2] : tm->tm_zone);
+ if (!i)
+ tm_info.flags |= n;
+ }
+ }
+ }
+ break;
+ case 'r': /* `ls -l' recent date */
+ p = tm_info.format[TM_RECENT];
+ goto push;
+ case 'z': /* time zone nation code */
+ if (!(flags & TM_UTC))
+ {
+ if ((zp = tm->tm_zone) != tm_info.local)
+ for (; zp >= tm_data.zone; zp--)
+ if (p = zp->type)
+ goto string;
+ else if (p = zp->type)
+ goto string;
+ }
+ break;
+ default:
+ format--;
+ break;
+ }
+ }
+ else
+ {
+ if (t)
+ {
+ now = tmxgettime();
+ p = warped(t, now) ? (char*)0 : (char*)format;
+ }
+ else
+ p = (char*)format;
+ i = 0;
+ while (n = *format)
+ {
+ format++;
+ if (n == c)
+ {
+ if (!p)
+ p = (char*)format;
+ if (++i == 2)
+ goto push_delimiter;
+ }
+ }
+ }
+ }
+ continue;
+ case 'r':
+ p = tm_info.format[TM_MERIDIAN_TIME];
+ goto push;
+ case 'R':
+ p = "%H:%M";
+ goto push;
+ case 's': /* (DEFACTO) seconds[.nanoseconds] since the epoch */
+ case '#':
+ now = t;
+ f = fmt;
+ *f++ = '%';
+ if (pad == '0')
+ *f++ = pad;
+ if (width)
+ f += sfsprintf(f, &fmt[sizeof(fmt)] - f, "%d", width);
+ f += sfsprintf(f, &fmt[sizeof(fmt)] - f, "I%du", sizeof(Tmxsec_t));
+ cp += sfsprintf(cp, ep - cp, fmt, tmxsec(now));
+ if (parts > 1)
+ {
+ n = sfsprintf(cp, ep - cp, ".%09I*u", sizeof(Tmxnsec_t), tmxnsec(now));
+ if (prec && n >= prec)
+ n = prec + 1;
+ cp += n;
+ }
+ continue;
+ case 'S': /* seconds */
+ cp = number(cp, ep, (long)tm->tm_sec, 2, width, pad);
+ if ((flags & TM_SUBSECOND) && (format - 2) != oformat)
+ {
+ p = ".%N";
+ goto push;
+ }
+ continue;
+ case 't':
+ if (cp < ep)
+ *cp++ = '\t';
+ continue;
+ case 'T':
+ p = tm_info.format[TM_TIME];
+ goto push;
+ case 'u': /* weekday number [1(Monday)-7] */
+ if (!(i = tm->tm_wday))
+ i = 7;
+ cp = number(cp, ep, (long)i, 0, width, pad);
+ continue;
+ case 'U': /* week number, Sunday as first day */
+ cp = number(cp, ep, (long)tmweek(tm, 0, -1, -1), 2, width, pad);
+ continue;
+#if 0
+ case 'v': /* (UNUSED) */
+ continue;
+#endif
+ case 'V': /* ISO week number */
+ cp = number(cp, ep, (long)tmweek(tm, 2, -1, -1), 2, width, pad);
+ continue;
+ case 'W': /* week number, Monday as first day */
+ cp = number(cp, ep, (long)tmweek(tm, 1, -1, -1), 2, width, pad);
+ continue;
+ case 'w': /* weekday number [0(Sunday)-6] */
+ cp = number(cp, ep, (long)tm->tm_wday, 0, width, pad);
+ continue;
+ case 'x':
+ p = tm_info.format[TM_DATE];
+ goto push;
+ case 'X':
+ p = tm_info.format[TM_TIME];
+ goto push;
+ case 'y': /* year in the form yy */
+ cp = number(cp, ep, (long)(tm->tm_year % 100), 2, width, pad);
+ continue;
+ case 'Y': /* year in the form ccyy */
+ cp = number(cp, ep, (long)(1900 + tm->tm_year), 4, width, pad);
+ continue;
+ case 'z': /* time zone west offset */
+ if (arg)
+ {
+ if ((zp = tmzone(arg, &f, 0, 0)) && !*f && tm->tm_zone != zp)
+ tm = tmxtm(tm, tmxtime(tm, tm->tm_zone->west + (tm->tm_isdst ? tm->tm_zone->dst : 0)), zp);
+ continue;
+ }
+ if ((ep - cp) >= 16)
+ cp = tmpoff(cp, ep - cp, "", (flags & TM_UTC) ? 0 : tm->tm_zone->west + (tm->tm_isdst ? tm->tm_zone->dst : 0), pad == '_' ? -24 * 60 : 24 * 60);
+ continue;
+ case 'Z': /* time zone */
+ if (arg)
+ {
+ if ((zp = tmzone(arg, &f, 0, 0)) && !*f && tm->tm_zone != zp)
+ tm = tmxtm(tm, tmxtime(tm, tm->tm_zone->west + (tm->tm_isdst ? tm->tm_zone->dst : 0)), zp);
+ continue;
+ }
+ p = (flags & TM_UTC) ? tm_info.format[TM_UT] : tm->tm_isdst && tm->tm_zone->daylight ? tm->tm_zone->daylight : tm->tm_zone->standard;
+ goto string;
+ case '=': /* (AST) OBSOLETE use %([+-]flag...)Qo (old %=[=][+-]flag) */
+ for (arg = argbuf; *format == '=' || *format == '-' || *format == '+' || *format == '!'; format++)
+ if (arg < &argbuf[sizeof(argbuf) - 2])
+ *arg++ = *format;
+ if (*arg++ = *format)
+ format++;
+ *arg = 0;
+ arg = argbuf;
+ goto options;
+ default:
+ if (cp < ep)
+ *cp++ = '%';
+ if (cp < ep)
+ *cp++ = c;
+ continue;
+ }
+ index:
+ p = tm_info.format[n];
+ string:
+ while (cp < ep && (*cp = *p++))
+ cp++;
+ continue;
+ options:
+ c = '+';
+ i = 0;
+ for (;;)
+ {
+ switch (*arg++)
+ {
+ case 0:
+ n = 0;
+ break;
+ case '=':
+ i = !i;
+ continue;
+ case '+':
+ case '-':
+ case '!':
+ c = *(arg - 1);
+ continue;
+ case 'l':
+ n = TM_LEAP;
+ break;
+ case 'n':
+ case 's':
+ n = TM_SUBSECOND;
+ break;
+ case 'u':
+ n = TM_UTC;
+ break;
+ default:
+ continue;
+ }
+ if (!n)
+ break;
+
+ /*
+ * right, the global state stinks
+ * but we respect its locale-like status
+ */
+
+ if (c == '+')
+ {
+ if (!(flags & n))
+ {
+ flags |= n;
+ tm_info.flags |= n;
+ tm = tmxtm(tm, t, (flags & TM_UTC) ? &tm_data.zone[2] : tm->tm_zone);
+ if (!i)
+ tm_info.flags &= ~n;
+ }
+ }
+ else if (flags & n)
+ {
+ flags &= ~n;
+ tm_info.flags &= ~n;
+ tm = tmxtm(tm, t, (flags & TM_UTC) ? &tm_data.zone[2] : tm->tm_zone);
+ if (!i)
+ tm_info.flags |= n;
+ }
+ }
+ continue;
+ push:
+ c = 0;
+ push_delimiter:
+ if (sp < &stack[elementsof(stack)])
+ {
+ sp->format = (char*)format;
+ format = p;
+ sp->delimiter = delimiter;
+ delimiter = c;
+ sp++;
+ }
+ continue;
+ }
+ tm_info.flags = flags;
+ if (cp >= ep)
+ cp = ep - 1;
+ *cp = 0;
+ return cp;
+}
diff --git a/src/lib/libast/tm/tmxgettime.c b/src/lib/libast/tm/tmxgettime.c
new file mode 100644
index 0000000..7ce13f3
--- /dev/null
+++ b/src/lib/libast/tm/tmxgettime.c
@@ -0,0 +1,44 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * Time_t conversion support
+ */
+
+#include <tmx.h>
+#include <tv.h>
+
+/*
+ * return current Time_t
+ */
+
+Time_t
+tmxgettime(void)
+{
+ Tv_t tv;
+
+ tvgettime(&tv);
+ return tmxsns(tv.tv_sec, tv.tv_nsec);
+}
diff --git a/src/lib/libast/tm/tmxleap.c b/src/lib/libast/tm/tmxleap.c
new file mode 100644
index 0000000..ce07c5a
--- /dev/null
+++ b/src/lib/libast/tm/tmxleap.c
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * Time_t conversion support
+ */
+
+#include <tmx.h>
+
+/*
+ * return t with leap seconds adjusted
+ * for direct localtime() access
+ */
+
+Time_t
+tmxleap(Time_t t)
+{
+ register Tm_leap_t* lp;
+ uint32_t sec;
+
+ tmset(tm_info.zone);
+ if (tm_info.flags & TM_ADJUST)
+ {
+ sec = tmxsec(t);
+ for (lp = &tm_data.leap[0]; sec < (lp->time - lp->total); lp++);
+ t = tmxsns(sec + lp->total, tmxnsec(t));
+ }
+ return t;
+}
diff --git a/src/lib/libast/tm/tmxmake.c b/src/lib/libast/tm/tmxmake.c
new file mode 100644
index 0000000..a985633
--- /dev/null
+++ b/src/lib/libast/tm/tmxmake.c
@@ -0,0 +1,140 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * Time_t conversion support
+ */
+
+#include <tmx.h>
+
+#include "FEATURE/tmlib"
+
+/*
+ * return Tm_t for t
+ * time zone and leap seconds accounted for in return value
+ */
+
+Tm_t*
+tmxtm(register Tm_t* tm, Time_t t, Tm_zone_t* zone)
+{
+ register struct tm* tp;
+ register Tm_leap_t* lp;
+ Time_t x;
+ time_t now;
+ int leapsec;
+ int y;
+ uint32_t n;
+ int32_t o;
+#if TMX_FLOAT
+ Time_t z;
+ uint32_t i;
+#endif
+
+ tmset(tm_info.zone);
+ leapsec = 0;
+ if ((tm_info.flags & (TM_ADJUST|TM_LEAP)) == (TM_ADJUST|TM_LEAP) && (n = tmxsec(t)))
+ {
+ for (lp = &tm_data.leap[0]; n < lp->time; lp++);
+ if (lp->total)
+ {
+ if (n == lp->time && (leapsec = (lp->total - (lp+1)->total)) < 0)
+ leapsec = 0;
+ t = tmxsns(n - lp->total, tmxnsec(t));
+ }
+ }
+ x = tmxsec(t);
+ if (!(tm->tm_zone = zone))
+ {
+ if (tm_info.flags & TM_UTC)
+ tm->tm_zone = &tm_data.zone[2];
+ else
+ tm->tm_zone = tm_info.zone;
+ }
+ if ((o = 60 * tm->tm_zone->west) && x > o)
+ {
+ x -= o;
+ o = 0;
+ }
+#if TMX_FLOAT
+ i = x / (24 * 60 * 60);
+ z = i;
+ n = x - z * (24 * 60 * 60);
+ tm->tm_sec = n % 60 + leapsec;
+ n /= 60;
+ tm->tm_min = n % 60;
+ n /= 60;
+ tm->tm_hour = n % 24;
+#define x i
+#else
+ tm->tm_sec = x % 60 + leapsec;
+ x /= 60;
+ tm->tm_min = x % 60;
+ x /= 60;
+ tm->tm_hour = x % 24;
+ x /= 24;
+#endif
+ tm->tm_wday = (x + 4) % 7;
+ tm->tm_year = (400 * (x + 25202)) / 146097 + 1;
+ n = tm->tm_year - 1;
+ x -= n * 365 + n / 4 - n / 100 + (n + (1900 - 1600)) / 400 - (1970 - 1901) * 365 - (1970 - 1901) / 4;
+ tm->tm_mon = 0;
+ tm->tm_mday = x + 1;
+ tm->tm_nsec = tmxnsec(t);
+ tmfix(tm);
+ n += 1900;
+ tm->tm_isdst = 0;
+ if (tm->tm_zone->daylight)
+ {
+ if ((y = tmequiv(tm) - 1900) == tm->tm_year)
+ now = tmxsec(t);
+ else
+ {
+ Tm_t te;
+
+ te = *tm;
+ te.tm_year = y;
+ now = tmxsec(tmxtime(&te, tm->tm_zone->west));
+ }
+ if ((tp = tmlocaltime(&now)) && ((tm->tm_isdst = tp->tm_isdst) || o))
+ {
+ tm->tm_min -= o / 60 + (tm->tm_isdst ? tm->tm_zone->dst : 0);
+ tmfix(tm);
+ }
+ }
+ return tm;
+}
+
+/*
+ * return Tm_t for t
+ * time zone and leap seconds accounted for in return value
+ */
+
+Tm_t*
+tmxmake(Time_t t)
+{
+ static Tm_t ts;
+
+ return tmxtm(&ts, t, NiL);
+}
diff --git a/src/lib/libast/tm/tmxscan.c b/src/lib/libast/tm/tmxscan.c
new file mode 100644
index 0000000..98d4749
--- /dev/null
+++ b/src/lib/libast/tm/tmxscan.c
@@ -0,0 +1,533 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * Time_t conversion support
+ *
+ * scan date expression in s using format
+ * if non-null, e points to the first invalid sequence in s
+ * if non-null, f points to the first unused format char
+ * t provides default values
+ */
+
+#include <tmx.h>
+#include <ctype.h>
+
+typedef struct
+{
+ int32_t nsec;
+ int year;
+ int mon;
+ int week;
+ int weektype;
+ int yday;
+ int mday;
+ int wday;
+ int hour;
+ int min;
+ int sec;
+ int meridian;
+ int zone;
+} Set_t;
+
+#define CLEAR(s) (s.year=s.mon=s.week=s.weektype=s.yday=s.mday=s.wday=s.hour=s.min=s.sec=s.meridian=(-1),s.nsec=1000000000L,s.zone=TM_LOCALZONE)
+
+#define INDEX(m,x) (((n)>=((x)-(m)))?((n)-=((x)-(m))):(n))
+
+#define NUMBER(d,m,x) do \
+ { \
+ n = 0; \
+ u = (char*)s; \
+ while (s < (const char*)(u + d) && *s >= '0' && *s <= '9') \
+ n = n * 10 + *s++ - '0'; \
+ if (u == (char*)s || n < m || n > x) \
+ goto next; \
+ } while (0)
+
+/*
+ * generate a Time_t from tm + set
+ */
+
+static Time_t
+gen(register Tm_t* tm, register Set_t* set)
+{
+ register int n;
+ int z;
+ Time_t t;
+
+ if (set->year >= 0)
+ tm->tm_year = set->year;
+ if (set->mon >= 0)
+ {
+ if (set->year < 0 && set->mon < tm->tm_mon)
+ tm->tm_year++;
+ tm->tm_mon = set->mon;
+ if (set->yday < 0 && set->mday < 0)
+ tm->tm_mday = set->mday = 1;
+ }
+ if (set->week >= 0)
+ {
+ if (set->mon < 0)
+ {
+ tmweek(tm, set->weektype, set->week, set->wday);
+ set->wday = -1;
+ }
+ }
+ else if (set->yday >= 0)
+ {
+ if (set->mon < 0)
+ {
+ tm->tm_mon = 0;
+ tm->tm_mday = set->yday + 1;
+ }
+ }
+ else if (set->mday >= 0)
+ tm->tm_mday = set->mday;
+ if (set->hour >= 0)
+ {
+ if (set->hour < tm->tm_hour && set->yday < 0 && set->mday < 0 && set->wday < 0)
+ tm->tm_mday++;
+ tm->tm_hour = set->hour;
+ tm->tm_min = (set->min >= 0) ? set->min : 0;
+ tm->tm_sec = (set->sec >= 0) ? set->sec : 0;
+ }
+ else if (set->min >= 0)
+ {
+ tm->tm_min = set->min;
+ tm->tm_sec = (set->sec >= 0) ? set->sec : 0;
+ }
+ else if (set->sec >= 0)
+ tm->tm_sec = set->sec;
+ if (set->nsec < 1000000000L)
+ tm->tm_nsec = set->nsec;
+ if (set->meridian > 0)
+ {
+ if (tm->tm_hour < 12)
+ tm->tm_hour += 12;
+ }
+ else if (set->meridian == 0)
+ {
+ if (tm->tm_hour >= 12)
+ tm->tm_hour -= 12;
+ }
+ t = tmxtime(tm, set->zone);
+ if (set->yday >= 0)
+ {
+ z = 1;
+ tm = tmxtm(tm, t, tm->tm_zone);
+ tm->tm_mday += set->yday - tm->tm_yday;
+ }
+ else if (set->wday >= 0)
+ {
+ z = 1;
+ tm = tmxtm(tm, t, tm->tm_zone);
+ if ((n = set->wday - tm->tm_wday) < 0)
+ n += 7;
+ tm->tm_mday += n;
+ }
+ else
+ z = 0;
+ if (set->nsec < 1000000000L)
+ {
+ if (!z)
+ {
+ z = 1;
+ tm = tmxtm(tm, t, tm->tm_zone);
+ }
+ tm->tm_nsec = set->nsec;
+ }
+ return z ? tmxtime(tm, set->zone) : t;
+}
+
+/*
+ * the format scan workhorse
+ */
+
+static Time_t
+scan(register const char* s, char** e, const char* format, char** f, Time_t t, long flags)
+{
+ register int d;
+ register int n;
+ register char* p;
+ register Tm_t* tm;
+ const char* b;
+ char* u;
+ char* stack[4];
+ int m;
+ int hi;
+ int lo;
+ int pedantic;
+ Time_t x;
+ Set_t set;
+ Tm_zone_t* zp;
+ Tm_t ts;
+
+ char** sp = &stack[0];
+
+ while (isspace(*s))
+ s++;
+ b = s;
+ again:
+ CLEAR(set);
+ tm = tmxtm(&ts, t, NiL);
+ pedantic = (flags & TM_PEDANTIC) != 0;
+ for (;;)
+ {
+ if (!(d = *format++))
+ {
+ if (sp <= &stack[0])
+ {
+ format--;
+ break;
+ }
+ format = (const char*)*--sp;
+ }
+ else if (!*s)
+ {
+ format--;
+ break;
+ }
+ else if (d == '%' && (d = *format) && format++ && d != '%')
+ {
+ more:
+ switch (d)
+ {
+ case 'a':
+ lo = TM_DAY_ABBREV;
+ hi = pedantic ? TM_DAY : TM_TIME;
+ goto get_wday;
+ case 'A':
+ lo = pedantic ? TM_DAY : TM_DAY_ABBREV;
+ hi = TM_TIME;
+ get_wday:
+ if ((n = tmlex(s, &u, tm_info.format + lo, hi - lo, NiL, 0)) < 0)
+ goto next;
+ s = u;
+ INDEX(TM_DAY_ABBREV, TM_DAY);
+ set.wday = n;
+ continue;
+ case 'b':
+ case 'h':
+ lo = TM_MONTH_ABBREV;
+ hi = pedantic ? TM_MONTH : TM_DAY_ABBREV;
+ goto get_mon;
+ case 'B':
+ lo = pedantic ? TM_MONTH : TM_MONTH_ABBREV;
+ hi = TM_DAY_ABBREV;
+ get_mon:
+ if ((n = tmlex(s, &u, tm_info.format + lo, hi - lo, NiL, 0)) < 0)
+ goto next;
+ s = u;
+ INDEX(TM_MONTH_ABBREV, TM_MONTH);
+ set.mon = n;
+ continue;
+ case 'c':
+ p = "%a %b %e %T %Y";
+ break;
+ case 'C':
+ NUMBER(2, 19, 99);
+ set.year = (n - 19) * 100 + tm->tm_year % 100;
+ continue;
+ case 'd':
+ if (pedantic && !isdigit(*s))
+ goto next;
+ /*FALLTHROUGH*/
+ case 'e':
+ NUMBER(2, 1, 31);
+ set.mday = n;
+ continue;
+ case 'D':
+ p = "%m/%d/%y";
+ break;
+ case 'E':
+ case 'O':
+ if (*format)
+ {
+ d = *format++;
+ goto more;
+ }
+ continue;
+ case 'F':
+ p = "%Y-%m-%d";
+ break;
+ case 'H':
+ case 'k':
+ NUMBER(2, 0, 23);
+ set.hour = n;
+ continue;
+ case 'I':
+ case 'l':
+ NUMBER(2, 1, 12);
+ set.hour = n;
+ continue;
+ case 'j':
+ NUMBER(3, 1, 366);
+ set.yday = n - 1;
+ continue;
+ case 'm':
+ NUMBER(2, 1, 12);
+ set.mon = n - 1;
+ continue;
+ case 'M':
+ NUMBER(2, 0, 59);
+ set.min = n;
+ continue;
+ case 'n':
+ if (pedantic)
+ while (*s == '\n')
+ s++;
+ else
+ while (isspace(*s))
+ s++;
+ continue;
+ case 'N':
+ NUMBER(9, 0, 999999999L);
+ set.nsec = n;
+ continue;
+ case 'p':
+ if ((n = tmlex(s, &u, tm_info.format + TM_MERIDIAN, TM_UT - TM_MERIDIAN, NiL, 0)) < 0)
+ goto next;
+ set.meridian = n;
+ s = u;
+ continue;
+ case 'r':
+ p = "%I:%M:%S %p";
+ break;
+ case 'R':
+ p = "%H:%M:%S";
+ break;
+ case 's':
+ x = strtoul(s, &u, 0);
+ if (s == u)
+ goto next;
+ tm = tmxtm(tm, tmxsns(x, 0), tm->tm_zone);
+ s = u;
+ CLEAR(set);
+ continue;
+ case 'S':
+ NUMBER(2, 0, 61);
+ set.sec = n;
+ continue;
+ case 'u':
+ NUMBER(2, 1, 7);
+ set.wday = n % 7;
+ continue;
+ case 'U':
+ NUMBER(2, 0, 52);
+ set.week = n;
+ set.weektype = 0;
+ continue;
+ case 'V':
+ NUMBER(2, 1, 53);
+ set.week = n;
+ set.weektype = 2;
+ continue;
+ case 'w':
+ NUMBER(2, 0, 6);
+ set.wday = n;
+ continue;
+ case 'W':
+ NUMBER(2, 0, 52);
+ set.week = n;
+ set.weektype = 1;
+ continue;
+ case 'x':
+ p = tm_info.format[TM_DATE];
+ break;
+ case 'X':
+ p = tm_info.format[TM_TIME];
+ break;
+ case 'y':
+ NUMBER(2, 0, 99);
+ if (n < TM_WINDOW)
+ n += 100;
+ set.year = n;
+ continue;
+ case 'Y':
+ NUMBER(4, 1969, 2100);
+ set.year = n - 1900;
+ continue;
+ case 'Z':
+ case 'q':
+ if (zp = tmtype(s, &u))
+ {
+ s = u;
+ u = zp->type;
+ }
+ else
+ u = 0;
+ if (d == 'q')
+ continue;
+ case 'z':
+ if ((zp = tmzone(s, &u, u, &m)))
+ {
+ s = u;
+ set.zone = zp->west + m;
+ tm_info.date = zp;
+ }
+ continue;
+ case '|':
+ s = b;
+ goto again;
+ case '&':
+ x = gen(tm, &set);
+ x = tmxdate(s, e, t);
+ if (s == (const char*)*e)
+ goto next;
+ t = x;
+ s = (const char*)*e;
+ if (!*format || *format == '%' && *(format + 1) == '|')
+ goto done;
+ goto again;
+ default:
+ goto next;
+ }
+ if (sp >= &stack[elementsof(stack)])
+ goto next;
+ *sp++ = (char*)format;
+ format = (const char*)p;
+ }
+ else if (isspace(d))
+ while (isspace(*s))
+ s++;
+ else if (*s != d)
+ break;
+ else
+ s++;
+ }
+ next:
+ if (sp > &stack[0])
+ format = (const char*)stack[0];
+ if (*format)
+ {
+ p = (char*)format;
+ if (!*s && *p == '%' && *(p + 1) == '|')
+ format += strlen(format);
+ else
+ while (*p)
+ if (*p++ == '%' && *p && *p++ == '|' && *p)
+ {
+ format = (const char*)p;
+ s = b;
+ goto again;
+ }
+ }
+ t = gen(tm, &set);
+ done:
+ if (e)
+ {
+ while (isspace(*s))
+ s++;
+ *e = (char*)s;
+ }
+ if (f)
+ {
+ while (isspace(*format))
+ format++;
+ *f = (char*)format;
+ }
+ return t;
+}
+
+/*
+ * format==0 DATEMSK
+ * *format==0 DATEMSK and tmxdate()
+ * *format!=0 format
+ */
+
+Time_t
+tmxscan(const char* s, char** e, const char* format, char** f, Time_t t, long flags)
+{
+ register char* v;
+ register char** p;
+ char* q;
+ char* r;
+ Time_t x;
+
+ static int initialized;
+ static char** datemask;
+
+ tmlocale();
+ if (!format || !*format)
+ {
+ if (!initialized)
+ {
+ register Sfio_t* sp;
+ register int n;
+ off_t m;
+
+ initialized = 1;
+ if ((v = getenv("DATEMSK")) && *v && (sp = sfopen(NiL, v, "r")))
+ {
+ for (n = 1; sfgetr(sp, '\n', 0); n++);
+ m = sfseek(sp, 0L, SEEK_CUR);
+ if (p = newof(0, char*, n, m))
+ {
+ sfseek(sp, 0L, SEEK_SET);
+ v = (char*)(p + n);
+ if (sfread(sp, v, m) != m)
+ {
+ free(p);
+ p = 0;
+ }
+ else
+ {
+ datemask = p;
+ v[m] = 0;
+ while (*v)
+ {
+ *p++ = v;
+ if (!(v = strchr(v, '\n')))
+ break;
+ *v++ = 0;
+ }
+ *p = 0;
+ }
+ }
+ }
+ }
+ if (p = datemask)
+ while (v = *p++)
+ {
+ x = scan(s, &q, v, &r, t, flags);
+ if (!*q && !*r)
+ {
+ if (e)
+ *e = q;
+ if (f)
+ *f = r;
+ return x;
+ }
+ }
+ if (f)
+ *f = (char*)format;
+ if (format)
+ return tmxdate(s, e, t);
+ if (e)
+ *e = (char*)s;
+ return 0;
+ }
+ return scan(s, e, format, f, t, flags);
+}
diff --git a/src/lib/libast/tm/tmxsettime.c b/src/lib/libast/tm/tmxsettime.c
new file mode 100644
index 0000000..90bee75
--- /dev/null
+++ b/src/lib/libast/tm/tmxsettime.c
@@ -0,0 +1,45 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * Time_t conversion support
+ */
+
+#include <tmx.h>
+#include <tv.h>
+
+/*
+ * return current current time to t
+ */
+
+int
+tmxsettime(Time_t t)
+{
+ Tv_t tv;
+
+ tv.tv_sec = tmxsec(t);
+ tv.tv_nsec = tmxnsec(t);
+ return tvsettime(&tv);
+}
diff --git a/src/lib/libast/tm/tmxsleep.c b/src/lib/libast/tm/tmxsleep.c
new file mode 100644
index 0000000..9de8f9a
--- /dev/null
+++ b/src/lib/libast/tm/tmxsleep.c
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * Time_t sleep
+ */
+
+#include <tmx.h>
+#include <tv.h>
+
+int
+tmxsleep(Time_t t)
+{
+ Tv_t tv;
+
+ tv.tv_sec = tmxsec(t);
+ tv.tv_nsec = tmxnsec(t);
+ return tvsleep(&tv, NiL);
+}
diff --git a/src/lib/libast/tm/tmxtime.c b/src/lib/libast/tm/tmxtime.c
new file mode 100644
index 0000000..6951f8a
--- /dev/null
+++ b/src/lib/libast/tm/tmxtime.c
@@ -0,0 +1,137 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * Time_t conversion support
+ */
+
+#include <tmx.h>
+
+#include "FEATURE/tmlib"
+
+/*
+ * convert Tm_t to Time_t
+ *
+ * if west==TM_LOCALZONE then the local timezone is used
+ * otherwise west is the number of minutes west
+ * of GMT with DST taken into account
+ *
+ * this routine works with a copy of Tm_t to avoid clashes
+ * with other tm*() that may return static Tm_t*
+ */
+
+Time_t
+tmxtime(register Tm_t* tm, int west)
+{
+ register Time_t t;
+ register Tm_leap_t* lp;
+ register int32_t y;
+ int n;
+ int sec;
+ time_t now;
+ struct tm* tl;
+ Tm_t* to;
+ Tm_t ts;
+
+ ts = *tm;
+ to = tm;
+ tm = &ts;
+ tmset(tm_info.zone);
+ tmfix(tm);
+ y = tm->tm_year;
+ if (y < 69 || y > (TMX_MAXYEAR - 1900))
+ return TMX_NOTIME;
+ y--;
+ t = y * 365 + y / 4 - y / 100 + (y + (1900 - 1600)) / 400 - (1970 - 1901) * 365 - (1970 - 1901) / 4;
+ if ((n = tm->tm_mon) > 11)
+ n = 11;
+ y += 1901;
+ if (n > 1 && tmisleapyear(y))
+ t++;
+ t += tm_data.sum[n] + tm->tm_mday - 1;
+ t *= 24;
+ t += tm->tm_hour;
+ t *= 60;
+ t += tm->tm_min;
+ t *= 60;
+ t += sec = tm->tm_sec;
+ if (west != TM_UTCZONE && !(tm_info.flags & TM_UTC))
+ {
+ /*
+ * time zone adjustments
+ */
+
+ if (west == TM_LOCALZONE)
+ {
+ t += tm_info.zone->west * 60;
+ if (!tm_info.zone->daylight)
+ tm->tm_isdst = 0;
+ else
+ {
+ y = tm->tm_year;
+ tm->tm_year = tmequiv(tm) - 1900;
+ now = tmxsec(tmxtime(tm, tm_info.zone->west));
+ tm->tm_year = y;
+ if (!(tl = tmlocaltime(&now)))
+ return TMX_NOTIME;
+ if (tm->tm_isdst = tl->tm_isdst)
+ t += tm_info.zone->dst * 60;
+ }
+ }
+ else
+ {
+ t += west * 60;
+ if (!tm_info.zone->daylight)
+ tm->tm_isdst = 0;
+ else if (tm->tm_isdst < 0)
+ {
+ y = tm->tm_year;
+ tm->tm_year = tmequiv(tm) - 1900;
+ tm->tm_isdst = 0;
+ now = tmxsec(tmxtime(tm, tm_info.zone->west));
+ tm->tm_year = y;
+ if (!(tl = tmlocaltime(&now)))
+ return TMX_NOTIME;
+ tm->tm_isdst = tl->tm_isdst;
+ }
+ }
+ }
+ else if (tm->tm_isdst)
+ tm->tm_isdst = 0;
+ *to = *tm;
+ if (tm_info.flags & TM_LEAP)
+ {
+ /*
+ * leap second adjustments
+ */
+
+ for (lp = &tm_data.leap[0]; t < lp->time - (lp+1)->total; lp++);
+ t += lp->total;
+ n = lp->total - (lp+1)->total;
+ if (t <= (lp->time + n) && (n > 0 && sec > 59 || n < 0 && sec > (59 + n) && sec <= 59))
+ t -= n;
+ }
+ return tmxsns(t, tm->tm_nsec);
+}
diff --git a/src/lib/libast/tm/tmxtouch.c b/src/lib/libast/tm/tmxtouch.c
new file mode 100644
index 0000000..e711a62
--- /dev/null
+++ b/src/lib/libast/tm/tmxtouch.c
@@ -0,0 +1,81 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * Time_t conversion support
+ */
+
+#include <tmx.h>
+#include <tv.h>
+
+/*
+ * touch path <atime,mtime,ctime>
+ * (flags&PATH_TOUCH_VERBATIM) treats times verbatim, otherwise:
+ * Time_t==0 current time
+ * Time_t==TMX_NOTIME retains path value
+ */
+
+int
+tmxtouch(const char* path, Time_t at, Time_t mt, Time_t ct, int flags)
+{
+ Tv_t av;
+ Tv_t mv;
+ Tv_t cv;
+ Tv_t* ap;
+ Tv_t* mp;
+ Tv_t* cp;
+
+ if (at == TMX_NOTIME && !(flags & PATH_TOUCH_VERBATIM))
+ ap = TV_TOUCH_RETAIN;
+ else if (!at && !(flags & PATH_TOUCH_VERBATIM))
+ ap = 0;
+ else
+ {
+ av.tv_sec = tmxsec(at);
+ av.tv_nsec = tmxnsec(at);
+ ap = &av;
+ }
+ if (mt == TMX_NOTIME && !(flags & PATH_TOUCH_VERBATIM))
+ mp = TV_TOUCH_RETAIN;
+ else if (!mt && !(flags & PATH_TOUCH_VERBATIM))
+ mp = 0;
+ else
+ {
+ mv.tv_sec = tmxsec(mt);
+ mv.tv_nsec = tmxnsec(mt);
+ mp = &mv;
+ }
+ if (ct == TMX_NOTIME && !(flags & PATH_TOUCH_VERBATIM))
+ cp = TV_TOUCH_RETAIN;
+ else if (!ct && !(flags & PATH_TOUCH_VERBATIM))
+ cp = 0;
+ else
+ {
+ cv.tv_sec = tmxsec(ct);
+ cv.tv_nsec = tmxnsec(ct);
+ cp = &cv;
+ }
+ return tvtouch(path, ap, mp, cp, flags & 1);
+}
diff --git a/src/lib/libast/tm/tmzone.c b/src/lib/libast/tm/tmzone.c
new file mode 100644
index 0000000..230a5f3
--- /dev/null
+++ b/src/lib/libast/tm/tmzone.c
@@ -0,0 +1,95 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * time conversion support
+ */
+
+#include <ast.h>
+#include <tm.h>
+
+/*
+ * return timezone pointer given name and type
+ *
+ * if type==0 then all time zone types match
+ * otherwise type must be one of tm_info.zone[].type
+ *
+ * if end is non-null then it will point to the next
+ * unmatched char in name
+ *
+ * if dst!=0 then it will point to 0 for standard zones
+ * and the offset for daylight zones
+ *
+ * 0 returned for no match
+ */
+
+Tm_zone_t*
+tmzone(register const char* name, char** end, const char* type, int* dst)
+{
+ register Tm_zone_t* zp;
+ register char* prev;
+ char* e;
+
+ static Tm_zone_t fixed;
+ static char off[16];
+
+ tmset(tm_info.zone);
+ if ((*name == '+' || *name == '-') && (fixed.west = tmgoff(name, &e, TM_LOCALZONE)) != TM_LOCALZONE && !*e)
+ {
+ strlcpy(fixed.standard = fixed.daylight = off, name, sizeof(off));
+ if (end)
+ *end = e;
+ if (dst)
+ *dst = 0;
+ return &fixed;
+ }
+ zp = tm_info.local;
+ prev = 0;
+ do
+ {
+ if (zp->type)
+ prev = zp->type;
+ if (!type || type == prev || !prev)
+ {
+ if (tmword(name, end, zp->standard, NiL, 0))
+ {
+ if (dst)
+ *dst = 0;
+ return zp;
+ }
+ if (zp->dst && zp->daylight && tmword(name, end, zp->daylight, NiL, 0))
+ {
+ if (dst)
+ *dst = zp->dst;
+ return zp;
+ }
+ }
+ if (zp == tm_info.local)
+ zp = tm_data.zone;
+ else
+ zp++;
+ } while (zp->standard);
+ return 0;
+}
diff --git a/src/lib/libast/tm/tvcmp.c b/src/lib/libast/tm/tvcmp.c
new file mode 100644
index 0000000..2716d3d
--- /dev/null
+++ b/src/lib/libast/tm/tvcmp.c
@@ -0,0 +1,46 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <tv.h>
+
+/*
+ * compare a with b
+ * strcmp semantics
+ */
+
+int
+tvcmp(register const Tv_t* a, register const Tv_t* b)
+{
+ if (a->tv_sec < b->tv_sec)
+ return -1;
+ if (a->tv_sec > b->tv_sec)
+ return 1;
+ if (a->tv_nsec != TV_NSEC_IGNORE && b->tv_nsec != TV_NSEC_IGNORE)
+ {
+ if (a->tv_nsec < b->tv_nsec)
+ return -1;
+ if (a->tv_nsec > b->tv_nsec)
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/lib/libast/tm/tvgettime.c b/src/lib/libast/tm/tvgettime.c
new file mode 100644
index 0000000..12866e3
--- /dev/null
+++ b/src/lib/libast/tm/tvgettime.c
@@ -0,0 +1,70 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <tv.h>
+#include <tm.h>
+
+#include "FEATURE/tvlib"
+
+int
+tvgettime(Tv_t* tv)
+{
+
+#if _lib_clock_gettime && defined(CLOCK_REALTIME)
+
+ struct timespec s;
+
+ clock_gettime(CLOCK_REALTIME, &s);
+ tv->tv_sec = s.tv_sec;
+ tv->tv_nsec = s.tv_nsec;
+
+#else
+
+#if defined(tmgettimeofday)
+
+ struct timeval v;
+
+ tmgettimeofday(&v);
+ tv->tv_sec = v.tv_sec;
+ tv->tv_nsec = v.tv_usec * 1000;
+
+#else
+
+ static time_t s;
+ static uint32_t n;
+
+ if ((tv->tv_sec = time(NiL)) != s)
+ {
+ s = tv->tv_sec;
+ n = 0;
+ }
+ else
+ n += 1000;
+ tv->tv_nsec = n;
+
+#endif
+
+#endif
+
+ return 0;
+}
diff --git a/src/lib/libast/tm/tvsettime.c b/src/lib/libast/tm/tvsettime.c
new file mode 100644
index 0000000..4e3842b
--- /dev/null
+++ b/src/lib/libast/tm/tvsettime.c
@@ -0,0 +1,72 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <tv.h>
+#include <tm.h>
+#include <errno.h>
+
+#include "FEATURE/tvlib"
+
+int
+tvsettime(const Tv_t* tv)
+{
+
+#if _lib_clock_settime && defined(CLOCK_REALTIME)
+
+ struct timespec s;
+
+ s.tv_sec = tv->tv_sec;
+ s.tv_nsec = tv->tv_nsec;
+ return clock_settime(CLOCK_REALTIME, &s);
+
+#else
+
+#if defined(tmsettimeofday)
+
+ struct timeval v;
+
+ v.tv_sec = tv->tv_sec;
+ v.tv_usec = tv->tv_nsec / 1000;
+ return tmsettimeofday(&v);
+
+#else
+
+#if _lib_stime
+
+ static time_t s;
+
+ s = tv->tv_sec + (tv->tv_nsec != 0);
+ return stime(s);
+
+#else
+
+ errno = EPERM;
+ return -1;
+
+#endif
+
+#endif
+
+#endif
+
+}
diff --git a/src/lib/libast/tm/tvsleep.c b/src/lib/libast/tm/tvsleep.c
new file mode 100644
index 0000000..78da802
--- /dev/null
+++ b/src/lib/libast/tm/tvsleep.c
@@ -0,0 +1,144 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+
+#include <tv.h>
+#include <tm.h>
+
+#include "FEATURE/tvlib"
+
+#if !_lib_nanosleep
+# if _lib_select
+# if _sys_select
+# include <sys/select.h>
+# else
+# include <sys/socket.h>
+# endif
+# else
+# if !_lib_usleep
+# if _lib_poll_notimer
+# undef _lib_poll
+# endif
+# if _lib_poll
+# include <poll.h>
+# endif
+# endif
+# endif
+#endif
+
+/*
+ * sleep for tv
+ * non-zero exit if sleep did not complete
+ * with remaining time in rv
+ */
+
+int
+tvsleep(register const Tv_t* tv, register Tv_t* rv)
+{
+
+#if _lib_nanosleep
+
+ struct timespec stv;
+ struct timespec srv;
+ int r;
+
+ stv.tv_sec = tv->tv_sec;
+ stv.tv_nsec = tv->tv_nsec;
+ if ((r = nanosleep(&stv, &srv)) && rv)
+ {
+ rv->tv_sec = srv.tv_sec;
+ rv->tv_nsec = srv.tv_nsec;
+ }
+ return r;
+
+#else
+
+#if _lib_select
+
+ struct timeval stv;
+
+ stv.tv_sec = tv->tv_sec;
+ stv.tv_usec = tv->tv_nsec / 1000;
+ if (select(0, NiL, NiL, NiL, &stv) < 0)
+ {
+ if (rv)
+ *rv = *tv;
+ return -1;
+ }
+ if (rv)
+ {
+ rv->tv_sec = stv.tv_sec;
+ rv->tv_nsec = stv.tv_usec * 1000;
+ }
+ return 0;
+
+#else
+
+ unsigned int s = tv->tv_sec;
+ uint32_t n = tv->tv_nsec;
+
+#if _lib_usleep
+
+
+ unsigned long t;
+
+ if (t = (n + 999L) / 1000L)
+ {
+ usleep(t);
+ s -= t / 1000000L;
+ n = 0;
+ }
+
+#else
+
+#if _lib_poll
+
+ struct pollfd pfd;
+ int t;
+
+ if ((t = (n + 999999L) / 1000000L) > 0)
+ {
+ poll(&pfd, 0, t);
+ s -= t / 1000L;
+ n = 0;
+ }
+
+#endif
+
+#endif
+
+ if ((s += (n + 999999999L) / 1000000000L) && (s = sleep(s)))
+ {
+ if (rv)
+ {
+ rv->tv_sec = s;
+ rv->tv_nsec = 0;
+ }
+ return -1;
+ }
+ return 0;
+
+#endif
+
+#endif
+
+}
diff --git a/src/lib/libast/tm/tvtouch.c b/src/lib/libast/tm/tvtouch.c
new file mode 100644
index 0000000..bd5fb5c
--- /dev/null
+++ b/src/lib/libast/tm/tvtouch.c
@@ -0,0 +1,295 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * Tv_t conversion support
+ */
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:hide utime
+#else
+#define utime ______utime
+#endif
+
+#ifndef _ATFILE_SOURCE
+#define _ATFILE_SOURCE 1
+#endif
+
+#include <ast.h>
+#include <ls.h>
+#include <tv.h>
+#include <times.h>
+#include <error.h>
+
+#include "FEATURE/tvlib"
+
+#if _hdr_utime && _lib_utime
+#include <utime.h>
+#endif
+
+#if defined(__STDPP__directive) && defined(__STDPP__hide)
+__STDPP__directive pragma pp:nohide utime
+#else
+#undef utime
+#endif
+
+#if _lib_utime
+#if _hdr_utime
+extern int utime(const char*, const struct utimbuf*);
+#else
+extern int utime(const char*, const time_t*);
+#endif
+#endif
+
+#define NS(n) (((uint32_t)(n))<1000000000L?(n):0)
+
+/*
+ * touch path <atime,mtime,ctime>
+ * Tv_t==0 uses current time
+ * Tv_t==TV_TOUCH_RETAIN retains path value if it exists, current time otherwise
+ * otherwise it is exact time
+ * file created if it doesn't exist and (flags&TV_TOUCH_CREATE)
+ * symlink not followed if (flags&TV_TOUCH_PHYSICAL)
+ * cv most likely ignored on most implementations
+ *
+ * NOTE: when *at() calls are integrated TV_TOUCH_* should be advertized!
+ */
+
+#define TV_TOUCH_CREATE 1
+#define TV_TOUCH_PHYSICAL 2
+
+#if !defined(UTIME_NOW) || !defined(UTIME_OMIT) || defined(__stub_utimensat)
+#undef _lib_utimensat
+#endif
+
+int
+tvtouch(const char* path, register const Tv_t* av, register const Tv_t* mv, const Tv_t* cv, int flags)
+{
+ int fd;
+ int mode;
+ int oerrno;
+ struct stat st;
+ Tv_t now;
+#if _lib_utimets || _lib_utimensat
+ struct timespec ts[2];
+#endif
+#if _lib_utimes
+ struct timeval am[2];
+#else
+#if _hdr_utime
+ struct utimbuf am;
+#else
+ time_t am[2];
+#endif
+#endif
+
+ oerrno = errno;
+#if _lib_utimensat
+ if (!av)
+ {
+ ts[0].tv_sec = 0;
+ ts[0].tv_nsec = UTIME_NOW;
+ }
+ else if (av == TV_TOUCH_RETAIN)
+ {
+ ts[0].tv_sec = 0;
+ ts[0].tv_nsec = UTIME_OMIT;
+ }
+ else
+ {
+ ts[0].tv_sec = av->tv_sec;
+ ts[0].tv_nsec = NS(av->tv_nsec);
+ }
+ if (!mv)
+ {
+ ts[1].tv_sec = 0;
+ ts[1].tv_nsec = UTIME_NOW;
+ }
+ else if (mv == TV_TOUCH_RETAIN)
+ {
+ ts[1].tv_sec = 0;
+ ts[1].tv_nsec = UTIME_OMIT;
+ }
+ else
+ {
+ ts[1].tv_sec = mv->tv_sec;
+ ts[1].tv_nsec = NS(mv->tv_nsec);
+ }
+ if (!cv && av == TV_TOUCH_RETAIN && mv == TV_TOUCH_RETAIN && !stat(path, &st) && !chmod(path, st.st_mode & S_IPERM))
+ return 0;
+ if (!utimensat(AT_FDCWD, path, ts[0].tv_nsec == UTIME_NOW && ts[1].tv_nsec == UTIME_NOW ? (struct timespec*)0 : ts, (flags & TV_TOUCH_PHYSICAL) ? AT_SYMLINK_NOFOLLOW : 0))
+ return 0;
+ if (errno != ENOSYS)
+ {
+ if (errno != ENOENT || !(flags & TV_TOUCH_CREATE))
+ return -1;
+ umask(mode = umask(0));
+ mode = (~mode) & (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+ if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, mode)) < 0)
+ return -1;
+ close(fd);
+ errno = oerrno;
+ if ((ts[0].tv_nsec != UTIME_NOW || ts[1].tv_nsec != UTIME_NOW) && utimensat(AT_FDCWD, path, ts, (flags & TV_TOUCH_PHYSICAL) ? AT_SYMLINK_NOFOLLOW : 0))
+ return -1;
+ return 0;
+ }
+#endif
+ if ((av == TV_TOUCH_RETAIN || mv == TV_TOUCH_RETAIN) && stat(path, &st))
+ {
+ errno = oerrno;
+ if (av == TV_TOUCH_RETAIN)
+ av = 0;
+ if (mv == TV_TOUCH_RETAIN)
+ mv = 0;
+ }
+ if (!av || !mv)
+ {
+ tvgettime(&now);
+ if (!av)
+ av = (const Tv_t*)&now;
+ if (!mv)
+ mv = (const Tv_t*)&now;
+ }
+#if _lib_utimets
+ if (av == TV_TOUCH_RETAIN)
+ {
+ ts[0].tv_sec = st.st_atime;
+ ts[0].tv_nsec = ST_ATIME_NSEC_GET(&st);
+ }
+ else
+ {
+ ts[0].tv_sec = av->tv_sec;
+ ts[0].tv_nsec = NS(av->tv_nsec);
+ }
+ if (mv == TV_TOUCH_RETAIN)
+ {
+ ts[1].tv_sec = st.st_mtime;
+ ts[1].tv_nsec = ST_MTIME_NSEC_GET(&st);
+ }
+ else
+ {
+ ts[1].tv_sec = mv->tv_sec;
+ ts[1].tv_nsec = NS(mv->tv_nsec);
+ }
+ if (!utimets(path, ts))
+ return 0;
+ if (errno != ENOENT && av == (const Tv_t*)&now && mv == (const Tv_t*)&now && !utimets(path, NiL))
+ {
+ errno = oerrno;
+ return 0;
+ }
+#else
+#if _lib_utimes
+ if (av == TV_TOUCH_RETAIN)
+ {
+ am[0].tv_sec = st.st_atime;
+ am[0].tv_usec = ST_ATIME_NSEC_GET(&st) / 1000;
+ }
+ else
+ {
+ am[0].tv_sec = av->tv_sec;
+ am[0].tv_usec = NS(av->tv_nsec) / 1000;
+ }
+ if (mv == TV_TOUCH_RETAIN)
+ {
+ am[1].tv_sec = st.st_mtime;
+ am[1].tv_usec = ST_MTIME_NSEC_GET(&st) / 1000;
+ }
+ else
+ {
+ am[1].tv_sec = mv->tv_sec;
+ am[1].tv_usec = NS(mv->tv_nsec) / 1000;
+ }
+ if (!utimes(path, am))
+ return 0;
+ if (errno != ENOENT && av == (const Tv_t*)&now && mv == (const Tv_t*)&now && !utimes(path, NiL))
+ {
+ errno = oerrno;
+ return 0;
+ }
+#else
+#if _lib_utime
+ am.actime = (av == TV_TOUCH_RETAIN) ? st.st_atime : av->tv_sec;
+ am.modtime = (mv == TV_TOUCH_RETAIN) ? st.st_mtime : mv->tv_sec;
+ if (!utime(path, &am))
+ return 0;
+#if _lib_utime_now
+ if (errno != ENOENT && av == (const Tv_t*)&now && mv == (const Tv_t*)&now && !utime(path, NiL))
+ {
+ errno = oerrno;
+ return 0;
+ }
+#endif
+#endif
+#endif
+ if (!access(path, F_OK))
+ {
+ if (av != (const Tv_t*)&now || mv != (const Tv_t*)&now)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ if ((fd = open(path, O_RDWR)) >= 0)
+ {
+ char c;
+
+ if (read(fd, &c, 1) == 1)
+ {
+ if (c = (lseek(fd, 0L, 0) == 0L && write(fd, &c, 1) == 1))
+ errno = oerrno;
+ close(fd);
+ if (c)
+ return 0;
+ }
+ close(fd);
+ }
+ }
+#endif
+ if (errno != ENOENT || !(flags & TV_TOUCH_CREATE))
+ return -1;
+ umask(mode = umask(0));
+ mode = (~mode) & (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+ if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, mode)) < 0)
+ return -1;
+ close(fd);
+ errno = oerrno;
+ if (av == (const Tv_t*)&now && mv == (const Tv_t*)&now)
+ return 0;
+#if _lib_utimets
+ return utimets(path, am);
+#else
+#if _lib_utimes
+ return utimes(path, am);
+#else
+#if _lib_utime
+ return utime(path, &am);
+#else
+ errno = EINVAL;
+ return -1;
+#endif
+#endif
+#endif
+
+}
diff --git a/src/lib/libast/uwin/a64l.c b/src/lib/libast/uwin/a64l.c
new file mode 100644
index 0000000..20416c6
--- /dev/null
+++ b/src/lib/libast/uwin/a64l.c
@@ -0,0 +1,76 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_a64l
+
+void _STUB_a64l(){}
+
+#else
+
+#define a64l ______a64l
+#define l64a ______l64a
+
+#include <stdlib.h>
+#include <string.h>
+
+#undef a64l
+#undef l64a
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+static char letter[65] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+extern long a64l(const char *str)
+{
+ register unsigned long ul = 0;
+ register int n = 6;
+ register int c;
+ register char *cp;
+ for(n=0; n <6; n++)
+ {
+ if((c= *str++)==0)
+ break;
+ if(!(cp=strchr(letter,c)))
+ break;
+ ul |= (cp-letter)<< (6*n);
+ }
+ return((long)ul);
+}
+
+extern char *l64a(long l)
+{
+ static char buff[7];
+ unsigned ul = ((unsigned long)l & 0xffffffff);
+ register char *cp = buff;
+ while(ul>0)
+ {
+ *cp++ = letter[ul&077];
+ ul >>= 6;
+ }
+ *cp = 0;
+ return(buff);
+}
+
+#endif
diff --git a/src/lib/libast/uwin/acosh.c b/src/lib/libast/uwin/acosh.c
new file mode 100644
index 0000000..9248e91
--- /dev/null
+++ b/src/lib/libast/uwin/acosh.c
@@ -0,0 +1,108 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_acosh
+
+void _STUB_acosh(){}
+
+#else
+
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)acosh.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* ACOSH(X)
+ * RETURN THE INVERSE HYPERBOLIC COSINE OF X
+ * DOUBLE PRECISION (VAX D FORMAT 56 BITS, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 2/16/85;
+ * REVISED BY K.C. NG on 3/6/85, 3/24/85, 4/16/85, 8/17/85.
+ *
+ * Required system supported functions :
+ * sqrt(x)
+ *
+ * Required kernel function:
+ * log1p(x) ...return log(1+x)
+ *
+ * Method :
+ * Based on
+ * acosh(x) = log [ x + sqrt(x*x-1) ]
+ * we have
+ * acosh(x) := log1p(x)+ln2, if (x > 1.0E20); else
+ * acosh(x) := log1p( sqrt(x-1) * (sqrt(x-1) + sqrt(x+1)) ) .
+ * These formulae avoid the over/underflow complication.
+ *
+ * Special cases:
+ * acosh(x) is NaN with signal if x<1.
+ * acosh(NaN) is NaN without signal.
+ *
+ * Accuracy:
+ * acosh(x) returns the exact inverse hyperbolic cosine of x nearly
+ * rounded. In a test run with 512,000 random arguments on a VAX, the
+ * maximum observed error was 3.30 ulps (units of the last place) at
+ * x=1.0070493753568216 .
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000)
+vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+
+ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000)
+ic(ln2lo, 1.9082149292705877000E-10,-33, 1.A39EF35793C76)
+
+#ifdef vccast
+#define ln2hi vccast(ln2hi)
+#define ln2lo vccast(ln2lo)
+#endif
+
+extern double acosh(x)
+double x;
+{
+ double t,big=1.E20; /* big+1==big */
+
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+
+ /* return log1p(x) + log(2) if x is large */
+ if(x>big) {t=log1p(x)+ln2lo; return(t+ln2hi);}
+
+ t=sqrt(x-1.0);
+ return(log1p(t*(t+sqrt(x+1.0))));
+}
+
+#endif
diff --git a/src/lib/libast/uwin/asinh.c b/src/lib/libast/uwin/asinh.c
new file mode 100644
index 0000000..6c8f54c
--- /dev/null
+++ b/src/lib/libast/uwin/asinh.c
@@ -0,0 +1,107 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_asinh
+
+void _STUB_asinh(){}
+
+#else
+
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)asinh.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* ASINH(X)
+ * RETURN THE INVERSE HYPERBOLIC SINE OF X
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 2/16/85;
+ * REVISED BY K.C. NG on 3/7/85, 3/24/85, 4/16/85.
+ *
+ * Required system supported functions :
+ * copysign(x,y)
+ * sqrt(x)
+ *
+ * Required kernel function:
+ * log1p(x) ...return log(1+x)
+ *
+ * Method :
+ * Based on
+ * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ]
+ * we have
+ * asinh(x) := x if 1+x*x=1,
+ * := sign(x)*(log1p(x)+ln2)) if sqrt(1+x*x)=x, else
+ * := sign(x)*log1p(|x| + |x|/(1/|x| + sqrt(1+(1/|x|)^2)) )
+ *
+ * Accuracy:
+ * asinh(x) returns the exact inverse hyperbolic sine of x nearly rounded.
+ * In a test run with 52,000 random arguments on a VAX, the maximum
+ * observed error was 1.58 ulps (units in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+#include "mathimpl.h"
+
+vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000)
+vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+
+ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000)
+ic(ln2lo, 1.9082149292705877000E-10, -33, 1.A39EF35793C76)
+
+#ifdef vccast
+#define ln2hi vccast(ln2hi)
+#define ln2lo vccast(ln2lo)
+#endif
+
+extern double asinh(x)
+double x;
+{
+ double t,s;
+ const static double small=1.0E-10, /* fl(1+small*small) == 1 */
+ big =1.0E20, /* fl(1+big) == big */
+ one =1.0 ;
+
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+ if((t=copysign(x,one))>small)
+ if(t<big) {
+ s=one/t; return(copysign(log1p(t+t/(s+sqrt(one+s*s))),x)); }
+ else /* if |x| > big */
+ {s=log1p(t)+ln2lo; return(copysign(s+ln2hi,x));}
+ else /* if |x| < small */
+ return(x);
+}
+
+#endif
diff --git a/src/lib/libast/uwin/atanh.c b/src/lib/libast/uwin/atanh.c
new file mode 100644
index 0000000..b5e9a78
--- /dev/null
+++ b/src/lib/libast/uwin/atanh.c
@@ -0,0 +1,89 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_atanh
+
+void _STUB_atanh(){}
+
+#else
+
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)atanh.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* ATANH(X)
+ * RETURN THE HYPERBOLIC ARC TANGENT OF X
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 1/8/85;
+ * REVISED BY K.C. NG on 2/7/85, 3/7/85, 8/18/85.
+ *
+ * Required kernel function:
+ * log1p(x) ...return log(1+x)
+ *
+ * Method :
+ * Return
+ * 1 2x x
+ * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
+ * 2 1 - x 1 - x
+ *
+ * Special cases:
+ * atanh(x) is NaN if |x| > 1 with signal;
+ * atanh(NaN) is that NaN with no signal;
+ * atanh(+-1) is +-INF with signal.
+ *
+ * Accuracy:
+ * atanh(x) returns the exact hyperbolic arc tangent of x nearly rounded.
+ * In a test run with 512,000 random arguments on a VAX, the maximum
+ * observed error was 1.87 ulps (units in the last place) at
+ * x= -3.8962076028810414000e-03.
+ */
+#include "mathimpl.h"
+
+#if defined(vax)||defined(tahoe)
+#include <errno.h>
+#endif /* defined(vax)||defined(tahoe) */
+
+extern double atanh(x)
+double x;
+{
+ double z;
+ z = copysign(0.5,x);
+ x = copysign(x,1.0);
+#if defined(vax)||defined(tahoe)
+ if (x == 1.0) {
+ return(copysign(1.0,z)*infnan(ERANGE)); /* sign(x)*INF */
+ }
+#endif /* defined(vax)||defined(tahoe) */
+ x = x/(1.0-x);
+ return( z*log1p(x+x) );
+}
+
+#endif
diff --git a/src/lib/libast/uwin/cbrt.c b/src/lib/libast/uwin/cbrt.c
new file mode 100644
index 0000000..f28d337
--- /dev/null
+++ b/src/lib/libast/uwin/cbrt.c
@@ -0,0 +1,38 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_cbrt
+
+void _STUB_cbrt(){}
+
+#else
+
+#include "mathimpl.h"
+
+extern double cbrt(double x)
+{
+ return(exp(log(x)/3.0));
+}
+
+
+#endif
diff --git a/src/lib/libast/uwin/crypt.c b/src/lib/libast/uwin/crypt.c
new file mode 100644
index 0000000..5d9569e
--- /dev/null
+++ b/src/lib/libast/uwin/crypt.c
@@ -0,0 +1,959 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_crypt
+
+void _STUB_crypt(){}
+
+#else
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Tom Truscott.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)crypt.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#define crypt ______crypt
+#define encrypt ______encrypt
+#define setkey ______setkey
+
+/* #include <unistd.h> */
+#include <stdio.h>
+#include <limits.h>
+#include <pwd.h>
+
+#undef crypt
+#undef encrypt
+#undef setkey
+
+#ifndef _PASSWORD_EFMT1
+#define _PASSWORD_EFMT1 '-'
+#endif
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+/*
+ * UNIX password, and DES, encryption.
+ * By Tom Truscott, trt@rti.rti.org,
+ * from algorithms by Robert W. Baldwin and James Gillogly.
+ *
+ * References:
+ * "Mathematical Cryptology for Computer Scientists and Mathematicians,"
+ * by Wayne Patterson, 1987, ISBN 0-8476-7438-X.
+ *
+ * "Password Security: A Case History," R. Morris and Ken Thompson,
+ * Communications of the ACM, vol. 22, pp. 594-597, Nov. 1979.
+ *
+ * "DES will be Totally Insecure within Ten Years," M.E. Hellman,
+ * IEEE Spectrum, vol. 16, pp. 32-39, July 1979.
+ */
+
+/* ===== Configuration ==================== */
+
+/*
+ * define "MUST_ALIGN" if your compiler cannot load/store
+ * long integers at arbitrary (e.g. odd) memory locations.
+ * (Either that or never pass unaligned addresses to des_cipher!)
+ */
+#if !defined(vax)
+#define MUST_ALIGN
+#endif
+
+#ifdef CHAR_BITS
+#if CHAR_BITS != 8
+ #error C_block structure assumes 8 bit characters
+#endif
+#endif
+
+/*
+ * define "LONG_IS_32_BITS" only if sizeof(long)==4.
+ * This avoids use of bit fields (your compiler may be sloppy with them).
+ */
+#if !defined(cray)
+#define LONG_IS_32_BITS
+#endif
+
+/*
+ * define "B64" to be the declaration for a 64 bit integer.
+ * XXX this feature is currently unused, see "endian" comment below.
+ */
+#if defined(cray)
+#define B64 long
+#endif
+#if defined(convex)
+#define B64 long long
+#endif
+
+/*
+ * define "LARGEDATA" to get faster permutations, by using about 72 kilobytes
+ * of lookup tables. This speeds up des_setkey() and des_cipher(), but has
+ * little effect on crypt().
+ */
+#if defined(notdef)
+#define LARGEDATA
+#endif
+
+/* ==================================== */
+
+/*
+ * Cipher-block representation (Bob Baldwin):
+ *
+ * DES operates on groups of 64 bits, numbered 1..64 (sigh). One
+ * representation is to store one bit per byte in an array of bytes. Bit N of
+ * the NBS spec is stored as the LSB of the Nth byte (index N-1) in the array.
+ * Another representation stores the 64 bits in 8 bytes, with bits 1..8 in the
+ * first byte, 9..16 in the second, and so on. The DES spec apparently has
+ * bit 1 in the MSB of the first byte, but that is particularly noxious so we
+ * bit-reverse each byte so that bit 1 is the LSB of the first byte, bit 8 is
+ * the MSB of the first byte. Specifically, the 64-bit input data and key are
+ * converted to LSB format, and the output 64-bit block is converted back into
+ * MSB format.
+ *
+ * DES operates internally on groups of 32 bits which are expanded to 48 bits
+ * by permutation E and shrunk back to 32 bits by the S boxes. To speed up
+ * the computation, the expansion is applied only once, the expanded
+ * representation is maintained during the encryption, and a compression
+ * permutation is applied only at the end. To speed up the S-box lookups,
+ * the 48 bits are maintained as eight 6 bit groups, one per byte, which
+ * directly feed the eight S-boxes. Within each byte, the 6 bits are the
+ * most significant ones. The low two bits of each byte are zero. (Thus,
+ * bit 1 of the 48 bit E expansion is stored as the "4"-valued bit of the
+ * first byte in the eight byte representation, bit 2 of the 48 bit value is
+ * the "8"-valued bit, and so on.) In fact, a combined "SPE"-box lookup is
+ * used, in which the output is the 64 bit result of an S-box lookup which
+ * has been permuted by P and expanded by E, and is ready for use in the next
+ * iteration. Two 32-bit wide tables, SPE[0] and SPE[1], are used for this
+ * lookup. Since each byte in the 48 bit path is a multiple of four, indexed
+ * lookup of SPE[0] and SPE[1] is simple and fast. The key schedule and
+ * "salt" are also converted to this 8*(6+2) format. The SPE table size is
+ * 8*64*8 = 4K bytes.
+ *
+ * To speed up bit-parallel operations (such as XOR), the 8 byte
+ * representation is "union"ed with 32 bit values "i0" and "i1", and, on
+ * machines which support it, a 64 bit value "b64". This data structure,
+ * "C_block", has two problems. First, alignment restrictions must be
+ * honored. Second, the byte-order (e.g. little-endian or big-endian) of
+ * the architecture becomes visible.
+ *
+ * The byte-order problem is unfortunate, since on the one hand it is good
+ * to have a machine-independent C_block representation (bits 1..8 in the
+ * first byte, etc.), and on the other hand it is good for the LSB of the
+ * first byte to be the LSB of i0. We cannot have both these things, so we
+ * currently use the "little-endian" representation and avoid any multi-byte
+ * operations that depend on byte order. This largely precludes use of the
+ * 64-bit datatype since the relative order of i0 and i1 are unknown. It
+ * also inhibits grouping the SPE table to look up 12 bits at a time. (The
+ * 12 bits can be stored in a 16-bit field with 3 low-order zeroes and 1
+ * high-order zero, providing fast indexing into a 64-bit wide SPE.) On the
+ * other hand, 64-bit datatypes are currently rare, and a 12-bit SPE lookup
+ * requires a 128 kilobyte table, so perhaps this is not a big loss.
+ *
+ * Permutation representation (Jim Gillogly):
+ *
+ * A transformation is defined by its effect on each of the 8 bytes of the
+ * 64-bit input. For each byte we give a 64-bit output that has the bits in
+ * the input distributed appropriately. The transformation is then the OR
+ * of the 8 sets of 64-bits. This uses 8*256*8 = 16K bytes of storage for
+ * each transformation. Unless LARGEDATA is defined, however, a more compact
+ * table is used which looks up 16 4-bit "chunks" rather than 8 8-bit chunks.
+ * The smaller table uses 16*16*8 = 2K bytes for each transformation. This
+ * is slower but tolerable, particularly for password encryption in which
+ * the SPE transformation is iterated many times. The small tables total 9K
+ * bytes, the large tables total 72K bytes.
+ *
+ * The transformations used are:
+ * IE3264: MSB->LSB conversion, initial permutation, and expansion.
+ * This is done by collecting the 32 even-numbered bits and applying
+ * a 32->64 bit transformation, and then collecting the 32 odd-numbered
+ * bits and applying the same transformation. Since there are only
+ * 32 input bits, the IE3264 transformation table is half the size of
+ * the usual table.
+ * CF6464: Compression, final permutation, and LSB->MSB conversion.
+ * This is done by two trivial 48->32 bit compressions to obtain
+ * a 64-bit block (the bit numbering is given in the "CIFP" table)
+ * followed by a 64->64 bit "cleanup" transformation. (It would
+ * be possible to group the bits in the 64-bit block so that 2
+ * identical 32->32 bit transformations could be used instead,
+ * saving a factor of 4 in space and possibly 2 in time, but
+ * byte-ordering and other complications rear their ugly head.
+ * Similar opportunities/problems arise in the key schedule
+ * transforms.)
+ * PC1ROT: MSB->LSB, PC1 permutation, rotate, and PC2 permutation.
+ * This admittedly baroque 64->64 bit transformation is used to
+ * produce the first code (in 8*(6+2) format) of the key schedule.
+ * PC2ROT[0]: Inverse PC2 permutation, rotate, and PC2 permutation.
+ * It would be possible to define 15 more transformations, each
+ * with a different rotation, to generate the entire key schedule.
+ * To save space, however, we instead permute each code into the
+ * next by using a transformation that "undoes" the PC2 permutation,
+ * rotates the code, and then applies PC2. Unfortunately, PC2
+ * transforms 56 bits into 48 bits, dropping 8 bits, so PC2 is not
+ * invertible. We get around that problem by using a modified PC2
+ * which retains the 8 otherwise-lost bits in the unused low-order
+ * bits of each byte. The low-order bits are cleared when the
+ * codes are stored into the key schedule.
+ * PC2ROT[1]: Same as PC2ROT[0], but with two rotations.
+ * This is faster than applying PC2ROT[0] twice,
+ *
+ * The Bell Labs "salt" (Bob Baldwin):
+ *
+ * The salting is a simple permutation applied to the 48-bit result of E.
+ * Specifically, if bit i (1 <= i <= 24) of the salt is set then bits i and
+ * i+24 of the result are swapped. The salt is thus a 24 bit number, with
+ * 16777216 possible values. (The original salt was 12 bits and could not
+ * swap bits 13..24 with 36..48.)
+ *
+ * It is possible, but ugly, to warp the SPE table to account for the salt
+ * permutation. Fortunately, the conditional bit swapping requires only
+ * about four machine instructions and can be done on-the-fly with about an
+ * 8% performance penalty.
+ */
+
+typedef union {
+ unsigned char b[8];
+ struct {
+#if defined(LONG_IS_32_BITS)
+ /* long is often faster than a 32-bit bit field */
+ long i0;
+ long i1;
+#else
+ long i0: 32;
+ long i1: 32;
+#endif
+ } b32;
+#if defined(B64)
+ B64 b64;
+#endif
+} C_block;
+
+/*
+ * Convert twenty-four-bit long in host-order
+ * to six bits (and 2 low-order zeroes) per char little-endian format.
+ */
+#define TO_SIX_BIT(rslt, src) { \
+ C_block cvt; \
+ cvt.b[0] = (unsigned char) src; src >>= 6; \
+ cvt.b[1] = (unsigned char) src; src >>= 6; \
+ cvt.b[2] = (unsigned char) src; src >>= 6; \
+ cvt.b[3] = (unsigned char) src; \
+ rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \
+ }
+
+/*
+ * These macros may someday permit efficient use of 64-bit integers.
+ */
+#define ZERO(d,d0,d1) d0 = 0, d1 = 0
+#define LOAD(d,d0,d1,bl) d0 = (bl).b32.i0, d1 = (bl).b32.i1
+#define LOADREG(d,d0,d1,s,s0,s1) d0 = s0, d1 = s1
+#define OR(d,d0,d1,bl) d0 |= (bl).b32.i0, d1 |= (bl).b32.i1
+#define STORE(s,s0,s1,bl) (bl).b32.i0 = s0, (bl).b32.i1 = s1
+#define DCL_BLOCK(d,d0,d1) long d0, d1
+/* proto(1) workarounds -- barf */
+#define DCL_BLOCK_D DCL_BLOCK(D,D0,D1)
+#define DCL_BLOCK_K DCL_BLOCK(K,K0,K1)
+
+#if defined(LARGEDATA)
+ /* Waste memory like crazy. Also, do permutations in line */
+#define LGCHUNKBITS 3
+#define CHUNKBITS (1<<LGCHUNKBITS)
+#define PERM6464(d,d0,d1,cpp,p) \
+ LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]); \
+ OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]); \
+ OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]); \
+ OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]); \
+ OR (d,d0,d1,(p)[(4<<CHUNKBITS)+(cpp)[4]]); \
+ OR (d,d0,d1,(p)[(5<<CHUNKBITS)+(cpp)[5]]); \
+ OR (d,d0,d1,(p)[(6<<CHUNKBITS)+(cpp)[6]]); \
+ OR (d,d0,d1,(p)[(7<<CHUNKBITS)+(cpp)[7]]);
+#define PERM3264(d,d0,d1,cpp,p) \
+ LOAD(d,d0,d1,(p)[(0<<CHUNKBITS)+(cpp)[0]]); \
+ OR (d,d0,d1,(p)[(1<<CHUNKBITS)+(cpp)[1]]); \
+ OR (d,d0,d1,(p)[(2<<CHUNKBITS)+(cpp)[2]]); \
+ OR (d,d0,d1,(p)[(3<<CHUNKBITS)+(cpp)[3]]);
+#else
+ /* "small data" */
+#define LGCHUNKBITS 2
+#define CHUNKBITS (1<<LGCHUNKBITS)
+#define PERM6464(d,d0,d1,cpp,p) \
+ { C_block tblk; permute(cpp,&tblk,p,8); LOAD (d,d0,d1,tblk); }
+#define PERM3264(d,d0,d1,cpp,p) \
+ { C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); }
+
+static void permute(unsigned char *cp, C_block *out, register C_block *p, int chars_in) {
+ register DCL_BLOCK_D;
+ register C_block *tp;
+ register int t;
+
+ ZERO(D,D0,D1);
+ do {
+ t = *cp++;
+ tp = &p[t&0xf]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
+ tp = &p[t>>4]; OR(D,D0,D1,*tp); p += (1<<CHUNKBITS);
+ } while (--chars_in > 0);
+ STORE(D,D0,D1,*out);
+}
+#endif /* LARGEDATA */
+
+
+/* ===== (mostly) Standard DES Tables ==================== */
+
+static unsigned char IP[] = { /* initial permutation */
+ 58, 50, 42, 34, 26, 18, 10, 2,
+ 60, 52, 44, 36, 28, 20, 12, 4,
+ 62, 54, 46, 38, 30, 22, 14, 6,
+ 64, 56, 48, 40, 32, 24, 16, 8,
+ 57, 49, 41, 33, 25, 17, 9, 1,
+ 59, 51, 43, 35, 27, 19, 11, 3,
+ 61, 53, 45, 37, 29, 21, 13, 5,
+ 63, 55, 47, 39, 31, 23, 15, 7,
+};
+
+/* The final permutation is the inverse of IP - no table is necessary */
+
+static unsigned char ExpandTr[] = { /* expansion operation */
+ 32, 1, 2, 3, 4, 5,
+ 4, 5, 6, 7, 8, 9,
+ 8, 9, 10, 11, 12, 13,
+ 12, 13, 14, 15, 16, 17,
+ 16, 17, 18, 19, 20, 21,
+ 20, 21, 22, 23, 24, 25,
+ 24, 25, 26, 27, 28, 29,
+ 28, 29, 30, 31, 32, 1,
+};
+
+static unsigned char PC1[] = { /* permuted choice table 1 */
+ 57, 49, 41, 33, 25, 17, 9,
+ 1, 58, 50, 42, 34, 26, 18,
+ 10, 2, 59, 51, 43, 35, 27,
+ 19, 11, 3, 60, 52, 44, 36,
+
+ 63, 55, 47, 39, 31, 23, 15,
+ 7, 62, 54, 46, 38, 30, 22,
+ 14, 6, 61, 53, 45, 37, 29,
+ 21, 13, 5, 28, 20, 12, 4,
+};
+
+static unsigned char Rotates[] = { /* PC1 rotation schedule */
+ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
+};
+
+/* note: each "row" of PC2 is left-padded with bits that make it invertible */
+static unsigned char PC2[] = { /* permuted choice table 2 */
+ 9, 18, 14, 17, 11, 24, 1, 5,
+ 22, 25, 3, 28, 15, 6, 21, 10,
+ 35, 38, 23, 19, 12, 4, 26, 8,
+ 43, 54, 16, 7, 27, 20, 13, 2,
+
+ 0, 0, 41, 52, 31, 37, 47, 55,
+ 0, 0, 30, 40, 51, 45, 33, 48,
+ 0, 0, 44, 49, 39, 56, 34, 53,
+ 0, 0, 46, 42, 50, 36, 29, 32,
+};
+
+static unsigned char S[8][64] = { /* 48->32 bit substitution tables */
+ /* S[1] */
+ 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
+ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
+ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
+ 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
+ /* S[2] */
+ 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
+ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
+ 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
+ 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
+ /* S[3] */
+ 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
+ 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
+ 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
+ 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
+ /* S[4] */
+ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
+ 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
+ 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
+ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
+ /* S[5] */
+ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
+ 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
+ 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
+ 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
+ /* S[6] */
+ 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
+ 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
+ 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
+ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
+ /* S[7] */
+ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
+ 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
+ 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
+ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
+ /* S[8] */
+ 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
+ 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
+ 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
+ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
+};
+
+static unsigned char P32Tr[] = { /* 32-bit permutation function */
+ 16, 7, 20, 21,
+ 29, 12, 28, 17,
+ 1, 15, 23, 26,
+ 5, 18, 31, 10,
+ 2, 8, 24, 14,
+ 32, 27, 3, 9,
+ 19, 13, 30, 6,
+ 22, 11, 4, 25,
+};
+
+static unsigned char CIFP[] = { /* compressed/interleaved permutation */
+ 1, 2, 3, 4, 17, 18, 19, 20,
+ 5, 6, 7, 8, 21, 22, 23, 24,
+ 9, 10, 11, 12, 25, 26, 27, 28,
+ 13, 14, 15, 16, 29, 30, 31, 32,
+
+ 33, 34, 35, 36, 49, 50, 51, 52,
+ 37, 38, 39, 40, 53, 54, 55, 56,
+ 41, 42, 43, 44, 57, 58, 59, 60,
+ 45, 46, 47, 48, 61, 62, 63, 64,
+};
+
+static unsigned char itoa64[] = /* 0..63 => ascii-64 */
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+
+/* ===== Tables that are initialized at run time ==================== */
+
+
+static unsigned char a64toi[128]; /* ascii-64 => 0..63 */
+
+/* Initial key schedule permutation */
+static C_block PC1ROT[64/CHUNKBITS][1<<CHUNKBITS];
+
+/* Subsequent key schedule rotation permutations */
+static C_block PC2ROT[2][64/CHUNKBITS][1<<CHUNKBITS];
+
+/* Initial permutation/expansion table */
+static C_block IE3264[32/CHUNKBITS][1<<CHUNKBITS];
+
+/* Table that combines the S, P, and E operations. */
+static long SPE[2][8][64];
+
+/* compressed/interleaved => final permutation table */
+static C_block CF6464[64/CHUNKBITS][1<<CHUNKBITS];
+
+
+/* ==================================== */
+
+static C_block constdatablock; /* encryption constant */
+static char cryptresult[1+4+4+11+1]; /* encrypted result */
+
+/*
+ * Initialize "perm" to represent transformation "p", which rearranges
+ * (perhaps with expansion and/or contraction) one packed array of bits
+ * (of size "chars_in" characters) into another array (of size "chars_out"
+ * characters).
+ *
+ * "perm" must be all-zeroes on entry to this routine.
+ */
+static void init_perm(C_block perm[64/CHUNKBITS][1<<CHUNKBITS],
+ unsigned char p[64], int chars_in, int chars_out) {
+ register int i, j, k, l;
+
+ for (k = 0; k < chars_out*8; k++) { /* each output bit position */
+ l = p[k] - 1; /* where this bit comes from */
+ if (l < 0)
+ continue; /* output bit is always 0 */
+ i = l>>LGCHUNKBITS; /* which chunk this bit comes from */
+ l = 1<<(l&(CHUNKBITS-1)); /* mask for this bit */
+ for (j = 0; j < (1<<CHUNKBITS); j++) { /* each chunk value */
+ if ((j & l) != 0)
+ perm[i][j].b[k>>3] |= 1<<(k&07);
+ }
+ }
+}
+
+/*
+ * Initialize various tables. This need only be done once. It could even be
+ * done at compile time, if the compiler were capable of that sort of thing.
+ */
+static void init_des(void) {
+ register int i, j;
+ register long k;
+ register int tableno;
+ static unsigned char perm[64], tmp32[32]; /* "static" for speed */
+
+ /*
+ * table that converts chars "./0-9A-Za-z"to integers 0-63.
+ */
+ for (i = 0; i < 64; i++)
+ a64toi[itoa64[i]] = i;
+
+ /*
+ * PC1ROT - bit reverse, then PC1, then Rotate, then PC2.
+ */
+ for (i = 0; i < 64; i++)
+ perm[i] = 0;
+ for (i = 0; i < 64; i++) {
+ if ((k = PC2[i]) == 0)
+ continue;
+ k += Rotates[0]-1;
+ if ((k%28) < Rotates[0]) k -= 28;
+ k = PC1[k];
+ if (k > 0) {
+ k--;
+ k = (k|07) - (k&07);
+ k++;
+ }
+ perm[i] = (unsigned char) k;
+ }
+#ifdef DEBUG
+ prtab("pc1tab", perm, 8);
+#endif
+ init_perm(PC1ROT, perm, 8, 8);
+
+ /*
+ * PC2ROT - PC2 inverse, then Rotate (once or twice), then PC2.
+ */
+ for (j = 0; j < 2; j++) {
+ unsigned char pc2inv[64];
+ for (i = 0; i < 64; i++)
+ perm[i] = pc2inv[i] = 0;
+ for (i = 0; i < 64; i++) {
+ if ((k = PC2[i]) == 0)
+ continue;
+ pc2inv[k-1] = i+1;
+ }
+ for (i = 0; i < 64; i++) {
+ if ((k = PC2[i]) == 0)
+ continue;
+ k += j;
+ if ((k%28) <= j) k -= 28;
+ perm[i] = pc2inv[k];
+ }
+#ifdef DEBUG
+ prtab("pc2tab", perm, 8);
+#endif
+ init_perm(PC2ROT[j], perm, 8, 8);
+ }
+
+ /*
+ * Bit reverse, then initial permutation, then expansion.
+ */
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < 8; j++) {
+ k = (j < 2)? 0: IP[ExpandTr[i*6+j-2]-1];
+ if (k > 32)
+ k -= 32;
+ else if (k > 0)
+ k--;
+ if (k > 0) {
+ k--;
+ k = (k|07) - (k&07);
+ k++;
+ }
+ perm[i*8+j] = (unsigned char) k;
+ }
+ }
+#ifdef DEBUG
+ prtab("ietab", perm, 8);
+#endif
+ init_perm(IE3264, perm, 4, 8);
+
+ /*
+ * Compression, then final permutation, then bit reverse.
+ */
+ for (i = 0; i < 64; i++) {
+ k = IP[CIFP[i]-1];
+ if (k > 0) {
+ k--;
+ k = (k|07) - (k&07);
+ k++;
+ }
+ perm[k-1] = i+1;
+ }
+#ifdef DEBUG
+ prtab("cftab", perm, 8);
+#endif
+ init_perm(CF6464, perm, 8, 8);
+
+ /*
+ * SPE table
+ */
+ for (i = 0; i < 48; i++)
+ perm[i] = P32Tr[ExpandTr[i]-1];
+ for (tableno = 0; tableno < 8; tableno++) {
+ for (j = 0; j < 64; j++) {
+ k = (((j >> 0) &01) << 5)|
+ (((j >> 1) &01) << 3)|
+ (((j >> 2) &01) << 2)|
+ (((j >> 3) &01) << 1)|
+ (((j >> 4) &01) << 0)|
+ (((j >> 5) &01) << 4);
+ k = S[tableno][k];
+ k = (((k >> 3)&01) << 0)|
+ (((k >> 2)&01) << 1)|
+ (((k >> 1)&01) << 2)|
+ (((k >> 0)&01) << 3);
+ for (i = 0; i < 32; i++)
+ tmp32[i] = 0;
+ for (i = 0; i < 4; i++)
+ tmp32[4 * tableno + i] = (k >> i) & 01;
+ k = 0;
+ for (i = 24; --i >= 0; )
+ k = (k<<1) | tmp32[perm[i]-1];
+ TO_SIX_BIT(SPE[0][tableno][j], k);
+ k = 0;
+ for (i = 24; --i >= 0; )
+ k = (k<<1) | tmp32[perm[i+24]-1];
+ TO_SIX_BIT(SPE[1][tableno][j], k);
+ }
+ }
+}
+
+/*
+ * The Key Schedule, filled in by des_setkey() or setkey().
+ */
+#define KS_SIZE 16
+static C_block KS[KS_SIZE];
+
+/*
+ * Set up the key schedule from the key.
+ */
+static int des_setkey(register const char *key) {
+ register DCL_BLOCK_K;
+ register C_block *ptabp;
+ register int i;
+ static int des_ready = 0;
+
+ if (!des_ready) {
+ init_des();
+ des_ready = 1;
+ }
+
+ PERM6464(K,K0,K1,(unsigned char *)key,(C_block *)PC1ROT);
+ key = (char *)&KS[0];
+ STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key);
+ for (i = 1; i < 16; i++) {
+ key += sizeof(C_block);
+ STORE(K,K0,K1,*(C_block *)key);
+ ptabp = (C_block *)PC2ROT[Rotates[i]-1];
+ PERM6464(K,K0,K1,(unsigned char *)key,ptabp);
+ STORE(K&~0x03030303L, K0&~0x03030303L, K1, *(C_block *)key);
+ }
+ return (0);
+}
+
+/*
+ * Encrypt (or decrypt if num_iter < 0) the 8 chars at "in" with abs(num_iter)
+ * iterations of DES, using the the given 24-bit salt and the pre-computed key
+ * schedule, and store the resulting 8 chars at "out" (in == out is permitted).
+ *
+ * NOTE: the performance of this routine is critically dependent on your
+ * compiler and machine architecture.
+ */
+static int des_cipher(const char *in, char *out, long salt, int num_iter) {
+ /* variables that we want in registers, most important first */
+#if defined(pdp11)
+ register int j;
+#endif
+ register long L0, L1, R0, R1, k;
+ register C_block *kp;
+ register int ks_inc, loop_count;
+ C_block B;
+
+ L0 = salt;
+ TO_SIX_BIT(salt, L0); /* convert to 4*(6+2) format */
+
+#if defined(vax) || defined(pdp11)
+ salt = ~salt; /* "x &~ y" is faster than "x & y". */
+#define SALT (~salt)
+#else
+#define SALT salt
+#endif
+
+#if defined(MUST_ALIGN)
+ B.b[0] = in[0]; B.b[1] = in[1]; B.b[2] = in[2]; B.b[3] = in[3];
+ B.b[4] = in[4]; B.b[5] = in[5]; B.b[6] = in[6]; B.b[7] = in[7];
+ LOAD(L,L0,L1,B);
+#else
+ LOAD(L,L0,L1,*(C_block *)in);
+#endif
+ LOADREG(R,R0,R1,L,L0,L1);
+ L0 &= 0x55555555L;
+ L1 &= 0x55555555L;
+ L0 = (L0 << 1) | L1; /* L0 is the even-numbered input bits */
+ R0 &= 0xaaaaaaaaL;
+ R1 = (R1 >> 1) & 0x55555555L;
+ L1 = R0 | R1; /* L1 is the odd-numbered input bits */
+ STORE(L,L0,L1,B);
+ PERM3264(L,L0,L1,B.b, (C_block *)IE3264); /* even bits */
+ PERM3264(R,R0,R1,B.b+4,(C_block *)IE3264); /* odd bits */
+
+ if (num_iter >= 0)
+ { /* encryption */
+ kp = &KS[0];
+ ks_inc = sizeof(*kp);
+ }
+ else
+ { /* decryption */
+ num_iter = -num_iter;
+ kp = &KS[KS_SIZE-1];
+ ks_inc = -((int) sizeof(*kp));
+ }
+
+ while (--num_iter >= 0) {
+ loop_count = 8;
+ do {
+
+#define SPTAB(t, i) (*(long *)((unsigned char *)t + i*(sizeof(long)/4)))
+#if defined(gould)
+ /* use this if B.b[i] is evaluated just once ... */
+#define DOXOR(x,y,i) x^=SPTAB(SPE[0][i],B.b[i]); y^=SPTAB(SPE[1][i],B.b[i]);
+#else
+#if defined(pdp11)
+ /* use this if your "long" int indexing is slow */
+#define DOXOR(x,y,i) j=B.b[i]; x^=SPTAB(SPE[0][i],j); y^=SPTAB(SPE[1][i],j);
+#else
+ /* use this if "k" is allocated to a register ... */
+#define DOXOR(x,y,i) k=B.b[i]; x^=SPTAB(SPE[0][i],k); y^=SPTAB(SPE[1][i],k);
+#endif
+#endif
+
+#define CRUNCH(p0, p1, q0, q1) \
+ k = (q0 ^ q1) & SALT; \
+ B.b32.i0 = k ^ q0 ^ kp->b32.i0; \
+ B.b32.i1 = k ^ q1 ^ kp->b32.i1; \
+ kp = (C_block *)((char *)kp+ks_inc); \
+ \
+ DOXOR(p0, p1, 0); \
+ DOXOR(p0, p1, 1); \
+ DOXOR(p0, p1, 2); \
+ DOXOR(p0, p1, 3); \
+ DOXOR(p0, p1, 4); \
+ DOXOR(p0, p1, 5); \
+ DOXOR(p0, p1, 6); \
+ DOXOR(p0, p1, 7);
+
+ CRUNCH(L0, L1, R0, R1);
+ CRUNCH(R0, R1, L0, L1);
+ } while (--loop_count != 0);
+ kp = (C_block *)((char *)kp-(ks_inc*KS_SIZE));
+
+
+ /* swap L and R */
+ L0 ^= R0; L1 ^= R1;
+ R0 ^= L0; R1 ^= L1;
+ L0 ^= R0; L1 ^= R1;
+ }
+
+ /* store the encrypted (or decrypted) result */
+ L0 = ((L0 >> 3) & 0x0f0f0f0fL) | ((L1 << 1) & 0xf0f0f0f0L);
+ L1 = ((R0 >> 3) & 0x0f0f0f0fL) | ((R1 << 1) & 0xf0f0f0f0L);
+ STORE(L,L0,L1,B);
+ PERM6464(L,L0,L1,B.b, (C_block *)CF6464);
+#if defined(MUST_ALIGN)
+ STORE(L,L0,L1,B);
+ out[0] = B.b[0]; out[1] = B.b[1]; out[2] = B.b[2]; out[3] = B.b[3];
+ out[4] = B.b[4]; out[5] = B.b[5]; out[6] = B.b[6]; out[7] = B.b[7];
+#else
+ STORE(L,L0,L1,*(C_block *)out);
+#endif
+ return (0);
+}
+
+/*
+ * "setkey" routine (for backwards compatibility)
+ */
+extern int setkey(register const char *key) {
+ register int i, j, k;
+ C_block keyblock;
+
+ for (i = 0; i < 8; i++) {
+ k = 0;
+ for (j = 0; j < 8; j++) {
+ k <<= 1;
+ k |= (unsigned char)*key++;
+ }
+ keyblock.b[i] = k;
+ }
+ return (des_setkey((char *)keyblock.b));
+}
+
+/*
+ * "encrypt" routine (for backwards compatibility)
+ */
+extern int encrypt(register char *block, int flag) {
+ register int i, j, k;
+ C_block cblock;
+
+ for (i = 0; i < 8; i++) {
+ k = 0;
+ for (j = 0; j < 8; j++) {
+ k <<= 1;
+ k |= (unsigned char)*block++;
+ }
+ cblock.b[i] = k;
+ }
+ if (des_cipher((char *)&cblock, (char *)&cblock, 0L, (flag ? -1: 1)))
+ return (1);
+ for (i = 7; i >= 0; i--) {
+ k = cblock.b[i];
+ for (j = 7; j >= 0; j--) {
+ *--block = k&01;
+ k >>= 1;
+ }
+ }
+ return (0);
+}
+
+/*
+ * Return a pointer to static data consisting of the "setting"
+ * followed by an encryption produced by the "key" and "setting".
+ */
+extern char * crypt(register const char *key, register const char *setting) {
+ register char *encp;
+ register long i;
+ register int t;
+ long salt;
+ int num_iter, salt_size;
+ C_block keyblock, rsltblock;
+
+#ifdef HL_NOENCRYPTION
+ char buff[1024];
+ strncpy(buff, key, 1024);
+ buff[1023] = 0;
+ return buff;
+#endif
+
+ for (i = 0; i < 8; i++) {
+ if ((t = 2*(unsigned char)(*key)) != 0)
+ key++;
+ keyblock.b[i] = t;
+ }
+ if (des_setkey((char *)keyblock.b)) /* also initializes "a64toi" */
+ return (NULL);
+
+ encp = &cryptresult[0];
+ switch (*setting) {
+ case _PASSWORD_EFMT1:
+ /*
+ * Involve the rest of the password 8 characters at a time.
+ */
+ while (*key) {
+ if (des_cipher((char *)&keyblock,
+ (char *)&keyblock, 0L, 1))
+ return (NULL);
+ for (i = 0; i < 8; i++) {
+ if ((t = 2*(unsigned char)(*key)) != 0)
+ key++;
+ keyblock.b[i] ^= t;
+ }
+ if (des_setkey((char *)keyblock.b))
+ return (NULL);
+ }
+
+ *encp++ = *setting++;
+
+ /* get iteration count */
+ num_iter = 0;
+ for (i = 4; --i >= 0; ) {
+ if ((t = (unsigned char)setting[i]) == '\0')
+ t = '.';
+ encp[i] = t;
+ num_iter = (num_iter<<6) | a64toi[t];
+ }
+ setting += 4;
+ encp += 4;
+ salt_size = 4;
+ break;
+ default:
+ num_iter = 25;
+ salt_size = 2;
+ }
+
+ salt = 0;
+ for (i = salt_size; --i >= 0; ) {
+ if ((t = (unsigned char)setting[i]) == '\0')
+ t = '.';
+ encp[i] = t;
+ salt = (salt<<6) | a64toi[t];
+ }
+ encp += salt_size;
+ if (des_cipher((char *)&constdatablock, (char *)&rsltblock,
+ salt, num_iter))
+ return (NULL);
+
+ /*
+ * Encode the 64 cipher bits as 11 ascii characters.
+ */
+ i = ((long)((rsltblock.b[0]<<8) | rsltblock.b[1])<<8) | rsltblock.b[2];
+ encp[3] = itoa64[i&0x3f]; i >>= 6;
+ encp[2] = itoa64[i&0x3f]; i >>= 6;
+ encp[1] = itoa64[i&0x3f]; i >>= 6;
+ encp[0] = itoa64[i]; encp += 4;
+ i = ((long)((rsltblock.b[3]<<8) | rsltblock.b[4])<<8) | rsltblock.b[5];
+ encp[3] = itoa64[i&0x3f]; i >>= 6;
+ encp[2] = itoa64[i&0x3f]; i >>= 6;
+ encp[1] = itoa64[i&0x3f]; i >>= 6;
+ encp[0] = itoa64[i]; encp += 4;
+ i = ((long)((rsltblock.b[6])<<8) | rsltblock.b[7])<<2;
+ encp[2] = itoa64[i&0x3f]; i >>= 6;
+ encp[1] = itoa64[i&0x3f]; i >>= 6;
+ encp[0] = itoa64[i];
+
+ encp[3] = 0;
+
+ return (cryptresult);
+}
+
+#ifdef DEBUG
+STATIC
+prtab(s, t, num_rows)
+ char *s;
+ unsigned char *t;
+ int num_rows;
+{
+ register int i, j;
+
+ (void)printf("%s:\n", s);
+ for (i = 0; i < num_rows; i++) {
+ for (j = 0; j < 8; j++) {
+ (void)printf("%3d", t[i*8+j]);
+ }
+ (void)printf("\n");
+ }
+ (void)printf("\n");
+}
+#endif
+
+#endif
diff --git a/src/lib/libast/uwin/erf.c b/src/lib/libast/uwin/erf.c
new file mode 100644
index 0000000..4a61f78
--- /dev/null
+++ b/src/lib/libast/uwin/erf.c
@@ -0,0 +1,403 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_erf
+
+void _STUB_erf(){}
+
+#else
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)erf.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* Modified Nov 30, 1992 P. McILROY:
+ * Replaced expansions for x >= 1.25 (error 1.7ulp vs ~6ulp)
+ * Replaced even+odd with direct calculation for x < .84375,
+ * to avoid destructive cancellation.
+ *
+ * Performance of erfc(x):
+ * In 300000 trials in the range [.83, .84375] the
+ * maximum observed error was 3.6ulp.
+ *
+ * In [.84735,1.25] the maximum observed error was <2.5ulp in
+ * 100000 runs in the range [1.2, 1.25].
+ *
+ * In [1.25,26] (Not including subnormal results)
+ * the error is < 1.7ulp.
+ */
+
+/* double erf(double x)
+ * double erfc(double x)
+ * x
+ * 2 |\
+ * erf(x) = --------- | exp(-t*t)dt
+ * sqrt(pi) \|
+ * 0
+ *
+ * erfc(x) = 1-erf(x)
+ *
+ * Method:
+ * 1. Reduce x to |x| by erf(-x) = -erf(x)
+ * 2. For x in [0, 0.84375]
+ * erf(x) = x + x*P(x^2)
+ * erfc(x) = 1 - erf(x) if x<=0.25
+ * = 0.5 + ((0.5-x)-x*P) if x in [0.25,0.84375]
+ * where
+ * 2 2 4 20
+ * P = P(x ) = (p0 + p1 * x + p2 * x + ... + p10 * x )
+ * is an approximation to (erf(x)-x)/x with precision
+ *
+ * -56.45
+ * | P - (erf(x)-x)/x | <= 2
+ *
+ *
+ * Remark. The formula is derived by noting
+ * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
+ * and that
+ * 2/sqrt(pi) = 1.128379167095512573896158903121545171688
+ * is close to one. The interval is chosen because the fixed
+ * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
+ * near 0.6174), and by some experiment, 0.84375 is chosen to
+ * guarantee the error is less than one ulp for erf.
+ *
+ * 3. For x in [0.84375,1.25], let s = x - 1, and
+ * c = 0.84506291151 rounded to single (24 bits)
+ * erf(x) = c + P1(s)/Q1(s)
+ * erfc(x) = (1-c) - P1(s)/Q1(s)
+ * |P1/Q1 - (erf(x)-c)| <= 2**-59.06
+ * Remark: here we use the taylor series expansion at x=1.
+ * erf(1+s) = erf(1) + s*Poly(s)
+ * = 0.845.. + P1(s)/Q1(s)
+ * That is, we use rational approximation to approximate
+ * erf(1+s) - (c = (single)0.84506291151)
+ * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
+ * where
+ * P1(s) = degree 6 poly in s
+ * Q1(s) = degree 6 poly in s
+ *
+ * 4. For x in [1.25, 2]; [2, 4]
+ * erf(x) = 1.0 - tiny
+ * erfc(x) = (1/x)exp(-x*x-(.5*log(pi) -.5z + R(z)/S(z))
+ *
+ * Where z = 1/(x*x), R is degree 9, and S is degree 3;
+ *
+ * 5. For x in [4,28]
+ * erf(x) = 1.0 - tiny
+ * erfc(x) = (1/x)exp(-x*x-(.5*log(pi)+eps + zP(z))
+ *
+ * Where P is degree 14 polynomial in 1/(x*x).
+ *
+ * Notes:
+ * Here 4 and 5 make use of the asymptotic series
+ * exp(-x*x)
+ * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) );
+ * x*sqrt(pi)
+ *
+ * where for z = 1/(x*x)
+ * P(z) ~ z/2*(-1 + z*3/2*(1 + z*5/2*(-1 + z*7/2*(1 +...))))
+ *
+ * Thus we use rational approximation to approximate
+ * erfc*x*exp(x*x) ~ 1/sqrt(pi);
+ *
+ * The error bound for the target function, G(z) for
+ * the interval
+ * [4, 28]:
+ * |eps + 1/(z)P(z) - G(z)| < 2**(-56.61)
+ * for [2, 4]:
+ * |R(z)/S(z) - G(z)| < 2**(-58.24)
+ * for [1.25, 2]:
+ * |R(z)/S(z) - G(z)| < 2**(-58.12)
+ *
+ * 6. For inf > x >= 28
+ * erf(x) = 1 - tiny (raise inexact)
+ * erfc(x) = tiny*tiny (raise underflow)
+ *
+ * 7. Special cases:
+ * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
+ * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
+ * erfc/erf(NaN) is NaN
+ */
+
+#if defined(vax) || defined(tahoe)
+#define _IEEE 0
+#define TRUNC(x) (double) (float) (x)
+#else
+#define _IEEE 1
+#define TRUNC(x) *(((int *) &x) + 1) &= 0xf8000000
+#define infnan(x) 0.0
+#endif
+
+#ifdef _IEEE_LIBM
+/*
+ * redefining "___function" to "function" in _IEEE_LIBM mode
+ */
+#include "ieee_libm.h"
+#endif
+#include "mathimpl.h"
+
+static double
+tiny = 1e-300,
+half = 0.5,
+one = 1.0,
+two = 2.0,
+c = 8.45062911510467529297e-01, /* (float)0.84506291151 */
+/*
+ * Coefficients for approximation to erf in [0,0.84375]
+ */
+p0t8 = 1.02703333676410051049867154944018394163280,
+p0 = 1.283791670955125638123339436800229927041e-0001,
+p1 = -3.761263890318340796574473028946097022260e-0001,
+p2 = 1.128379167093567004871858633779992337238e-0001,
+p3 = -2.686617064084433642889526516177508374437e-0002,
+p4 = 5.223977576966219409445780927846432273191e-0003,
+p5 = -8.548323822001639515038738961618255438422e-0004,
+p6 = 1.205520092530505090384383082516403772317e-0004,
+p7 = -1.492214100762529635365672665955239554276e-0005,
+p8 = 1.640186161764254363152286358441771740838e-0006,
+p9 = -1.571599331700515057841960987689515895479e-0007,
+p10= 1.073087585213621540635426191486561494058e-0008;
+/*
+ * Coefficients for approximation to erf in [0.84375,1.25]
+ */
+static double
+pa0 = -2.362118560752659485957248365514511540287e-0003,
+pa1 = 4.148561186837483359654781492060070469522e-0001,
+pa2 = -3.722078760357013107593507594535478633044e-0001,
+pa3 = 3.183466199011617316853636418691420262160e-0001,
+pa4 = -1.108946942823966771253985510891237782544e-0001,
+pa5 = 3.547830432561823343969797140537411825179e-0002,
+pa6 = -2.166375594868790886906539848893221184820e-0003,
+qa1 = 1.064208804008442270765369280952419863524e-0001,
+qa2 = 5.403979177021710663441167681878575087235e-0001,
+qa3 = 7.182865441419627066207655332170665812023e-0002,
+qa4 = 1.261712198087616469108438860983447773726e-0001,
+qa5 = 1.363708391202905087876983523620537833157e-0002,
+qa6 = 1.198449984679910764099772682882189711364e-0002;
+/*
+ * log(sqrt(pi)) for large x expansions.
+ * The tail (lsqrtPI_lo) is included in the rational
+ * approximations.
+*/
+static double
+ lsqrtPI_hi = .5723649429247000819387380943226;
+/*
+ * lsqrtPI_lo = .000000000000000005132975581353913;
+ *
+ * Coefficients for approximation to erfc in [2, 4]
+*/
+static double
+rb0 = -1.5306508387410807582e-010, /* includes lsqrtPI_lo */
+rb1 = 2.15592846101742183841910806188e-008,
+rb2 = 6.24998557732436510470108714799e-001,
+rb3 = 8.24849222231141787631258921465e+000,
+rb4 = 2.63974967372233173534823436057e+001,
+rb5 = 9.86383092541570505318304640241e+000,
+rb6 = -7.28024154841991322228977878694e+000,
+rb7 = 5.96303287280680116566600190708e+000,
+rb8 = -4.40070358507372993983608466806e+000,
+rb9 = 2.39923700182518073731330332521e+000,
+rb10 = -6.89257464785841156285073338950e-001,
+sb1 = 1.56641558965626774835300238919e+001,
+sb2 = 7.20522741000949622502957936376e+001,
+sb3 = 9.60121069770492994166488642804e+001;
+/*
+ * Coefficients for approximation to erfc in [1.25, 2]
+*/
+static double
+rc0 = -2.47925334685189288817e-007, /* includes lsqrtPI_lo */
+rc1 = 1.28735722546372485255126993930e-005,
+rc2 = 6.24664954087883916855616917019e-001,
+rc3 = 4.69798884785807402408863708843e+000,
+rc4 = 7.61618295853929705430118701770e+000,
+rc5 = 9.15640208659364240872946538730e-001,
+rc6 = -3.59753040425048631334448145935e-001,
+rc7 = 1.42862267989304403403849619281e-001,
+rc8 = -4.74392758811439801958087514322e-002,
+rc9 = 1.09964787987580810135757047874e-002,
+rc10 = -1.28856240494889325194638463046e-003,
+sc1 = 9.97395106984001955652274773456e+000,
+sc2 = 2.80952153365721279953959310660e+001,
+sc3 = 2.19826478142545234106819407316e+001;
+/*
+ * Coefficients for approximation to erfc in [4,28]
+ */
+static double
+rd0 = -2.1491361969012978677e-016, /* includes lsqrtPI_lo */
+rd1 = -4.99999999999640086151350330820e-001,
+rd2 = 6.24999999772906433825880867516e-001,
+rd3 = -1.54166659428052432723177389562e+000,
+rd4 = 5.51561147405411844601985649206e+000,
+rd5 = -2.55046307982949826964613748714e+001,
+rd6 = 1.43631424382843846387913799845e+002,
+rd7 = -9.45789244999420134263345971704e+002,
+rd8 = 6.94834146607051206956384703517e+003,
+rd9 = -5.27176414235983393155038356781e+004,
+rd10 = 3.68530281128672766499221324921e+005,
+rd11 = -2.06466642800404317677021026611e+006,
+rd12 = 7.78293889471135381609201431274e+006,
+rd13 = -1.42821001129434127360582351685e+007;
+
+extern double erf(x)
+ double x;
+{
+ double R,S,P,Q,ax,s,y,z,r,fabs(),exp();
+ if(!finite(x)) { /* erf(nan)=nan */
+ if (isnan(x))
+ return(x);
+ return (x > 0 ? one : -one); /* erf(+/-inf)= +/-1 */
+ }
+ if ((ax = x) < 0)
+ ax = - ax;
+ if (ax < .84375) {
+ if (ax < 3.7e-09) {
+ if (ax < 1.0e-308)
+ return 0.125*(8.0*x+p0t8*x); /*avoid underflow */
+ return x + p0*x;
+ }
+ y = x*x;
+ r = y*(p1+y*(p2+y*(p3+y*(p4+y*(p5+
+ y*(p6+y*(p7+y*(p8+y*(p9+y*p10)))))))));
+ return x + x*(p0+r);
+ }
+ if (ax < 1.25) { /* 0.84375 <= |x| < 1.25 */
+ s = fabs(x)-one;
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+ if (x>=0)
+ return (c + P/Q);
+ else
+ return (-c - P/Q);
+ }
+ if (ax >= 6.0) { /* inf>|x|>=6 */
+ if (x >= 0.0)
+ return (one-tiny);
+ else
+ return (tiny-one);
+ }
+ /* 1.25 <= |x| < 6 */
+ z = -ax*ax;
+ s = -one/z;
+ if (ax < 2.0) {
+ R = rc0+s*(rc1+s*(rc2+s*(rc3+s*(rc4+s*(rc5+
+ s*(rc6+s*(rc7+s*(rc8+s*(rc9+s*rc10)))))))));
+ S = one+s*(sc1+s*(sc2+s*sc3));
+ } else {
+ R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+
+ s*(rb6+s*(rb7+s*(rb8+s*(rb9+s*rb10)))))))));
+ S = one+s*(sb1+s*(sb2+s*sb3));
+ }
+ y = (R/S -.5*s) - lsqrtPI_hi;
+ z += y;
+ z = exp(z)/ax;
+ if (x >= 0)
+ return (one-z);
+ else
+ return (z-one);
+}
+
+extern double erfc(x)
+ double x;
+{
+ double R,S,P,Q,s,ax,y,z,r,fabs(),__exp__D();
+ if (!finite(x)) {
+ if (isnan(x)) /* erfc(NaN) = NaN */
+ return(x);
+ else if (x > 0) /* erfc(+-inf)=0,2 */
+ return 0.0;
+ else
+ return 2.0;
+ }
+ if ((ax = x) < 0)
+ ax = -ax;
+ if (ax < .84375) { /* |x|<0.84375 */
+ if (ax < 1.38777878078144568e-17) /* |x|<2**-56 */
+ return one-x;
+ y = x*x;
+ r = y*(p1+y*(p2+y*(p3+y*(p4+y*(p5+
+ y*(p6+y*(p7+y*(p8+y*(p9+y*p10)))))))));
+ if (ax < .0625) { /* |x|<2**-4 */
+ return (one-(x+x*(p0+r)));
+ } else {
+ r = x*(p0+r);
+ r += (x-half);
+ return (half - r);
+ }
+ }
+ if (ax < 1.25) { /* 0.84375 <= |x| < 1.25 */
+ s = ax-one;
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+ if (x>=0) {
+ z = one-c; return z - P/Q;
+ } else {
+ z = c+P/Q; return one+z;
+ }
+ }
+ if (ax >= 28) /* Out of range */
+ if (x>0)
+ return (tiny*tiny);
+ else
+ return (two-tiny);
+ z = ax;
+ TRUNC(z);
+ y = z - ax; y *= (ax+z);
+ z *= -z; /* Here z + y = -x^2 */
+ s = one/(-z-y); /* 1/(x*x) */
+ if (ax >= 4) { /* 6 <= ax */
+ R = s*(rd1+s*(rd2+s*(rd3+s*(rd4+s*(rd5+
+ s*(rd6+s*(rd7+s*(rd8+s*(rd9+s*(rd10
+ +s*(rd11+s*(rd12+s*rd13))))))))))));
+ y += rd0;
+ } else if (ax >= 2) {
+ R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(rb5+
+ s*(rb6+s*(rb7+s*(rb8+s*(rb9+s*rb10)))))))));
+ S = one+s*(sb1+s*(sb2+s*sb3));
+ y += R/S;
+ R = -.5*s;
+ } else {
+ R = rc0+s*(rc1+s*(rc2+s*(rc3+s*(rc4+s*(rc5+
+ s*(rc6+s*(rc7+s*(rc8+s*(rc9+s*rc10)))))))));
+ S = one+s*(sc1+s*(sc2+s*sc3));
+ y += R/S;
+ R = -.5*s;
+ }
+ /* return exp(-x^2 - lsqrtPI_hi + R + y)/x; */
+ s = ((R + y) - lsqrtPI_hi) + z;
+ y = (((z-s) - lsqrtPI_hi) + R) + y;
+ r = __exp__D(s, y)/x;
+ if (x>0)
+ return r;
+ else
+ return two-r;
+}
+
+#endif
diff --git a/src/lib/libast/uwin/err.c b/src/lib/libast/uwin/err.c
new file mode 100644
index 0000000..123a64e
--- /dev/null
+++ b/src/lib/libast/uwin/err.c
@@ -0,0 +1,124 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "FEATURE/uwin"
+
+#if !_UWIN
+
+void _STUB_err(){}
+
+#else
+
+#pragma prototyped
+
+/*
+ * bsd 4.4 compatibility
+ *
+ * NOTE: errorv(ERROR_NOID) => the first arg is the printf format
+ */
+
+#include <ast.h>
+#include <error.h>
+
+#include <windows.h>
+
+#ifdef __EXPORT__
+#define extern __EXPORT__
+#endif
+
+static void
+errmsg(int level, int code, const char* fmt, va_list ap)
+{
+ if (!error_info.id)
+ {
+ struct _astdll* dp = _ast_getdll();
+ char* s;
+ char* t;
+
+ if (s = dp->_ast__argv[0])
+ {
+ if (t = strrchr(s, '/'))
+ s = t + 1;
+ error_info.id = s;
+ }
+ }
+ errorv(fmt, level|ERROR_NOID, ap);
+ if ((level & ERROR_LEVEL) >= ERROR_ERROR)
+ exit(code);
+}
+
+extern void verr(int code, const char* fmt, va_list ap)
+{
+ errmsg(ERROR_ERROR|ERROR_SYSTEM, code, fmt, ap);
+}
+
+extern void err(int code, const char* fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ errmsg(ERROR_ERROR|ERROR_SYSTEM, code, fmt, ap);
+ va_end(ap);
+}
+
+extern void verrx(int code, const char* fmt, va_list ap)
+{
+ errmsg(ERROR_ERROR, code, fmt, ap);
+}
+
+extern void errx(int code, const char* fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ errmsg(ERROR_ERROR, code, fmt, ap);
+ va_end(ap);
+}
+
+extern void vwarn(const char* fmt, va_list ap)
+{
+ errmsg(ERROR_WARNING|ERROR_SYSTEM, 0, fmt, ap);
+}
+
+extern void warn(const char* fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ errmsg(ERROR_WARNING|ERROR_SYSTEM, 0, fmt, ap);
+ va_end(ap);
+}
+
+extern void vwarnx(const char* fmt, va_list ap)
+{
+ errmsg(ERROR_WARNING, 0, fmt, ap);
+}
+
+extern void warnx(const char* fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ errmsg(ERROR_WARNING, 0, fmt, ap);
+ va_end(ap);
+}
+
+#endif
diff --git a/src/lib/libast/uwin/exp.c b/src/lib/libast/uwin/exp.c
new file mode 100644
index 0000000..d1e15bd
--- /dev/null
+++ b/src/lib/libast/uwin/exp.c
@@ -0,0 +1,213 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN
+
+void _STUB_exp(){}
+
+#else
+
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)exp.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* EXP(X)
+ * RETURN THE EXPONENTIAL OF X
+ * DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS)
+ * CODED IN C BY K.C. NG, 1/19/85;
+ * REVISED BY K.C. NG on 2/6/85, 2/15/85, 3/7/85, 3/24/85, 4/16/85, 6/14/86.
+ *
+ * Required system supported functions:
+ * scalb(x,n)
+ * copysign(x,y)
+ * finite(x)
+ *
+ * Method:
+ * 1. Argument Reduction: given the input x, find r and integer k such
+ * that
+ * x = k*ln2 + r, |r| <= 0.5*ln2 .
+ * r will be represented as r := z+c for better accuracy.
+ *
+ * 2. Compute exp(r) by
+ *
+ * exp(r) = 1 + r + r*R1/(2-R1),
+ * where
+ * R1 = x - x^2*(p1+x^2*(p2+x^2*(p3+x^2*(p4+p5*x^2)))).
+ *
+ * 3. exp(x) = 2^k * exp(r) .
+ *
+ * Special cases:
+ * exp(INF) is INF, exp(NaN) is NaN;
+ * exp(-INF)= 0;
+ * for finite argument, only exp(0)=1 is exact.
+ *
+ * Accuracy:
+ * exp(x) returns the exponential of x nearly rounded. In a test run
+ * with 1,156,000 random arguments on a VAX, the maximum observed
+ * error was 0.869 ulps (units in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000)
+vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+vc(lnhuge, 9.4961163736712506989E1 ,ec1d,43bd,9010,a73e, 7, .BDEC1DA73E9010)
+vc(lntiny,-9.5654310917272452386E1 ,4f01,c3bf,33af,d72e, 7,-.BF4F01D72E33AF)
+vc(invln2, 1.4426950408889634148E0 ,aa3b,40b8,17f1,295c, 1, .B8AA3B295C17F1)
+vc(p1, 1.6666666666666602251E-1 ,aaaa,3f2a,a9f1,aaaa, -2, .AAAAAAAAAAA9F1)
+vc(p2, -2.7777777777015591216E-3 ,0b60,bc36,ec94,b5f5, -8,-.B60B60B5F5EC94)
+vc(p3, 6.6137563214379341918E-5 ,b355,398a,f15f,792e, -13, .8AB355792EF15F)
+vc(p4, -1.6533902205465250480E-6 ,ea0e,b6dd,5f84,2e93, -19,-.DDEA0E2E935F84)
+vc(p5, 4.1381367970572387085E-8 ,bb4b,3431,2683,95f5, -24, .B1BB4B95F52683)
+
+#ifdef vccast
+#define ln2hi vccast(ln2hi)
+#define ln2lo vccast(ln2lo)
+#define lnhuge vccast(lnhuge)
+#define lntiny vccast(lntiny)
+#define invln2 vccast(invln2)
+#define p1 vccast(p1)
+#define p2 vccast(p2)
+#define p3 vccast(p3)
+#define p4 vccast(p4)
+#define p5 vccast(p5)
+#endif
+
+ic(p1, 1.6666666666666601904E-1, -3, 1.555555555553E)
+ic(p2, -2.7777777777015593384E-3, -9, -1.6C16C16BEBD93)
+ic(p3, 6.6137563214379343612E-5, -14, 1.1566AAF25DE2C)
+ic(p4, -1.6533902205465251539E-6, -20, -1.BBD41C5D26BF1)
+ic(p5, 4.1381367970572384604E-8, -25, 1.6376972BEA4D0)
+ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000)
+ic(ln2lo, 1.9082149292705877000E-10,-33, 1.A39EF35793C76)
+ic(lnhuge, 7.1602103751842355450E2, 9, 1.6602B15B7ECF2)
+ic(lntiny,-7.5137154372698068983E2, 9, -1.77AF8EBEAE354)
+ic(invln2, 1.4426950408889633870E0, 0, 1.71547652B82FE)
+
+#if !_lib_exp
+
+extern double exp(x)
+double x;
+{
+ double z,hi,lo,c;
+ int k;
+
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+ if( x <= lnhuge ) {
+ if( x >= lntiny ) {
+
+ /* argument reduction : x --> x - k*ln2 */
+
+ k=invln2*x+copysign(0.5,x); /* k=NINT(x/ln2) */
+
+ /* express x-k*ln2 as hi-lo and let x=hi-lo rounded */
+
+ hi=x-k*ln2hi;
+ x=hi-(lo=k*ln2lo);
+
+ /* return 2^k*[1+x+x*c/(2+c)] */
+ z=x*x;
+ c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5))));
+ return scalb(1.0+(hi-(lo-(x*c)/(2.0-c))),k);
+
+ }
+ /* end of x > lntiny */
+
+ else
+ /* exp(-big#) underflows to zero */
+ if(finite(x)) return(scalb(1.0,-5000));
+
+ /* exp(-INF) is zero */
+ else return(0.0);
+ }
+ /* end of x < lnhuge */
+
+ else
+ /* exp(INF) is INF, exp(+big#) overflows to INF */
+ return( finite(x) ? scalb(1.0,5000) : x);
+}
+
+#endif
+
+/* returns exp(r = x + c) for |c| < |x| with no overlap. */
+
+double __exp__D(x, c)
+double x, c;
+{
+ double z,hi,lo;
+ int k;
+
+#if !defined(vax)&&!defined(tahoe)
+ if (x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+ if ( x <= lnhuge ) {
+ if ( x >= lntiny ) {
+
+ /* argument reduction : x --> x - k*ln2 */
+ z = invln2*x;
+ k = (int)z + copysign(.5, x);
+
+ /* express (x+c)-k*ln2 as hi-lo and let x=hi-lo rounded */
+
+ hi=(x-k*ln2hi); /* Exact. */
+ x= hi - (lo = k*ln2lo-c);
+ /* return 2^k*[1+x+x*c/(2+c)] */
+ z=x*x;
+ c= x - z*(p1+z*(p2+z*(p3+z*(p4+z*p5))));
+ c = (x*c)/(2.0-c);
+
+ return scalb(1.+(hi-(lo - c)), k);
+ }
+ /* end of x > lntiny */
+
+ else
+ /* exp(-big#) underflows to zero */
+ if(finite(x)) return(scalb(1.0,-5000));
+
+ /* exp(-INF) is zero */
+ else return(0.0);
+ }
+ /* end of x < lnhuge */
+
+ else
+ /* exp(INF) is INF, exp(+big#) overflows to INF */
+ return( finite(x) ? scalb(1.0,5000) : x);
+}
+
+#endif
diff --git a/src/lib/libast/uwin/exp__E.c b/src/lib/libast/uwin/exp__E.c
new file mode 100644
index 0000000..5c131a8
--- /dev/null
+++ b/src/lib/libast/uwin/exp__E.c
@@ -0,0 +1,142 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN
+
+void _STUB_exp__E(){}
+
+#else
+
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)exp__E.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* exp__E(x,c)
+ * ASSUMPTION: c << x SO THAT fl(x+c)=x.
+ * (c is the correction term for x)
+ * exp__E RETURNS
+ *
+ * / exp(x+c) - 1 - x , 1E-19 < |x| < .3465736
+ * exp__E(x,c) = |
+ * \ 0 , |x| < 1E-19.
+ *
+ * DOUBLE PRECISION (IEEE 53 bits, VAX D FORMAT 56 BITS)
+ * KERNEL FUNCTION OF EXP, EXPM1, POW FUNCTIONS
+ * CODED IN C BY K.C. NG, 1/31/85;
+ * REVISED BY K.C. NG on 3/16/85, 4/16/85.
+ *
+ * Required system supported function:
+ * copysign(x,y)
+ *
+ * Method:
+ * 1. Rational approximation. Let r=x+c.
+ * Based on
+ * 2 * sinh(r/2)
+ * exp(r) - 1 = ---------------------- ,
+ * cosh(r/2) - sinh(r/2)
+ * exp__E(r) is computed using
+ * x*x (x/2)*W - ( Q - ( 2*P + x*P ) )
+ * --- + (c + x*[---------------------------------- + c ])
+ * 2 1 - W
+ * where P := p1*x^2 + p2*x^4,
+ * Q := q1*x^2 + q2*x^4 (for 56 bits precision, add q3*x^6)
+ * W := x/2-(Q-x*P),
+ *
+ * (See the listing below for the values of p1,p2,q1,q2,q3. The poly-
+ * nomials P and Q may be regarded as the approximations to sinh
+ * and cosh :
+ * sinh(r/2) = r/2 + r * P , cosh(r/2) = 1 + Q . )
+ *
+ * The coefficients were obtained by a special Remez algorithm.
+ *
+ * Approximation error:
+ *
+ * | exp(x) - 1 | 2**(-57), (IEEE double)
+ * | ------------ - (exp__E(x,0)+x)/x | <=
+ * | x | 2**(-69). (VAX D)
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(p1, 1.5150724356786683059E-2 ,3abe,3d78,066a,67e1, -6, .F83ABE67E1066A)
+vc(p2, 6.3112487873718332688E-5 ,5b42,3984,0173,48cd, -13, .845B4248CD0173)
+vc(q1, 1.1363478204690669916E-1 ,b95a,3ee8,ec45,44a2, -3, .E8B95A44A2EC45)
+vc(q2, 1.2624568129896839182E-3 ,7905,3ba5,f5e7,72e4, -9, .A5790572E4F5E7)
+vc(q3, 1.5021856115869022674E-6 ,9eb4,36c9,c395,604a, -19, .C99EB4604AC395)
+
+ic(p1, 1.3887401997267371720E-2, -7, 1.C70FF8B3CC2CF)
+ic(p2, 3.3044019718331897649E-5, -15, 1.15317DF4526C4)
+ic(q1, 1.1110813732786649355E-1, -4, 1.C719538248597)
+ic(q2, 9.9176615021572857300E-4, -10, 1.03FC4CB8C98E8)
+
+#ifdef vccast
+#define p1 vccast(p1)
+#define p2 vccast(p2)
+#define q1 vccast(q1)
+#define q2 vccast(q2)
+#define q3 vccast(q3)
+#endif
+
+double __exp__E(x,c)
+double x,c;
+{
+ const static double zero=0.0, one=1.0, half=1.0/2.0, small=1.0E-19;
+ double z,p,q,xp,xh,w;
+ if(copysign(x,one)>small) {
+ z = x*x ;
+ p = z*( p1 +z* p2 );
+#if defined(vax)||defined(tahoe)
+ q = z*( q1 +z*( q2 +z* q3 ));
+#else /* defined(vax)||defined(tahoe) */
+ q = z*( q1 +z* q2 );
+#endif /* defined(vax)||defined(tahoe) */
+ xp= x*p ;
+ xh= x*half ;
+ w = xh-(q-xp) ;
+ p = p+p;
+ c += x*((xh*w-(q-(p+xp)))/(one-w)+c);
+ return(z*half+c);
+ }
+ /* end of |x| > small */
+
+ else {
+ if(x!=zero) one+small; /* raise the inexact flag */
+ return(copysign(zero,x));
+ }
+}
+
+#endif
diff --git a/src/lib/libast/uwin/expm1.c b/src/lib/libast/uwin/expm1.c
new file mode 100644
index 0000000..1e7f694
--- /dev/null
+++ b/src/lib/libast/uwin/expm1.c
@@ -0,0 +1,173 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_expm1
+
+void _STUB_expm1(){}
+
+#else
+
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)expm1.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* EXPM1(X)
+ * RETURN THE EXPONENTIAL OF X MINUS ONE
+ * DOUBLE PRECISION (IEEE 53 BITS, VAX D FORMAT 56 BITS)
+ * CODED IN C BY K.C. NG, 1/19/85;
+ * REVISED BY K.C. NG on 2/6/85, 3/7/85, 3/21/85, 4/16/85.
+ *
+ * Required system supported functions:
+ * scalb(x,n)
+ * copysign(x,y)
+ * finite(x)
+ *
+ * Kernel function:
+ * exp__E(x,c)
+ *
+ * Method:
+ * 1. Argument Reduction: given the input x, find r and integer k such
+ * that
+ * x = k*ln2 + r, |r| <= 0.5*ln2 .
+ * r will be represented as r := z+c for better accuracy.
+ *
+ * 2. Compute EXPM1(r)=exp(r)-1 by
+ *
+ * EXPM1(r=z+c) := z + exp__E(z,c)
+ *
+ * 3. EXPM1(x) = 2^k * ( EXPM1(r) + 1-2^-k ).
+ *
+ * Remarks:
+ * 1. When k=1 and z < -0.25, we use the following formula for
+ * better accuracy:
+ * EXPM1(x) = 2 * ( (z+0.5) + exp__E(z,c) )
+ * 2. To avoid rounding error in 1-2^-k where k is large, we use
+ * EXPM1(x) = 2^k * { [z+(exp__E(z,c)-2^-k )] + 1 }
+ * when k>56.
+ *
+ * Special cases:
+ * EXPM1(INF) is INF, EXPM1(NaN) is NaN;
+ * EXPM1(-INF)= -1;
+ * for finite argument, only EXPM1(0)=0 is exact.
+ *
+ * Accuracy:
+ * EXPM1(x) returns the exact (exp(x)-1) nearly rounded. In a test run with
+ * 1,166,000 random arguments on a VAX, the maximum observed error was
+ * .872 ulps (units of the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000)
+vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+vc(lnhuge, 9.4961163736712506989E1 ,ec1d,43bd,9010,a73e, 7, .BDEC1DA73E9010)
+vc(invln2, 1.4426950408889634148E0 ,aa3b,40b8,17f1,295c, 1, .B8AA3B295C17F1)
+
+ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000)
+ic(ln2lo, 1.9082149292705877000E-10, -33, 1.A39EF35793C76)
+ic(lnhuge, 7.1602103751842355450E2, 9, 1.6602B15B7ECF2)
+ic(invln2, 1.4426950408889633870E0, 0, 1.71547652B82FE)
+
+#ifdef vccast
+#define ln2hi vccast(ln2hi)
+#define ln2lo vccast(ln2lo)
+#define lnhuge vccast(lnhuge)
+#define invln2 vccast(invln2)
+#endif
+
+extern double expm1(x)
+double x;
+{
+ const static double one=1.0, half=1.0/2.0;
+ double z,hi,lo,c;
+ int k;
+#if defined(vax)||defined(tahoe)
+ static prec=56;
+#else /* defined(vax)||defined(tahoe) */
+ static prec=53;
+#endif /* defined(vax)||defined(tahoe) */
+
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+
+ if( x <= lnhuge ) {
+ if( x >= -40.0 ) {
+
+ /* argument reduction : x - k*ln2 */
+ k= (int)(invln2*x)+copysign(0.5,x); /* k=NINT(x/ln2) */
+ hi=x-k*ln2hi ;
+ z=hi-(lo=k*ln2lo);
+ c=(hi-z)-lo;
+
+ if(k==0) return(z+__exp__E(z,c));
+ if(k==1)
+ if(z< -0.25)
+ {x=z+half;x +=__exp__E(z,c); return(x+x);}
+ else
+ {z+=__exp__E(z,c); x=half+z; return(x+x);}
+ /* end of k=1 */
+
+ else {
+ if(k<=prec)
+ { x=one-scalb(one,-k); z += __exp__E(z,c);}
+ else if(k<100)
+ { x = __exp__E(z,c)-scalb(one,-k); x+=z; z=one;}
+ else
+ { x = __exp__E(z,c)+z; z=one;}
+
+ return (scalb(x+z,k));
+ }
+ }
+ /* end of x > lnunfl */
+
+ else
+ /* expm1(-big#) rounded to -1 (inexact) */
+ if(finite(x))
+ { ln2hi+ln2lo; return(-one);}
+
+ /* expm1(-INF) is -1 */
+ else return(-one);
+ }
+ /* end of x < lnhuge */
+
+ else
+ /* expm1(INF) is INF, expm1(+big#) overflows to INF */
+ return( finite(x) ? scalb(one,5000) : x);
+}
+
+#endif
diff --git a/src/lib/libast/uwin/gamma.c b/src/lib/libast/uwin/gamma.c
new file mode 100644
index 0000000..0cb1d1f
--- /dev/null
+++ b/src/lib/libast/uwin/gamma.c
@@ -0,0 +1,343 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_gamma
+
+void _STUB_gamma(){}
+
+#else
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)gamma.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/*
+ * This code by P. McIlroy, Oct 1992;
+ *
+ * The financial support of UUNET Communications Services is greatfully
+ * acknowledged.
+ */
+
+#define gamma ______gamma
+
+#include <math.h>
+#include <errno.h>
+#include "mathimpl.h"
+
+#undef gamma
+
+/* METHOD:
+ * x < 0: Use reflection formula, G(x) = pi/(sin(pi*x)*x*G(x))
+ * At negative integers, return +Inf, and set errno.
+ *
+ * x < 6.5:
+ * Use argument reduction G(x+1) = xG(x) to reach the
+ * range [1.066124,2.066124]. Use a rational
+ * approximation centered at the minimum (x0+1) to
+ * ensure monotonicity.
+ *
+ * x >= 6.5: Use the asymptotic approximation (Stirling's formula)
+ * adjusted for equal-ripples:
+ *
+ * log(G(x)) ~= (x-.5)*(log(x)-1) + .5(log(2*pi)-1) + 1/x*P(1/(x*x))
+ *
+ * Keep extra precision in multiplying (x-.5)(log(x)-1), to
+ * avoid premature round-off.
+ *
+ * Special values:
+ * non-positive integer: Set overflow trap; return +Inf;
+ * x > 171.63: Set overflow trap; return +Inf;
+ * NaN: Set invalid trap; return NaN
+ *
+ * Accuracy: Gamma(x) is accurate to within
+ * x > 0: error provably < 0.9ulp.
+ * Maximum observed in 1,000,000 trials was .87ulp.
+ * x < 0:
+ * Maximum observed error < 4ulp in 1,000,000 trials.
+ */
+
+static double neg_gam __P((double));
+static double small_gam __P((double));
+static double smaller_gam __P((double));
+static struct Double large_gam __P((double));
+static struct Double ratfun_gam __P((double, double));
+
+/*
+ * Rational approximation, A0 + x*x*P(x)/Q(x), on the interval
+ * [1.066.., 2.066..] accurate to 4.25e-19.
+ */
+#define LEFT -.3955078125 /* left boundary for rat. approx */
+#define x0 .461632144968362356785 /* xmin - 1 */
+
+#define a0_hi 0.88560319441088874992
+#define a0_lo -.00000000000000004996427036469019695
+#define P0 6.21389571821820863029017800727e-01
+#define P1 2.65757198651533466104979197553e-01
+#define P2 5.53859446429917461063308081748e-03
+#define P3 1.38456698304096573887145282811e-03
+#define P4 2.40659950032711365819348969808e-03
+#define Q0 1.45019531250000000000000000000e+00
+#define Q1 1.06258521948016171343454061571e+00
+#define Q2 -2.07474561943859936441469926649e-01
+#define Q3 -1.46734131782005422506287573015e-01
+#define Q4 3.07878176156175520361557573779e-02
+#define Q5 5.12449347980666221336054633184e-03
+#define Q6 -1.76012741431666995019222898833e-03
+#define Q7 9.35021023573788935372153030556e-05
+#define Q8 6.13275507472443958924745652239e-06
+/*
+ * Constants for large x approximation (x in [6, Inf])
+ * (Accurate to 2.8*10^-19 absolute)
+ */
+#define lns2pi_hi 0.418945312500000
+#define lns2pi_lo -.000006779295327258219670263595
+#define Pa0 8.33333333333333148296162562474e-02
+#define Pa1 -2.77777777774548123579378966497e-03
+#define Pa2 7.93650778754435631476282786423e-04
+#define Pa3 -5.95235082566672847950717262222e-04
+#define Pa4 8.41428560346653702135821806252e-04
+#define Pa5 -1.89773526463879200348872089421e-03
+#define Pa6 5.69394463439411649408050664078e-03
+#define Pa7 -1.44705562421428915453880392761e-02
+
+static const double zero = 0., one = 1.0, tiny = 1e-300;
+static int endian;
+/*
+ * TRUNC sets trailing bits in a floating-point number to zero.
+ * is a temporary variable.
+ */
+#if defined(vax) || defined(tahoe)
+#define _IEEE 0
+#define TRUNC(x) x = (double) (float) (x)
+#else
+#define _IEEE 1
+#define TRUNC(x) *(((int *) &x) + endian) &= 0xf8000000
+#define infnan(x) 0.0
+#endif
+
+extern double gamma(x)
+ double x;
+{
+ struct Double u;
+ endian = (*(int *) &one) ? 1 : 0;
+
+ if (x >= 6) {
+ if(x > 171.63)
+ return(one/zero);
+ u = large_gam(x);
+ return(__exp__D(u.a, u.b));
+ } else if (x >= 1.0 + LEFT + x0)
+ return (small_gam(x));
+ else if (x > 1.e-17)
+ return (smaller_gam(x));
+ else if (x > -1.e-17) {
+ if (x == 0.0)
+ if (!_IEEE) return (infnan(ERANGE));
+ else return (one/x);
+ one+1e-20; /* Raise inexact flag. */
+ return (one/x);
+ } else if (!finite(x)) {
+ if (_IEEE) /* x = NaN, -Inf */
+ return (x*x);
+ else
+ return (infnan(EDOM));
+ } else
+ return (neg_gam(x));
+}
+/*
+ * Accurate to max(ulp(1/128) absolute, 2^-66 relative) error.
+ */
+static struct Double
+large_gam(x)
+ double x;
+{
+ double z, p;
+ struct Double t, u, v;
+
+ z = one/(x*x);
+ p = Pa0+z*(Pa1+z*(Pa2+z*(Pa3+z*(Pa4+z*(Pa5+z*(Pa6+z*Pa7))))));
+ p = p/x;
+
+ u = __log__D(x);
+ u.a -= one;
+ v.a = (x -= .5);
+ TRUNC(v.a);
+ v.b = x - v.a;
+ t.a = v.a*u.a; /* t = (x-.5)*(log(x)-1) */
+ t.b = v.b*u.a + x*u.b;
+ /* return t.a + t.b + lns2pi_hi + lns2pi_lo + p */
+ t.b += lns2pi_lo; t.b += p;
+ u.a = lns2pi_hi + t.b; u.a += t.a;
+ u.b = t.a - u.a;
+ u.b += lns2pi_hi; u.b += t.b;
+ return (u);
+}
+/*
+ * Good to < 1 ulp. (provably .90 ulp; .87 ulp on 1,000,000 runs.)
+ * It also has correct monotonicity.
+ */
+static double
+small_gam(x)
+ double x;
+{
+ double y, ym1, t;
+ struct Double yy, r;
+ y = x - one;
+ ym1 = y - one;
+ if (y <= 1.0 + (LEFT + x0)) {
+ yy = ratfun_gam(y - x0, 0);
+ return (yy.a + yy.b);
+ }
+ r.a = y;
+ TRUNC(r.a);
+ yy.a = r.a - one;
+ y = ym1;
+ yy.b = r.b = y - yy.a;
+ /* Argument reduction: G(x+1) = x*G(x) */
+ for (ym1 = y-one; ym1 > LEFT + x0; y = ym1--, yy.a--) {
+ t = r.a*yy.a;
+ r.b = r.a*yy.b + y*r.b;
+ r.a = t;
+ TRUNC(r.a);
+ r.b += (t - r.a);
+ }
+ /* Return r*gamma(y). */
+ yy = ratfun_gam(y - x0, 0);
+ y = r.b*(yy.a + yy.b) + r.a*yy.b;
+ y += yy.a*r.a;
+ return (y);
+}
+/*
+ * Good on (0, 1+x0+LEFT]. Accurate to 1ulp.
+ */
+static double
+smaller_gam(x)
+ double x;
+{
+ double t, d;
+ struct Double r, xx;
+ if (x < x0 + LEFT) {
+ t = x, TRUNC(t);
+ d = (t+x)*(x-t);
+ t *= t;
+ xx.a = (t + x), TRUNC(xx.a);
+ xx.b = x - xx.a; xx.b += t; xx.b += d;
+ t = (one-x0); t += x;
+ d = (one-x0); d -= t; d += x;
+ x = xx.a + xx.b;
+ } else {
+ xx.a = x, TRUNC(xx.a);
+ xx.b = x - xx.a;
+ t = x - x0;
+ d = (-x0 -t); d += x;
+ }
+ r = ratfun_gam(t, d);
+ d = r.a/x, TRUNC(d);
+ r.a -= d*xx.a; r.a -= d*xx.b; r.a += r.b;
+ return (d + r.a/x);
+}
+/*
+ * returns (z+c)^2 * P(z)/Q(z) + a0
+ */
+static struct Double
+ratfun_gam(z, c)
+ double z, c;
+{
+ double p, q;
+ struct Double r, t;
+
+ q = Q0 +z*(Q1+z*(Q2+z*(Q3+z*(Q4+z*(Q5+z*(Q6+z*(Q7+z*Q8)))))));
+ p = P0 + z*(P1 + z*(P2 + z*(P3 + z*P4)));
+
+ /* return r.a + r.b = a0 + (z+c)^2*p/q, with r.a truncated to 26 bits. */
+ p = p/q;
+ t.a = z, TRUNC(t.a); /* t ~= z + c */
+ t.b = (z - t.a) + c;
+ t.b *= (t.a + z);
+ q = (t.a *= t.a); /* t = (z+c)^2 */
+ TRUNC(t.a);
+ t.b += (q - t.a);
+ r.a = p, TRUNC(r.a); /* r = P/Q */
+ r.b = p - r.a;
+ t.b = t.b*p + t.a*r.b + a0_lo;
+ t.a *= r.a; /* t = (z+c)^2*(P/Q) */
+ r.a = t.a + a0_hi, TRUNC(r.a);
+ r.b = ((a0_hi-r.a) + t.a) + t.b;
+ return (r); /* r = a0 + t */
+}
+
+static double
+neg_gam(x)
+ double x;
+{
+ int sgn = 1;
+ struct Double lg, lsine;
+ double y, z;
+
+ y = floor(x + .5);
+ if (y == x) /* Negative integer. */
+ if(!_IEEE)
+ return (infnan(ERANGE));
+ else
+ return (one/zero);
+ z = fabs(x - y);
+ y = .5*ceil(x);
+ if (y == ceil(y))
+ sgn = -1;
+ if (z < .25)
+ z = sin(M_PI*z);
+ else
+ z = cos(M_PI*(0.5-z));
+ /* Special case: G(1-x) = Inf; G(x) may be nonzero. */
+ if (x < -170) {
+ if (x < -190)
+ return ((double)sgn*tiny*tiny);
+ y = one - x; /* exact: 128 < |x| < 255 */
+ lg = large_gam(y);
+ lsine = __log__D(M_PI/z); /* = TRUNC(log(u)) + small */
+ lg.a -= lsine.a; /* exact (opposite signs) */
+ lg.b -= lsine.b;
+ y = -(lg.a + lg.b);
+ z = (y + lg.a) + lg.b;
+ y = __exp__D(y, z);
+ if (sgn < 0) y = -y;
+ return (y);
+ }
+ y = one-x;
+ if (one-y == x)
+ y = gamma(y);
+ else /* 1-x is inexact */
+ y = -x*gamma(-x);
+ if (sgn < 0) y = -y;
+ return (M_PI / (y*z));
+}
+
+#endif
diff --git a/src/lib/libast/uwin/getpass.c b/src/lib/libast/uwin/getpass.c
new file mode 100644
index 0000000..bb65996
--- /dev/null
+++ b/src/lib/libast/uwin/getpass.c
@@ -0,0 +1,79 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_getpass
+
+void _STUB_getpass(){}
+
+#else
+
+#pragma prototyped
+
+#define getpass ______getpass
+
+#include <ast.h>
+#include <termios.h>
+#include <signal.h>
+
+#undef getpass
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+static int interrupt;
+static void handler(int sig)
+{
+ interrupt++;
+}
+
+extern char* getpass(const char *prompt)
+{
+ struct termios told,tnew;
+ Sfio_t *iop;
+ static char *cp, passwd[32];
+ void (*savesig)(int);
+ if(!(iop = sfopen((Sfio_t*)0, "/dev/tty", "r")))
+ return(0);
+ if(tcgetattr(sffileno(iop),&told) < 0)
+ return(0);
+ interrupt = 0;
+ tnew = told;
+ tnew.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL);
+ if(tcsetattr(sffileno(iop),TCSANOW,&tnew) < 0)
+ return(0);
+ savesig = signal(SIGINT, handler);
+ sfputr(sfstderr,prompt,-1);
+ if(cp = sfgetr(iop,'\n',1))
+ strncpy(passwd,cp,sizeof(passwd)-1);
+ tcsetattr(sffileno(iop),TCSANOW,&told);
+ sfputc(sfstderr,'\n');
+ sfclose(iop);
+ signal(SIGINT, savesig);
+ if(interrupt)
+ kill(getpid(),SIGINT);
+ return(cp?passwd:0);
+}
+
+
+#endif
diff --git a/src/lib/libast/uwin/lgamma.c b/src/lib/libast/uwin/lgamma.c
new file mode 100644
index 0000000..d37357d
--- /dev/null
+++ b/src/lib/libast/uwin/lgamma.c
@@ -0,0 +1,316 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_lgamma
+
+void _STUB_lgamma(){}
+
+#else
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)lgamma.c 8.2 (Berkeley) 11/30/93";
+#endif /* not lint */
+
+/*
+ * Coded by Peter McIlroy, Nov 1992;
+ *
+ * The financial support of UUNET Communications Services is greatfully
+ * acknowledged.
+ */
+
+#define gamma ______gamma
+#define lgamma ______lgamma
+
+#include <math.h>
+#include <errno.h>
+#include "mathimpl.h"
+
+#undef gamma
+#undef lgamma
+
+/* Log gamma function.
+ * Error: x > 0 error < 1.3ulp.
+ * x > 4, error < 1ulp.
+ * x > 9, error < .6ulp.
+ * x < 0, all bets are off. (When G(x) ~ 1, log(G(x)) ~ 0)
+ * Method:
+ * x > 6:
+ * Use the asymptotic expansion (Stirling's Formula)
+ * 0 < x < 6:
+ * Use gamma(x+1) = x*gamma(x) for argument reduction.
+ * Use rational approximation in
+ * the range 1.2, 2.5
+ * Two approximations are used, one centered at the
+ * minimum to ensure monotonicity; one centered at 2
+ * to maintain small relative error.
+ * x < 0:
+ * Use the reflection formula,
+ * G(1-x)G(x) = PI/sin(PI*x)
+ * Special values:
+ * non-positive integer returns +Inf.
+ * NaN returns NaN
+*/
+static int endian;
+#if defined(vax) || defined(tahoe)
+#define _IEEE 0
+/* double and float have same size exponent field */
+#define TRUNC(x) x = (double) (float) (x)
+#else
+#define _IEEE 1
+#define TRUNC(x) *(((int *) &x) + endian) &= 0xf8000000
+#define infnan(x) 0.0
+#endif
+
+static double small_lgam(double);
+static double large_lgam(double);
+static double neg_lgam(double);
+static double zero = 0.0, one = 1.0;
+int signgam;
+
+#define UNDERFL (1e-1020 * 1e-1020)
+
+#define LEFT (1.0 - (x0 + .25))
+#define RIGHT (x0 - .218)
+/*
+ * Constants for approximation in [1.244,1.712]
+*/
+#define x0 0.461632144968362356785
+#define x0_lo -.000000000000000015522348162858676890521
+#define a0_hi -0.12148629128932952880859
+#define a0_lo .0000000007534799204229502
+#define r0 -2.771227512955130520e-002
+#define r1 -2.980729795228150847e-001
+#define r2 -3.257411333183093394e-001
+#define r3 -1.126814387531706041e-001
+#define r4 -1.129130057170225562e-002
+#define r5 -2.259650588213369095e-005
+#define s0 1.714457160001714442e+000
+#define s1 2.786469504618194648e+000
+#define s2 1.564546365519179805e+000
+#define s3 3.485846389981109850e-001
+#define s4 2.467759345363656348e-002
+/*
+ * Constants for approximation in [1.71, 2.5]
+*/
+#define a1_hi 4.227843350984671344505727574870e-01
+#define a1_lo 4.670126436531227189e-18
+#define p0 3.224670334241133695662995251041e-01
+#define p1 3.569659696950364669021382724168e-01
+#define p2 1.342918716072560025853732668111e-01
+#define p3 1.950702176409779831089963408886e-02
+#define p4 8.546740251667538090796227834289e-04
+#define q0 1.000000000000000444089209850062e+00
+#define q1 1.315850076960161985084596381057e+00
+#define q2 6.274644311862156431658377186977e-01
+#define q3 1.304706631926259297049597307705e-01
+#define q4 1.102815279606722369265536798366e-02
+#define q5 2.512690594856678929537585620579e-04
+#define q6 -1.003597548112371003358107325598e-06
+/*
+ * Stirling's Formula, adjusted for equal-ripple. x in [6,Inf].
+*/
+#define lns2pi .418938533204672741780329736405
+#define pb0 8.33333333333333148296162562474e-02
+#define pb1 -2.77777777774548123579378966497e-03
+#define pb2 7.93650778754435631476282786423e-04
+#define pb3 -5.95235082566672847950717262222e-04
+#define pb4 8.41428560346653702135821806252e-04
+#define pb5 -1.89773526463879200348872089421e-03
+#define pb6 5.69394463439411649408050664078e-03
+#define pb7 -1.44705562421428915453880392761e-02
+
+extern __pure double lgamma(double x)
+{
+ double r;
+
+ signgam = 1;
+ endian = ((*(int *) &one)) ? 1 : 0;
+
+ if (!finite(x))
+ if (_IEEE)
+ return (x+x);
+ else return (infnan(EDOM));
+
+ if (x > 6 + RIGHT) {
+ r = large_lgam(x);
+ return (r);
+ } else if (x > 1e-16)
+ return (small_lgam(x));
+ else if (x > -1e-16) {
+ if (x < 0)
+ signgam = -1, x = -x;
+ return (-log(x));
+ } else
+ return (neg_lgam(x));
+}
+
+static double
+large_lgam(double x)
+{
+ double z, p, x1;
+ struct Double t, u, v;
+ u = __log__D(x);
+ u.a -= 1.0;
+ if (x > 1e15) {
+ v.a = x - 0.5;
+ TRUNC(v.a);
+ v.b = (x - v.a) - 0.5;
+ t.a = u.a*v.a;
+ t.b = x*u.b + v.b*u.a;
+ if (_IEEE == 0 && !finite(t.a))
+ return(infnan(ERANGE));
+ return(t.a + t.b);
+ }
+ x1 = 1./x;
+ z = x1*x1;
+ p = pb0+z*(pb1+z*(pb2+z*(pb3+z*(pb4+z*(pb5+z*(pb6+z*pb7))))));
+ /* error in approximation = 2.8e-19 */
+
+ p = p*x1; /* error < 2.3e-18 absolute */
+ /* 0 < p < 1/64 (at x = 5.5) */
+ v.a = x = x - 0.5;
+ TRUNC(v.a); /* truncate v.a to 26 bits. */
+ v.b = x - v.a;
+ t.a = v.a*u.a; /* t = (x-.5)*(log(x)-1) */
+ t.b = v.b*u.a + x*u.b;
+ t.b += p; t.b += lns2pi; /* return t + lns2pi + p */
+ return (t.a + t.b);
+}
+
+static double
+small_lgam(double x)
+{
+ int x_int;
+ double y, z, t, r = 0, p, q, hi, lo;
+ struct Double rr;
+ x_int = (int)(x + .5);
+ y = x - x_int;
+ if (x_int <= 2 && y > RIGHT) {
+ t = y - x0;
+ y--; x_int++;
+ goto CONTINUE;
+ } else if (y < -LEFT) {
+ t = y +(1.0-x0);
+CONTINUE:
+ z = t - x0_lo;
+ p = r0+z*(r1+z*(r2+z*(r3+z*(r4+z*r5))));
+ q = s0+z*(s1+z*(s2+z*(s3+z*s4)));
+ r = t*(z*(p/q) - x0_lo);
+ t = .5*t*t;
+ z = 1.0;
+ switch (x_int) {
+ case 6: z = (y + 5);
+ case 5: z *= (y + 4);
+ case 4: z *= (y + 3);
+ case 3: z *= (y + 2);
+ rr = __log__D(z);
+ rr.b += a0_lo; rr.a += a0_hi;
+ return(((r+rr.b)+t+rr.a));
+ case 2: return(((r+a0_lo)+t)+a0_hi);
+ case 0: r -= log1p(x);
+ default: rr = __log__D(x);
+ rr.a -= a0_hi; rr.b -= a0_lo;
+ return(((r - rr.b) + t) - rr.a);
+ }
+ } else {
+ p = p0+y*(p1+y*(p2+y*(p3+y*p4)));
+ q = q0+y*(q1+y*(q2+y*(q3+y*(q4+y*(q5+y*q6)))));
+ p = p*(y/q);
+ t = (double)(float) y;
+ z = y-t;
+ hi = (double)(float) (p+a1_hi);
+ lo = a1_hi - hi; lo += p; lo += a1_lo;
+ r = lo*y + z*hi; /* q + r = y*(a0+p/q) */
+ q = hi*t;
+ z = 1.0;
+ switch (x_int) {
+ case 6: z = (y + 5);
+ case 5: z *= (y + 4);
+ case 4: z *= (y + 3);
+ case 3: z *= (y + 2);
+ rr = __log__D(z);
+ r += rr.b; r += q;
+ return(rr.a + r);
+ case 2: return (q+ r);
+ case 0: rr = __log__D(x);
+ r -= rr.b; r -= log1p(x);
+ r += q; r-= rr.a;
+ return(r);
+ default: rr = __log__D(x);
+ r -= rr.b;
+ q -= rr.a;
+ return (r+q);
+ }
+ }
+}
+
+static double
+neg_lgam(double x)
+{
+ int xi;
+ double y, z, one = 1.0, zero = 0.0;
+ extern double gamma();
+
+ /* avoid destructive cancellation as much as possible */
+ if (x > -170) {
+ xi = (int)x;
+ if (xi == x)
+ if (_IEEE)
+ return(one/zero);
+ else
+ return(infnan(ERANGE));
+ y = gamma(x);
+ if (y < 0)
+ y = -y, signgam = -1;
+ return (log(y));
+ }
+ z = floor(x + .5);
+ if (z == x) { /* convention: G(-(integer)) -> +Inf */
+ if (_IEEE)
+ return (one/zero);
+ else
+ return (infnan(ERANGE));
+ }
+ y = .5*ceil(x);
+ if (y == ceil(y))
+ signgam = -1;
+ x = -x;
+ z = fabs(x + z); /* 0 < z <= .5 */
+ if (z < .25)
+ z = sin(M_PI*z);
+ else
+ z = cos(M_PI*(0.5-z));
+ z = log(M_PI/(z*x));
+ y = large_lgam(x);
+ return (z - y);
+}
+
+#endif
diff --git a/src/lib/libast/uwin/log.c b/src/lib/libast/uwin/log.c
new file mode 100644
index 0000000..e9365a3
--- /dev/null
+++ b/src/lib/libast/uwin/log.c
@@ -0,0 +1,496 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN
+
+void _STUB_log(){}
+
+#else
+
+/*
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)log.c 8.2 (Berkeley) 11/30/93";
+#endif /* not lint */
+
+#include <math.h>
+#include <errno.h>
+
+#include "mathimpl.h"
+
+/* Table-driven natural logarithm.
+ *
+ * This code was derived, with minor modifications, from:
+ * Peter Tang, "Table-Driven Implementation of the
+ * Logarithm in IEEE Floating-Point arithmetic." ACM Trans.
+ * Math Software, vol 16. no 4, pp 378-400, Dec 1990).
+ *
+ * Calculates log(2^m*F*(1+f/F)), |f/j| <= 1/256,
+ * where F = j/128 for j an integer in [0, 128].
+ *
+ * log(2^m) = log2_hi*m + log2_tail*m
+ * since m is an integer, the dominant term is exact.
+ * m has at most 10 digits (for subnormal numbers),
+ * and log2_hi has 11 trailing zero bits.
+ *
+ * log(F) = logF_hi[j] + logF_lo[j] is in tabular form in log_table.h
+ * logF_hi[] + 512 is exact.
+ *
+ * log(1+f/F) = 2*f/(2*F + f) + 1/12 * (2*f/(2*F + f))**3 + ...
+ * the leading term is calculated to extra precision in two
+ * parts, the larger of which adds exactly to the dominant
+ * m and F terms.
+ * There are two cases:
+ * 1. when m, j are non-zero (m | j), use absolute
+ * precision for the leading term.
+ * 2. when m = j = 0, |1-x| < 1/256, and log(x) ~= (x-1).
+ * In this case, use a relative precision of 24 bits.
+ * (This is done differently in the original paper)
+ *
+ * Special cases:
+ * 0 return signalling -Inf
+ * neg return signalling NaN
+ * +Inf return +Inf
+*/
+
+#if defined(vax) || defined(tahoe)
+#define _IEEE 0
+#define TRUNC(x) x = (double) (float) (x)
+#else
+#define _IEEE 1
+#define endian (((*(int *) &one)) ? 1 : 0)
+#define TRUNC(x) *(((int *) &x) + endian) &= 0xf8000000
+#define infnan(x) 0.0
+#endif
+
+#define N 128
+
+/* Table of log(Fj) = logF_head[j] + logF_tail[j], for Fj = 1+j/128.
+ * Used for generation of extend precision logarithms.
+ * The constant 35184372088832 is 2^45, so the divide is exact.
+ * It ensures correct reading of logF_head, even for inaccurate
+ * decimal-to-binary conversion routines. (Everybody gets the
+ * right answer for integers less than 2^53.)
+ * Values for log(F) were generated using error < 10^-57 absolute
+ * with the bc -l package.
+*/
+static double A1 = .08333333333333178827;
+static double A2 = .01250000000377174923;
+static double A3 = .002232139987919447809;
+static double A4 = .0004348877777076145742;
+
+static double logF_head[N+1] = {
+ 0.,
+ .007782140442060381246,
+ .015504186535963526694,
+ .023167059281547608406,
+ .030771658666765233647,
+ .038318864302141264488,
+ .045809536031242714670,
+ .053244514518837604555,
+ .060624621816486978786,
+ .067950661908525944454,
+ .075223421237524235039,
+ .082443669210988446138,
+ .089612158689760690322,
+ .096729626458454731618,
+ .103796793681567578460,
+ .110814366340264314203,
+ .117783035656430001836,
+ .124703478501032805070,
+ .131576357788617315236,
+ .138402322859292326029,
+ .145182009844575077295,
+ .151916042025732167530,
+ .158605030176659056451,
+ .165249572895390883786,
+ .171850256926518341060,
+ .178407657472689606947,
+ .184922338493834104156,
+ .191394852999565046047,
+ .197825743329758552135,
+ .204215541428766300668,
+ .210564769107350002741,
+ .216873938300523150246,
+ .223143551314024080056,
+ .229374101064877322642,
+ .235566071312860003672,
+ .241719936886966024758,
+ .247836163904594286577,
+ .253915209980732470285,
+ .259957524436686071567,
+ .265963548496984003577,
+ .271933715484010463114,
+ .277868451003087102435,
+ .283768173130738432519,
+ .289633292582948342896,
+ .295464212893421063199,
+ .301261330578199704177,
+ .307025035294827830512,
+ .312755710004239517729,
+ .318453731118097493890,
+ .324119468654316733591,
+ .329753286372579168528,
+ .335355541920762334484,
+ .340926586970454081892,
+ .346466767346100823488,
+ .351976423156884266063,
+ .357455888922231679316,
+ .362905493689140712376,
+ .368325561158599157352,
+ .373716409793814818840,
+ .379078352934811846353,
+ .384411698910298582632,
+ .389716751140440464951,
+ .394993808240542421117,
+ .400243164127459749579,
+ .405465108107819105498,
+ .410659924985338875558,
+ .415827895143593195825,
+ .420969294644237379543,
+ .426084395310681429691,
+ .431173464818130014464,
+ .436236766774527495726,
+ .441274560805140936281,
+ .446287102628048160113,
+ .451274644139630254358,
+ .456237433481874177232,
+ .461175715122408291790,
+ .466089729924533457960,
+ .470979715219073113985,
+ .475845904869856894947,
+ .480688529345570714212,
+ .485507815781602403149,
+ .490303988045525329653,
+ .495077266798034543171,
+ .499827869556611403822,
+ .504556010751912253908,
+ .509261901790523552335,
+ .513945751101346104405,
+ .518607764208354637958,
+ .523248143765158602036,
+ .527867089620485785417,
+ .532464798869114019908,
+ .537041465897345915436,
+ .541597282432121573947,
+ .546132437597407260909,
+ .550647117952394182793,
+ .555141507540611200965,
+ .559615787935399566777,
+ .564070138285387656651,
+ .568504735352689749561,
+ .572919753562018740922,
+ .577315365035246941260,
+ .581691739635061821900,
+ .586049045003164792433,
+ .590387446602107957005,
+ .594707107746216934174,
+ .599008189645246602594,
+ .603290851438941899687,
+ .607555250224322662688,
+ .611801541106615331955,
+ .616029877215623855590,
+ .620240409751204424537,
+ .624433288012369303032,
+ .628608659422752680256,
+ .632766669570628437213,
+ .636907462236194987781,
+ .641031179420679109171,
+ .645137961373620782978,
+ .649227946625615004450,
+ .653301272011958644725,
+ .657358072709030238911,
+ .661398482245203922502,
+ .665422632544505177065,
+ .669430653942981734871,
+ .673422675212350441142,
+ .677398823590920073911,
+ .681359224807238206267,
+ .685304003098281100392,
+ .689233281238557538017,
+ .693147180560117703862
+};
+
+static double logF_tail[N+1] = {
+ 0.,
+ -.00000000000000543229938420049,
+ .00000000000000172745674997061,
+ -.00000000000001323017818229233,
+ -.00000000000001154527628289872,
+ -.00000000000000466529469958300,
+ .00000000000005148849572685810,
+ -.00000000000002532168943117445,
+ -.00000000000005213620639136504,
+ -.00000000000001819506003016881,
+ .00000000000006329065958724544,
+ .00000000000008614512936087814,
+ -.00000000000007355770219435028,
+ .00000000000009638067658552277,
+ .00000000000007598636597194141,
+ .00000000000002579999128306990,
+ -.00000000000004654729747598444,
+ -.00000000000007556920687451336,
+ .00000000000010195735223708472,
+ -.00000000000017319034406422306,
+ -.00000000000007718001336828098,
+ .00000000000010980754099855238,
+ -.00000000000002047235780046195,
+ -.00000000000008372091099235912,
+ .00000000000014088127937111135,
+ .00000000000012869017157588257,
+ .00000000000017788850778198106,
+ .00000000000006440856150696891,
+ .00000000000016132822667240822,
+ -.00000000000007540916511956188,
+ -.00000000000000036507188831790,
+ .00000000000009120937249914984,
+ .00000000000018567570959796010,
+ -.00000000000003149265065191483,
+ -.00000000000009309459495196889,
+ .00000000000017914338601329117,
+ -.00000000000001302979717330866,
+ .00000000000023097385217586939,
+ .00000000000023999540484211737,
+ .00000000000015393776174455408,
+ -.00000000000036870428315837678,
+ .00000000000036920375082080089,
+ -.00000000000009383417223663699,
+ .00000000000009433398189512690,
+ .00000000000041481318704258568,
+ -.00000000000003792316480209314,
+ .00000000000008403156304792424,
+ -.00000000000034262934348285429,
+ .00000000000043712191957429145,
+ -.00000000000010475750058776541,
+ -.00000000000011118671389559323,
+ .00000000000037549577257259853,
+ .00000000000013912841212197565,
+ .00000000000010775743037572640,
+ .00000000000029391859187648000,
+ -.00000000000042790509060060774,
+ .00000000000022774076114039555,
+ .00000000000010849569622967912,
+ -.00000000000023073801945705758,
+ .00000000000015761203773969435,
+ .00000000000003345710269544082,
+ -.00000000000041525158063436123,
+ .00000000000032655698896907146,
+ -.00000000000044704265010452446,
+ .00000000000034527647952039772,
+ -.00000000000007048962392109746,
+ .00000000000011776978751369214,
+ -.00000000000010774341461609578,
+ .00000000000021863343293215910,
+ .00000000000024132639491333131,
+ .00000000000039057462209830700,
+ -.00000000000026570679203560751,
+ .00000000000037135141919592021,
+ -.00000000000017166921336082431,
+ -.00000000000028658285157914353,
+ -.00000000000023812542263446809,
+ .00000000000006576659768580062,
+ -.00000000000028210143846181267,
+ .00000000000010701931762114254,
+ .00000000000018119346366441110,
+ .00000000000009840465278232627,
+ -.00000000000033149150282752542,
+ -.00000000000018302857356041668,
+ -.00000000000016207400156744949,
+ .00000000000048303314949553201,
+ -.00000000000071560553172382115,
+ .00000000000088821239518571855,
+ -.00000000000030900580513238244,
+ -.00000000000061076551972851496,
+ .00000000000035659969663347830,
+ .00000000000035782396591276383,
+ -.00000000000046226087001544578,
+ .00000000000062279762917225156,
+ .00000000000072838947272065741,
+ .00000000000026809646615211673,
+ -.00000000000010960825046059278,
+ .00000000000002311949383800537,
+ -.00000000000058469058005299247,
+ -.00000000000002103748251144494,
+ -.00000000000023323182945587408,
+ -.00000000000042333694288141916,
+ -.00000000000043933937969737844,
+ .00000000000041341647073835565,
+ .00000000000006841763641591466,
+ .00000000000047585534004430641,
+ .00000000000083679678674757695,
+ -.00000000000085763734646658640,
+ .00000000000021913281229340092,
+ -.00000000000062242842536431148,
+ -.00000000000010983594325438430,
+ .00000000000065310431377633651,
+ -.00000000000047580199021710769,
+ -.00000000000037854251265457040,
+ .00000000000040939233218678664,
+ .00000000000087424383914858291,
+ .00000000000025218188456842882,
+ -.00000000000003608131360422557,
+ -.00000000000050518555924280902,
+ .00000000000078699403323355317,
+ -.00000000000067020876961949060,
+ .00000000000016108575753932458,
+ .00000000000058527188436251509,
+ -.00000000000035246757297904791,
+ -.00000000000018372084495629058,
+ .00000000000088606689813494916,
+ .00000000000066486268071468700,
+ .00000000000063831615170646519,
+ .00000000000025144230728376072,
+ -.00000000000017239444525614834
+};
+
+#if !_lib_log
+
+extern double
+#ifdef _ANSI_SOURCE
+log(double x)
+#else
+log(x) double x;
+#endif
+{
+ int m, j;
+ double F, f, g, q, u, u2, v, zero = 0.0, one = 1.0;
+ volatile double u1;
+
+ /* Catch special cases */
+ if (x <= 0)
+ if (_IEEE && x == zero) /* log(0) = -Inf */
+ return (-one/zero);
+ else if (_IEEE) /* log(neg) = NaN */
+ return (zero/zero);
+ else if (x == zero) /* NOT REACHED IF _IEEE */
+ return (infnan(-ERANGE));
+ else
+ return (infnan(EDOM));
+ else if (!finite(x))
+ if (_IEEE) /* x = NaN, Inf */
+ return (x+x);
+ else
+ return (infnan(ERANGE));
+
+ /* Argument reduction: 1 <= g < 2; x/2^m = g; */
+ /* y = F*(1 + f/F) for |f| <= 2^-8 */
+
+ m = logb(x);
+ g = ldexp(x, -m);
+ if (_IEEE && m == -1022) {
+ j = logb(g), m += j;
+ g = ldexp(g, -j);
+ }
+ j = N*(g-1) + .5;
+ F = (1.0/N) * j + 1; /* F*128 is an integer in [128, 512] */
+ f = g - F;
+
+ /* Approximate expansion for log(1+f/F) ~= u + q */
+ g = 1/(2*F+f);
+ u = 2*f*g;
+ v = u*u;
+ q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
+
+ /* case 1: u1 = u rounded to 2^-43 absolute. Since u < 2^-8,
+ * u1 has at most 35 bits, and F*u1 is exact, as F has < 8 bits.
+ * It also adds exactly to |m*log2_hi + log_F_head[j] | < 750
+ */
+ if (m | j)
+ u1 = u + 513, u1 -= 513;
+
+ /* case 2: |1-x| < 1/256. The m- and j- dependent terms are zero;
+ * u1 = u to 24 bits.
+ */
+ else
+ u1 = u, TRUNC(u1);
+ u2 = (2.0*(f - F*u1) - u1*f) * g;
+ /* u1 + u2 = 2f/(2F+f) to extra precision. */
+
+ /* log(x) = log(2^m*F*(1+f/F)) = */
+ /* (m*log2_hi+logF_head[j]+u1) + (m*log2_lo+logF_tail[j]+q); */
+ /* (exact) + (tiny) */
+
+ u1 += m*logF_head[N] + logF_head[j]; /* exact */
+ u2 = (u2 + logF_tail[j]) + q; /* tiny */
+ u2 += logF_tail[N]*m;
+ return (u1 + u2);
+}
+
+#endif
+
+/*
+ * Extra precision variant, returning struct {double a, b;};
+ * log(x) = a+b to 63 bits, with a is rounded to 26 bits.
+ */
+struct Double
+#ifdef _ANSI_SOURCE
+__log__D(double x)
+#else
+__log__D(x) double x;
+#endif
+{
+ int m, j;
+ double F, f, g, q, u, v, u2, one = 1.0;
+ volatile double u1;
+ struct Double r;
+
+ /* Argument reduction: 1 <= g < 2; x/2^m = g; */
+ /* y = F*(1 + f/F) for |f| <= 2^-8 */
+
+ m = (int)logb(x);
+ g = ldexp(x, -m);
+ if (_IEEE && m == -1022) {
+ j = (int)logb(g), m += j;
+ g = ldexp(g, -j);
+ }
+ j = (int)(N*(g-1) + .5);
+ F = (1.0/N) * j + 1;
+ f = g - F;
+
+ g = 1/(2*F+f);
+ u = 2*f*g;
+ v = u*u;
+ q = u*v*(A1 + v*(A2 + v*(A3 + v*A4)));
+ if (m | j)
+ u1 = u + 513, u1 -= 513;
+ else
+ u1 = u, TRUNC(u1);
+ u2 = (2.0*(f - F*u1) - u1*f) * g;
+
+ u1 += m*logF_head[N] + logF_head[j];
+
+ u2 += logF_tail[j]; u2 += q;
+ u2 += logF_tail[N]*m;
+ r.a = u1 + u2; /* Only difference is here */
+ TRUNC(r.a);
+ r.b = (u1 - r.a) + u2;
+ return (r);
+}
+
+#endif
diff --git a/src/lib/libast/uwin/log1p.c b/src/lib/libast/uwin/log1p.c
new file mode 100644
index 0000000..1fad21f
--- /dev/null
+++ b/src/lib/libast/uwin/log1p.c
@@ -0,0 +1,176 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_log1p
+
+void _STUB_log1p(){}
+
+#else
+
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)log1p.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* LOG1P(x)
+ * RETURN THE LOGARITHM OF 1+x
+ * DOUBLE PRECISION (VAX D FORMAT 56 bits, IEEE DOUBLE 53 BITS)
+ * CODED IN C BY K.C. NG, 1/19/85;
+ * REVISED BY K.C. NG on 2/6/85, 3/7/85, 3/24/85, 4/16/85.
+ *
+ * Required system supported functions:
+ * scalb(x,n)
+ * copysign(x,y)
+ * logb(x)
+ * finite(x)
+ *
+ * Required kernel function:
+ * log__L(z)
+ *
+ * Method :
+ * 1. Argument Reduction: find k and f such that
+ * 1+x = 2^k * (1+f),
+ * where sqrt(2)/2 < 1+f < sqrt(2) .
+ *
+ * 2. Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+ * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ * log(1+f) is computed by
+ *
+ * log(1+f) = 2s + s*log__L(s*s)
+ * where
+ * log__L(z) = z*(L1 + z*(L2 + z*(... (L6 + z*L7)...)))
+ *
+ * See log__L() for the values of the coefficients.
+ *
+ * 3. Finally, log(1+x) = k*ln2 + log(1+f).
+ *
+ * Remarks 1. In step 3 n*ln2 will be stored in two floating point numbers
+ * n*ln2hi + n*ln2lo, where ln2hi is chosen such that the last
+ * 20 bits (for VAX D format), or the last 21 bits ( for IEEE
+ * double) is 0. This ensures n*ln2hi is exactly representable.
+ * 2. In step 1, f may not be representable. A correction term c
+ * for f is computed. It follows that the correction term for
+ * f - t (the leading term of log(1+f) in step 2) is c-c*x. We
+ * add this correction term to n*ln2lo to attenuate the error.
+ *
+ *
+ * Special cases:
+ * log1p(x) is NaN with signal if x < -1; log1p(NaN) is NaN with no signal;
+ * log1p(INF) is +INF; log1p(-1) is -INF with signal;
+ * only log1p(0)=0 is exact for finite argument.
+ *
+ * Accuracy:
+ * log1p(x) returns the exact log(1+x) nearly rounded. In a test run
+ * with 1,536,000 random arguments on a VAX, the maximum observed
+ * error was .846 ulps (units in the last place).
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include <errno.h>
+#include "mathimpl.h"
+
+vc(ln2hi, 6.9314718055829871446E-1 ,7217,4031,0000,f7d0, 0, .B17217F7D00000)
+vc(ln2lo, 1.6465949582897081279E-12 ,bcd5,2ce7,d9cc,e4f1, -39, .E7BCD5E4F1D9CC)
+vc(sqrt2, 1.4142135623730950622E0 ,04f3,40b5,de65,33f9, 1, .B504F333F9DE65)
+
+ic(ln2hi, 6.9314718036912381649E-1, -1, 1.62E42FEE00000)
+ic(ln2lo, 1.9082149292705877000E-10, -33, 1.A39EF35793C76)
+ic(sqrt2, 1.4142135623730951455E0, 0, 1.6A09E667F3BCD)
+
+#ifdef vccast
+#define ln2hi vccast(ln2hi)
+#define ln2lo vccast(ln2lo)
+#define sqrt2 vccast(sqrt2)
+#endif
+
+extern double log1p(x)
+double x;
+{
+ const static double zero=0.0, negone= -1.0, one=1.0,
+ half=1.0/2.0, small=1.0E-20; /* 1+small == 1 */
+ double z,s,t,c;
+ int k;
+
+#if !defined(vax)&&!defined(tahoe)
+ if(x!=x) return(x); /* x is NaN */
+#endif /* !defined(vax)&&!defined(tahoe) */
+
+ if(finite(x)) {
+ if( x > negone ) {
+
+ /* argument reduction */
+ if(copysign(x,one)<small) return(x);
+ k=(int)logb(one+x); z=scalb(x,-k); t=scalb(one,-k);
+ if(z+t >= sqrt2 )
+ { k += 1 ; z *= half; t *= half; }
+ t += negone; x = z + t;
+ c = (t-x)+z ; /* correction term for x */
+
+ /* compute log(1+x) */
+ s = x/(2+x); t = x*x*half;
+ c += (k*ln2lo-c*x);
+ z = c+s*(t+__log__L(s*s));
+ x += (z - t) ;
+
+ return(k*ln2hi+x);
+ }
+ /* end of if (x > negone) */
+
+ else {
+#if defined(vax)||defined(tahoe)
+ if ( x == negone )
+ return (infnan(-ERANGE)); /* -INF */
+ else
+ return (infnan(EDOM)); /* NaN */
+#else /* defined(vax)||defined(tahoe) */
+ /* x = -1, return -INF with signal */
+ if ( x == negone ) return( negone/zero );
+
+ /* negative argument for log, return NaN with signal */
+ else return ( zero / zero );
+#endif /* defined(vax)||defined(tahoe) */
+ }
+ }
+ /* end of if (finite(x)) */
+
+ /* log(-INF) is NaN */
+ else if(x<0)
+ return(zero/zero);
+
+ /* log(+INF) is INF */
+ else return(x);
+}
+
+#endif
diff --git a/src/lib/libast/uwin/log__L.c b/src/lib/libast/uwin/log__L.c
new file mode 100644
index 0000000..3276e69
--- /dev/null
+++ b/src/lib/libast/uwin/log__L.c
@@ -0,0 +1,116 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN
+
+void _STUB_log__L(){}
+
+#else
+
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)log__L.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/* log__L(Z)
+ * LOG(1+X) - 2S X
+ * RETURN --------------- WHERE Z = S*S, S = ------- , 0 <= Z <= .0294...
+ * S 2 + X
+ *
+ * DOUBLE PRECISION (VAX D FORMAT 56 bits or IEEE DOUBLE 53 BITS)
+ * KERNEL FUNCTION FOR LOG; TO BE USED IN LOG1P, LOG, AND POW FUNCTIONS
+ * CODED IN C BY K.C. NG, 1/19/85;
+ * REVISED BY K.C. Ng, 2/3/85, 4/16/85.
+ *
+ * Method :
+ * 1. Polynomial approximation: let s = x/(2+x).
+ * Based on log(1+x) = log(1+s) - log(1-s)
+ * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+ *
+ * (log(1+x) - 2s)/s is computed by
+ *
+ * z*(L1 + z*(L2 + z*(... (L7 + z*L8)...)))
+ *
+ * where z=s*s. (See the listing below for Lk's values.) The
+ * coefficients are obtained by a special Remez algorithm.
+ *
+ * Accuracy:
+ * Assuming no rounding error, the maximum magnitude of the approximation
+ * error (absolute) is 2**(-58.49) for IEEE double, and 2**(-63.63)
+ * for VAX D format.
+ *
+ * Constants:
+ * The hexadecimal values are the intended ones for the following constants.
+ * The decimal values may be used, provided that the compiler will convert
+ * from decimal to binary accurately enough to produce the hexadecimal values
+ * shown.
+ */
+
+#include "mathimpl.h"
+
+vc(L1, 6.6666666666666703212E-1 ,aaaa,402a,aac5,aaaa, 0, .AAAAAAAAAAAAC5)
+vc(L2, 3.9999999999970461961E-1 ,cccc,3fcc,2684,cccc, -1, .CCCCCCCCCC2684)
+vc(L3, 2.8571428579395698188E-1 ,4924,3f92,5782,92f8, -1, .92492492F85782)
+vc(L4, 2.2222221233634724402E-1 ,8e38,3f63,af2c,39b7, -2, .E38E3839B7AF2C)
+vc(L5, 1.8181879517064680057E-1 ,2eb4,3f3a,655e,cc39, -2, .BA2EB4CC39655E)
+vc(L6, 1.5382888777946145467E-1 ,8551,3f1d,781d,e8c5, -2, .9D8551E8C5781D)
+vc(L7, 1.3338356561139403517E-1 ,95b3,3f08,cd92,907f, -2, .8895B3907FCD92)
+vc(L8, 1.2500000000000000000E-1 ,0000,3f00,0000,0000, -2, .80000000000000)
+
+ic(L1, 6.6666666666667340202E-1, -1, 1.5555555555592)
+ic(L2, 3.9999999999416702146E-1, -2, 1.999999997FF24)
+ic(L3, 2.8571428742008753154E-1, -2, 1.24924941E07B4)
+ic(L4, 2.2222198607186277597E-1, -3, 1.C71C52150BEA6)
+ic(L5, 1.8183562745289935658E-1, -3, 1.74663CC94342F)
+ic(L6, 1.5314087275331442206E-1, -3, 1.39A1EC014045B)
+ic(L7, 1.4795612545334174692E-1, -3, 1.2F039F0085122)
+
+#ifdef vccast
+#define L1 vccast(L1)
+#define L2 vccast(L2)
+#define L3 vccast(L3)
+#define L4 vccast(L4)
+#define L5 vccast(L5)
+#define L6 vccast(L6)
+#define L7 vccast(L7)
+#define L8 vccast(L8)
+#endif
+
+double __log__L(z)
+double z;
+{
+#if defined(vax)||defined(tahoe)
+ return(z*(L1+z*(L2+z*(L3+z*(L4+z*(L5+z*(L6+z*(L7+z*L8))))))));
+#else /* defined(vax)||defined(tahoe) */
+ return(z*(L1+z*(L2+z*(L3+z*(L4+z*(L5+z*(L6+z*L7)))))));
+#endif /* defined(vax)||defined(tahoe) */
+}
+
+#endif
diff --git a/src/lib/libast/uwin/mathimpl.h b/src/lib/libast/uwin/mathimpl.h
new file mode 100644
index 0000000..12857f0
--- /dev/null
+++ b/src/lib/libast/uwin/mathimpl.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1988, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)mathimpl.h 8.1 (Berkeley) 6/4/93
+ */
+
+#include <sys/cdefs.h>
+#include <math.h>
+
+#if defined(vax)||defined(tahoe)
+
+/* Deal with different ways to concatenate in cpp */
+# ifdef __STDC__
+# define cat3(a,b,c) a ## b ## c
+# else
+# define cat3(a,b,c) a/**/b/**/c
+# endif
+
+/* Deal with vax/tahoe byte order issues */
+# ifdef vax
+# define cat3t(a,b,c) cat3(a,b,c)
+# else
+# define cat3t(a,b,c) cat3(a,c,b)
+# endif
+
+# define vccast(name) (*(const double *)(cat3(name,,x)))
+
+ /*
+ * Define a constant to high precision on a Vax or Tahoe.
+ *
+ * Args are the name to define, the decimal floating point value,
+ * four 16-bit chunks of the float value in hex
+ * (because the vax and tahoe differ in float format!), the power
+ * of 2 of the hex-float exponent, and the hex-float mantissa.
+ * Most of these arguments are not used at compile time; they are
+ * used in a post-check to make sure the constants were compiled
+ * correctly.
+ *
+ * People who want to use the constant will have to do their own
+ * #define foo vccast(foo)
+ * since CPP cannot do this for them from inside another macro (sigh).
+ * We define "vccast" if this needs doing.
+ */
+# define vc(name, value, x1,x2,x3,x4, bexp, xval) \
+ const static long cat3(name,,x)[] = {cat3t(0x,x1,x2), cat3t(0x,x3,x4)};
+
+# define ic(name, value, bexp, xval) ;
+
+#else /* vax or tahoe */
+
+ /* Hooray, we have an IEEE machine */
+# undef vccast
+# define vc(name, value, x1,x2,x3,x4, bexp, xval) ;
+
+# define ic(name, value, bexp, xval) \
+ const static double name = value;
+
+#endif /* defined(vax)||defined(tahoe) */
+
+
+/*
+ * Functions internal to the math package, yet not static.
+ */
+extern double __exp__E();
+extern double __log__L();
+
+struct Double {double a, b;};
+double __exp__D __P((double, double));
+struct Double __log__D __P((double));
+
+/*
+ * All externs exported after this point
+ */
+#if defined(_BLD_ast) && defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern double copysign(double, double);
diff --git a/src/lib/libast/uwin/mini.sym b/src/lib/libast/uwin/mini.sym
new file mode 100644
index 0000000..3a75e54
--- /dev/null
+++ b/src/lib/libast/uwin/mini.sym
@@ -0,0 +1,84 @@
+_ast_init
+_sfdlen
+_sffilbuf
+_sfflsbuf
+_sfgetl
+_sfgetl2
+_sfgetu
+_sfgetu2
+_sfllen
+_sfputd
+_sfputl
+_sfputu
+_stdgets
+_stdscanf
+_stdsprintf
+_stkseek
+printf
+remove
+sfclose
+sfclrerr
+sfclrlock
+sfdisc
+sfdlen
+sfdostext
+sfeof
+sferror
+sffcvt
+sffileno
+sfgetc
+sfgetd
+sfgetl
+sfgetr
+sfgetu
+sfkeyprintf
+sfllen
+sfmove
+sfnew
+sfnotify
+sfnputc
+sfopen
+sfpkrd
+sfpoll
+sfpool
+sfpopen
+sfprintf
+sfprints
+sfpurge
+sfputc
+sfputd
+sfputl
+sfputr
+sfputu
+sfrd
+sfread
+sfreserve
+sfscanf
+sfseek
+sfset
+sfsetbuf
+sfsetfd
+sfsize
+sfsk
+sfslen
+sfslowio
+sfsprintf
+sfsscanf
+sfstack
+sfstacked
+sfswap
+sfsync
+sftell
+sftmp
+sfulen
+sfungetc
+sfvalue
+sfvprintf
+sfvscanf
+sfwr
+sfwrite
+sigflag
+sprintf
+system
+mktemp
+strdup
diff --git a/src/lib/libast/uwin/rand48.c b/src/lib/libast/uwin/rand48.c
new file mode 100644
index 0000000..184a3b7
--- /dev/null
+++ b/src/lib/libast/uwin/rand48.c
@@ -0,0 +1,177 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_srand48
+
+void _STUB_srand48(){}
+
+#else
+
+#define drand48 ______drand48
+#define erand48 ______erand48
+#define jrand48 ______jrand48
+#define lcong48 ______lcong48
+#define lrand48 ______lrand48
+#define mrand48 ______mrand48
+#define nrand48 ______nrand48
+#define seed48 ______seed48
+#define srand48 ______srand48
+
+#include <stdlib.h>
+
+#undef drand48
+#undef erand48
+#undef jrand48
+#undef lcong48
+#undef lrand48
+#undef mrand48
+#undef nrand48
+#undef seed48
+#undef srand48
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#define A 0x5DEECE66D
+#define A0 0X5
+#define A1 0xDEEC
+#define A2 0xE66D
+#define C 0xB
+#define XINIT 0x330E
+#define SCALE 3.55271e-15
+
+static unsigned short oldval[3];
+static unsigned short X[3] = { 0, 0, XINIT};
+static unsigned short a[3] = { A0, A1, A2};
+static unsigned short c = C;
+
+static void multadd(unsigned short x[3], unsigned short a[3], unsigned short c)
+{
+ register unsigned long r = c;
+ unsigned short x2 = x[2];
+ unsigned short x1 = x[1];
+ r += a[2]*x2;
+ x[2] = (unsigned short)r;
+ r >>= 16;
+ r += a[1]*x2;
+ r += a[2]*x1;
+ x[1] = (unsigned short)r;
+ r >>= 16;
+ r += a[2]*x[0];
+ r += a[1]*x1;
+ r += a[0]*x2;
+ x[0] = (unsigned short)r;
+}
+
+extern double drand48(void)
+{
+ double d;
+ unsigned long u;
+ multadd(X,a,c);
+ u = (X[0]<<16) + X[1];
+ d = (u*65536.) + X[2];
+ return(d*SCALE);
+}
+
+extern double erand48(unsigned short xsubi[3])
+{
+ double d;
+ unsigned long u;
+ multadd(xsubi,a,c);
+ u = (xsubi[0]<<16) + xsubi[1];
+ d = (u*65536.) + xsubi[2];
+ return(d*SCALE);
+}
+
+extern long jrand48(unsigned short xsubi[3])
+{
+ long u;
+ multadd(xsubi,a,c);
+ u = (xsubi[0]<<16) | xsubi[1];
+ return((long)u);
+}
+
+extern void lcong48(unsigned short param[7])
+{
+ X[0] = param[0];
+ X[1] = param[1];
+ X[2] = param[2];
+ a[0] = param[3];
+ a[1] = param[4];
+ a[2] = param[5];
+ c = param[6];
+}
+
+extern long lrand48(void)
+{
+ long l;
+ multadd(X,a,c);
+ l = (X[0]<<15)|(X[1]>>1);
+ return(l);
+}
+
+extern long mrand48(void)
+{
+ unsigned long u;
+ multadd(X,a,c);
+ u = (X[0]<<16) | X[1];
+ return((long)u);
+}
+
+extern long nrand48(unsigned short xsubi[3])
+{
+ long l;
+ multadd(xsubi,a,c);
+ l = (xsubi[0]<<15)|(xsubi[1]>>1);
+ return(l);
+}
+
+extern unsigned short *seed48(unsigned short seed[3])
+{
+ unsigned short *sp = (unsigned short*)&X;
+ a[0] = A0;
+ a[1] = A1;
+ a[2] = A2;
+ c = C;
+ oldval[0] = X[2];
+ oldval[1] = X[1];
+ oldval[2] = X[0];
+ X[0] = seed[2];
+ X[1] = seed[1];
+ X[2] = seed[0];
+ return(oldval);
+}
+
+extern void srand48(long seedval)
+{
+ a[0] = A0;
+ a[1] = A1;
+ a[2] = A2;
+ c = C;
+ X[0] = (unsigned short)(((unsigned long)seedval) >> 16);
+ X[1] = (unsigned short)seedval;
+ X[2] = XINIT;
+}
+
+#endif
diff --git a/src/lib/libast/uwin/random.c b/src/lib/libast/uwin/random.c
new file mode 100644
index 0000000..6b46d63
--- /dev/null
+++ b/src/lib/libast/uwin/random.c
@@ -0,0 +1,381 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_random
+
+void _STUB_random(){}
+
+#else
+
+/*
+ * Copyright (c) 1983
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This is derived from the Berkeley source:
+ * @(#)random.c 5.5 (Berkeley) 7/6/88
+ * It was reworked for the GNU C Library by Roland McGrath.
+ */
+
+#define initstate ______initstate
+#define random ______random
+#define setstate ______setstate
+#define srandom ______srandom
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+#undef initstate
+#undef random
+#undef setstate
+#undef srandom
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern long int random();
+
+#define PTR char*
+
+/* An improved random number generation package. In addition to the standard
+ rand()/srand() like interface, this package also has a special state info
+ interface. The initstate() routine is called with a seed, an array of
+ bytes, and a count of how many bytes are being passed in; this array is
+ then initialized to contain information for random number generation with
+ that much state information. Good sizes for the amount of state
+ information are 32, 64, 128, and 256 bytes. The state can be switched by
+ calling the setstate() function with the same array as was initiallized
+ with initstate(). By default, the package runs with 128 bytes of state
+ information and generates far better random numbers than a linear
+ congruential generator. If the amount of state information is less than
+ 32 bytes, a simple linear congruential R.N.G. is used. Internally, the
+ state information is treated as an array of longs; the zeroeth element of
+ the array is the type of R.N.G. being used (small integer); the remainder
+ of the array is the state information for the R.N.G. Thus, 32 bytes of
+ state information will give 7 longs worth of state information, which will
+ allow a degree seven polynomial. (Note: The zeroeth word of state
+ information also has some other information stored in it; see setstate
+ for details). The random number generation technique is a linear feedback
+ shift register approach, employing trinomials (since there are fewer terms
+ to sum up that way). In this approach, the least significant bit of all
+ the numbers in the state table will act as a linear feedback shift register,
+ and will have period 2^deg - 1 (where deg is the degree of the polynomial
+ being used, assuming that the polynomial is irreducible and primitive).
+ The higher order bits will have longer periods, since their values are
+ also influenced by pseudo-random carries out of the lower bits. The
+ total period of the generator is approximately deg*(2**deg - 1); thus
+ doubling the amount of state information has a vast influence on the
+ period of the generator. Note: The deg*(2**deg - 1) is an approximation
+ only good for large deg, when the period of the shift register is the
+ dominant factor. With deg equal to seven, the period is actually much
+ longer than the 7*(2**7 - 1) predicted by this formula. */
+
+
+
+/* For each of the currently supported random number generators, we have a
+ break value on the amount of state information (you need at least thi
+ bytes of state info to support this random number generator), a degree for
+ the polynomial (actually a trinomial) that the R.N.G. is based on, and
+ separation between the two lower order coefficients of the trinomial. */
+
+/* Linear congruential. */
+#define TYPE_0 0
+#define BREAK_0 8
+#define DEG_0 0
+#define SEP_0 0
+
+/* x**7 + x**3 + 1. */
+#define TYPE_1 1
+#define BREAK_1 32
+#define DEG_1 7
+#define SEP_1 3
+
+/* x**15 + x + 1. */
+#define TYPE_2 2
+#define BREAK_2 64
+#define DEG_2 15
+#define SEP_2 1
+
+/* x**31 + x**3 + 1. */
+#define TYPE_3 3
+#define BREAK_3 128
+#define DEG_3 31
+#define SEP_3 3
+
+/* x**63 + x + 1. */
+#define TYPE_4 4
+#define BREAK_4 256
+#define DEG_4 63
+#define SEP_4 1
+
+
+/* Array versions of the above information to make code run faster.
+ Relies on fact that TYPE_i == i. */
+
+#define MAX_TYPES 5 /* Max number of types above. */
+
+static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
+static int seps[MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
+
+
+
+/* Initially, everything is set up as if from:
+ initstate(1, randtbl, 128);
+ Note that this initialization takes advantage of the fact that srandom
+ advances the front and rear pointers 10*rand_deg times, and hence the
+ rear pointer which starts at 0 will also end up at zero; thus the zeroeth
+ element of the state information, which contains info about the current
+ position of the rear pointer is just
+ (MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3. */
+
+static long int randtbl[DEG_3 + 1] =
+ {
+ TYPE_3,
+ -851904987, -43806228, -2029755270, 1390239686, -1912102820,
+ -485608943, 1969813258, -1590463333, -1944053249, 455935928, 508023712,
+ -1714531963, 1800685987, -2015299881, 654595283, -1149023258,
+ -1470005550, -1143256056, -1325577603, -1568001885, 1275120390,
+ -607508183, -205999574, -1696891592, 1492211999, -1528267240,
+ -952028296, -189082757, 362343714, 1424981831, 2039449641,
+ };
+
+/* FPTR and RPTR are two pointers into the state info, a front and a rear
+ pointer. These two pointers are always rand_sep places aparts, as they
+ cycle through the state information. (Yes, this does mean we could get
+ away with just one pointer, but the code for random is more efficient
+ this way). The pointers are left positioned as they would be from the call:
+ initstate(1, randtbl, 128);
+ (The position of the rear pointer, rptr, is really 0 (as explained above
+ in the initialization of randtbl) because the state table pointer is set
+ to point to randtbl[1] (as explained below).) */
+
+static long int *fptr = &randtbl[SEP_3 + 1];
+static long int *rptr = &randtbl[1];
+
+
+
+/* The following things are the pointer to the state information table,
+ the type of the current generator, the degree of the current polynomial
+ being used, and the separation between the two pointers.
+ Note that for efficiency of random, we remember the first location of
+ the state information, not the zeroeth. Hence it is valid to access
+ state[-1], which is used to store the type of the R.N.G.
+ Also, we remember the last location, since this is more efficient than
+ indexing every time to find the address of the last element to see if
+ the front and rear pointers have wrapped. */
+
+static long int *state = &randtbl[1];
+
+static int rand_type = TYPE_3;
+static int rand_deg = DEG_3;
+static int rand_sep = SEP_3;
+
+static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
+
+/* Initialize the random number generator based on the given seed. If the
+ type is the trivial no-state-information type, just remember the seed.
+ Otherwise, initializes state[] based on the given "seed" via a linear
+ congruential generator. Then, the pointers are set to known locations
+ that are exactly rand_sep places apart. Lastly, it cycles the state
+ information a given number of times to get rid of any initial dependencies
+ introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
+ for default usage relies on values produced by this routine. */
+extern void srandom(unsigned int x)
+{
+ state[0] = x;
+ if (rand_type != TYPE_0)
+ {
+ register long int i;
+ for (i = 1; i < rand_deg; ++i)
+ state[i] = (1103515145 * state[i - 1]) + 12345;
+ fptr = &state[rand_sep];
+ rptr = &state[0];
+ for (i = 0; i < 10 * rand_deg; ++i)
+ (void) random();
+ }
+}
+
+/* Initialize the state information in the given array of N bytes for
+ future random number generation. Based on the number of bytes we
+ are given, and the break values for the different R.N.G.'s, we choose
+ the best (largest) one we can and set things up for it. srandom is
+ then called to initialize the state information. Note that on return
+ from srandom, we set state[-1] to be the type multiplexed with the current
+ value of the rear pointer; this is so successive calls to initstate won't
+ lose this information and will be able to restart with setstate.
+ Note: The first thing we do is save the current state, if any, just like
+ setstate so that it doesn't matter when initstate is called.
+ Returns a pointer to the old state. */
+extern char* initstate(unsigned int seed, char* arg_state, size_t n)
+{
+ PTR ostate = (PTR) &state[-1];
+
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
+ if (n < BREAK_1)
+ {
+ if (n < BREAK_0)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+ rand_type = TYPE_0;
+ rand_deg = DEG_0;
+ rand_sep = SEP_0;
+ }
+ else if (n < BREAK_2)
+ {
+ rand_type = TYPE_1;
+ rand_deg = DEG_1;
+ rand_sep = SEP_1;
+ }
+ else if (n < BREAK_3)
+ {
+ rand_type = TYPE_2;
+ rand_deg = DEG_2;
+ rand_sep = SEP_2;
+ }
+ else if (n < BREAK_4)
+ {
+ rand_type = TYPE_3;
+ rand_deg = DEG_3;
+ rand_sep = SEP_3;
+ }
+ else
+ {
+ rand_type = TYPE_4;
+ rand_deg = DEG_4;
+ rand_sep = SEP_4;
+ }
+
+ state = &((long int *) arg_state)[1]; /* First location. */
+ /* Must set END_PTR before srandom. */
+ end_ptr = &state[rand_deg];
+ srandom(seed);
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
+
+ return ostate;
+}
+
+/* Restore the state from the given state array.
+ Note: It is important that we also remember the locations of the pointers
+ in the current state information, and restore the locations of the pointers
+ from the old state information. This is done by multiplexing the pointer
+ location into the zeroeth word of the state information. Note that due
+ to the order in which things are done, it is OK to call setstate with the
+ same state as the current state
+ Returns a pointer to the old state information. */
+extern char *setstate(const char *arg_state)
+{
+ register long int *new_state = (long int *) arg_state;
+ register int type = new_state[0] % MAX_TYPES;
+ register int rear = new_state[0] / MAX_TYPES;
+ PTR ostate = (PTR) &state[-1];
+
+ if (rand_type == TYPE_0)
+ state[-1] = rand_type;
+ else
+ state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
+
+ switch (type)
+ {
+ case TYPE_0:
+ case TYPE_1:
+ case TYPE_2:
+ case TYPE_3:
+ case TYPE_4:
+ rand_type = type;
+ rand_deg = degrees[type];
+ rand_sep = seps[type];
+ break;
+ default:
+ /* State info munged. */
+ errno = EINVAL;
+ return NULL;
+ }
+
+ state = &new_state[1];
+ if (rand_type != TYPE_0)
+ {
+ rptr = &state[rear];
+ fptr = &state[(rear + rand_sep) % rand_deg];
+ }
+ /* Set end_ptr too. */
+ end_ptr = &state[rand_deg];
+
+ return ostate;
+}
+
+/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
+ congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
+ same in all ther other cases due to all the global variables that have been
+ set up. The basic operation is to add the number at the rear pointer into
+ the one at the front pointer. Then both pointers are advanced to the next
+ location cyclically in the table. The value returned is the sum generated,
+ reduced to 31 bits by throwing away the "least random" low bit.
+ Note: The code takes advantage of the fact that both the front and
+ rear pointers can't wrap on the same call by not testing the rear
+ pointer if the front one has wrapped. Returns a 31-bit random number. */
+
+extern long int random()
+{
+ if (rand_type == TYPE_0)
+ {
+ state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX;
+ return state[0];
+ }
+ else
+ {
+ long int i;
+ *fptr += *rptr;
+ /* Chucking least random bit. */
+ i = (*fptr >> 1) & LONG_MAX;
+ ++fptr;
+ if (fptr >= end_ptr)
+ {
+ fptr = state;
+ ++rptr;
+ }
+ else
+ {
+ ++rptr;
+ if (rptr >= end_ptr)
+ rptr = state;
+ }
+ return i;
+ }
+}
+
+#endif
diff --git a/src/lib/libast/uwin/rcmd.c b/src/lib/libast/uwin/rcmd.c
new file mode 100644
index 0000000..af29684
--- /dev/null
+++ b/src/lib/libast/uwin/rcmd.c
@@ -0,0 +1,571 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_rcmd
+
+void _STUB_rcmd(){}
+
+#else
+
+/*
+ * Copyright (c) 1983
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)rcmd.c 5.17 (Berkeley) 6/27/88";
+#endif /* LIBC_SCCS and not lint */
+
+#include "rlib.h"
+#include <pwd.h>
+#include <sys/file.h>
+#include <sys/signal.h>
+#if 1
+#define _PATH_HEQUIV "/etc/hosts.equiv"
+#endif
+#include <sys/stat.h>
+
+#if NLS
+#include "nl_types.h"
+#endif
+
+#ifdef YP
+#include <rpcsvc/ypclnt.h>
+extern void setnetgrent(const char *);
+extern void endnetgrent(void);
+extern int getnetgrent(char **, char **, char **);
+static char *nisdomain = NULL;
+static int _checknetgrouphost(const char *, const char *, int);
+static int _checknetgroupuser(const char *, const char *);
+#endif
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+extern int rresvport(int *alport)
+{
+ struct sockaddr_in sin;
+ int s;
+
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+ s = socket(AF_INET, SOCK_STREAM, 0);
+ if (s < 0)
+ return (-1);
+ for (;;) {
+ sin.sin_port = htons((u_short)*alport);
+ if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
+ return (s);
+ if (errno != EADDRINUSE) {
+ (void) close(s);
+ return (-1);
+ }
+ (*alport)--;
+ if (*alport == IPPORT_RESERVED/2) {
+ (void) close(s);
+ errno = EAGAIN; /* close */
+ return (-1);
+ }
+ }
+}
+
+extern int rcmd(char **ahost, unsigned short rport, const char *locuser, const char *remuser, const char *cmd, int *fd2p)
+{
+ int s, timo = 1;
+#ifdef F_SETOWN
+ pid_t pid;
+#endif
+#ifdef _POSIX_SOURCE
+ sigset_t set, oset;
+#else
+ long oldmask;
+#endif
+ struct sockaddr_in sin, from;
+ char c;
+ int lport = IPPORT_RESERVED - 1;
+ struct hostent *hp;
+
+#if NLS
+ libc_nls_init();
+#endif
+
+#ifdef F_SETOWN
+ pid = getpid();
+#endif
+ hp = gethostbyname(*ahost);
+ if (hp == 0) {
+#if NLS
+ fprintf(stderr, "%s: %s\n", *ahost,
+ catgets(_libc_cat, HerrorListSet,
+ 2, "unknown host"));
+#else
+ fprintf(stderr, "%s: unknown host\n", *ahost);
+#endif
+ return (-1);
+ }
+ *ahost = hp->h_name;
+#ifdef SIGURG
+#ifdef _POSIX_SOURCE
+ sigemptyset (&set);
+ sigaddset (&set, SIGURG);
+ sigprocmask (SIG_BLOCK, &set, &oset);
+#else
+ oldmask = sigblock(sigmask(SIGURG));
+#endif
+#endif
+ for (;;) {
+ s = rresvport(&lport);
+ if (s < 0) {
+ if (errno == EAGAIN)
+#if NLS
+ fprintf(stderr, "socket: %s\n",
+ catgets(_libc_cat, NetMiscSet,
+ NetMiscAllPortsInUse,
+ "All ports in use"));
+#else
+ fprintf(stderr, "socket: All ports in use\n");
+#endif
+ else
+#if NLS
+ perror(catgets(_libc_cat, NetMiscSet,
+ NetMiscRcmdSocket,
+ "rcmd: socket"));
+#else
+perror("rcmd: socket");
+#endif
+#ifdef SIGURG
+#ifdef _POSIX_SOURCE
+sigprocmask (SIG_SETMASK, &oset,
+(sigset_t *)NULL);
+#else
+sigsetmask(oldmask);
+#endif
+#endif
+return (-1);
+ }
+#ifdef F_SETOWN
+ fcntl(s, F_SETOWN, pid);
+#endif
+ sin.sin_family = hp->h_addrtype;
+ bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length);
+ sin.sin_port = rport;
+ if (connect(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
+ break;
+ (void) close(s);
+ if (errno == EADDRINUSE) {
+ lport--;
+ continue;
+ }
+ if (errno == ECONNREFUSED && timo <= 16) {
+ sleep(timo);
+ timo *= 2;
+ continue;
+ }
+ if (hp->h_addr_list[1] != NULL) {
+ int oerrno = errno;
+
+ fprintf(stderr,
+#if NLS
+ "%s %s: ", catgets(_libc_cat, NetMiscSet,
+ NetMiscAllPortsInUse,
+ "connect to address"),
+ inet_ntoa(sin.sin_addr));
+
+#else
+
+ "connect to address %s: ", inet_ntoa(sin.sin_addr));
+#endif
+ errno = oerrno;
+ perror(0);
+ hp->h_addr_list++;
+ bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr,
+ hp->h_length);
+
+#if NLS
+ fprintf(stderr, catgets(_libc_cat, NetMiscSet,
+ NetMiscTrying,
+ "Trying %s...\n"),
+#else
+ fprintf(stderr, "Trying %s...\n",
+#endif
+ inet_ntoa(sin.sin_addr));
+ continue;
+ }
+ perror(hp->h_name);
+#ifdef SIGURG
+#ifdef _POSIX_SOURCE
+ sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
+#else
+ sigsetmask(oldmask);
+#endif
+#endif
+ return (-1);
+ }
+ lport--;
+ if (fd2p == 0) {
+ write(s, "", 1);
+ lport = 0;
+ } else {
+ char num[8];
+ int s2 = rresvport(&lport), s3;
+ int len = sizeof (from);
+
+ if (s2 < 0)
+ goto bad;
+ listen(s2, 1);
+ (void) snprintf(num, sizeof(num), "%d", lport);
+ if (write(s, num, strlen(num)+1) != strlen(num)+1) {
+#if NLS
+ perror(catgets(_libc_cat, NetMiscSet,
+ NetMiscSettingUpStderr,
+ "write: setting up stderr"));
+#else
+ perror("write: setting up stderr");
+#endif
+ (void) close(s2);
+ goto bad;
+ }
+ s3 = accept(s2, (struct sockaddr *)&from, &len);
+ (void) close(s2);
+ if (s3 < 0) {
+#if NLS
+ perror(catgets(_libc_cat, NetMiscSet,
+ NetMiscAccept,
+ "accept"));
+#else
+ perror("accept");
+#endif
+ lport = 0;
+ goto bad;
+ }
+ *fd2p = s3;
+ from.sin_port = ntohs((u_short)from.sin_port);
+ if (from.sin_family != AF_INET ||
+ from.sin_port >= IPPORT_RESERVED) {
+ fprintf(stderr,
+#if NLS
+ "%s\n",
+ catgets(_libc_cat, NetMiscSet,
+ NetMiscProtocolFailure,
+ "socket: protocol failure in circuit setup."));
+#else
+ "socket: protocol failure in circuit setup.\n");
+#endif
+ goto bad2;
+ }
+ }
+ (void) write(s, locuser, strlen(locuser)+1);
+ (void) write(s, remuser, strlen(remuser)+1);
+ (void) write(s, cmd, strlen(cmd)+1);
+ if (read(s, &c, 1) != 1) {
+ perror(*ahost);
+ goto bad2;
+ }
+ if (c != 0) {
+ while (read(s, &c, 1) == 1) {
+ (void) write(2, &c, 1);
+ if (c == '\n')
+ break;
+ }
+ goto bad2;
+ }
+#ifdef SIGURG
+#ifdef _POSIX_SOURCE
+ sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
+#else
+ sigsetmask(oldmask);
+#endif
+#endif
+ return (s);
+bad2:
+ if (lport)
+ (void) close(*fd2p);
+bad:
+ (void) close(s);
+#ifdef SIGURG
+#ifdef _POSIX_SOURCE
+ sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
+#else
+ sigsetmask(oldmask);
+#endif
+#endif
+ return (-1);
+}
+
+extern int ruserok(const char *rhost, int superuser, const char *ruser, const char *luser)
+{
+ FILE *hostf;
+ char fhost[MAXHOSTNAMELEN];
+ int first = 1;
+ register const char *sp;
+ register char *p;
+ int baselen = -1;
+ uid_t saveuid;
+
+ saveuid = geteuid();
+ sp = rhost;
+ p = fhost;
+ while (*sp) {
+ if (*sp == '.') {
+ if (baselen == -1)
+ baselen = sp - rhost;
+ *p++ = *sp++;
+ } else {
+ *p++ = isupper(*sp) ? tolower(*sp++) : *sp++;
+ }
+ }
+ *p = '\0';
+ hostf = superuser ? (FILE *)0 : fopen(_PATH_HEQUIV, "r");
+again:
+ if (hostf) {
+ if (!_validuser(hostf, fhost, luser, ruser, baselen)) {
+ (void) fclose(hostf);
+ seteuid(saveuid);
+ return(0);
+ }
+ (void) fclose(hostf);
+ }
+ if (first == 1) {
+ struct stat sbuf;
+ struct passwd *pwd;
+ char pbuf[MAXPATHLEN];
+
+ first = 0;
+ if ((pwd = getpwnam(luser)) == NULL)
+ return(-1);
+ (void)strcpy(pbuf, pwd->pw_dir);
+ (void)strcat(pbuf, "/.rhosts");
+ (void)seteuid(pwd->pw_uid);
+ if ((hostf = fopen(pbuf, "r")) == NULL) {
+ seteuid(saveuid);
+ return(-1);
+ }
+ (void)fstat(fileno(hostf), &sbuf);
+ if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) {
+ fclose(hostf);
+ seteuid(saveuid);
+ return(-1);
+ }
+ goto again;
+ }
+ seteuid(saveuid);
+ return (-1);
+}
+
+int
+_validuser(FILE *hostf, const char *rhost, const char *luser,
+const char *ruser, int baselen)
+{
+ char *user;
+ char ahost[MAXHOSTNAMELEN];
+ register char *p;
+ int hostvalid = 0;
+ int uservalid = 0;
+
+ while (fgets(ahost, sizeof (ahost), hostf)) {
+ /* We need to get rid of all comments. */
+ p = strchr (ahost, '#');
+ if (p) *p = '\0';
+ p = ahost;
+ while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
+ *p = isupper(*p) ? tolower(*p) : *p;
+ p++;
+ }
+ if (*p == ' ' || *p == '\t') {
+ *p++ = '\0';
+ while (*p == ' ' || *p == '\t')
+ p++;
+ user = p;
+ while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
+ p++;
+ } else
+ user = p;
+ *p = '\0';
+ /* Adding new authentication -Nilendu */
+
+ /* enable all host for + entry */
+ if ('+' == ahost[0] && '\0' == ahost[1] )
+ hostvalid = 1;
+
+ /* enable all user for + entry */
+ if ('+' == user[0] && '\0' == user[1] )
+ uservalid = 1;
+
+ /* disable all host for - entry */
+ if ('-' == ahost[0] && '\0' == ahost[1] )
+ hostvalid = 0;
+
+ /* disable all user for - entry */
+ if ('-' == user[0] && '\0' == user[1] )
+ uservalid = 0;
+
+
+#ifdef YP
+ /* disable host from -hostname entry */
+ if ('-' == ahost[0] && '@' != ahost[1]
+ && _checkhost(rhost, &ahost[1], baselen))
+ return -1;
+ /* disable host from -@netgroup entry for host */
+ if ('-' == ahost[0] && '@' == ahost[1] && '\0' != ahost[2]
+ && _checknetgrouphost(rhost, &ahost[2], baselen))
+ return -1;
+ /* disable user from -user entry */
+ if ('\0' != *user && user[0] == '-' && user[1] != '@'
+ && !strcmp(&user[1], ruser))
+ return -1;
+ /* disable user from -@netgroup entry for user */
+ if ('\0' != *user && user[0] == '-' && user[1] == '@'
+ && user[2] != '\0' && _checknetgroupuser(ruser, &user[2]))
+ return -1;
+ /* enable host from +@netgroup entry for host */
+ if ('+' == ahost[0] && '@' == ahost[1] && '\0' != ahost[2])
+ hostvalid = _checknetgrouphost(rhost, &ahost[2], baselen);
+ else
+ hostvalid = _checkhost(rhost, ahost, baselen);
+ /* enable user from +@netgroup entry for user */
+ if ('\0' != *user && user[0] == '+'
+ && user[1] == '@' && user[2] != '\0')
+ uservalid = _checknetgroupuser(ruser, &user[2]);
+ else
+ uservalid = !strcmp(ruser, *user ? user : luser);
+
+ if (hostvalid && uservalid)
+ return 0;
+#else
+ hostvalid = hostvalid ? 1 : _checkhost(rhost, ahost, baselen);
+ uservalid = uservalid ? 1 : !stricmp(ruser,*user ? user : luser);
+ if (hostvalid && uservalid)
+ return 0;
+
+#endif /* YP */
+ hostvalid = uservalid = 0;
+ }
+ return (-1);
+}
+
+int
+_checkhost(const char *rhost, const char *lhost, int len)
+{
+ static char ldomain[MAXHOSTNAMELEN + 1];
+ static char *domainp = NULL;
+ static int nodomain = 0;
+ register char *cp;
+
+ if (len == -1)
+ return(!strcmp(rhost, lhost));
+ if (strncmp(rhost, lhost, len))
+ return(0);
+ if (!strcmp(rhost, lhost))
+ return(1);
+ if (*(lhost + len) != '\0')
+ return(0);
+ if (nodomain)
+ return(0);
+ if (!domainp) {
+ if (gethostname(ldomain, sizeof(ldomain)) == -1) {
+ nodomain = 1;
+ return(0);
+ }
+ ldomain[MAXHOSTNAMELEN] = (char) 0;
+ if ((domainp = index(ldomain, '.')) == (char *)NULL) {
+ nodomain = 1;
+ return(0);
+ }
+ for (cp = ++domainp; *cp; ++cp)
+ if (isupper(*cp))
+ *cp = tolower(*cp);
+ }
+ return(!strcmp(domainp, rhost + len +1));
+}
+
+#ifdef YP
+static int
+_checknetgrouphost(const char *rhost, const char *netgr, int baselen)
+{
+ char *host, *user, *domain;
+ int status;
+
+ if (NULL == nisdomain)
+ yp_get_default_domain(&nisdomain);
+
+ setnetgrent(netgr);
+ while (1)
+ {
+ while (1 == (status = getnetgrent(&host, &user, &domain))
+ && NULL == host
+ && NULL != domain
+ && 0 != strcmp(domain, nisdomain))
+ ; /* find valid host entry */
+
+ if (0 == status || NULL == host)
+ {
+ endnetgrent();
+ return 0;
+ }
+
+ if(1 == _checkhost(rhost, host, baselen))
+ {
+ endnetgrent();
+ return 1;
+ }
+ }
+}
+
+static int
+_checknetgroupuser(const char *ruser, const char *netgr)
+{
+ char *host, *user, *domain;
+ int status;
+
+ if (NULL == nisdomain)
+ yp_get_default_domain(&nisdomain);
+
+ setnetgrent(netgr);
+ while (1)
+ {
+ while (1 == (status = getnetgrent(&host, &user, &domain))
+ && NULL == user
+ && NULL != domain
+ && 0 != strcmp(domain, nisdomain))
+ ; /* find valid user entry */
+
+ if (0 == status || NULL == user)
+ {
+ endnetgrent();
+ return 0;
+ }
+
+ if(0 == strcmp(ruser, user))
+ {
+ endnetgrent();
+ return 1;
+ }
+ }
+}
+#endif /* YP */
+
+#endif
diff --git a/src/lib/libast/uwin/rint.c b/src/lib/libast/uwin/rint.c
new file mode 100644
index 0000000..9c88011
--- /dev/null
+++ b/src/lib/libast/uwin/rint.c
@@ -0,0 +1,41 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "FEATURE/uwin"
+
+#if !_UWIN || _lib_ceil && _lib_floor && _lib_rint
+
+void _STUB_rint(){}
+
+#else
+
+#include <math.h>
+
+extern double rint(x)
+double x;
+{
+ double d = floor((x+=.5));
+ if(d==x && d/2.!=floor(d/2))
+ d = d-1;
+ return(d);
+}
+
+#endif
diff --git a/src/lib/libast/uwin/rlib.h b/src/lib/libast/uwin/rlib.h
new file mode 100644
index 0000000..bb9738b
--- /dev/null
+++ b/src/lib/libast/uwin/rlib.h
@@ -0,0 +1,80 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include <ast_std.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <ctype.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/time.h>
+
+#if 0
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <net/if.h>
+#include <linux/sockios.h>
+#endif
+
+#ifndef sigmask
+#define sigmask(n) ((unsigned long)1 << ((n) - 1))
+#endif
+
+extern void _sethtent(int f);
+extern void _endhtent(void);
+extern struct hostent *_gethtent(void);
+extern struct hostent *_gethtbyname(const char *name);
+extern struct hostent *_gethtbyaddr(const char *addr, int len,
+ int type);
+extern int _validuser(FILE *hostf, const char *rhost,
+ const char *luser, const char *ruser, int baselen);
+extern int _checkhost(const char *rhost, const char *lhost, int len);
+
+#if 0
+extern void putlong(u_long l, u_char *msgp);
+extern void putshort(u_short l, u_char *msgp);
+extern u_int32_t _getlong(register const u_char *msgp);
+extern u_int16_t _getshort(register const u_char *msgp);
+extern void p_query(char *msg);
+extern void fp_query(char *msg, FILE *file);
+extern char *p_cdname(char *cp, char *msg, FILE *file);
+extern char *p_rr(char *cp, char *msg, FILE *file);
+extern char *p_type(int type);
+extern char * p_class(int class);
+extern char *p_time(u_long value);
+#endif
+
+extern char * hostalias(const char *name);
+extern void sethostfile(char *name);
+extern void _res_close (void);
+extern void ruserpass(const char *host, char **aname, char **apass);
+extern char* index(const char*, int);
+extern int strcasecmp(const char*, const char*);
+extern void bcopy(const void*, void*, size_t);
diff --git a/src/lib/libast/uwin/support.c b/src/lib/libast/uwin/support.c
new file mode 100644
index 0000000..769444e
--- /dev/null
+++ b/src/lib/libast/uwin/support.c
@@ -0,0 +1,605 @@
+#include "FEATURE/uwin"
+
+#if !_UWIN || (_lib__copysign||_lib_copysign) && _lib_logb && (_lib__finite||_lib_finite) && (_lib_drem||_lib_remainder) && _lib_sqrt && _lib_ilogb && (_lib__scalb||_lib_scalb)
+
+void _STUB_support(){}
+
+#else
+
+/*
+ * Copyright (c) 1985, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)support.c 8.1 (Berkeley) 6/4/93";
+#endif /* not lint */
+
+/*
+ * Some IEEE standard 754 recommended functions and remainder and sqrt for
+ * supporting the C elementary functions.
+ ******************************************************************************
+ * WARNING:
+ * These codes are developed (in double) to support the C elementary
+ * functions temporarily. They are not universal, and some of them are very
+ * slow (in particular, drem and sqrt is extremely inefficient). Each
+ * computer system should have its implementation of these functions using
+ * its own assembler.
+ ******************************************************************************
+ *
+ * IEEE 754 required operations:
+ * drem(x,p)
+ * returns x REM y = x - [x/y]*y , where [x/y] is the integer
+ * nearest x/y; in half way case, choose the even one.
+ * sqrt(x)
+ * returns the square root of x correctly rounded according to
+ * the rounding mod.
+ *
+ * IEEE 754 recommended functions:
+ * (a) copysign(x,y)
+ * returns x with the sign of y.
+ * (b) scalb(x,N)
+ * returns x * (2**N), for integer values N.
+ * (c) logb(x)
+ * returns the unbiased exponent of x, a signed integer in
+ * double precision, except that logb(0) is -INF, logb(INF)
+ * is +INF, and logb(NAN) is that NAN.
+ * (d) finite(x)
+ * returns the value TRUE if -INF < x < +INF and returns
+ * FALSE otherwise.
+ *
+ *
+ * CODED IN C BY K.C. NG, 11/25/84;
+ * REVISED BY K.C. NG on 1/22/85, 2/13/85, 3/24/85.
+ */
+
+#include "mathimpl.h"
+
+#if defined(vax)||defined(tahoe) /* VAX D format */
+#include <errno.h>
+ static const unsigned short msign=0x7fff , mexp =0x7f80 ;
+ static const short prep1=57, gap=7, bias=129 ;
+ static const double novf=1.7E38, nunf=3.0E-39, zero=0.0 ;
+#else /* defined(vax)||defined(tahoe) */
+ static const unsigned short msign=0x7fff, mexp =0x7ff0 ;
+ static const short prep1=54, gap=4, bias=1023 ;
+ static const double novf=1.7E308, nunf=3.0E-308,zero=0.0;
+#endif /* defined(vax)||defined(tahoe) */
+
+#if !_lib__scalb || !_lib_scalb
+
+extern double _scalb(x,N)
+double x; double N;
+{
+ int k;
+
+#ifdef national
+ unsigned short *px=(unsigned short *) &x + 3;
+#else /* national */
+ unsigned short *px=(unsigned short *) &x;
+#endif /* national */
+
+ if( x == zero ) return(x);
+
+#if defined(vax)||defined(tahoe)
+ if( (k= *px & mexp ) != ~msign ) {
+ if (N < -260)
+ return(nunf*nunf);
+ else if (N > 260) {
+ return(copysign(infnan(ERANGE),x));
+ }
+#else /* defined(vax)||defined(tahoe) */
+ if( (k= *px & mexp ) != mexp ) {
+ if( N<-2100) return(nunf*nunf); else if(N>2100) return(novf+novf);
+ if( k == 0 ) {
+ x *= scalb(1.0,prep1); N -= prep1; return(scalb(x,N));}
+#endif /* defined(vax)||defined(tahoe) */
+
+ if((k = (k>>gap)+ N) > 0 )
+ if( k < (mexp>>gap) ) *px = (*px&~mexp) | (k<<gap);
+ else x=novf+novf; /* overflow */
+ else
+ if( k > -prep1 )
+ /* gradual underflow */
+ {*px=(*px&~mexp)|(short)(1<<gap); x *= scalb(1.0,k-1);}
+ else
+ return(nunf*nunf);
+ }
+ return(x);
+}
+
+#endif
+
+#if !_lib_scalb
+
+extern double scalb(x,N)
+double x; double N;
+{
+ return _scalb(x, N);
+}
+
+#endif
+
+#if !_lib__copysign
+
+extern double _copysign(x,y)
+double x,y;
+{
+#ifdef national
+ unsigned short *px=(unsigned short *) &x+3,
+ *py=(unsigned short *) &y+3;
+#else /* national */
+ unsigned short *px=(unsigned short *) &x,
+ *py=(unsigned short *) &y;
+#endif /* national */
+
+#if defined(vax)||defined(tahoe)
+ if ( (*px & mexp) == 0 ) return(x);
+#endif /* defined(vax)||defined(tahoe) */
+
+ *px = ( *px & msign ) | ( *py & ~msign );
+ return(x);
+}
+
+#endif
+
+#if !_lib_copysign
+
+extern double copysign(x,y)
+double x,y;
+{
+ return _copysign(x,y);
+}
+
+#endif
+
+#if !_lib_logb
+
+extern double logb(x)
+double x;
+{
+
+#ifdef national
+ short *px=(short *) &x+3, k;
+#else /* national */
+ short *px=(short *) &x, k;
+#endif /* national */
+
+#if defined(vax)||defined(tahoe)
+ return (int)(((*px&mexp)>>gap)-bias);
+#else /* defined(vax)||defined(tahoe) */
+ if( (k= *px & mexp ) != mexp )
+ if ( k != 0 )
+ return ( (k>>gap) - bias );
+ else if( x != zero)
+ return ( -1022.0 );
+ else
+ return(-(1.0/zero));
+ else if(x != x)
+ return(x);
+ else
+ {*px &= msign; return(x);}
+#endif /* defined(vax)||defined(tahoe) */
+}
+
+#endif
+
+#if !_lib__finite
+
+extern int _finite(x)
+double x;
+{
+#if defined(vax)||defined(tahoe)
+ return(1);
+#else /* defined(vax)||defined(tahoe) */
+#ifdef national
+ return( (*((short *) &x+3 ) & mexp ) != mexp );
+#else /* national */
+ return( (*((short *) &x ) & mexp ) != mexp );
+#endif /* national */
+#endif /* defined(vax)||defined(tahoe) */
+}
+
+#endif
+
+#if !_lib_finite
+
+extern int finite(x)
+double x;
+{
+ return _finite(x);
+}
+
+#endif
+
+#if !_lib_drem
+
+extern double drem(x,p)
+double x,p;
+{
+#if _lib_remainder
+ return remainder(x,p);
+#else
+ short sign;
+ double hp,dp,tmp;
+ unsigned short k;
+#ifdef national
+ unsigned short
+ *px=(unsigned short *) &x +3,
+ *pp=(unsigned short *) &p +3,
+ *pd=(unsigned short *) &dp +3,
+ *pt=(unsigned short *) &tmp+3;
+#else /* national */
+ unsigned short
+ *px=(unsigned short *) &x ,
+ *pp=(unsigned short *) &p ,
+ *pd=(unsigned short *) &dp ,
+ *pt=(unsigned short *) &tmp;
+#endif /* national */
+
+ *pp &= msign ;
+
+#if defined(vax)||defined(tahoe)
+ if( ( *px & mexp ) == ~msign ) /* is x a reserved operand? */
+#else /* defined(vax)||defined(tahoe) */
+ if( ( *px & mexp ) == mexp )
+#endif /* defined(vax)||defined(tahoe) */
+ return (x-p)-(x-p); /* create nan if x is inf */
+ if (p == zero) {
+#if defined(vax)||defined(tahoe)
+ return(infnan(EDOM));
+#else /* defined(vax)||defined(tahoe) */
+ return zero/zero;
+#endif /* defined(vax)||defined(tahoe) */
+ }
+
+#if defined(vax)||defined(tahoe)
+ if( ( *pp & mexp ) == ~msign ) /* is p a reserved operand? */
+#else /* defined(vax)||defined(tahoe) */
+ if( ( *pp & mexp ) == mexp )
+#endif /* defined(vax)||defined(tahoe) */
+ { if (p != p) return p; else return x;}
+
+ else if ( ((*pp & mexp)>>gap) <= 1 )
+ /* subnormal p, or almost subnormal p */
+ { double b; b=scalb(1.0,(int)prep1);
+ p *= b; x = drem(x,p); x *= b; return(drem(x,p)/b);}
+ else if ( p >= novf/2)
+ { p /= 2 ; x /= 2; return(drem(x,p)*2);}
+ else
+ {
+ dp=p+p; hp=p/2;
+ sign= *px & ~msign ;
+ *px &= msign ;
+ while ( x > dp )
+ {
+ k=(*px & mexp) - (*pd & mexp) ;
+ tmp = dp ;
+ *pt += k ;
+
+#if defined(vax)||defined(tahoe)
+ if( x < tmp ) *pt -= 128 ;
+#else /* defined(vax)||defined(tahoe) */
+ if( x < tmp ) *pt -= 16 ;
+#endif /* defined(vax)||defined(tahoe) */
+
+ x -= tmp ;
+ }
+ if ( x > hp )
+ { x -= p ; if ( x >= hp ) x -= p ; }
+
+#if defined(vax)||defined(tahoe)
+ if (x)
+#endif /* defined(vax)||defined(tahoe) */
+ *px ^= sign;
+ return( x);
+
+ }
+#endif
+}
+
+#endif
+
+#if !_lib_remainder
+
+extern double remainder(x,p)
+double x,p;
+{
+ return drem(x,p);
+}
+
+#endif
+
+#if !_lib_sqrt
+
+extern double sqrt(x)
+double x;
+{
+ double q,s,b,r;
+ double t;
+ double const zero=0.0;
+ int m,n,i;
+#if defined(vax)||defined(tahoe)
+ int k=54;
+#else /* defined(vax)||defined(tahoe) */
+ int k=51;
+#endif /* defined(vax)||defined(tahoe) */
+
+ /* sqrt(NaN) is NaN, sqrt(+-0) = +-0 */
+ if(x!=x||x==zero) return(x);
+
+ /* sqrt(negative) is invalid */
+ if(x<zero) {
+#if defined(vax)||defined(tahoe)
+ return (infnan(EDOM)); /* NaN */
+#else /* defined(vax)||defined(tahoe) */
+ return(zero/zero);
+#endif /* defined(vax)||defined(tahoe) */
+ }
+
+ /* sqrt(INF) is INF */
+ if(!finite(x)) return(x);
+
+ /* scale x to [1,4) */
+ n=logb(x);
+ x=scalb(x,-n);
+ if((m=logb(x))!=0) x=scalb(x,-m); /* subnormal number */
+ m += n;
+ n = m/2;
+ if((n+n)!=m) {x *= 2; m -=1; n=m/2;}
+
+ /* generate sqrt(x) bit by bit (accumulating in q) */
+ q=1.0; s=4.0; x -= 1.0; r=1;
+ for(i=1;i<=k;i++) {
+ t=s+1; x *= 4; r /= 2;
+ if(t<=x) {
+ s=t+t+2, x -= t; q += r;}
+ else
+ s *= 2;
+ }
+
+ /* generate the last bit and determine the final rounding */
+ r/=2; x *= 4;
+ if(x==zero) goto end; 100+r; /* trigger inexact flag */
+ if(s<x) {
+ q+=r; x -=s; s += 2; s *= 2; x *= 4;
+ t = (x-s)-5;
+ b=1.0+3*r/4; if(b==1.0) goto end; /* b==1 : Round-to-zero */
+ b=1.0+r/4; if(b>1.0) t=1; /* b>1 : Round-to-(+INF) */
+ if(t>=0) q+=r; } /* else: Round-to-nearest */
+ else {
+ s *= 2; x *= 4;
+ t = (x-s)-1;
+ b=1.0+3*r/4; if(b==1.0) goto end;
+ b=1.0+r/4; if(b>1.0) t=1;
+ if(t>=0) q+=r; }
+
+end: return(scalb(q,n));
+}
+
+#endif
+
+#if 0
+/* DREM(X,Y)
+ * RETURN X REM Y =X-N*Y, N=[X/Y] ROUNDED (ROUNDED TO EVEN IN THE HALF WAY CASE)
+ * DOUBLE PRECISION (VAX D format 56 bits, IEEE DOUBLE 53 BITS)
+ * INTENDED FOR ASSEMBLY LANGUAGE
+ * CODED IN C BY K.C. NG, 3/23/85, 4/8/85.
+ *
+ * Warning: this code should not get compiled in unless ALL of
+ * the following machine-dependent routines are supplied.
+ *
+ * Required machine dependent functions (not on a VAX):
+ * swapINX(i): save inexact flag and reset it to "i"
+ * swapENI(e): save inexact enable and reset it to "e"
+ */
+
+extern double drem(x,y)
+double x,y;
+{
+
+#ifdef national /* order of words in floating point number */
+ static const n0=3,n1=2,n2=1,n3=0;
+#else /* VAX, SUN, ZILOG, TAHOE */
+ static const n0=0,n1=1,n2=2,n3=3;
+#endif
+
+ static const unsigned short mexp =0x7ff0, m25 =0x0190, m57 =0x0390;
+ static const double zero=0.0;
+ double hy,y1,t,t1;
+ short k;
+ long n;
+ int i,e;
+ unsigned short xexp,yexp, *px =(unsigned short *) &x ,
+ nx,nf, *py =(unsigned short *) &y ,
+ sign, *pt =(unsigned short *) &t ,
+ *pt1 =(unsigned short *) &t1 ;
+
+ xexp = px[n0] & mexp ; /* exponent of x */
+ yexp = py[n0] & mexp ; /* exponent of y */
+ sign = px[n0] &0x8000; /* sign of x */
+
+/* return NaN if x is NaN, or y is NaN, or x is INF, or y is zero */
+ if(x!=x) return(x); if(y!=y) return(y); /* x or y is NaN */
+ if( xexp == mexp ) return(zero/zero); /* x is INF */
+ if(y==zero) return(y/y);
+
+/* save the inexact flag and inexact enable in i and e respectively
+ * and reset them to zero
+ */
+ i=swapINX(0); e=swapENI(0);
+
+/* subnormal number */
+ nx=0;
+ if(yexp==0) {t=1.0,pt[n0]+=m57; y*=t; nx=m57;}
+
+/* if y is tiny (biased exponent <= 57), scale up y to y*2**57 */
+ if( yexp <= m57 ) {py[n0]+=m57; nx+=m57; yexp+=m57;}
+
+ nf=nx;
+ py[n0] &= 0x7fff;
+ px[n0] &= 0x7fff;
+
+/* mask off the least significant 27 bits of y */
+ t=y; pt[n3]=0; pt[n2]&=0xf800; y1=t;
+
+/* LOOP: argument reduction on x whenever x > y */
+loop:
+ while ( x > y )
+ {
+ t=y;
+ t1=y1;
+ xexp=px[n0]&mexp; /* exponent of x */
+ k=xexp-yexp-m25;
+ if(k>0) /* if x/y >= 2**26, scale up y so that x/y < 2**26 */
+ {pt[n0]+=k;pt1[n0]+=k;}
+ n=x/t; x=(x-n*t1)-n*(t-t1);
+ }
+ /* end while (x > y) */
+
+ if(nx!=0) {t=1.0; pt[n0]+=nx; x*=t; nx=0; goto loop;}
+
+/* final adjustment */
+
+ hy=y/2.0;
+ if(x>hy||((x==hy)&&n%2==1)) x-=y;
+ px[n0] ^= sign;
+ if(nf!=0) { t=1.0; pt[n0]-=nf; x*=t;}
+
+/* restore inexact flag and inexact enable */
+ swapINX(i); swapENI(e);
+
+ return(x);
+}
+#endif
+
+#if 0
+/* SQRT
+ * RETURN CORRECTLY ROUNDED (ACCORDING TO THE ROUNDING MODE) SQRT
+ * FOR IEEE DOUBLE PRECISION ONLY, INTENDED FOR ASSEMBLY LANGUAGE
+ * CODED IN C BY K.C. NG, 3/22/85.
+ *
+ * Warning: this code should not get compiled in unless ALL of
+ * the following machine-dependent routines are supplied.
+ *
+ * Required machine dependent functions:
+ * swapINX(i) ...return the status of INEXACT flag and reset it to "i"
+ * swapRM(r) ...return the current Rounding Mode and reset it to "r"
+ * swapENI(e) ...return the status of inexact enable and reset it to "e"
+ * addc(t) ...perform t=t+1 regarding t as a 64 bit unsigned integer
+ * subc(t) ...perform t=t-1 regarding t as a 64 bit unsigned integer
+ */
+
+static const unsigned long table[] = {
+0, 1204, 3062, 5746, 9193, 13348, 18162, 23592, 29598, 36145, 43202, 50740,
+58733, 67158, 75992, 85215, 83599, 71378, 60428, 50647, 41945, 34246, 27478,
+21581, 16499, 12183, 8588, 5674, 3403, 1742, 661, 130, };
+
+extern double newsqrt(x)
+double x;
+{
+ double y,z,t,addc(),subc()
+ double const b54=134217728.*134217728.; /* b54=2**54 */
+ long mx,scalx;
+ long const mexp=0x7ff00000;
+ int i,j,r,e,swapINX(),swapRM(),swapENI();
+ unsigned long *py=(unsigned long *) &y ,
+ *pt=(unsigned long *) &t ,
+ *px=(unsigned long *) &x ;
+#ifdef national /* ordering of word in a floating point number */
+ const int n0=1, n1=0;
+#else
+ const int n0=0, n1=1;
+#endif
+/* Rounding Mode: RN ...round-to-nearest
+ * RZ ...round-towards 0
+ * RP ...round-towards +INF
+ * RM ...round-towards -INF
+ */
+ const int RN=0,RZ=1,RP=2,RM=3;
+ /* machine dependent: work on a Zilog Z8070
+ * and a National 32081 & 16081
+ */
+
+/* exceptions */
+ if(x!=x||x==0.0) return(x); /* sqrt(NaN) is NaN, sqrt(+-0) = +-0 */
+ if(x<0) return((x-x)/(x-x)); /* sqrt(negative) is invalid */
+ if((mx=px[n0]&mexp)==mexp) return(x); /* sqrt(+INF) is +INF */
+
+/* save, reset, initialize */
+ e=swapENI(0); /* ...save and reset the inexact enable */
+ i=swapINX(0); /* ...save INEXACT flag */
+ r=swapRM(RN); /* ...save and reset the Rounding Mode to RN */
+ scalx=0;
+
+/* subnormal number, scale up x to x*2**54 */
+ if(mx==0) {x *= b54 ; scalx-=0x01b00000;}
+
+/* scale x to avoid intermediate over/underflow:
+ * if (x > 2**512) x=x/2**512; if (x < 2**-512) x=x*2**512 */
+ if(mx>0x5ff00000) {px[n0] -= 0x20000000; scalx+= 0x10000000;}
+ if(mx<0x1ff00000) {px[n0] += 0x20000000; scalx-= 0x10000000;}
+
+/* magic initial approximation to almost 8 sig. bits */
+ py[n0]=(px[n0]>>1)+0x1ff80000;
+ py[n0]=py[n0]-table[(py[n0]>>15)&31];
+
+/* Heron's rule once with correction to improve y to almost 18 sig. bits */
+ t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0;
+
+/* triple to almost 56 sig. bits; now y approx. sqrt(x) to within 1 ulp */
+ t=y*y; z=t; pt[n0]+=0x00100000; t+=z; z=(x-z)*y;
+ t=z/(t+x) ; pt[n0]+=0x00100000; y+=t;
+
+/* twiddle last bit to force y correctly rounded */
+ swapRM(RZ); /* ...set Rounding Mode to round-toward-zero */
+ swapINX(0); /* ...clear INEXACT flag */
+ swapENI(e); /* ...restore inexact enable status */
+ t=x/y; /* ...chopped quotient, possibly inexact */
+ j=swapINX(i); /* ...read and restore inexact flag */
+ if(j==0) { if(t==y) goto end; else t=subc(t); } /* ...t=t-ulp */
+ b54+0.1; /* ..trigger inexact flag, sqrt(x) is inexact */
+ if(r==RN) t=addc(t); /* ...t=t+ulp */
+ else if(r==RP) { t=addc(t);y=addc(y);}/* ...t=t+ulp;y=y+ulp; */
+ y=y+t; /* ...chopped sum */
+ py[n0]=py[n0]-0x00100000; /* ...correctly rounded sqrt(x) */
+end: py[n0]=py[n0]+scalx; /* ...scale back y */
+ swapRM(r); /* ...restore Rounding Mode */
+ return(y);
+}
+#endif
+
+#if !_lib_ilogb
+
+extern int ilogb(double x)
+{
+ return((int)logb(x));
+}
+
+#endif
+
+#endif
diff --git a/src/lib/libast/vec/vecargs.c b/src/lib/libast/vec/vecargs.c
new file mode 100644
index 0000000..421ade0
--- /dev/null
+++ b/src/lib/libast/vec/vecargs.c
@@ -0,0 +1,76 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * string vector argv insertion
+ */
+
+#include <ast.h>
+#include <vecargs.h>
+#include <ctype.h>
+
+/*
+ * insert the string vector vec between
+ * (*argvp)[0] and (*argvp)[1], sliding (*argvp)[1] ... over
+ * null and blank args are deleted
+ *
+ * vecfree always called
+ *
+ * -1 returned if insertion failed
+ */
+
+int
+vecargs(register char** vec, int* argcp, char*** argvp)
+{
+ register char** argv;
+ register char** oargv;
+ char** ovec;
+ char* s;
+ int num;
+
+ if (!vec) return(-1);
+ if ((num = (char**)(*(vec - 1)) - vec) > 0)
+ {
+ if (!(argv = newof(0, char*, num + *argcp + 1, 0)))
+ {
+ vecfree(vec, 0);
+ return(-1);
+ }
+ oargv = *argvp;
+ *argvp = argv;
+ *argv++ = *oargv++;
+ ovec = vec;
+ while (s = *argv = *vec++)
+ {
+ while (isspace(*s)) s++;
+ if (*s) argv++;
+ }
+ vecfree(ovec, 1);
+ while (*argv = *oargv++) argv++;
+ *argcp = argv - *argvp;
+ }
+ else vecfree(vec, 0);
+ return(0);
+}
diff --git a/src/lib/libast/vec/vecfile.c b/src/lib/libast/vec/vecfile.c
new file mode 100644
index 0000000..6c6991b
--- /dev/null
+++ b/src/lib/libast/vec/vecfile.c
@@ -0,0 +1,62 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Research
+ *
+ * string vector load support
+ */
+
+#include <ast.h>
+#include <ls.h>
+#include <vecargs.h>
+
+/*
+ * load a string vector from lines in file
+ */
+
+char**
+vecfile(const char* file)
+{
+ register int n;
+ register char* buf;
+ register char** vec;
+ int fd;
+ struct stat st;
+
+ vec = 0;
+ if ((fd = open(file, O_RDONLY)) >= 0)
+ {
+ if (!fstat(fd, &st) && S_ISREG(st.st_mode) && (n = st.st_size) > 0 && (buf = newof(0, char, n + 1, 0)))
+ {
+ if (read(fd, buf, n) == n)
+ {
+ buf[n] = 0;
+ vec = vecload(buf);
+ }
+ if (!vec) free(buf);
+ }
+ close(fd);
+ }
+ return(vec);
+}
diff --git a/src/lib/libast/vec/vecfree.c b/src/lib/libast/vec/vecfree.c
new file mode 100644
index 0000000..12b3bc2
--- /dev/null
+++ b/src/lib/libast/vec/vecfree.c
@@ -0,0 +1,48 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * file to string vector support
+ */
+
+#include <ast.h>
+#include <vecargs.h>
+
+/*
+ * free a string vector generated by vecload()
+ *
+ * retain!=0 frees the string pointers but retains the string data
+ * in this case the data is permanently allocated
+ */
+
+void
+vecfree(register char** vec, int retain)
+{
+ if (vec)
+ {
+ if (*(vec -= 2) && !retain) free(*vec);
+ free(vec);
+ }
+}
diff --git a/src/lib/libast/vec/vecload.c b/src/lib/libast/vec/vecload.c
new file mode 100644
index 0000000..5f83470
--- /dev/null
+++ b/src/lib/libast/vec/vecload.c
@@ -0,0 +1,96 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * string vector load support
+ */
+
+#include <ast.h>
+#include <vecargs.h>
+
+/*
+ * load a string vector from lines in buf
+ * buf may be modified on return
+ *
+ * each line in buf is treated as a new vector element
+ * lines with # as first char are comments
+ * \ as the last char joins consecutive lines
+ *
+ * the vector ends with a 0 sentinel
+ *
+ * the string array pointer is returned
+ */
+
+char**
+vecload(char* buf)
+{
+ register char* s;
+ register int n;
+ register char** p;
+ char** vec;
+
+ vec = 0;
+ n = (*buf == '#') ? -1 : 0;
+ for (s = buf;; s++)
+ {
+ if (*s == '\n')
+ {
+ if (s > buf && *(s - 1) == '\\') *(s - 1) = *s = ' ';
+ else
+ {
+ *s = 0;
+ if (*(s + 1) != '#')
+ {
+ n++;
+ if (!*(s + 1)) break;
+ }
+ }
+ }
+ else if (!*s)
+ {
+ n++;
+ break;
+ }
+ }
+ if (n < 0) n = 0;
+ if (p = newof(0, char*, n + 3, 0))
+ {
+ *p++ = s = buf;
+ vec = ++p;
+ if (n > 0) for (;;)
+ {
+ if (*s != '#')
+ {
+ *p++ = s;
+ if (--n <= 0) break;
+ }
+ while (*s) s++;
+ s++;
+ }
+ *p = 0;
+ *(vec - 1) = (char*)p;
+ }
+ return(vec);
+}
diff --git a/src/lib/libast/vec/vecstring.c b/src/lib/libast/vec/vecstring.c
new file mode 100644
index 0000000..6aeac9d
--- /dev/null
+++ b/src/lib/libast/vec/vecstring.c
@@ -0,0 +1,46 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * Glenn Fowler
+ * AT&T Bell Laboratories
+ *
+ * string vector load support
+ */
+
+#include <ast.h>
+#include <vecargs.h>
+
+/*
+ * load a string vector from lines in str
+ */
+
+char**
+vecstring(const char* str)
+{
+ register char* buf;
+ register char** vec;
+
+ if (!str || !*str || !(buf = strdup(str))) vec = 0;
+ else if (!(vec = vecload(buf))) free(buf);
+ return(vec);
+}
diff --git a/src/lib/libast/vmalloc/malloc.c b/src/lib/libast/vmalloc/malloc.c
new file mode 100644
index 0000000..e69523a
--- /dev/null
+++ b/src/lib/libast/vmalloc/malloc.c
@@ -0,0 +1,1438 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_malloc(){}
+
+#else
+
+#if _UWIN
+
+#define calloc ______calloc
+#define _ast_free ______free
+#define malloc ______malloc
+#define mallinfo ______mallinfo
+#define mallopt ______mallopt
+#define mstats ______mstats
+#define realloc ______realloc
+
+#define _STDLIB_H_ 1
+
+extern int atexit(void(*)(void));
+extern char* getenv(const char*);
+
+#endif
+
+#include "vmhdr.h"
+#include <errno.h>
+
+#if _UWIN
+
+#include <malloc.h>
+
+#define _map_malloc 1
+#define _mal_alloca 1
+
+#undef calloc
+#define calloc _ast_calloc
+#undef _ast_free
+#define free _ast_free
+#undef malloc
+#define malloc _ast_malloc
+#undef mallinfo
+typedef struct ______mallinfo Mallinfo_t;
+#undef mallopt
+#undef mstats
+typedef struct ______mstats Mstats_t;
+#undef realloc
+#define realloc _ast_realloc
+
+#endif
+
+#if __STD_C
+#define F0(f,t0) f(t0)
+#define F1(f,t1,a1) f(t1 a1)
+#define F2(f,t1,a1,t2,a2) f(t1 a1, t2 a2)
+#else
+#define F0(f,t0) f()
+#define F1(f,t1,a1) f(a1) t1 a1;
+#define F2(f,t1,a1,t2,a2) f(a1, a2) t1 a1; t2 a2;
+#endif
+
+/*
+ * define _AST_std_malloc=1 to force the standard malloc
+ * if _map_malloc is also defined then _ast_malloc etc.
+ * will simply call malloc etc.
+ */
+
+#if !defined(_AST_std_malloc) && __CYGWIN__
+#define _AST_std_malloc 1
+#endif
+
+/* malloc compatibility functions
+**
+** These are aware of debugging/profiling and are driven by the
+** VMALLOC_OPTIONS environment variable which is a comma or space
+** separated list of [no]name[=value] options:
+**
+** abort if Vmregion==Vmdebug then VM_DBABORT is set,
+** otherwise _BLD_DEBUG enabled assertions abort()
+** on failure
+** break try sbrk() block allocator first
+** check if Vmregion==Vmbest then the region is checked every op
+** free disable addfreelist()
+** keep disable free -- if code works with this enabled then it
+** probably accesses free'd data
+** method=m sets Vmregion=m if not defined, m (Vm prefix optional)
+** may be one of { best debug last profile }
+** period=n sets Vmregion=Vmdebug if not defined, if
+** Vmregion==Vmdebug the region is checked every n ops
+** profile=f sets Vmregion=Vmprofile if not set, if
+** Vmregion==Vmprofile then profile info printed to file f
+** start=n sets Vmregion=Vmdebug if not defined, if
+** Vmregion==Vmdebug region checking starts after n ops
+** trace=f enables tracing to file f
+** warn=f sets Vmregion=Vmdebug if not defined, if
+** Vmregion==Vmdebug then warnings printed to file f
+** watch=a sets Vmregion=Vmdebug if not defined, if
+** Vmregion==Vmdebug then address a is watched
+**
+** Output files are created if they don't exist. &n and /dev/fd/n name
+** the file descriptor n which must be open for writing. The pattern %p
+** in a file name is replaced by the process ID.
+**
+** VMALLOC_OPTIONS combines the features of these previously used env vars:
+** { VMCHECK VMDEBUG VMETHOD VMPROFILE VMTRACE }
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+
+#if _sys_stat
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+
+#ifdef S_IRUSR
+#define CREAT_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
+#else
+#define CREAT_MODE 0644
+#endif
+
+static Vmulong_t _Vmdbstart = 0;
+static Vmulong_t _Vmdbcheck = 0;
+static Vmulong_t _Vmdbtime = 0;
+static int _Vmpffd = -1;
+
+#if ( !_std_malloc || !_BLD_ast ) && !_AST_std_malloc
+
+#if !_map_malloc
+#undef calloc
+#undef cfree
+#undef free
+#undef mallinfo
+#undef malloc
+#undef mallopt
+#undef memalign
+#undef mstats
+#undef realloc
+#undef valloc
+
+#if _malloc_hook
+
+#include <malloc.h>
+
+#undef calloc
+#undef cfree
+#undef free
+#undef malloc
+#undef memalign
+#undef realloc
+
+#define calloc _ast_calloc
+#define cfree _ast_cfree
+#define free _ast_free
+#define malloc _ast_malloc
+#define memalign _ast_memalign
+#define realloc _ast_realloc
+
+#endif
+
+#endif
+
+#if _WINIX
+
+#include <ast_windows.h>
+
+#if _UWIN
+
+#define VMRECORD(p) _vmrecord(p)
+#define VMBLOCK { int _vmblock = _sigblock();
+#define VMUNBLOCK _sigunblock(_vmblock); }
+
+extern int _sigblock(void);
+extern void _sigunblock(int);
+extern unsigned long _record[2048];
+
+__inline Void_t* _vmrecord(Void_t* p)
+{
+ register unsigned long v = ((unsigned long)p)>>16;
+
+ _record[v>>5] |= 1<<((v&0x1f));
+ return p;
+}
+
+#else
+
+#define getenv(s) lcl_getenv(s)
+
+static char*
+lcl_getenv(const char* s)
+{
+ int n;
+ static char buf[512];
+
+ if (!(n = GetEnvironmentVariable(s, buf, sizeof(buf))) || n > sizeof(buf))
+ return 0;
+ return buf;
+}
+
+#endif /* _UWIN */
+
+#endif /* _WINIX */
+
+#ifndef VMRECORD
+#define VMRECORD(p) (p)
+#define VMBLOCK
+#define VMUNBLOCK
+#endif
+
+#if defined(__EXPORT__)
+#define extern extern __EXPORT__
+#endif
+
+static int _Vmflinit = 0;
+#define VMFLINIT() \
+ { if(!_Vmflinit) vmflinit(); \
+ if(_Vmdbcheck) \
+ { if(_Vmdbtime < _Vmdbstart) _Vmdbtime += 1; \
+ else if((_Vmdbtime += 1) < _Vmdbstart) _Vmdbtime = _Vmdbstart; \
+ if(_Vmdbtime >= _Vmdbstart && (_Vmdbtime % _Vmdbcheck) == 0 && \
+ Vmregion->meth.meth == VM_MTDEBUG) \
+ vmdbcheck(Vmregion); \
+ } \
+ }
+
+#if __STD_C
+static int vmflinit(void)
+#else
+static int vmflinit()
+#endif
+{
+ char* file;
+ int line;
+ Void_t* func;
+
+ /* this must be done now to avoid any inadvertent recursion (more below) */
+ _Vmflinit = 1;
+ VMFLF(Vmregion,file,line,func);
+
+ /* if getenv() calls malloc(), the options may not affect the eventual region */
+ VMOPTIONS();
+
+ /* reset file and line number to correct values for the call */
+ Vmregion->file = file;
+ Vmregion->line = line;
+ Vmregion->func = func;
+
+ return 0;
+}
+
+/* use multiple regions to reduce blocking by concurrent threads */
+#if _mem_mmap_anon || _mem_mmap_zero
+static Vmalloc_t *Region[64]; /* list of concurrent regions */
+static unsigned int Regmax = 64; /* max number of regions */
+#else
+static Vmalloc_t* Region[1]; /* list of concurrent regions */
+static unsigned int Regmax = 0;
+#endif
+static unsigned int Regnum = 0; /* current #concurrent regions */
+
+/* statistics */
+static unsigned int Regopen = 0; /* #allocation calls opened */
+static unsigned int Reglock = 0; /* #allocation calls locked */
+static unsigned int Regprobe = 0; /* #probes to find a region */
+
+int setregmax(int regmax)
+{
+ int oldmax = Regmax;
+
+ if(regmax >= Regnum && regmax <= sizeof(Region)/sizeof(Region[0]))
+ Regmax = regmax;
+
+ return oldmax;
+}
+
+/* return statistics */
+int _mallocstat(Vmstat_t* st)
+{
+ Vmstat_t vmst;
+ int k;
+
+ if(vmstat(Vmregion, st) < 0) /* add up all stats */
+ return -1;
+ for(k = 0; k < Regnum; ++k)
+ { if(!Region[k])
+ continue;
+ if(vmstat(Region[k], &vmst) < 0 )
+ return -1;
+ st->n_busy += vmst.n_busy;
+ st->n_free += vmst.n_free;
+ st->s_busy += vmst.s_busy;
+ st->s_free += vmst.s_free;
+ st->m_busy += vmst.m_busy;
+ st->m_free += vmst.m_free;
+ st->n_seg += vmst.n_seg;
+ st->extent += vmst.extent;
+ }
+
+ st->n_region = Regnum+1;
+ st->n_open = Regopen;
+ st->n_lock = Reglock;
+ st->n_probe = Regprobe;
+
+ return 0;
+}
+
+/* find the region that a block was allocated from */
+static Vmalloc_t* regionof(Void_t* addr)
+{
+ int k;
+
+#if USE_NATIVE
+#define CAUTIOUS 1
+#else
+#define CAUTIOUS 0
+#endif
+ if(CAUTIOUS || Vmregion->meth.meth != VM_MTBEST )
+ { /* addr will not be dereferenced here */
+ if(vmaddr(Vmregion,addr) == 0 )
+ return Vmregion;
+ for(k = 0; k < Regnum; ++k)
+ if(Region[k] && vmaddr(Region[k], addr) == 0 )
+ return Region[k];
+ return NIL(Vmalloc_t*);
+ }
+ else
+ { /* fast, but susceptible to bad data */
+ Vmdata_t *vd = SEG(BLOCK(addr))->vmdt;
+ if(Vmregion->data == vd )
+ return Vmregion;
+ for(k = 0; k < Regnum; ++k)
+ if(Region[k] && Region[k]->data == vd)
+ return Region[k];
+ return NIL(Vmalloc_t*);
+ }
+}
+
+/* manage a cache of free objects */
+typedef struct _regfree_s
+{ struct _regfree_s* next;
+} Regfree_t;
+static Regfree_t *Regfree;
+
+static void addfreelist(Regfree_t* data)
+{
+ unsigned int k;
+ Regfree_t *head;
+
+ for(k = 0;; ASOLOOP(k) )
+ { data->next = head = Regfree;
+ if(asocasptr(&Regfree, head, data) == (Void_t*)head )
+ return;
+ }
+}
+
+static void clrfreelist()
+{
+ Regfree_t *list, *next;
+ Vmalloc_t *vm;
+
+ if(!(list = Regfree) )
+ return; /* nothing to do */
+
+ if(asocasptr(&Regfree, list, NIL(Regfree_t*)) != list )
+ return; /* somebody else is doing it */
+
+ for(; list; list = next)
+ { next = list->next;
+ if(vm = regionof((Void_t*)list))
+ { if(asocasint(&vm->data->lock, 0, 1) == 0) /* can free this now */
+ { (void)(*vm->meth.freef)(vm, (Void_t*)list, 1);
+ vm->data->lock = 0;
+ }
+ else addfreelist(list); /* ah well, back in the queue */
+ }
+ }
+}
+
+/* get a suitable region to allocate from */
+typedef struct _regdisc_s
+{ Vmdisc_t disc;
+ char slop[64]; /* to absorb any extra data in Vmdcsystem */
+} Regdisc_t;
+
+static int regexcept(Vmalloc_t* vm, int type, Void_t* data, Vmdisc_t* disc)
+{
+ if(type == VM_OPEN)
+ { if(data) /* make vmopen allocate all memory using discipline */
+ *(Void_t**)data = data; /* just make it non-NULL */
+ return 0;
+ }
+ return 0;
+}
+
+static Vmalloc_t* getregion(int* local)
+{
+ Vmalloc_t *vm;
+ int p, pos;
+
+ static unsigned int Rand = 0xdeadbeef; /* a cheap prng */
+#define RAND() (Rand = Rand*16777617 + 3)
+
+ clrfreelist();
+
+ if(Regmax <= 0 )
+ { /* uni-process/thread */
+ *local = 1;
+ Vmregion->data->lock = 1;
+ return Vmregion;
+ }
+ else if(asocasint(&Vmregion->data->lock, 0, 1) == 0 )
+ { /* Vmregion is open, so use it */
+ *local = 1;
+ asoincint(&Regopen);
+ return Vmregion;
+ }
+
+ asoincint(&Regprobe); /* probe Region[] to find an open region */
+ if(Regnum == 0)
+ pos = 0;
+ else for(pos = p = RAND()%Regnum;; )
+ { if(Region[p] && asocasint(&Region[p]->data->lock, 0, 1) == 0 )
+ { *local = 1;
+ asoincint(&Regopen);
+ return Region[p];
+ }
+ if((p = (p+1)%Regnum) == pos )
+ break;
+ }
+
+ /* grab the next open slot for a new region */
+ while((p = Regnum) < Regmax)
+ if(asocasint(&Regnum, p, p+1) == p )
+ break;
+ if(p < Regmax) /* this slot is now ours */
+ { static Regdisc_t Regdisc;
+ if(!Regdisc.disc.exceptf) /* one time initialization */
+ { GETPAGESIZE(_Vmpagesize);
+ memcpy(&Regdisc, Vmdcsystem, Vmdcsystem->size);
+ Regdisc.disc.round = ROUND(_Vmpagesize, 64*1024);
+ Regdisc.disc.exceptf = regexcept;
+ }
+
+ /**/ASSERT(Region[p] == NIL(Vmalloc_t*));
+ if((vm = vmopen(&Regdisc.disc, Vmbest, VM_SHARE)) != NIL(Vmalloc_t*) )
+ { vm->data->lock = 1; /* lock new region now */
+ *local = 1;
+ asoincint(&Regopen);
+ return (Region[p] = vm);
+ }
+ else Region[p] = Vmregion; /* better than nothing */
+ }
+
+ /* must return something */
+ vm = Region[pos] ? Region[pos] : Vmregion;
+ if(asocasint(&vm->data->lock, 0, 1) == 0)
+ { *local = 1;
+ asoincint(&Regopen);
+ }
+ else
+ { *local = 0;
+ asoincint(&Reglock);
+ }
+ return vm;
+}
+
+#if __STD_C
+extern Void_t* calloc(reg size_t n_obj, reg size_t s_obj)
+#else
+extern Void_t* calloc(n_obj, s_obj)
+reg size_t n_obj;
+reg size_t s_obj;
+#endif
+{
+ Void_t *addr;
+ Vmalloc_t *vm;
+ int local = 0;
+ VMFLINIT();
+
+ vm = getregion(&local);
+ addr = (*vm->meth.resizef)(vm, NIL(Void_t*), n_obj*s_obj, VM_RSZERO, local);
+ if(local)
+ { /**/ASSERT(vm->data->lock == 1);
+ vm->data->lock = 0;
+ }
+ return VMRECORD(addr);
+}
+
+#if __STD_C
+extern Void_t* malloc(reg size_t size)
+#else
+extern Void_t* malloc(size)
+reg size_t size;
+#endif
+{
+ Void_t *addr;
+ Vmalloc_t *vm;
+ int local = 0;
+ VMFLINIT();
+
+ vm = getregion(&local);
+ addr = (*vm->meth.allocf)(vm, size, local);
+ if(local)
+ { /**/ASSERT(vm->data->lock == 1);
+ vm->data->lock = 0;
+ }
+ return VMRECORD(addr);
+}
+
+#if __STD_C
+extern Void_t* realloc(reg Void_t* data, reg size_t size)
+#else
+extern Void_t* realloc(data,size)
+reg Void_t* data; /* block to be reallocated */
+reg size_t size; /* new size */
+#endif
+{
+ ssize_t copy;
+ Void_t *addr;
+ Vmalloc_t *vm;
+ VMFLINIT();
+
+ if(!data)
+ return malloc(size);
+ else if((vm = regionof(data)) )
+ { if(vm == Vmregion && vm != Vmheap) /* no multiple region usage here */
+ { addr = (*vm->meth.resizef)(vm, data, size, VM_RSCOPY|VM_RSMOVE, 0);
+ return VMRECORD(addr);
+ }
+ if(asocasint(&vm->data->lock, 0, 1) == 0 ) /* region is open */
+ { addr = (*vm->meth.resizef)(vm, data, size, VM_RSCOPY|VM_RSMOVE, 1);
+ vm->data->lock = 0;
+ return VMRECORD(addr);
+ }
+ else if(Regmax > 0 && Vmregion == Vmheap && (addr = malloc(size)) )
+ { if((copy = SIZE(BLOCK(data))&~BITS) > size )
+ copy = size;
+ memcpy(addr, data, copy);
+ addfreelist((Regfree_t*)data);
+ return VMRECORD(addr);
+ }
+ else /* this may block but it is the best that we can do now */
+ { addr = (*vm->meth.resizef)(vm, data, size, VM_RSCOPY|VM_RSMOVE, 0);
+ return VMRECORD(addr);
+ }
+ }
+ else /* not our data */
+ {
+#if USE_NATIVE
+#undef realloc /* let the native realloc() take care of it */
+#if __STD_C
+ extern Void_t* realloc(Void_t*, size_t);
+#else
+ extern Void_t* realloc();
+#endif
+ return realloc(data, size);
+#else
+ return NIL(Void_t*);
+#endif
+ }
+}
+
+#if __STD_C
+extern void free(reg Void_t* data)
+#else
+extern void free(data)
+reg Void_t* data;
+#endif
+{
+ Vmalloc_t *vm;
+ VMFLINIT();
+
+ if(!data || (_Vmassert & VM_keep))
+ return;
+ else if((vm = regionof(data)) )
+ {
+ if(vm == Vmregion && Vmregion != Vmheap || (_Vmassert & VM_free))
+ (void)(*vm->meth.freef)(vm, data, 0);
+ else addfreelist((Regfree_t*)data);
+ return;
+ }
+ else /* not our data */
+ {
+#if USE_NATIVE
+#undef free /* let the native free() take care of it */
+#if __STD_C
+ extern void free(Void_t*);
+#else
+ extern void free();
+#endif
+ free(data);
+#endif
+ return;
+ }
+}
+
+#if __STD_C
+extern void cfree(reg Void_t* data)
+#else
+extern void cfree(data)
+reg Void_t* data;
+#endif
+{
+ free(data);
+}
+
+#if __STD_C
+extern Void_t* memalign(reg size_t align, reg size_t size)
+#else
+extern Void_t* memalign(align, size)
+reg size_t align;
+reg size_t size;
+#endif
+{
+ Void_t *addr;
+ Vmalloc_t *vm;
+ int local = 0;
+ VMFLINIT();
+
+ vm = getregion(&local);
+ VMBLOCK
+ addr = (*vm->meth.alignf)(vm, size, align, local);
+ if(local)
+ { /**/ASSERT(vm->data->lock == 1);
+ vm->data->lock = 0;
+ }
+ VMUNBLOCK
+ return VMRECORD(addr);
+}
+
+#if __STD_C
+extern int posix_memalign(reg Void_t **memptr, reg size_t align, reg size_t size)
+#else
+extern int posix_memalign(memptr, align, size)
+reg Void_t** memptr;
+reg size_t align;
+reg size_t size;
+#endif
+{
+ Void_t *mem;
+
+ if(align == 0 || (align%sizeof(Void_t*)) != 0 || ((align-1)&align) != 0 )
+ return EINVAL;
+
+ if(!(mem = memalign(align, size)) )
+ return ENOMEM;
+
+ *memptr = mem;
+ return 0;
+}
+
+#if __STD_C
+extern Void_t* valloc(reg size_t size)
+#else
+extern Void_t* valloc(size)
+reg size_t size;
+#endif
+{
+ VMFLINIT();
+
+ GETPAGESIZE(_Vmpagesize);
+ return VMRECORD(memalign(_Vmpagesize, size));
+}
+
+#if __STD_C
+extern Void_t* pvalloc(reg size_t size)
+#else
+extern Void_t* pvalloc(size)
+reg size_t size;
+#endif
+{
+ VMFLINIT();
+
+ GETPAGESIZE(_Vmpagesize);
+ return VMRECORD(memalign(_Vmpagesize, ROUND(size,_Vmpagesize)) );
+}
+
+#if !_PACKAGE_ast
+#if __STD_C
+char* strdup(const char* s)
+#else
+char* strdup(s)
+char* s;
+#endif
+{
+ char *ns;
+ size_t n;
+
+ if(!s)
+ return NIL(char*);
+ else
+ { n = strlen(s);
+ if((ns = malloc(n+1)) )
+ memcpy(ns,s,n+1);
+ return ns;
+ }
+}
+#endif /* _PACKAGE_ast */
+
+#if !_lib_alloca || _mal_alloca
+#ifndef _stk_down
+#define _stk_down 0
+#endif
+typedef struct _alloca_s Alloca_t;
+union _alloca_u
+{ struct
+ { char* addr;
+ Alloca_t* next;
+ } head;
+ char array[ALIGN];
+};
+struct _alloca_s
+{ union _alloca_u head;
+ Vmuchar_t data[1];
+};
+
+#if __STD_C
+extern Void_t* alloca(size_t size)
+#else
+extern Void_t* alloca(size)
+size_t size;
+#endif
+{ char array[ALIGN];
+ char* file;
+ int line;
+ Void_t* func;
+ Alloca_t* f;
+ Vmalloc_t *vm;
+ static Alloca_t* Frame;
+
+ VMFLINIT();
+
+ VMFLF(Vmregion,file,line,func); /* save info before freeing frames */
+
+ while(Frame) /* free unused frames */
+ { if(( _stk_down && &array[0] > Frame->head.head.addr) ||
+ (!_stk_down && &array[0] < Frame->head.head.addr) )
+ { f = Frame; Frame = f->head.head.next;
+ if((vm = regionof(f)) )
+ (void)(*vm->meth.freef)(vm, f, 0);
+ /* else: something bad happened. just keep going */
+ }
+ else break;
+ }
+
+ Vmregion->file = file; /* restore file/line info before allocation */
+ Vmregion->line = line;
+ Vmregion->func = func;
+
+ f = (Alloca_t*)(*Vmregion->meth.allocf)(Vmregion, size+sizeof(Alloca_t)-1, 0);
+
+ /* if f is NULL, this mimics a stack overflow with a memory error! */
+ f->head.head.addr = &array[0];
+ f->head.head.next = Frame;
+ Frame = f;
+
+ return (Void_t*)f->data;
+}
+#endif /*!_lib_alloca || _mal_alloca*/
+
+#if _map_malloc
+
+/* not sure of all the implications -- 0 is conservative for now */
+#define USE_NATIVE 0 /* native free/realloc on non-vmalloc ptrs */
+
+#else
+
+#if _malloc_hook
+
+static void vm_free_hook(void* ptr, const void* caller)
+{
+ free(ptr);
+}
+
+static void* vm_malloc_hook(size_t size, const void* caller)
+{
+ void* r;
+
+ r = malloc(size);
+ return r;
+}
+
+static void* vm_memalign_hook(size_t align, size_t size, const void* caller)
+{
+ void* r;
+
+ r = memalign(align, size);
+ return r;
+}
+
+static void* vm_realloc_hook(void* ptr, size_t size, const void* caller)
+{
+ void* r;
+
+ r = realloc(ptr, size);
+ return r;
+}
+
+static void vm_initialize_hook(void)
+{
+ __free_hook = vm_free_hook;
+ __malloc_hook = vm_malloc_hook;
+ __memalign_hook = vm_memalign_hook;
+ __realloc_hook = vm_realloc_hook;
+}
+
+void (*__malloc_initialize_hook)(void) = vm_initialize_hook;
+
+#if 0 /* 2012-02-29 this may be needed to cover shared libs */
+
+void __attribute__ ((constructor)) vm_initialize_initialize_hook(void)
+{
+ vm_initialize_hook();
+ __malloc_initialize_hook = vm_initialize_hook;
+}
+
+#endif
+
+#else
+
+/* intercept _* __* __libc_* variants */
+
+#if __lib__malloc
+extern Void_t* F2(_calloc, size_t,n, size_t,m) { return calloc(n, m); }
+extern Void_t F1(_cfree, Void_t*,p) { free(p); }
+extern Void_t F1(_free, Void_t*,p) { free(p); }
+extern Void_t* F1(_malloc, size_t,n) { return malloc(n); }
+#if _lib_memalign
+extern Void_t* F2(_memalign, size_t,a, size_t,n) { return memalign(a, n); }
+#endif
+#if _lib_pvalloc
+extern Void_t* F1(_pvalloc, size_t,n) { return pvalloc(n); }
+#endif
+extern Void_t* F2(_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
+#if _lib_valloc
+extern Void_t* F1(_valloc, size_t,n) { return valloc(n); }
+#endif
+#endif
+
+#if _lib___malloc
+extern Void_t* F2(__calloc, size_t,n, size_t,m) { return calloc(n, m); }
+extern Void_t F1(__cfree, Void_t*,p) { free(p); }
+extern Void_t F1(__free, Void_t*,p) { free(p); }
+extern Void_t* F1(__malloc, size_t,n) { return malloc(n); }
+#if _lib_memalign
+extern Void_t* F2(__memalign, size_t,a, size_t,n) { return memalign(a, n); }
+#endif
+#if _lib_pvalloc
+extern Void_t* F1(__pvalloc, size_t,n) { return pvalloc(n); }
+#endif
+extern Void_t* F2(__realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
+#if _lib_valloc
+extern Void_t* F1(__valloc, size_t,n) { return valloc(n); }
+#endif
+#endif
+
+#if _lib___libc_malloc
+extern Void_t* F2(__libc_calloc, size_t,n, size_t,m) { return calloc(n, m); }
+extern Void_t F1(__libc_cfree, Void_t*,p) { free(p); }
+extern Void_t F1(__libc_free, Void_t*,p) { free(p); }
+extern Void_t* F1(__libc_malloc, size_t,n) { return malloc(n); }
+#if _lib_memalign
+extern Void_t* F2(__libc_memalign, size_t,a, size_t,n) { return memalign(a, n); }
+#endif
+#if _lib_pvalloc
+extern Void_t* F1(__libc_pvalloc, size_t,n) { return pvalloc(n); }
+#endif
+extern Void_t* F2(__libc_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
+#if _lib_valloc
+extern Void_t* F1(__libc_valloc, size_t,n) { return valloc(n); }
+#endif
+#endif
+
+#endif /* _malloc_hook */
+
+#endif /* _map_malloc */
+
+#undef extern
+
+#if _hdr_malloc /* need the mallint interface for statistics, etc. */
+
+#undef calloc
+#define calloc ______calloc
+#undef cfree
+#define cfree ______cfree
+#undef free
+#define free ______free
+#undef malloc
+#define malloc ______malloc
+#undef pvalloc
+#define pvalloc ______pvalloc
+#undef realloc
+#define realloc ______realloc
+#undef valloc
+#define valloc ______valloc
+
+#if !_UWIN
+
+#include <malloc.h>
+
+typedef struct mallinfo Mallinfo_t;
+typedef struct mstats Mstats_t;
+
+#endif
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#if _lib_mallopt
+#if __STD_C
+extern int mallopt(int cmd, int value)
+#else
+extern int mallopt(cmd, value)
+int cmd;
+int value;
+#endif
+{
+ VMFLINIT();
+ return 0;
+}
+#endif /*_lib_mallopt*/
+
+#if _lib_mallinfo && _mem_arena_mallinfo
+#if __STD_C
+extern Mallinfo_t mallinfo(void)
+#else
+extern Mallinfo_t mallinfo()
+#endif
+{
+ Vmstat_t sb;
+ Mallinfo_t mi;
+
+ VMFLINIT();
+ memset(&mi,0,sizeof(mi));
+ if(vmstat(Vmregion,&sb) >= 0)
+ { mi.arena = sb.extent;
+ mi.ordblks = sb.n_busy+sb.n_free;
+ mi.uordblks = sb.s_busy;
+ mi.fordblks = sb.s_free;
+ }
+ return mi;
+}
+#endif /* _lib_mallinfo */
+
+#if _lib_mstats && _mem_bytes_total_mstats
+#if __STD_C
+extern Mstats_t mstats(void)
+#else
+extern Mstats_t mstats()
+#endif
+{
+ Vmstat_t sb;
+ Mstats_t ms;
+
+ VMFLINIT();
+ memset(&ms,0,sizeof(ms));
+ if(vmstat(Vmregion,&sb) >= 0)
+ { ms.bytes_total = sb.extent;
+ ms.chunks_used = sb.n_busy;
+ ms.bytes_used = sb.s_busy;
+ ms.chunks_free = sb.n_free;
+ ms.bytes_free = sb.s_free;
+ }
+ return ms;
+}
+#endif /*_lib_mstats*/
+
+#undef extern
+
+#endif/*_hdr_malloc*/
+
+#else
+
+/*
+ * even though there is no malloc override, still provide
+ * _ast_* counterparts for object compatibility
+ */
+
+#define setregmax(n)
+
+#undef calloc
+extern Void_t* calloc _ARG_((size_t, size_t));
+
+#undef cfree
+extern void cfree _ARG_((Void_t*));
+
+#undef free
+extern void free _ARG_((Void_t*));
+
+#undef malloc
+extern Void_t* malloc _ARG_((size_t));
+
+#if _lib_memalign
+#undef memalign
+extern Void_t* memalign _ARG_((size_t, size_t));
+#endif
+
+#if _lib_pvalloc
+#undef pvalloc
+extern Void_t* pvalloc _ARG_((size_t));
+#endif
+
+#undef realloc
+extern Void_t* realloc _ARG_((Void_t*, size_t));
+
+#if _lib_valloc
+#undef valloc
+extern Void_t* valloc _ARG_((size_t));
+#endif
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#if !_malloc_hook
+
+extern Void_t F1(_ast_free, Void_t*,p) { free(p); }
+extern Void_t* F1(_ast_malloc, size_t,n) { return malloc(n); }
+#if _lib_memalign
+extern Void_t* F2(_ast_memalign, size_t,a, size_t,n) { return memalign(a, n); }
+#endif
+extern Void_t* F2(_ast_realloc, Void_t*,p, size_t,n) { return realloc(p, n); }
+
+#endif
+
+extern Void_t* F2(_ast_calloc, size_t,n, size_t,m) { return calloc(n, m); }
+extern Void_t F1(_ast_cfree, Void_t*,p) { free(p); }
+#if _lib_pvalloc
+extern Void_t* F1(_ast_pvalloc, size_t,n) { return pvalloc(n); }
+#endif
+#if _lib_valloc
+extern Void_t* F1(_ast_valloc, size_t,n) { return valloc(n); }
+#endif
+
+#undef extern
+
+#if _hdr_malloc
+
+#undef mallinfo
+#undef mallopt
+#undef mstats
+
+#define calloc ______calloc
+#define cfree ______cfree
+#define free ______free
+#define malloc ______malloc
+#define pvalloc ______pvalloc
+#define realloc ______realloc
+#define valloc ______valloc
+
+#if !_UWIN
+
+#if !_malloc_hook
+
+#include <malloc.h>
+
+#endif
+
+typedef struct mallinfo Mallinfo_t;
+typedef struct mstats Mstats_t;
+
+#endif
+
+#if defined(__EXPORT__)
+#define extern __EXPORT__
+#endif
+
+#if _lib_mallopt
+extern int F2(_ast_mallopt, int,cmd, int,value) { return mallopt(cmd, value); }
+#endif
+
+#if _lib_mallinfo && _mem_arena_mallinfo
+extern Mallinfo_t F0(_ast_mallinfo, void) { return mallinfo(); }
+#endif
+
+#if _lib_mstats && _mem_bytes_total_mstats
+extern Mstats_t F0(_ast_mstats, void) { return mstats(); }
+#endif
+
+#undef extern
+
+#endif /*_hdr_malloc*/
+
+#endif /*!_std_malloc*/
+
+#if __STD_C
+static Vmulong_t atou(char** sp)
+#else
+static Vmulong_t atou(sp)
+char** sp;
+#endif
+{
+ char* s = *sp;
+ Vmulong_t v = 0;
+
+ if(s[0] == '0' && (s[1] == 'x' || s[1] == 'X') )
+ { for(s += 2; *s; ++s)
+ { if(*s >= '0' && *s <= '9')
+ v = (v << 4) + (*s - '0');
+ else if(*s >= 'a' && *s <= 'f')
+ v = (v << 4) + (*s - 'a') + 10;
+ else if(*s >= 'A' && *s <= 'F')
+ v = (v << 4) + (*s - 'A') + 10;
+ else break;
+ }
+ }
+ else
+ { for(; *s; ++s)
+ { if(*s >= '0' && *s <= '9')
+ v = v*10 + (*s - '0');
+ else break;
+ }
+ }
+
+ *sp = s;
+ return v;
+}
+
+#if __STD_C
+static char* insertpid(char* begs, char* ends)
+#else
+static char* insertpid(begs,ends)
+char* begs;
+char* ends;
+#endif
+{ int pid;
+ char* s;
+
+ if((pid = getpid()) < 0)
+ return NIL(char*);
+
+ s = ends;
+ do
+ { if(s == begs)
+ return NIL(char*);
+ *--s = '0' + pid%10;
+ } while((pid /= 10) > 0);
+ while(s < ends)
+ *begs++ = *s++;
+
+ return begs;
+}
+
+#if __STD_C
+static int createfile(char* file)
+#else
+static int createfile(file)
+char* file;
+#endif
+{
+ char buf[1024];
+ char *next, *endb;
+ int fd;
+
+ next = buf;
+ endb = buf + sizeof(buf);
+ while(*file)
+ { if(*file == '%')
+ { switch(file[1])
+ {
+ case 'p' :
+ if(!(next = insertpid(next,endb)) )
+ return -1;
+ file += 2;
+ break;
+ default :
+ goto copy;
+ }
+ }
+ else
+ { copy:
+ *next++ = *file++;
+ }
+
+ if(next >= endb)
+ return -1;
+ }
+
+ *next = '\0';
+ file = buf;
+ if (*file == '&' && *(file += 1) || strncmp(file, "/dev/fd/", 8) == 0 && *(file += 8))
+ fd = dup((int)atou(&file));
+ else if (*file)
+#if _PACKAGE_ast
+ fd = open(file, O_WRONLY|O_CREAT|O_TRUNC, CREAT_MODE);
+#else
+ fd = creat(file, CREAT_MODE);
+#endif
+ else
+ return -1;
+#if _PACKAGE_ast
+#ifdef FD_CLOEXEC
+ if (fd >= 0)
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+#endif
+#endif
+ return fd;
+}
+
+#if __STD_C
+static void pfprint(void)
+#else
+static void pfprint()
+#endif
+{
+ if(Vmregion->meth.meth == VM_MTPROFILE)
+ vmprofile(Vmregion,_Vmpffd);
+}
+
+/*
+ * initialize runtime options from the VMALLOC_OPTIONS env var
+ */
+
+#define COPY(t,e,f) while ((*t = *f++) && t < e) t++
+
+#if __STD_C
+void _vmoptions(void)
+#else
+void _vmoptions()
+#endif
+{
+ Vmalloc_t* vm = 0;
+ char* trace = 0;
+ char* s;
+ char* t;
+ char* v;
+ Vmulong_t n;
+ int fd;
+ char buf[1024];
+
+ _Vmoptions = 1;
+ t = buf;
+ v = &buf[sizeof(buf)-1];
+ if (s = getenv("VMALLOC_OPTIONS"))
+ COPY(t, v, s);
+ if (t > buf)
+ {
+ *t = 0;
+ s = buf;
+ for (;;)
+ {
+ while (*s == ',' || *s == ' ' || *s == '\t' || *s == '\r' || *s == '\n')
+ s++;
+ if (!*(t = s))
+ break;
+ v = 0;
+ while (*s)
+ if (*s == ',' || *s == ' ' || *s == '\t' || *s == '\r' || *s == '\n')
+ {
+ *s++ = 0;
+ break;
+ }
+ else if (!v && *s == '=')
+ {
+ *s++ = 0;
+ if (!*(v = s))
+ v = 0;
+ }
+ else
+ s++;
+ if (t[0] == 'n' && t[1] == 'o')
+ continue;
+ switch (t[0])
+ {
+ case 'a': /* abort */
+ if (!vm)
+ vm = vmopen(Vmdcsystem, Vmdebug, 0);
+ if (vm && vm->meth.meth == VM_MTDEBUG)
+ vmset(vm, VM_DBABORT, 1);
+ else
+ _Vmassert |= VM_abort;
+ break;
+ case 'b': /* break */
+ _Vmassert |= VM_break;
+ break;
+ case 'c': /* check */
+ _Vmassert |= VM_check;
+ break;
+ case 'f': /* free */
+ _Vmassert |= VM_free;
+ break;
+ case 'k': /* keep */
+ _Vmassert |= VM_keep;
+ break;
+ case 'm':
+ if (v && !vm)
+ {
+ if ((v[0] == 'V' || v[0] == 'v') && (v[1] == 'M' || v[1] == 'm'))
+ v += 2;
+ if (strcmp(v, "debug") == 0)
+ vm = vmopen(Vmdcsystem, Vmdebug, 0);
+ else if (strcmp(v, "profile") == 0)
+ vm = vmopen(Vmdcsystem, Vmprofile, 0);
+ else if (strcmp(v, "last") == 0)
+ vm = vmopen(Vmdcsystem, Vmlast, 0);
+ else if (strcmp(v, "best") == 0)
+ vm = Vmheap;
+ }
+ break;
+ case 'p':
+ if (v)
+ switch (t[1])
+ {
+ case 'e': /* period=<count> */
+ if (!vm)
+ vm = vmopen(Vmdcsystem, Vmdebug, 0);
+ if (vm && vm->meth.meth == VM_MTDEBUG)
+ _Vmdbcheck = atou(&v);
+ break;
+ case 'r': /* profile=<path> */
+ if (!vm)
+ vm = vmopen(Vmdcsystem, Vmprofile, 0);
+ if (v && vm && vm->meth.meth == VM_MTPROFILE)
+ _Vmpffd = createfile(v);
+ break;
+ }
+ break;
+ case 's': /* start=<count> */
+ if (!vm)
+ vm = vmopen(Vmdcsystem, Vmdebug, 0);
+ if (v && vm && vm->meth.meth == VM_MTDEBUG)
+ _Vmdbstart = atou(&v);
+ break;
+ case 't': /* trace=<path> */
+ trace = v;
+ break;
+ case 'w':
+ if (t[1] == 'a')
+ switch (t[2])
+ {
+ case 'r': /* warn=<path> */
+ if (!vm)
+ vm = vmopen(Vmdcsystem, Vmdebug, 0);
+ if (v && vm && vm->meth.meth == VM_MTDEBUG && (fd = createfile(v)) >= 0)
+ vmdebug(fd);
+ break;
+ case 't': /* watch=<addr> */
+ if (!vm)
+ vm = vmopen(Vmdcsystem, Vmdebug, 0);
+ if (v && vm && vm->meth.meth == VM_MTDEBUG && (n = atou(&v)) >= 0)
+ vmdbwatch((Void_t*)n);
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ /* slip in the new region now so that malloc() will work fine */
+
+ if (vm)
+ {
+ if (vm->meth.meth == VM_MTDEBUG)
+ _Vmdbcheck = 1;
+ Vmregion = vm;
+ }
+
+ /* enable tracing -- this currently disables multiple regions */
+
+ if (trace)
+ {
+ setregmax(0);
+ if ((fd = createfile(trace)) >= 0)
+ {
+ vmset(Vmregion, VM_TRACE, 1);
+ vmtrace(fd);
+ }
+ }
+ else if (Vmregion != Vmheap || asometh(0, 0)->type == ASO_SIGNAL)
+ setregmax(0);
+
+ /* make sure that profile data is output upon exiting */
+
+ if (vm && vm->meth.meth == VM_MTPROFILE)
+ {
+ if (_Vmpffd < 0)
+ _Vmpffd = 2;
+ /* this may wind up calling malloc(), but region is ok now */
+ atexit(pfprint);
+ }
+ else if (_Vmpffd >= 0)
+ {
+ close(_Vmpffd);
+ _Vmpffd = -1;
+ }
+}
+
+/*
+ * ast semi-private workaround for system functions
+ * that misbehave by passing bogus addresses to free()
+ *
+ * not prototyped in any header to keep it ast semi-private
+ *
+ * to keep malloc() data by disabling free()
+ * extern _vmkeep(int);
+ * int r = _vmkeep(1);
+ * and to restore to the previous state
+ * (void)_vmkeep(r);
+ */
+
+int
+#if __STD_C
+_vmkeep(int v)
+#else
+_vmkeep(v)
+int v;
+#endif
+{
+ int r;
+
+ r = !!(_Vmassert & VM_keep);
+ if (v)
+ _Vmassert |= VM_keep;
+ else
+ _Vmassert &= ~VM_keep;
+ return r;
+}
+
+#endif /*_UWIN*/
diff --git a/src/lib/libast/vmalloc/vmbest.c b/src/lib/libast/vmalloc/vmbest.c
new file mode 100644
index 0000000..553d83a
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmbest.c
@@ -0,0 +1,1390 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmbest(){}
+
+#else
+
+#include "vmhdr.h"
+
+/* Best-fit allocation method. This is based on a best-fit strategy
+** using a splay tree for storage of lists of free blocks of the same
+** size. Recent free blocks may be cached for fast reuse.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+
+#ifdef DEBUG
+static int N_free; /* # of free calls */
+static int N_alloc; /* # of alloc calls */
+static int N_resize; /* # of resize calls */
+static int N_wild; /* # allocated from the wild block */
+static int N_last; /* # allocated from last free block */
+static int N_reclaim; /* # of bestreclaim calls */
+#endif /*DEBUG*/
+
+#define COMPACT 8 /* factor to decide when to compact */
+
+/* Check to see if a block is in the free tree */
+#if __STD_C
+static int vmintree(Block_t* node, Block_t* b)
+#else
+static int vmintree(node,b)
+Block_t* node;
+Block_t* b;
+#endif
+{ Block_t* t;
+
+ for(t = node; t; t = LINK(t))
+ if(t == b)
+ return 1;
+ if(LEFT(node) && vmintree(LEFT(node),b))
+ return 1;
+ if(RIGHT(node) && vmintree(RIGHT(node),b))
+ return 1;
+ return 0;
+}
+
+#if __STD_C
+static int vmonlist(Block_t* list, Block_t* b)
+#else
+static int vmonlist(list,b)
+Block_t* list;
+Block_t* b;
+#endif
+{
+ for(; list; list = LINK(list))
+ if(list == b)
+ return 1;
+ return 0;
+}
+
+/* Check to see if a block is known to be free */
+#if __STD_C
+static int vmisfree(Vmdata_t* vd, Block_t* b)
+#else
+static int vmisfree(vd,b)
+Vmdata_t* vd;
+Block_t* b;
+#endif
+{
+ if(SIZE(b) & (BUSY|JUNK|PFREE))
+ return 0;
+
+ if(b == vd->wild)
+ return 1;
+
+ if(SIZE(b) < MAXTINY)
+ return vmonlist(TINY(vd)[INDEX(SIZE(b))], b);
+
+ if(vd->root)
+ return vmintree(vd->root, b);
+
+ return 0;
+}
+
+/* Check to see if a block is known to be junked */
+#if __STD_C
+static int vmisjunk(Vmdata_t* vd, Block_t* b)
+#else
+static int vmisjunk(vd,b)
+Vmdata_t* vd;
+Block_t* b;
+#endif
+{
+ Block_t* t;
+
+ if((SIZE(b)&BUSY) == 0 || (SIZE(b)&JUNK) == 0)
+ return 0;
+
+ if(b == vd->free) /* recently freed */
+ return 1;
+
+ /* check the list that b is supposed to be in */
+ for(t = CACHE(vd)[C_INDEX(SIZE(b))]; t; t = LINK(t))
+ if(t == b)
+ return 1;
+
+ /* on occasions, b may be put onto the catch-all list */
+ if(C_INDEX(SIZE(b)) < S_CACHE)
+ for(t = CACHE(vd)[S_CACHE]; t; t = LINK(t))
+ if(t == b)
+ return 1;
+
+ return 0;
+}
+
+/* check to see if the free tree is in good shape */
+#if __STD_C
+static int vmchktree(Block_t* node)
+#else
+static int vmchktree(node)
+Block_t* node;
+#endif
+{ Block_t* t;
+
+ if(SIZE(node) & BITS)
+ { /**/ASSERT(0); return -1; }
+
+ for(t = LINK(node); t; t = LINK(t))
+ if(SIZE(t) != SIZE(node))
+ { /**/ASSERT(0); return -1; }
+
+ if((t = LEFT(node)) )
+ { if(SIZE(t) >= SIZE(node) )
+ { /**/ASSERT(0); return -1; }
+ else return vmchktree(t);
+ }
+ if((t = RIGHT(node)) )
+ { if(SIZE(t) <= SIZE(node) )
+ { /**/ASSERT(0); return -1; }
+ else return vmchktree(t);
+ }
+
+ return 0;
+}
+
+#if __STD_C
+int _vmbestcheck(Vmdata_t* vd, Block_t* freeb)
+#else
+int _vmbestcheck(vd, freeb)
+Vmdata_t* vd;
+Block_t* freeb; /* known to be free but not on any free list */
+#endif
+{
+ reg Seg_t *seg;
+ reg Block_t *b, *endb, *nextb;
+ int rv = 0;
+
+ if(!CHECK())
+ return 0;
+
+ /* make sure the free tree is still in shape */
+ if(vd->root && vmchktree(vd->root) < 0 )
+ { rv = -1; /**/ASSERT(0); }
+
+ for(seg = vd->seg; seg && rv == 0; seg = seg->next)
+ { b = SEGBLOCK(seg);
+ endb = (Block_t*)(seg->baddr - sizeof(Head_t));
+ for(; b < endb && rv == 0; b = nextb)
+ { nextb = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
+
+ if(!ISBUSY(SIZE(b)) ) /* a completely free block */
+ { /* there should be no marked bits of any type */
+ if(SIZE(b) & (BUSY|JUNK|PFREE) )
+ { rv = -1; /**/ASSERT(0); }
+
+ /* next block must be busy and marked PFREE */
+ if(!ISBUSY(SIZE(nextb)) || !ISPFREE(SIZE(nextb)) )
+ { rv = -1; /**/ASSERT(0); }
+
+ /* must have a self-reference pointer */
+ if(SELF(b) != b)
+ { rv = -1; /**/ASSERT(0); }
+
+ /* segment pointer should be well-defined */
+ if(!TINIEST(b) && SEG(b) != seg)
+ { rv = -1; /**/ASSERT(0); }
+
+ /* must be on a free list */
+ if(b != freeb && !vmisfree(vd, b) )
+ { rv = -1; /**/ASSERT(0); }
+ }
+ else
+ { /* segment pointer should be well-defined */
+ if(SEG(b) != seg)
+ { rv = -1; /**/ASSERT(0); }
+
+ /* next block should not be marked PFREE */
+ if(ISPFREE(SIZE(nextb)) )
+ { rv = -1; /**/ASSERT(0); }
+
+ /* if PFREE, last block should be free */
+ if(ISPFREE(SIZE(b)) && LAST(b) != freeb &&
+ !vmisfree(vd, LAST(b)) )
+ { rv = -1; /**/ASSERT(0); }
+
+ /* if free but unreclaimed, should be junk */
+ if(ISJUNK(SIZE(b)) && !vmisjunk(vd, b))
+ { rv = -1; /**/ASSERT(0); }
+ }
+ }
+ }
+
+ return rv;
+}
+
+/* Tree rotation functions */
+#define RROTATE(x,y) (LEFT(x) = RIGHT(y), RIGHT(y) = (x), (x) = (y))
+#define LROTATE(x,y) (RIGHT(x) = LEFT(y), LEFT(y) = (x), (x) = (y))
+#define RLINK(s,x) ((s) = LEFT(s) = (x))
+#define LLINK(s,x) ((s) = RIGHT(s) = (x))
+
+/* Find and delete a suitable element in the free tree. */
+#if __STD_C
+static Block_t* bestsearch(Vmdata_t* vd, reg size_t size, Block_t* wanted)
+#else
+static Block_t* bestsearch(vd, size, wanted)
+Vmdata_t* vd;
+reg size_t size;
+Block_t* wanted;
+#endif
+{
+ reg size_t s;
+ reg Block_t *t, *root, *l, *r;
+ Block_t link;
+
+ /* extracting a tiniest block from its list */
+ if((root = wanted) && size == TINYSIZE)
+ { reg Seg_t* seg;
+
+ l = TLEFT(root);
+ if((r = LINK(root)) )
+ TLEFT(r) = l;
+ if(l)
+ LINK(l) = r;
+ else TINY(vd)[0] = r;
+
+ seg = vd->seg;
+ if(!seg->next)
+ SEG(root) = seg;
+ else for(;; seg = seg->next)
+ { if((Vmuchar_t*)root > (Vmuchar_t*)seg->addr &&
+ (Vmuchar_t*)root < seg->baddr)
+ { SEG(root) = seg;
+ break;
+ }
+ }
+
+ return root;
+ }
+
+ /**/ASSERT(!vd->root || vmchktree(vd->root) == 0);
+
+ /* find the right one to delete */
+ l = r = &link;
+ if((root = vd->root) ) do
+ { /**/ ASSERT(!ISBITS(size) && !ISBITS(SIZE(root)));
+ if(size == (s = SIZE(root)) )
+ break;
+ if(size < s)
+ { if((t = LEFT(root)) )
+ { if(size <= (s = SIZE(t)) )
+ { RROTATE(root,t);
+ if(size == s)
+ break;
+ t = LEFT(root);
+ }
+ else
+ { LLINK(l,t);
+ t = RIGHT(t);
+ }
+ }
+ RLINK(r,root);
+ }
+ else
+ { if((t = RIGHT(root)) )
+ { if(size >= (s = SIZE(t)) )
+ { LROTATE(root,t);
+ if(size == s)
+ break;
+ t = RIGHT(root);
+ }
+ else
+ { RLINK(r,t);
+ t = LEFT(t);
+ }
+ }
+ LLINK(l,root);
+ }
+ /**/ ASSERT(root != t);
+ } while((root = t) );
+
+ if(root) /* found it, now isolate it */
+ { RIGHT(l) = LEFT(root);
+ LEFT(r) = RIGHT(root);
+ }
+ else /* nothing exactly fit */
+ { LEFT(r) = NIL(Block_t*);
+ RIGHT(l) = NIL(Block_t*);
+
+ /* grab the least one from the right tree */
+ if((root = LEFT(&link)) )
+ { while((t = LEFT(root)) )
+ RROTATE(root,t);
+ LEFT(&link) = RIGHT(root);
+ }
+ }
+
+ if(root && (r = LINK(root)) )
+ { /* head of a link list, use next one for root */
+ LEFT(r) = RIGHT(&link);
+ RIGHT(r) = LEFT(&link);
+ }
+ else if(!(r = LEFT(&link)) )
+ r = RIGHT(&link);
+ else /* graft left tree to right tree */
+ { while((t = LEFT(r)) )
+ RROTATE(r,t);
+ LEFT(r) = RIGHT(&link);
+ }
+ vd->root = r; /**/ASSERT(!r || !ISBITS(SIZE(r)));
+
+ /**/ASSERT(!vd->root || vmchktree(vd->root) == 0);
+ /**/ASSERT(!wanted || wanted == root);
+
+ return root;
+}
+
+/* Reclaim all delayed free blocks into the free tree */
+#if __STD_C
+static int bestreclaim(reg Vmdata_t* vd, Block_t* wanted, int c)
+#else
+static int bestreclaim(vd, wanted, c)
+reg Vmdata_t* vd;
+Block_t* wanted;
+int c;
+#endif
+{
+ reg size_t size, s;
+ reg Block_t *fp, *np, *t, *list;
+ reg int n, saw_wanted;
+
+ /**/COUNT(N_reclaim);
+ /**/ASSERT(_vmbestcheck(vd, NIL(Block_t*)) == 0);
+
+ if((fp = vd->free) )
+ { LINK(fp) = CACHE(vd)[S_CACHE]; CACHE(vd)[S_CACHE] = fp;
+ vd->free = NIL(Block_t*);
+ }
+
+ saw_wanted = wanted ? 0 : 1;
+ for(n = S_CACHE; n >= c; --n)
+ { list = CACHE(vd)[n]; CACHE(vd)[n] = NIL(Block_t*);
+ while((fp = list) )
+ { /* Note that below here we allow ISJUNK blocks to be
+ ** forward-merged even though they are not removed from
+ ** the list immediately. In this way, the list is
+ ** scanned only once. It works because the LINK and SIZE
+ ** fields are not destroyed during the merging. This can
+ ** be seen by observing that a tiniest block has a 2-word
+ ** header and a 2-word body. Merging a tiniest block
+ ** (1seg) and the next block (2seg) looks like this:
+ ** 1seg size link left 2seg size link left ....
+ ** 1seg size link left rite xxxx xxxx .... self
+ ** After the merge, the 2seg word is replaced by the RIGHT
+ ** pointer of the new block and somewhere beyond the
+ ** two xxxx fields, the SELF pointer will replace some
+ ** other word. The important part is that the two xxxx
+ ** fields are kept intact.
+ */
+ list = LINK(list); /**/ASSERT(!vmonlist(list,fp));
+
+ size = SIZE(fp);
+ if(!ISJUNK(size)) /* already done */
+ continue;
+
+ if(ISPFREE(size)) /* backward merge */
+ { fp = LAST(fp);
+ s = SIZE(fp); /**/ASSERT(!(s&BITS));
+ REMOVE(vd,fp,INDEX(s),t,bestsearch);
+ size = (size&~BITS) + s + sizeof(Head_t);
+ }
+ else size &= ~BITS;
+
+ for(;;) /* forward merge */
+ { np = (Block_t*)((Vmuchar_t*)fp+size+sizeof(Head_t));
+ s = SIZE(np); /**/ASSERT(s > 0);
+ if(!ISBUSY(s))
+ { /**/ASSERT((s&BITS) == 0);
+ if(np == vd->wild)
+ vd->wild = NIL(Block_t*);
+ else REMOVE(vd,np,INDEX(s),t,bestsearch);
+ }
+ else if(ISJUNK(s))
+ { /* reclaim any touched junk list */
+ if((int)C_INDEX(s) < c)
+ c = C_INDEX(s);
+ SIZE(np) = 0;
+ CLRBITS(s);
+ }
+ else break;
+ size += s + sizeof(Head_t);
+ }
+ SIZE(fp) = size;
+
+ /* tell next block that this one is free */
+ np = NEXT(fp); /**/ASSERT(ISBUSY(SIZE(np)));
+ /**/ASSERT(!ISJUNK(SIZE(np)));
+ SETPFREE(SIZE(np));
+ SELF(fp) = fp;
+
+ if(fp == wanted) /* to be consumed soon */
+ { /**/ASSERT(!saw_wanted); /* should be seen just once */
+ saw_wanted = 1;
+ continue;
+ }
+
+ /* wilderness preservation */
+ if(np->body.data >= vd->seg->baddr)
+ { vd->wild = fp;
+ continue;
+ }
+
+ /* tiny block goes to tiny list */
+ if(size < MAXTINY)
+ { s = INDEX(size);
+ np = LINK(fp) = TINY(vd)[s];
+ if(s == 0) /* TINIEST block */
+ { if(np)
+ TLEFT(np) = fp;
+ TLEFT(fp) = NIL(Block_t*);
+ }
+ else
+ { if(np)
+ LEFT(np) = fp;
+ LEFT(fp) = NIL(Block_t*);
+ SETLINK(fp);
+ }
+ TINY(vd)[s] = fp;
+ continue;
+ }
+
+ LEFT(fp) = RIGHT(fp) = LINK(fp) = NIL(Block_t*);
+ if(!(np = vd->root) ) /* inserting into an empty tree */
+ { vd->root = fp;
+ continue;
+ }
+
+ size = SIZE(fp);
+ while(1) /* leaf insertion */
+ { /**/ASSERT(np != fp);
+ if((s = SIZE(np)) > size)
+ { if((t = LEFT(np)) )
+ { /**/ ASSERT(np != t);
+ np = t;
+ }
+ else
+ { LEFT(np) = fp;
+ break;
+ }
+ }
+ else if(s < size)
+ { if((t = RIGHT(np)) )
+ { /**/ ASSERT(np != t);
+ np = t;
+ }
+ else
+ { RIGHT(np) = fp;
+ break;
+ }
+ }
+ else /* s == size */
+ { if((t = LINK(np)) )
+ { LINK(fp) = t;
+ LEFT(t) = fp;
+ }
+ LINK(np) = fp;
+ LEFT(fp) = np;
+ SETLINK(fp);
+ break;
+ }
+ }
+ }
+ }
+
+ /**/ASSERT(!wanted || saw_wanted == 1);
+ /**/ASSERT(_vmbestcheck(vd, wanted) == 0);
+ return saw_wanted;
+}
+
+#if __STD_C
+static int bestcompact(Vmalloc_t* vm, int local)
+#else
+static int bestcompact(vm, local)
+Vmalloc_t* vm;
+int local;
+#endif
+{
+ reg Seg_t *seg, *next;
+ reg Block_t *bp, *tp;
+ reg size_t size, segsize, round;
+ reg Vmdata_t* vd = vm->data;
+
+ SETLOCK(vm, local);
+
+ bestreclaim(vd,NIL(Block_t*),0);
+
+ for(seg = vd->seg; seg; seg = next)
+ { next = seg->next;
+
+ bp = BLOCK(seg->baddr);
+ if(!ISPFREE(SIZE(bp)) )
+ continue;
+
+ bp = LAST(bp); /**/ASSERT(vmisfree(vd,bp));
+ size = SIZE(bp);
+ if(bp == vd->wild)
+ { /* During large block allocations, _Vmextend might
+ ** have been enlarged the rounding factor. Reducing
+ ** it a bit help avoiding getting large raw memory.
+ */
+ if((round = vm->disc->round) == 0)
+ round = _Vmpagesize;
+ if(size > COMPACT*vd->incr && vd->incr > round)
+ vd->incr /= 2;
+
+ /* for the bottom segment, we don't necessarily want
+ ** to return raw memory too early. vd->pool has an
+ ** approximation of the average size of recently freed
+ ** blocks. If this is large, the application is managing
+ ** large blocks so we throttle back memory chopping
+ ** to avoid thrashing the underlying memory system.
+ */
+ if(size <= COMPACT*vd->incr || size <= COMPACT*vd->pool)
+ continue;
+
+ vd->wild = NIL(Block_t*);
+ vd->pool = 0;
+ }
+ else REMOVE(vd,bp,INDEX(size),tp,bestsearch);
+ tp = NEXT(bp); /* avoid strict-aliasing pun */
+ CLRPFREE(SIZE(tp));
+
+ if(size < (segsize = seg->size))
+ size += sizeof(Head_t);
+
+ if((size = (*_Vmtruncate)(vm,seg,size,0)) > 0)
+ { if(size >= segsize) /* entire segment deleted */
+ continue;
+ /**/ASSERT(SEG(BLOCK(seg->baddr)) == seg);
+
+ if((size = (seg->baddr - ((Vmuchar_t*)bp) - sizeof(Head_t))) > 0)
+ SIZE(bp) = size - sizeof(Head_t);
+ else bp = NIL(Block_t*);
+ }
+
+ if(bp)
+ { /**/ ASSERT(SIZE(bp) >= BODYSIZE);
+ /**/ ASSERT(SEGWILD(bp));
+ /**/ ASSERT(!vd->root || !vmintree(vd->root,bp));
+ SIZE(bp) |= BUSY|JUNK;
+ LINK(bp) = CACHE(vd)[C_INDEX(SIZE(bp))];
+ CACHE(vd)[C_INDEX(SIZE(bp))] = bp;
+ }
+ }
+
+ if(!local && _Vmtrace && (vd->mode&VM_TRACE) && VMETHOD(vd) == VM_MTBEST)
+ (*_Vmtrace)(vm, (Vmuchar_t*)0, (Vmuchar_t*)0, 0, 0);
+
+ CLRLOCK(vm, local); /**/ASSERT(_vmbestcheck(vd, NIL(Block_t*)) == 0);
+
+ return 0;
+}
+
+#if __STD_C
+static Void_t* bestalloc(Vmalloc_t* vm, size_t size , int local)
+#else
+static Void_t* bestalloc(vm, size, local)
+Vmalloc_t* vm; /* region allocating from */
+size_t size; /* desired block size */
+int local; /* internal call */
+#endif
+{
+ reg Vmdata_t* vd = vm->data;
+ reg size_t s;
+ reg int n;
+ reg Block_t *tp, *np, *ap;
+ size_t orgsize = size;
+
+ /**/COUNT(N_alloc);
+ /**/ASSERT(local ? (vd->lock == 1) : 1 );
+
+ SETLOCK(vm,local);
+
+ /**/ ASSERT(_vmbestcheck(vd, NIL(Block_t*)) == 0);
+ /**/ ASSERT(HEADSIZE == sizeof(Head_t));
+ /**/ ASSERT(BODYSIZE == sizeof(Body_t));
+ /**/ ASSERT((ALIGN%(BITS+1)) == 0 );
+ /**/ ASSERT((sizeof(Head_t)%ALIGN) == 0 );
+ /**/ ASSERT((sizeof(Body_t)%ALIGN) == 0 );
+ /**/ ASSERT((BODYSIZE%ALIGN) == 0 );
+ /**/ ASSERT(sizeof(Block_t) == (sizeof(Body_t)+sizeof(Head_t)) );
+
+ /* for ANSI requirement that malloc(0) returns non-NULL pointer */
+ size = size <= BODYSIZE ? BODYSIZE : ROUND(size,ALIGN);
+
+ if((tp = vd->free) ) /* reuse last free piece if appropriate */
+ { /**/ASSERT(ISBUSY(SIZE(tp)) );
+ /**/ASSERT(ISJUNK(SIZE(tp)) );
+ /**/COUNT(N_last);
+
+ vd->free = NIL(Block_t*);
+ if((s = SIZE(tp)) >= size && s < (size << 1) )
+ { if(s >= size + (sizeof(Head_t)+BODYSIZE) )
+ { SIZE(tp) = size;
+ np = NEXT(tp);
+ SEG(np) = SEG(tp);
+ SIZE(np) = ((s&~BITS) - (size+sizeof(Head_t)))|JUNK|BUSY;
+ vd->free = np;
+ SIZE(tp) |= s&BITS;
+ }
+ CLRJUNK(SIZE(tp));
+ goto done;
+ }
+
+ LINK(tp) = CACHE(vd)[S_CACHE];
+ CACHE(vd)[S_CACHE] = tp;
+ }
+
+ for(n = S_CACHE; n >= 0; --n) /* best-fit except for coalescing */
+ { bestreclaim(vd,NIL(Block_t*),n);
+ if(vd->root && (tp = bestsearch(vd,size,NIL(Block_t*))) )
+ goto got_block;
+ }
+
+ /**/ASSERT(!vd->free);
+ if((tp = vd->wild) && SIZE(tp) >= size)
+ { /**/COUNT(N_wild);
+ vd->wild = NIL(Block_t*);
+ goto got_block;
+ }
+
+ /* need to extend the arena */
+ KPVCOMPACT(vm,bestcompact);
+ if((tp = (*_Vmextend)(vm,size,bestsearch)) )
+ { got_block:
+ /**/ ASSERT(!ISBITS(SIZE(tp)));
+ /**/ ASSERT(SIZE(tp) >= size);
+ /**/ ASSERT((SIZE(tp)%ALIGN) == 0);
+ /**/ ASSERT(!vd->free);
+
+ /* tell next block that we are no longer a free block */
+ np = NEXT(tp);
+ CLRPFREE(SIZE(np)); /**/ ASSERT(ISBUSY(SIZE(np)));
+
+ if((s = SIZE(tp)-size) >= (sizeof(Head_t)+BODYSIZE) )
+ { SIZE(tp) = size;
+
+ np = NEXT(tp);
+ SEG(np) = SEG(tp);
+ SIZE(np) = (s - sizeof(Head_t)) | BUSY|JUNK;
+
+ if(VMWILD(vd,np))
+ { SIZE(np) &= ~BITS;
+ SELF(np) = np;
+ ap = NEXT(np); /**/ASSERT(ISBUSY(SIZE(ap)));
+ SETPFREE(SIZE(ap));
+ vd->wild = np;
+ }
+ else vd->free = np;
+ }
+
+ SETBUSY(SIZE(tp));
+ }
+
+done:
+ if(tp && !local && (vd->mode&VM_TRACE) && _Vmtrace && VMETHOD(vd) == VM_MTBEST)
+ (*_Vmtrace)(vm,NIL(Vmuchar_t*),(Vmuchar_t*)DATA(tp),orgsize,0);
+
+ CLRLOCK(vm,local); /**/ASSERT(_vmbestcheck(vd, NIL(Block_t*)) == 0);
+
+ return tp ? DATA(tp) : NIL(Void_t*);
+}
+
+#if __STD_C
+static long bestaddr(Vmalloc_t* vm, Void_t* addr, int local )
+#else
+static long bestaddr(vm, addr, local)
+Vmalloc_t* vm; /* region allocating from */
+Void_t* addr; /* address to check */
+int local;
+#endif
+{
+ reg Seg_t* seg;
+ reg Block_t *b, *endb;
+ reg long offset;
+ reg Vmdata_t* vd = vm->data;
+
+ /**/ASSERT(local ? (vd->lock == 1) : 1 );
+ SETLOCK(vm, local);
+
+ offset = -1L; b = endb = NIL(Block_t*);
+ for(seg = vd->seg; seg; seg = seg->next)
+ { b = SEGBLOCK(seg);
+ endb = (Block_t*)(seg->baddr - sizeof(Head_t));
+ if((Vmuchar_t*)addr > (Vmuchar_t*)b &&
+ (Vmuchar_t*)addr < (Vmuchar_t*)endb)
+ break;
+ }
+
+ if(local ) /* from bestfree or bestresize */
+ { b = BLOCK(addr);
+ if(seg && SEG(b) == seg && ISBUSY(SIZE(b)) && !ISJUNK(SIZE(b)) )
+ offset = 0;
+ }
+ else if(seg)
+ { while(b < endb)
+ { reg Vmuchar_t* data = (Vmuchar_t*)DATA(b);
+ reg size_t size = SIZE(b)&~BITS;
+
+ if((Vmuchar_t*)addr >= data && (Vmuchar_t*)addr < data+size)
+ { if(ISJUNK(SIZE(b)) || !ISBUSY(SIZE(b)))
+ offset = -1L;
+ else offset = (Vmuchar_t*)addr - data;
+ goto done;
+ }
+
+ b = (Block_t*)((Vmuchar_t*)DATA(b) + size);
+ }
+ }
+
+done:
+ CLRLOCK(vm,local);
+ return offset;
+}
+
+#if __STD_C
+static int bestfree(Vmalloc_t* vm, Void_t* data, int local )
+#else
+static int bestfree(vm, data, local )
+Vmalloc_t* vm;
+Void_t* data;
+int local;
+#endif
+{
+ reg Vmdata_t* vd = vm->data;
+ reg Block_t *bp;
+ reg size_t s;
+
+#ifdef DEBUG
+ if(((char*)data - (char*)0) <= 1)
+ { _Vmassert |= VM_check;
+ _vmbestcheck(vd, NIL(Block_t*));
+ if (!data)
+ _Vmassert &= ~VM_check;
+ return 0;
+ }
+#else
+ if(!data) /* ANSI-ism */
+ return 0;
+#endif
+
+ /**/COUNT(N_free);
+ /**/ASSERT(local ? (vd->lock == 1) : 1 );
+
+ SETLOCK(vm, local);
+
+ /**/ASSERT(KPVADDR(vm, data, bestaddr) == 0);
+ /**/ASSERT(_vmbestcheck(vd, NIL(Block_t*)) == 0);
+ bp = BLOCK(data); s = SIZE(bp);
+
+ /* Keep an approximate average free block size.
+ ** This is used in bestcompact() to decide when to release
+ ** raw memory back to the underlying memory system.
+ */
+ vd->pool = (vd->pool + (s&~BITS))/2;
+
+ if(ISBUSY(s) && !ISJUNK(s))
+ { SETJUNK(SIZE(bp));
+ if(s < MAXCACHE)
+ { /**/ASSERT(!vmonlist(CACHE(vd)[INDEX(s)], bp) );
+ LINK(bp) = CACHE(vd)[INDEX(s)];
+ CACHE(vd)[INDEX(s)] = bp;
+ }
+ else if(!vd->free)
+ vd->free = bp;
+ else
+ { /**/ASSERT(!vmonlist(CACHE(vd)[S_CACHE], bp) );
+ LINK(bp) = CACHE(vd)[S_CACHE];
+ CACHE(vd)[S_CACHE] = bp;
+ }
+
+ /* coalesce on freeing large blocks to avoid fragmentation */
+ if(SIZE(bp) >= 2*vd->incr)
+ { bestreclaim(vd,NIL(Block_t*),0);
+ if(vd->wild && SIZE(vd->wild) >= COMPACT*vd->incr)
+ KPVCOMPACT(vm,bestcompact);
+ }
+ }
+
+ if(!local && _Vmtrace && (vd->mode&VM_TRACE) && VMETHOD(vd) == VM_MTBEST )
+ (*_Vmtrace)(vm,(Vmuchar_t*)data,NIL(Vmuchar_t*), (s&~BITS), 0);
+
+ CLRLOCK(vm, local); /**/ASSERT(_vmbestcheck(vd, NIL(Block_t*)) == 0);
+
+ return 0;
+}
+
+#if __STD_C
+static Void_t* bestresize(Vmalloc_t* vm, Void_t* data, reg size_t size, int type, int local)
+#else
+static Void_t* bestresize(vm, data, size, type, local)
+Vmalloc_t* vm; /* region allocating from */
+Void_t* data; /* old block of data */
+reg size_t size; /* new size */
+int type; /* !=0 to move, <0 for not copy */
+int local;
+#endif
+{
+ reg Block_t *rp, *np, *t;
+ size_t s, bs;
+ size_t oldz = 0, orgsize = size;
+ Void_t *oldd = 0, *orgdata = data;
+ Vmdata_t *vd = vm->data;
+
+ /**/COUNT(N_resize);
+ /**/ASSERT(local ? (vd->lock == 1) : 1);
+
+ if(!data) /* resizing a NULL block is the same as allocating */
+ { data = bestalloc(vm, size, local);
+ if(data && (type&VM_RSZERO) )
+ memset((Void_t*)data, 0, size);
+ return data;
+ }
+ if(size == 0) /* resizing to zero size is the same as freeing */
+ { (void)bestfree(vm, data, local);
+ return NIL(Void_t*);
+ }
+
+ SETLOCK(vm, local);
+
+ /**/ASSERT(KPVADDR(vm, data, bestaddr) == 0);
+ /**/ASSERT(_vmbestcheck(vd, NIL(Block_t*)) == 0);
+ size = size <= BODYSIZE ? BODYSIZE : ROUND(size,ALIGN);
+ rp = BLOCK(data); /**/ASSERT(ISBUSY(SIZE(rp)) && !ISJUNK(SIZE(rp)));
+ oldz = SIZE(rp); CLRBITS(oldz);
+ if(oldz < size)
+ { np = (Block_t*)((Vmuchar_t*)rp + oldz + sizeof(Head_t));
+ do /* forward merge as much as possible */
+ { s = SIZE(np); /**/ASSERT(!ISPFREE(s));
+ if(np == vd->free)
+ { vd->free = NIL(Block_t*);
+ CLRBITS(s);
+ }
+ else if(ISJUNK(s) )
+ { if(!bestreclaim(vd,np,C_INDEX(s)) )
+ /**/ASSERT(0); /* oops: did not see np! */
+ s = SIZE(np); /**/ASSERT(s%ALIGN == 0);
+ }
+ else if(!ISBUSY(s) )
+ { if(np == vd->wild)
+ vd->wild = NIL(Block_t*);
+ else REMOVE(vd,np,INDEX(s),t,bestsearch);
+ }
+ else break;
+
+ SIZE(rp) += (s += sizeof(Head_t)); /**/ASSERT((s%ALIGN) == 0);
+ np = (Block_t*)((Vmuchar_t*)np + s);
+ CLRPFREE(SIZE(np));
+ } while(SIZE(rp) < size);
+
+ if(SIZE(rp) < size && size > vd->incr && SEGWILD(rp) )
+ { reg Seg_t* seg;
+
+ s = (size - SIZE(rp)) + sizeof(Head_t); s = ROUND(s,vd->incr);
+ seg = SEG(rp);
+ if((*vm->disc->memoryf)(vm,seg->addr,seg->extent,seg->extent+s,
+ vm->disc) == seg->addr )
+ { SIZE(rp) += s;
+ seg->extent += s;
+ seg->size += s;
+ seg->baddr += s;
+ s = (SIZE(rp)&~BITS) + sizeof(Head_t);
+ np = (Block_t*)((Vmuchar_t*)rp + s);
+ SEG(np) = seg;
+ SIZE(np) = BUSY;
+ }
+ }
+ }
+
+ if((s = SIZE(rp)) >= (size + (BODYSIZE+sizeof(Head_t))) )
+ { SIZE(rp) = size;
+ np = NEXT(rp);
+ SEG(np) = SEG(rp);
+ SIZE(np) = (((s&~BITS)-size) - sizeof(Head_t))|BUSY|JUNK;
+ CPYBITS(SIZE(rp),s);
+ rp = np;
+ goto do_free;
+ }
+ else if((bs = s&~BITS) < size)
+ { if(!(type&(VM_RSMOVE|VM_RSCOPY)) )
+ data = NIL(Void_t*); /* old data is not moveable */
+ else
+ { oldd = data;
+ if((data = KPVALLOC(vm,size,bestalloc)) )
+ { if(type&VM_RSCOPY)
+ memcpy(data, oldd, bs);
+
+ do_free: /* reclaim these right away */
+ SETJUNK(SIZE(rp));
+ LINK(rp) = CACHE(vd)[S_CACHE];
+ CACHE(vd)[S_CACHE] = rp;
+ bestreclaim(vd, NIL(Block_t*), S_CACHE);
+ }
+ }
+ }
+
+ if(data && (type&VM_RSZERO) && (size = SIZE(BLOCK(data))&~BITS) > oldz )
+ memset((Void_t*)((Vmuchar_t*)data + oldz), 0, size-oldz);
+
+ if(!local && _Vmtrace && data && (vd->mode&VM_TRACE) && VMETHOD(vd) == VM_MTBEST)
+ (*_Vmtrace)(vm, (Vmuchar_t*)orgdata, (Vmuchar_t*)data, orgsize, 0);
+
+ CLRLOCK(vm, local); /**/ASSERT(_vmbestcheck(vd, NIL(Block_t*)) == 0);
+
+ return data;
+}
+
+#if __STD_C
+static long bestsize(Vmalloc_t* vm, Void_t* addr, int local )
+#else
+static long bestsize(vm, addr, local)
+Vmalloc_t* vm; /* region allocating from */
+Void_t* addr; /* address to check */
+int local;
+#endif
+{
+ Seg_t *seg;
+ Block_t *b, *endb;
+ long size;
+ Vmdata_t *vd = vm->data;
+
+ SETLOCK(vm, local);
+
+ size = -1L;
+ for(seg = vd->seg; seg; seg = seg->next)
+ { b = SEGBLOCK(seg);
+ endb = (Block_t*)(seg->baddr - sizeof(Head_t));
+ if((Vmuchar_t*)addr <= (Vmuchar_t*)b ||
+ (Vmuchar_t*)addr >= (Vmuchar_t*)endb)
+ continue;
+ while(b < endb)
+ { if(addr == DATA(b))
+ { if(!ISBUSY(SIZE(b)) || ISJUNK(SIZE(b)) )
+ size = -1L;
+ else size = (long)SIZE(b)&~BITS;
+ goto done;
+ }
+ else if((Vmuchar_t*)addr <= (Vmuchar_t*)b)
+ break;
+
+ b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
+ }
+ }
+
+done:
+ CLRLOCK(vm, local);
+ return size;
+}
+
+#if __STD_C
+static Void_t* bestalign(Vmalloc_t* vm, size_t size, size_t align, int local)
+#else
+static Void_t* bestalign(vm, size, align, local)
+Vmalloc_t* vm;
+size_t size;
+size_t align;
+int local;
+#endif
+{
+ Vmuchar_t *data;
+ Block_t *tp, *np;
+ Seg_t *seg;
+ size_t s, extra;
+ size_t orgsize = size, orgalign = align;
+ Vmdata_t *vd = vm->data;
+
+ if(size <= 0 || align <= 0)
+ return NIL(Void_t*);
+
+ SETLOCK(vm, local);
+
+ /**/ASSERT(_vmbestcheck(vd, NIL(Block_t*)) == 0);
+ size = size <= BODYSIZE ? BODYSIZE : ROUND(size,ALIGN);
+ align = MULTIPLE(align,ALIGN);
+
+ /* hack so that dbalign() can store header data */
+ if(VMETHOD(vd) != VM_MTDEBUG)
+ extra = 0;
+ else
+ { extra = DB_HEAD;
+ while(align < extra || (align - extra) < sizeof(Block_t))
+ align *= 2;
+ }
+
+ /* reclaim all free blocks now to avoid fragmentation */
+ bestreclaim(vd,NIL(Block_t*),0);
+
+ s = size + 2*(align+sizeof(Head_t)+extra);
+ if(!(data = (Vmuchar_t*)KPVALLOC(vm,s,bestalloc)) )
+ goto done;
+
+ tp = BLOCK(data);
+ seg = SEG(tp);
+
+ /* get an aligned address that we can live with */
+ if((s = (size_t)((VLONG(data)+extra)%align)) != 0)
+ data += align-s; /**/ASSERT(((VLONG(data)+extra)%align) == 0);
+
+ if((np = BLOCK(data)) != tp ) /* need to free left part */
+ { if(((Vmuchar_t*)np - (Vmuchar_t*)tp) < (ssize_t)(sizeof(Block_t)+extra) )
+ { data += align;
+ np = BLOCK(data);
+ } /**/ASSERT(((VLONG(data)+extra)%align) == 0);
+
+ s = (Vmuchar_t*)np - (Vmuchar_t*)tp;
+ SIZE(np) = ((SIZE(tp)&~BITS) - s)|BUSY;
+ SEG(np) = seg;
+
+ SIZE(tp) = (s - sizeof(Head_t)) | (SIZE(tp)&BITS) | JUNK;
+ /**/ ASSERT(SIZE(tp) >= sizeof(Body_t) );
+ LINK(tp) = CACHE(vd)[C_INDEX(SIZE(tp))];
+ CACHE(vd)[C_INDEX(SIZE(tp))] = tp;
+ }
+
+ /* free left-over if too big */
+ if((s = SIZE(np) - size) >= sizeof(Block_t))
+ { SIZE(np) = size;
+
+ tp = NEXT(np);
+ SIZE(tp) = ((s & ~BITS) - sizeof(Head_t)) | BUSY | JUNK;
+ SEG(tp) = seg;
+ LINK(tp) = CACHE(vd)[C_INDEX(SIZE(tp))];
+ CACHE(vd)[C_INDEX(SIZE(tp))] = tp;
+
+ SIZE(np) |= s&BITS;
+ }
+
+ bestreclaim(vd,NIL(Block_t*),0); /* coalesce all free blocks */
+
+ if(!local && _Vmtrace && (vd->mode&VM_TRACE) )
+ (*_Vmtrace)(vm,NIL(Vmuchar_t*),data,orgsize,orgalign);
+
+done:
+ CLRLOCK(vm, local); /**/ASSERT(_vmbestcheck(vd, NIL(Block_t*)) == 0);
+
+ return (Void_t*)data;
+}
+
+/* The below implements the discipline Vmdcsbrk and the heap region Vmheap.
+** There are 5 alternative ways to get raw memory:
+** win32, sbrk, mmap_anon, mmap_zero and reusing the native malloc
+** The selection of method done here is to enable our malloc implementation
+** to work with concurrent threads. The sbrk/brk interface is unfortunately
+** not atomic. Thus, we prefer mmap_anon or mmap_zero if they are available.
+*/
+#if _mem_win32
+#undef _mem_mmap_anon
+#undef _mem_mmap_zero
+#undef _mem_sbrk
+#endif
+#if _mem_mmap_anon
+#undef _mem_mmap_zero
+#if !_PACKAGE_ast
+#undef _mem_sbrk
+#endif
+#endif
+#if _mem_mmap_zero
+#if !_PACKAGE_ast
+#undef _mem_sbrk
+#endif
+#endif
+
+#if _SUNOS /* sunos guarantees that brk-addresses are valid */
+#define chkaddr(a,n) (0)
+
+#else /* make sure that allocated memory are addressable */
+#include <signal.h>
+typedef void (*Sig_f)(int);
+static int Gotsegv = 0;
+
+static void sigsegv(int sig)
+{
+ if(sig == SIGSEGV)
+ Gotsegv = 1;
+}
+static int chkaddr(Vmuchar_t* addr, size_t nsize)
+{
+ Sig_f segv;
+ int rv;
+
+ Gotsegv = 0; /* catch segment fault */
+ segv = signal(SIGSEGV, sigsegv);
+
+ rv = *(addr+nsize-1);
+ rv = Gotsegv ? -1 : rv;
+
+ signal(SIGSEGV, segv); /* restore signal catcher */
+ Gotsegv = 0;
+
+ return rv;
+}
+#endif /*_SUNOS*/
+
+#if _mem_win32 /* getting memory on a window system */
+#if _PACKAGE_ast
+#include <ast_windows.h>
+#else
+#include <windows.h>
+#endif
+
+static Void_t* win32mem(Void_t* caddr, size_t csize, size_t nsize)
+{ /**/ ASSERT(csize > 0 || nsize > 0)
+ if(csize == 0)
+ { caddr = (Void_t*)VirtualAlloc(0,nsize,MEM_COMMIT,PAGE_READWRITE);
+ return caddr;
+ }
+ else if(nsize == 0)
+ { (void)VirtualFree((LPVOID)caddr,0,MEM_RELEASE);
+ return caddr;
+ }
+ else return NIL(Void_t*);
+}
+#endif /* _mem_win32 */
+
+#if _mem_sbrk /* getting space via brk/sbrk - not concurrent-ready */
+static Void_t* sbrkmem(Void_t* caddr, size_t csize, size_t nsize)
+{
+ Vmuchar_t *addr = (Vmuchar_t*)sbrk(0);
+
+ if(!addr || addr == (Vmuchar_t*)(-1) )
+ return NIL(Void_t*);
+
+ if(csize > 0 && addr != (Vmuchar_t*)caddr+csize)
+ return NIL(Void_t*);
+ else if(csize == 0)
+ caddr = addr;
+
+ /**/ASSERT(addr == (Vmuchar_t*)caddr+csize);
+ if(nsize < csize)
+ addr -= csize-nsize;
+ else if((addr += nsize-csize) < (Vmuchar_t*)caddr )
+ return NIL(Void_t*);
+
+ if(brk(addr) != 0 )
+ return NIL(Void_t*);
+ else if(nsize > csize && chkaddr(caddr, nsize) < 0 )
+ { (void)brk((Vmuchar_t*)caddr+csize);
+ return NIL(Void_t*);
+ }
+ else return caddr;
+}
+#endif /* _mem_sbrk */
+
+#if _mem_mmap_anon || _mem_mmap_zero /* get space using mmap */
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#ifndef MAP_ANON
+#ifdef MAP_ANONYMOUS
+#define MAP_ANON MAP_ANONYMOUS
+#else
+#define MAP_ANON 0
+#endif
+#endif /*MAP_ANON*/
+
+#ifndef OPEN_MAX
+#define OPEN_MAX 64
+#endif
+#define FD_PRIVATE (3*OPEN_MAX/4) /* private file descriptor */
+#define FD_INIT (-1) /* uninitialized file desc */
+#define FD_NONE (-2) /* no mapping with file desc */
+
+typedef struct _mmdisc_s
+{ Vmdisc_t disc;
+ int fd;
+ off_t offset;
+} Mmdisc_t;
+
+static Void_t* mmapmem(Void_t* caddr, size_t csize, size_t nsize, Mmdisc_t* mmdc)
+{
+#if _mem_mmap_zero
+ if(mmdc) /* /dev/zero mapping */
+ { if(mmdc->fd == FD_INIT ) /* open /dev/zero for mapping */
+ { int fd;
+ if((fd = open("/dev/zero", O_RDONLY)) < 0 )
+ { mmdc->fd = FD_NONE;
+ return NIL(Void_t*);
+ }
+ if(fd >= FD_PRIVATE || (mmdc->fd = dup2(fd, FD_PRIVATE)) < 0 )
+ mmdc->fd = fd;
+ else close(fd);
+#ifdef FD_CLOEXEC
+ fcntl(mmdc->fd, F_SETFD, FD_CLOEXEC);
+#endif
+ }
+
+ if(mmdc->fd == FD_NONE)
+ return NIL(Void_t*);
+ }
+#endif /* _mem_mmap_zero */
+
+ /**/ASSERT(csize > 0 || nsize > 0);
+ if(csize == 0)
+ { nsize = ROUND(nsize, _Vmpagesize);
+ caddr = NIL(Void_t*);
+#if _mem_mmap_zero
+ if(mmdc && mmdc->fd >= 0 )
+ caddr = mmap(0, nsize, PROT_READ|PROT_WRITE, MAP_PRIVATE, mmdc->fd, mmdc->offset);
+#endif
+#if _mem_mmap_anon
+ if(!mmdc )
+ caddr = mmap(0, nsize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+#endif
+ if(!caddr || caddr == (Void_t*)(-1))
+ return NIL(Void_t*);
+ else if(chkaddr((Vmuchar_t*)caddr, nsize) < 0 )
+ { (void)munmap(caddr, nsize);
+ return NIL(Void_t*);
+ }
+ else
+ { if(mmdc)
+ mmdc->offset += nsize;
+ return caddr;
+ }
+ }
+ else if(nsize == 0)
+ { Vmuchar_t *addr = (Vmuchar_t*)sbrk(0);
+ if(addr < (Vmuchar_t*)caddr ) /* in sbrk space */
+ return NIL(Void_t*);
+ else
+ { (void)munmap(caddr, csize);
+ return caddr;
+ }
+ }
+ else return NIL(Void_t*);
+}
+#endif /* _mem_map_anon || _mem_mmap_zero */
+
+#if _std_malloc /* using native malloc as a last resource */
+static Void_t* mallocmem(Void_t* caddr, size_t csize, size_t nsize)
+{
+ /**/ASSERT(csize > 0 || nsize > 0);
+ if(csize == 0)
+ return (Void_t*)malloc(nsize);
+ else if(nsize == 0)
+ { free(caddr);
+ return caddr;
+ }
+ else return NIL(Void_t*);
+}
+#endif
+
+/* A discipline to get raw memory using VirtualAlloc/mmap/sbrk */
+static Void_t* getmemory(Vmalloc_t* vm, Void_t* caddr, size_t csize, size_t nsize, Vmdisc_t* disc)
+{
+ Vmuchar_t *addr;
+
+ if((csize > 0 && !caddr) || (csize == 0 && nsize == 0) )
+ return NIL(Void_t*);
+
+#if _mem_win32
+ if((addr = win32mem(caddr, csize, nsize)) )
+ return (Void_t*)addr;
+#endif
+#if _mem_sbrk
+ if((_Vmassert & VM_break) && (addr = sbrkmem(caddr, csize, nsize)) )
+ return (Void_t*)addr;
+#endif
+#if _mem_mmap_anon
+ if((addr = mmapmem(caddr, csize, nsize, (Mmdisc_t*)0)) )
+ return (Void_t*)addr;
+#endif
+#if _mem_mmap_zero
+ if((addr = mmapmem(caddr, csize, nsize, (Mmdisc_t*)disc)) )
+ return (Void_t*)addr;
+#endif
+#if _mem_sbrk
+ if(!(_Vmassert & VM_break) && (addr = sbrkmem(caddr, csize, nsize)) )
+ return (Void_t*)addr;
+#endif
+#if _std_malloc
+ if((addr = mallocmem(caddr, csize, nsize)) )
+ return (Void_t*)addr;
+#endif
+ return NIL(Void_t*);
+}
+
+#if _mem_mmap_zero || _mem_mmap_anon
+static Mmdisc_t _Vmdcsystem = { { getmemory, NIL(Vmexcept_f), 64*1024, sizeof(Mmdisc_t) }, FD_INIT, 0 };
+#else
+static Vmdisc_t _Vmdcsystem = { getmemory, NIL(Vmexcept_f), 0, sizeof(Vmdisc_t) };
+#endif
+
+static Vmethod_t _Vmbest =
+{
+ bestalloc,
+ bestresize,
+ bestfree,
+ bestaddr,
+ bestsize,
+ bestcompact,
+ bestalign,
+ VM_MTBEST
+};
+
+/* The heap region */
+static Vmdata_t _Vmdata =
+{
+ 0, /* lock */
+ VM_MTBEST|VM_SHARE, /* mode */
+ 0, /* incr */
+ 0, /* pool */
+ NIL(Seg_t*), /* seg */
+ NIL(Block_t*), /* free */
+ NIL(Block_t*), /* wild */
+ NIL(Block_t*) /* root */
+ /* tiny[] */
+ /* cache[] */
+};
+Vmalloc_t _Vmheap =
+{
+ { bestalloc,
+ bestresize,
+ bestfree,
+ bestaddr,
+ bestsize,
+ bestcompact,
+ bestalign,
+ VM_MTBEST
+ },
+ NIL(char*), /* file */
+ 0, /* line */
+ 0, /* func */
+ (Vmdisc_t*)(&_Vmdcsystem), /* disc */
+ &_Vmdata, /* data */
+ NIL(Vmalloc_t*) /* next */
+};
+
+__DEFINE__(Vmalloc_t*, Vmheap, &_Vmheap);
+__DEFINE__(Vmalloc_t*, Vmregion, &_Vmheap);
+__DEFINE__(Vmethod_t*, Vmbest, &_Vmbest);
+__DEFINE__(Vmdisc_t*, Vmdcsystem, (Vmdisc_t*)(&_Vmdcsystem) );
+__DEFINE__(Vmdisc_t*, Vmdcsbrk, (Vmdisc_t*)(&_Vmdcsystem) );
+
+#ifdef NoF
+NoF(vmbest)
+#endif
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmclear.c b/src/lib/libast/vmalloc/vmclear.c
new file mode 100644
index 0000000..c4b8107
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmclear.c
@@ -0,0 +1,85 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmclear(){}
+
+#else
+
+#include "vmhdr.h"
+
+/* Clear out all allocated space.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+#if __STD_C
+int vmclear(Vmalloc_t* vm)
+#else
+int vmclear(vm)
+Vmalloc_t* vm;
+#endif
+{
+ Seg_t *seg, *next;
+ Block_t *tp;
+ size_t size, s;
+ Vmdata_t *vd = vm->data;
+
+ SETLOCK(vm, 0);
+
+ vd->free = vd->wild = NIL(Block_t*);
+ vd->pool = 0;
+
+ if(vd->mode&(VM_MTBEST|VM_MTDEBUG|VM_MTPROFILE) )
+ { vd->root = NIL(Block_t*);
+ for(s = 0; s < S_TINY; ++s)
+ TINY(vd)[s] = NIL(Block_t*);
+ for(s = 0; s <= S_CACHE; ++s)
+ CACHE(vd)[s] = NIL(Block_t*);
+ }
+
+ for(seg = vd->seg; seg; seg = next)
+ { next = seg->next;
+
+ tp = SEGBLOCK(seg);
+ size = seg->baddr - ((Vmuchar_t*)tp) - 2*sizeof(Head_t);
+
+ SEG(tp) = seg;
+ SIZE(tp) = size;
+ if((vd->mode&(VM_MTLAST|VM_MTPOOL)) )
+ seg->free = tp;
+ else
+ { SIZE(tp) |= BUSY|JUNK;
+ LINK(tp) = CACHE(vd)[C_INDEX(SIZE(tp))];
+ CACHE(vd)[C_INDEX(SIZE(tp))] = tp;
+ }
+
+ tp = BLOCK(seg->baddr);
+ SEG(tp) = seg;
+ SIZE(tp) = BUSY;
+ }
+
+ CLRLOCK(vm, 0);
+
+ return 0;
+}
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmclose.c b/src/lib/libast/vmalloc/vmclose.c
new file mode 100644
index 0000000..65a3a7e
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmclose.c
@@ -0,0 +1,91 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmclose(){}
+
+#else
+
+#include "vmhdr.h"
+
+/* Close down a region.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+#if __STD_C
+int vmclose(Vmalloc_t* vm)
+#else
+int vmclose(vm)
+Vmalloc_t* vm;
+#endif
+{
+ Seg_t *seg, *vmseg, *next;
+ Vmalloc_t *v, *last, vmp;
+ Vmdata_t* vd = vm->data;
+ Vmdisc_t* disc = vm->disc;
+ int mode, rv = 0;
+
+ if(vm == Vmheap) /* the heap is never freed */
+ return -1;
+
+ if(vm->disc->exceptf && /* announcing closing event */
+ (rv = (*vm->disc->exceptf)(vm,VM_CLOSE,(Void_t*)1,vm->disc)) < 0 )
+ return -1;
+
+ mode = vd->mode; /* remember this in case it gets destroyed below */
+
+ if((mode&VM_MTPROFILE) && _Vmpfclose)
+ (*_Vmpfclose)(vm);
+
+ /* remove from linked list of regions */
+ _vmlock(NIL(Vmalloc_t*), 1);
+ for(last = Vmheap, v = last->next; v; last = v, v = v->next)
+ { if(v == vm)
+ { last->next = v->next;
+ break;
+ }
+ }
+ _vmlock(NIL(Vmalloc_t*), 0);
+
+ if(rv == 0) /* deallocate memory obtained from the system */
+ { /* lock-free because alzheimer can cause deadlocks :) */
+ vmseg = NIL(Seg_t*);
+ for(seg = vd->seg; seg; seg = next)
+ { next = seg->next;
+ if(seg->extent == seg->size) /* root segment */
+ vmseg = seg; /* don't free this yet */
+ else (*disc->memoryf)(vm,seg->addr,seg->extent,0,disc);
+ }
+ if(vmseg) /* now safe to free root segment */
+ (*disc->memoryf)(vm,vmseg->addr,vmseg->extent,0,disc);
+ }
+
+ if(disc->exceptf) /* finalizing closing */
+ (void)(*disc->exceptf)(vm, VM_ENDCLOSE, (Void_t*)0, disc);
+
+ if(!(mode & VM_MEMORYF) )
+ vmfree(Vmheap,vm);
+
+ return 0;
+}
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmdcheap.c b/src/lib/libast/vmalloc/vmdcheap.c
new file mode 100644
index 0000000..88edc72
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmdcheap.c
@@ -0,0 +1,63 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmdcheap(){}
+
+#else
+
+#include "vmhdr.h"
+
+/* A discipline to get memory from the heap.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+#if __STD_C
+static Void_t* heapmem(Vmalloc_t* vm, Void_t* caddr,
+ size_t csize, size_t nsize,
+ Vmdisc_t* disc)
+#else
+static Void_t* heapmem(vm, caddr, csize, nsize, disc)
+Vmalloc_t* vm; /* region doing allocation from */
+Void_t* caddr; /* current low address */
+size_t csize; /* current size */
+size_t nsize; /* new size */
+Vmdisc_t* disc; /* discipline structure */
+#endif
+{
+ if(csize == 0 && nsize == 0)
+ return NIL(Void_t*);
+ else if(csize == 0)
+ return vmalloc(Vmheap,nsize);
+ else if(nsize == 0)
+ return vmfree(Vmheap,caddr) >= 0 ? caddr : NIL(Void_t*);
+ else return vmresize(Vmheap,caddr,nsize,0);
+}
+
+static Vmdisc_t _Vmdcheap = { heapmem, NIL(Vmexcept_f), 0 };
+__DEFINE__(Vmdisc_t*,Vmdcheap,&_Vmdcheap);
+
+#ifdef NoF
+NoF(vmdcheap)
+#endif
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmdebug.c b/src/lib/libast/vmalloc/vmdebug.c
new file mode 100644
index 0000000..160c189
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmdebug.c
@@ -0,0 +1,745 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmdebug(){}
+
+#else
+
+#include "vmhdr.h"
+
+/* Method to help with debugging. This does rigorous checks on
+** addresses and arena integrity.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+
+/* structure to keep track of file names */
+typedef struct _dbfile_s Dbfile_t;
+struct _dbfile_s
+{ Dbfile_t* next;
+ char file[1];
+};
+static Dbfile_t* Dbfile;
+
+/* global watch list */
+#define S_WATCH 32
+static int Dbnwatch;
+static Void_t* Dbwatch[S_WATCH];
+
+/* types of warnings reported by dbwarn() */
+#define DB_CHECK 0
+#define DB_ALLOC 1
+#define DB_FREE 2
+#define DB_RESIZE 3
+#define DB_WATCH 4
+#define DB_RESIZED 5
+
+static int Dbinit = 0;
+#define DBINIT() (Dbinit ? 0 : (dbinit(), Dbinit=1) )
+static void dbinit()
+{ int fd;
+ if((fd = vmtrace(-1)) >= 0)
+ vmtrace(fd);
+}
+
+static int Dbfd = 2; /* default warning file descriptor */
+#if __STD_C
+int vmdebug(int fd)
+#else
+int vmdebug(fd)
+int fd;
+#endif
+{
+ int old = Dbfd;
+ Dbfd = fd;
+ return old;
+}
+
+
+/* just an entry point to make it easy to set break point */
+#if __STD_C
+static void vmdbwarn(Vmalloc_t* vm, char* mesg, int n)
+#else
+static void vmdbwarn(vm, mesg, n)
+Vmalloc_t* vm;
+char* mesg;
+int n;
+#endif
+{
+ reg Vmdata_t* vd = vm->data;
+
+ write(Dbfd,mesg,n);
+ if(vd->mode&VM_DBABORT)
+ abort();
+}
+
+/* issue a warning of some type */
+#if __STD_C
+static void dbwarn(Vmalloc_t* vm, Void_t* data, int where,
+ char* file, int line, Void_t* func, int type)
+#else
+static void dbwarn(vm, data, where, file, line, func, type)
+Vmalloc_t* vm; /* region holding the block */
+Void_t* data; /* data block */
+int where; /* byte that was corrupted */
+char* file; /* file where call originates */
+int line; /* line number of call */
+Void_t* func; /* function called from */
+int type; /* operation being done */
+#endif
+{
+ char buf[1024], *bufp, *endbuf, *s;
+#define SLOP 64 /* enough for a message and an int */
+
+ DBINIT();
+
+ bufp = buf;
+ endbuf = buf + sizeof(buf);
+
+ if(type == DB_ALLOC)
+ bufp = (*_Vmstrcpy)(bufp, "alloc error", ':');
+ else if(type == DB_FREE)
+ bufp = (*_Vmstrcpy)(bufp, "free error", ':');
+ else if(type == DB_RESIZE)
+ bufp = (*_Vmstrcpy)(bufp, "resize error", ':');
+ else if(type == DB_CHECK)
+ bufp = (*_Vmstrcpy)(bufp, "corrupted data", ':');
+ else if(type == DB_WATCH)
+ bufp = (*_Vmstrcpy)(bufp, "alert", ':');
+
+ /* region info */
+ bufp = (*_Vmstrcpy)(bufp, "region", '=');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(vm), 0), ':');
+
+ if(data)
+ { bufp = (*_Vmstrcpy)(bufp,"block",'=');
+ bufp = (*_Vmstrcpy)(bufp,(*_Vmitoa)(VLONG(data),0),':');
+ }
+
+ if(!data)
+ { if(where == DB_ALLOC)
+ bufp = (*_Vmstrcpy)(bufp, "can't get memory", ':');
+ else bufp = (*_Vmstrcpy)(bufp, "region is locked", ':');
+ }
+ else if(type == DB_FREE || type == DB_RESIZE)
+ { if(where == 0)
+ bufp = (*_Vmstrcpy)(bufp, "unallocated block", ':');
+ else bufp = (*_Vmstrcpy)(bufp, "already freed", ':');
+ }
+ else if(type == DB_WATCH)
+ { bufp = (*_Vmstrcpy)(bufp, "size", '=');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(DBSIZE(data),-1), ':');
+ if(where == DB_ALLOC)
+ bufp = (*_Vmstrcpy)(bufp,"just allocated", ':');
+ else if(where == DB_FREE)
+ bufp = (*_Vmstrcpy)(bufp,"being freed", ':');
+ else if(where == DB_RESIZE)
+ bufp = (*_Vmstrcpy)(bufp,"being resized", ':');
+ else if(where == DB_RESIZED)
+ bufp = (*_Vmstrcpy)(bufp,"just resized", ':');
+ }
+ else if(type == DB_CHECK)
+ { bufp = (*_Vmstrcpy)(bufp, "bad byte at", '=');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(where),-1), ':');
+ if((s = DBFILE(data)) && (bufp + strlen(s) + SLOP) < endbuf)
+ { bufp = (*_Vmstrcpy)(bufp,"allocated at", '=');
+ bufp = (*_Vmstrcpy)(bufp, s, ',');
+ bufp = (*_Vmstrcpy)(bufp,(*_Vmitoa)(VLONG(DBLINE(data)),-1),':');
+ }
+ }
+
+ /* location where offending call originates from */
+ if(file && file[0] && line > 0 && (bufp + strlen(file) + SLOP) < endbuf)
+ { bufp = (*_Vmstrcpy)(bufp, "detected at", '=');
+ bufp = (*_Vmstrcpy)(bufp, file, ',');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(line),-1), ',');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(func),-1), ':');
+ }
+
+ *bufp++ = '\n';
+ *bufp = '\0';
+
+ vmdbwarn(vm,buf,(bufp-buf));
+}
+
+/* check for watched address and issue warnings */
+#if __STD_C
+static void dbwatch(Vmalloc_t* vm, Void_t* data,
+ char* file, int line, Void_t* func, int type)
+#else
+static void dbwatch(vm, data, file, line, func, type)
+Vmalloc_t* vm;
+Void_t* data;
+char* file;
+int line;
+Void_t* func;
+int type;
+#endif
+{
+ reg int n;
+
+ for(n = Dbnwatch; n >= 0; --n)
+ { if(Dbwatch[n] == data)
+ { dbwarn(vm,data,type,file,line,func,DB_WATCH);
+ return;
+ }
+ }
+}
+
+/* record information about the block */
+#if __STD_C
+static void dbsetinfo(Vmuchar_t* data, size_t size, char* file, int line)
+#else
+static void dbsetinfo(data, size, file, line)
+Vmuchar_t* data; /* real address not the one from Vmbest */
+size_t size; /* the actual requested size */
+char* file; /* file where the request came from */
+int line; /* and line number */
+#endif
+{
+ reg Vmuchar_t *begp, *endp;
+ reg Dbfile_t *last, *db;
+
+ DBINIT();
+
+ /* find the file structure */
+ if(!file || !file[0])
+ db = NIL(Dbfile_t*);
+ else
+ { for(last = NIL(Dbfile_t*), db = Dbfile; db; last = db, db = db->next)
+ if(strcmp(db->file,file) == 0)
+ break;
+ if(!db)
+ { db = (Dbfile_t*)vmalloc(Vmheap,sizeof(Dbfile_t)+strlen(file));
+ if(db)
+ { (*_Vmstrcpy)(db->file,file,0);
+ db->next = Dbfile;
+ Dbfile = db;
+ }
+ }
+ else if(last) /* move-to-front heuristic */
+ { last->next = db->next;
+ db->next = Dbfile;
+ Dbfile = db;
+ }
+ }
+
+ DBSETFL(data,(db ? db->file : NIL(char*)),line);
+ DBSIZE(data) = size;
+ DBSEG(data) = SEG(DBBLOCK(data));
+
+ DBHEAD(data,begp,endp);
+ while(begp < endp)
+ *begp++ = DB_MAGIC;
+ DBTAIL(data,begp,endp);
+ while(begp < endp)
+ *begp++ = DB_MAGIC;
+}
+
+/* Check to see if an address is in some data block of a region.
+** This returns -(offset+1) if block is already freed, +(offset+1)
+** if block is live, 0 if no match.
+*/
+#if __STD_C
+static long dbaddr(Vmalloc_t* vm, Void_t* addr, int local)
+#else
+static long dbaddr(vm, addr, local)
+Vmalloc_t* vm;
+Void_t* addr;
+int local;
+#endif
+{
+ reg Block_t *b, *endb;
+ reg Seg_t *seg;
+ reg Vmuchar_t *data;
+ reg long offset = -1L;
+ reg Vmdata_t *vd = vm->data;
+
+ SETLOCK(vm, local);
+
+ b = endb = NIL(Block_t*);
+ for(seg = vd->seg; seg; seg = seg->next)
+ { b = SEGBLOCK(seg);
+ endb = (Block_t*)(seg->baddr - sizeof(Head_t));
+ if((Vmuchar_t*)addr > (Vmuchar_t*)b &&
+ (Vmuchar_t*)addr < (Vmuchar_t*)endb)
+ break;
+ }
+ if(!seg)
+ goto done;
+
+ if(local) /* must be vmfree or vmresize checking address */
+ { if(DBSEG(addr) == seg)
+ { b = DBBLOCK(addr);
+ if(ISBUSY(SIZE(b)) && !ISJUNK(SIZE(b)) )
+ offset = 0;
+ else offset = -2L;
+ }
+ goto done;
+ }
+
+ while(b < endb)
+ { data = (Vmuchar_t*)DATA(b);
+ if((Vmuchar_t*)addr >= data && (Vmuchar_t*)addr < data+SIZE(b))
+ { if(ISBUSY(SIZE(b)) && !ISJUNK(SIZE(b)) )
+ { data = DB2DEBUG(data);
+ if((Vmuchar_t*)addr >= data &&
+ (Vmuchar_t*)addr < data+DBSIZE(data))
+ offset = (Vmuchar_t*)addr - data;
+ }
+ goto done;
+ }
+
+ b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
+ }
+
+done:
+ CLRLOCK(vm, local);
+ return offset;
+}
+
+
+#if __STD_C
+static long dbsize(Vmalloc_t* vm, Void_t* addr, int local)
+#else
+static long dbsize(vm, addr, local)
+Vmalloc_t* vm;
+Void_t* addr;
+int local;
+#endif
+{
+ Block_t *b, *endb;
+ Seg_t *seg;
+ long size;
+ Vmdata_t *vd = vm->data;
+
+ SETLOCK(vm, local);
+
+ size = -1L;
+ for(seg = vd->seg; seg; seg = seg->next)
+ { b = SEGBLOCK(seg);
+ endb = (Block_t*)(seg->baddr - sizeof(Head_t));
+ if((Vmuchar_t*)addr <= (Vmuchar_t*)b ||
+ (Vmuchar_t*)addr >= (Vmuchar_t*)endb)
+ continue;
+ while(b < endb)
+ { if(addr == (Void_t*)DB2DEBUG(DATA(b)))
+ { if(ISBUSY(SIZE(b)) && !ISJUNK(SIZE(b)) )
+ size = (long)DBSIZE(addr);
+ goto done;
+ }
+
+ b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
+ }
+ }
+
+done:
+ CLRLOCK(vm, local);
+ return size;
+}
+
+#if __STD_C
+static Void_t* dballoc(Vmalloc_t* vm, size_t size, int local)
+#else
+static Void_t* dballoc(vm, size, local)
+Vmalloc_t* vm;
+size_t size;
+int local;
+#endif
+{
+ size_t s;
+ Vmuchar_t *data;
+ char *file;
+ int line;
+ Void_t *func;
+ Vmdata_t *vd = vm->data;
+ VMFLF(vm,file,line,func);
+
+ SETLOCK(vm, local);
+
+ if(vd->mode&VM_DBCHECK)
+ vmdbcheck(vm);
+
+ s = ROUND(size,ALIGN) + DB_EXTRA;
+ if(s < sizeof(Body_t)) /* no tiny blocks during Vmdebug */
+ s = sizeof(Body_t);
+
+ if(!(data = (Vmuchar_t*)KPVALLOC(vm,s,(*(Vmbest->allocf))) ) )
+ { dbwarn(vm,NIL(Vmuchar_t*),DB_ALLOC,file,line,func,DB_ALLOC);
+ goto done;
+ }
+
+ data = DB2DEBUG(data);
+ dbsetinfo(data,size,file,line);
+
+ if((vd->mode&VM_TRACE) && _Vmtrace)
+ { vm->file = file; vm->line = line; vm->func = func;
+ (*_Vmtrace)(vm,NIL(Vmuchar_t*),data,size,0);
+ }
+
+ if(Dbnwatch > 0 )
+ dbwatch(vm,data,file,line,func,DB_ALLOC);
+
+done:
+ CLRLOCK(vm, local);
+
+ return (Void_t*)data;
+}
+
+
+#if __STD_C
+static int dbfree(Vmalloc_t* vm, Void_t* data, int local )
+#else
+static int dbfree(vm, data, local )
+Vmalloc_t* vm;
+Void_t* data;
+int local;
+#endif
+{
+ char *file;
+ int line;
+ Void_t *func;
+ long offset;
+ int rv, *ip, *endip;
+ Vmdata_t *vd = vm->data;
+ VMFLF(vm,file,line,func);
+
+ if(!data)
+ return 0;
+
+ SETLOCK(vm, local);
+
+ if(vd->mode&VM_DBCHECK)
+ vmdbcheck(vm);
+
+ if((offset = KPVADDR(vm,data,dbaddr)) != 0)
+ { dbwarn(vm,(Vmuchar_t*)data,offset == -1L ? 0 : 1,file,line,func,DB_FREE);
+ rv = -1;
+ }
+ else
+ { if(Dbnwatch > 0)
+ dbwatch(vm,data,file,line,func,DB_FREE);
+
+ if((vd->mode&VM_TRACE) && _Vmtrace)
+ { vm->file = file; vm->line = line; vm->func = func;
+ (*_Vmtrace)(vm,(Vmuchar_t*)data,NIL(Vmuchar_t*),DBSIZE(data),0);
+ }
+
+ /* clear free space */
+ ip = (int*)data;
+ endip = ip + (DBSIZE(data)+sizeof(int)-1)/sizeof(int);
+ while(ip < endip)
+ *ip++ = 0;
+
+ rv = KPVFREE((vm), (Void_t*)DB2BEST(data), (*Vmbest->freef));
+ }
+
+ CLRLOCK(vm, local);
+ return rv;
+}
+
+/* Resizing an existing block */
+#if __STD_C
+static Void_t* dbresize(Vmalloc_t* vm, Void_t* addr, reg size_t size, int type, int local)
+#else
+static Void_t* dbresize(vm, addr, size, type, local)
+Vmalloc_t* vm; /* region allocating from */
+Void_t* addr; /* old block of data */
+reg size_t size; /* new size */
+int type; /* !=0 for movable, >0 for copy */
+int local;
+#endif
+{
+ Vmuchar_t *data;
+ long offset;
+ size_t s, oldsize;
+ char *file, *oldfile;
+ int line, oldline;
+ Void_t *func;
+ Vmdata_t *vd = vm->data;
+ VMFLF(vm,file,line,func);
+
+ if(!addr)
+ { vm->file = file; vm->line = line;
+ data = (Vmuchar_t*)dballoc(vm, size, local);
+ if(data && (type&VM_RSZERO) )
+ memset((Void_t*)data, 0, size);
+ return data;
+ }
+ if(size == 0)
+ { vm->file = file; vm->line = line;
+ (void)dbfree(vm, addr, local);
+ return NIL(Void_t*);
+ }
+
+ SETLOCK(vm, local);
+
+ if(vd->mode&VM_DBCHECK)
+ vmdbcheck(vm);
+
+ if((offset = KPVADDR(vm,addr,dbaddr)) != 0)
+ { dbwarn(vm,(Vmuchar_t*)addr,offset == -1L ? 0 : 1,file,line,func,DB_RESIZE);
+ data = NIL(Vmuchar_t*);
+ }
+ else
+ { if(Dbnwatch > 0)
+ dbwatch(vm,addr,file,line,func,DB_RESIZE);
+
+ /* Vmbest data block */
+ data = DB2BEST(addr);
+ oldsize = DBSIZE(addr);
+ oldfile = DBFILE(addr);
+ oldline = DBLINE(addr);
+
+ /* do the resize */
+ s = ROUND(size,ALIGN) + DB_EXTRA;
+ if(s < sizeof(Body_t))
+ s = sizeof(Body_t);
+ data = (Vmuchar_t*)KPVRESIZE(vm,(Void_t*)data,s,
+ (type&~VM_RSZERO),(*(Vmbest->resizef)) );
+ if(!data) /* failed, reset data for old block */
+ { dbwarn(vm,NIL(Vmuchar_t*),DB_ALLOC,file,line,func,DB_RESIZE);
+ dbsetinfo((Vmuchar_t*)addr,oldsize,oldfile,oldline);
+ }
+ else
+ { data = DB2DEBUG(data);
+ dbsetinfo(data,size,file,line);
+
+ if((vd->mode&VM_TRACE) && _Vmtrace)
+ { vm->file = file; vm->line = line;
+ (*_Vmtrace)(vm,(Vmuchar_t*)addr,data,size,0);
+ }
+ if(Dbnwatch > 0)
+ dbwatch(vm,data,file,line,func,DB_RESIZED);
+ }
+
+ if(data && (type&VM_RSZERO) && size > oldsize)
+ { Vmuchar_t *d = data+oldsize, *ed = data+size;
+ do { *d++ = 0; } while(d < ed);
+ }
+ }
+
+ CLRLOCK(vm, local);
+
+ return (Void_t*)data;
+}
+
+/* compact any residual free space */
+#if __STD_C
+static int dbcompact(Vmalloc_t* vm, int local)
+#else
+static int dbcompact(vm, local)
+Vmalloc_t* vm;
+int local;
+#endif
+{
+ return (*(Vmbest->compactf))(vm, local);
+}
+
+/* check for memory overwrites over all live blocks */
+#if __STD_C
+int vmdbcheck(Vmalloc_t* vm)
+#else
+int vmdbcheck(vm)
+Vmalloc_t* vm;
+#endif
+{
+ reg Block_t *b, *endb;
+ reg Seg_t* seg;
+ int rv;
+ reg Vmdata_t* vd = vm->data;
+
+ /* check the meta-data of this region */
+ if(vd->mode & (VM_MTDEBUG|VM_MTBEST|VM_MTPROFILE))
+ { if(_vmbestcheck(vd, NIL(Block_t*)) < 0)
+ return -1;
+ if(!(vd->mode&VM_MTDEBUG) )
+ return 0;
+ }
+ else return -1;
+
+ rv = 0;
+ for(seg = vd->seg; seg; seg = seg->next)
+ { b = SEGBLOCK(seg);
+ endb = (Block_t*)(seg->baddr - sizeof(Head_t));
+ while(b < endb)
+ { reg Vmuchar_t *data, *begp, *endp;
+
+ if(ISJUNK(SIZE(b)) || !ISBUSY(SIZE(b)))
+ goto next;
+
+ data = DB2DEBUG(DATA(b));
+ if(DBISBAD(data)) /* seen this before */
+ { rv += 1;
+ goto next;
+ }
+
+ DBHEAD(data,begp,endp);
+ for(; begp < endp; ++begp)
+ if(*begp != DB_MAGIC)
+ goto set_bad;
+
+ DBTAIL(data,begp,endp);
+ for(; begp < endp; ++begp)
+ { if(*begp == DB_MAGIC)
+ continue;
+ set_bad:
+ dbwarn(vm,data,begp-data,vm->file,vm->line,0,DB_CHECK);
+ DBSETBAD(data);
+ rv += 1;
+ goto next;
+ }
+
+ next: b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS));
+ }
+ }
+
+ return rv;
+}
+
+/* set/delete an address to watch */
+#if __STD_C
+Void_t* vmdbwatch(Void_t* addr)
+#else
+Void_t* vmdbwatch(addr)
+Void_t* addr; /* address to insert */
+#endif
+{
+ reg int n;
+ reg Void_t* out;
+
+ out = NIL(Void_t*);
+ if(!addr)
+ Dbnwatch = 0;
+ else
+ { for(n = Dbnwatch - 1; n >= 0; --n)
+ if(Dbwatch[n] == addr)
+ break;
+ if(n < 0) /* insert */
+ { if(Dbnwatch == S_WATCH)
+ { /* delete left-most */
+ out = Dbwatch[0];
+ Dbnwatch -= 1;
+ for(n = 0; n < Dbnwatch; ++n)
+ Dbwatch[n] = Dbwatch[n+1];
+ }
+ Dbwatch[Dbnwatch] = addr;
+ Dbnwatch += 1;
+ }
+ }
+ return out;
+}
+
+#if __STD_C
+static Void_t* dbalign(Vmalloc_t* vm, size_t size, size_t align, int local)
+#else
+static Void_t* dbalign(vm, size, align, local)
+Vmalloc_t* vm;
+size_t size;
+size_t align;
+int local;
+#endif
+{
+ Vmuchar_t *data;
+ size_t s;
+ char *file;
+ int line;
+ Void_t *func;
+ Vmdata_t *vd = vm->data;
+ VMFLF(vm,file,line,func);
+
+ if(size <= 0 || align <= 0)
+ return NIL(Void_t*);
+
+ SETLOCK(vm, local);
+
+ if((s = ROUND(size,ALIGN) + DB_EXTRA) < sizeof(Body_t))
+ s = sizeof(Body_t);
+
+ if((data = (Vmuchar_t*)KPVALIGN(vm,s,align,(*(Vmbest->alignf)))) )
+ { data += DB_HEAD;
+ dbsetinfo(data,size,file,line);
+
+ if((vd->mode&VM_TRACE) && _Vmtrace)
+ { vm->file = file; vm->line = line; vm->func = func;
+ (*_Vmtrace)(vm,NIL(Vmuchar_t*),data,size,align);
+ }
+ }
+
+ CLRLOCK(vm, local);
+
+ return (Void_t*)data;
+}
+
+/* print statistics of region vm. If vm is NULL, use Vmregion */
+#if __STD_C
+ssize_t vmdbstat(Vmalloc_t* vm)
+#else
+ssize_t vmdbstat(vm)
+Vmalloc_t* vm;
+#endif
+{ Vmstat_t st;
+ char buf[1024], *bufp;
+
+ vmstat(vm ? vm : Vmregion, &st);
+ bufp = buf;
+ bufp = (*_Vmstrcpy)(bufp, "n_busy", '=');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.n_busy),-1), ',');
+ bufp = (*_Vmstrcpy)(bufp, " s_busy", '=');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.s_busy),-1), '\n');
+ bufp = (*_Vmstrcpy)(bufp, "n_free", '=');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.n_free),-1), ',');
+ bufp = (*_Vmstrcpy)(bufp, " s_free", '=');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.s_free),-1), '\n');
+ bufp = (*_Vmstrcpy)(bufp, "m_busy", '=');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.m_busy),-1), ',');
+ bufp = (*_Vmstrcpy)(bufp, " m_free", '=');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.m_free),-1), '\n');
+ bufp = (*_Vmstrcpy)(bufp, "n_segment", '=');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.n_seg),-1), ',');
+ bufp = (*_Vmstrcpy)(bufp, " extent", '=');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(st.extent),-1), '\n');
+ *bufp = 0;
+ write(Dbfd, buf, strlen(buf));
+ return strlen(buf);
+}
+
+static Vmethod_t _Vmdebug =
+{
+ dballoc,
+ dbresize,
+ dbfree,
+ dbaddr,
+ dbsize,
+ dbcompact,
+ dbalign,
+ VM_MTDEBUG
+};
+
+__DEFINE__(Vmethod_t*,Vmdebug,&_Vmdebug);
+
+#ifdef NoF
+NoF(vmdebug)
+#endif
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmdisc.c b/src/lib/libast/vmalloc/vmdisc.c
new file mode 100644
index 0000000..3f4efbf
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmdisc.c
@@ -0,0 +1,55 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmdisc(){}
+
+#else
+
+#include "vmhdr.h"
+
+/* Change the discipline for a region. The old discipline
+** is returned. If the new discipline is NULL then the
+** discipline is not changed.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+#if __STD_C
+Vmdisc_t* vmdisc(Vmalloc_t* vm, Vmdisc_t* disc)
+#else
+Vmdisc_t* vmdisc(vm, disc)
+Vmalloc_t* vm;
+Vmdisc_t* disc;
+#endif
+{
+ Vmdisc_t* old = vm->disc;
+
+ if(disc)
+ { if(old->exceptf &&
+ (*old->exceptf)(vm,VM_DISC,(Void_t*)disc,old) != 0 )
+ return NIL(Vmdisc_t*);
+ vm->disc = disc;
+ }
+ return old;
+}
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmexit.c b/src/lib/libast/vmalloc/vmexit.c
new file mode 100644
index 0000000..c027fd5
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmexit.c
@@ -0,0 +1,100 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmexit(){}
+
+#else
+
+#include "vmhdr.h"
+
+/*
+** Any required functions for process exiting.
+** Written by Kiem-Phong Vo, kpv@research.att.com (05/25/93).
+*/
+#if _PACKAGE_ast || _lib_atexit
+
+void _STUB_vmexit(){}
+
+#else
+
+#if _lib_onexit
+
+#if __STD_C
+int atexit(void (*exitf)(void))
+#else
+int atexit(exitf)
+void (*exitf)();
+#endif
+{
+ return onexit(exitf);
+}
+
+#else /*!_lib_onexit*/
+
+typedef struct _exit_s
+{ struct _exit_s* next;
+ void(* exitf)_ARG_((void));
+} Exit_t;
+static Exit_t* Exit;
+
+#if __STD_C
+atexit(void (*exitf)(void))
+#else
+atexit(exitf)
+void (*exitf)();
+#endif
+{ Exit_t* e;
+
+ if(!(e = (Exit_t*)malloc(sizeof(Exit_t))) )
+ return -1;
+ e->exitf = exitf;
+ e->next = Exit;
+ Exit = e;
+ return 0;
+}
+
+#if __STD_C
+void exit(int type)
+#else
+void exit(type)
+int type;
+#endif
+{
+ Exit_t* e;
+
+ for(e = Exit; e; e = e->next)
+ (*e->exitf)();
+
+#if _exit_cleanup
+ _cleanup();
+#endif
+
+ _exit(type);
+ return type;
+}
+
+#endif /* _lib_onexit || _lib_on_exit */
+
+#endif /*!PACKAGE_ast*/
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmgetmem.c b/src/lib/libast/vmalloc/vmgetmem.c
new file mode 100644
index 0000000..e205fd3
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmgetmem.c
@@ -0,0 +1,51 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include <vmalloc.h>
+
+/*
+ * vm open/close/resize - a handy default for discipline memory functions
+ *
+ * vmgetmem(0,0,0) open new region
+ * vmgetmem(r,0,0) free region
+ * vmgetmem(r,0,n) allocate n bytes initialized to 0
+ * vmgetmem(r,p,0) free p
+ * vmgetmem(r,p,n) realloc p to n bytes
+ *
+ * Written by Glenn S. Fowler.
+ */
+
+#if __STD_C
+Void_t* vmgetmem(Vmalloc_t* vm, Void_t* data, size_t size)
+#else
+Void_t* vmgetmem(vm, data, size)
+Vmalloc_t* vm;
+Void_t* data;
+size_t size;
+#endif
+{
+ if (!vm)
+ return vmopen(Vmdcheap, Vmbest, 0);
+ if (data || size)
+ return vmresize(vm, data, size, VM_RSMOVE|VM_RSCOPY|VM_RSZERO);
+ vmclose(vm);
+ return 0;
+}
diff --git a/src/lib/libast/vmalloc/vmhdr.h b/src/lib/libast/vmalloc/vmhdr.h
new file mode 100644
index 0000000..25997ac
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmhdr.h
@@ -0,0 +1,530 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#ifndef _VMHDR_H
+#define _VMHDR_H 1
+#ifndef _BLD_vmalloc
+#define _BLD_vmalloc 1
+#endif
+
+/* Common types, and macros for vmalloc functions.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+
+#ifndef __STD_C /* this is normally in vmalloc.h but it's included late here */
+#ifdef __STDC__
+#define __STD_C 1
+#else
+#if __cplusplus || c_plusplus
+#define __STD_C 1
+#else
+#define __STD_C 0
+#endif /*__cplusplus*/
+#endif /*__STDC__*/
+#endif /*__STD_C*/
+
+#if _PACKAGE_ast
+
+#if !_UWIN
+#define getpagesize ______getpagesize
+#define _npt_getpagesize 1
+#define brk ______brk
+#define sbrk ______sbrk
+#define _npt_sbrk 1
+#endif
+
+#include <ast.h>
+
+#if _npt_getpagesize
+#undef getpagesize
+#endif
+#if _npt_sbrk
+#undef brk
+#undef sbrk
+#endif
+
+#else
+
+#include <ast_common.h>
+
+#if !_UWIN
+#define _npt_getpagesize 1
+#define _npt_sbrk 1
+#endif
+
+#undef free
+#undef malloc
+#undef realloc
+
+#endif /*_PACKAGE_ast*/
+
+#include "FEATURE/vmalloc"
+
+#include <aso.h> /* atomic scalor operations */
+#include <setjmp.h> /* use the type jmp_buf for alignment */
+
+/* extra information needed about methods to get memory from the system */
+#if defined(_WIN32)
+#define _mem_win32 1 /* use the VirtualAlloc interface */
+#endif
+#if !_mem_win32 && !_mem_sbrk && !_mem_mmap_anon && !_mem_mmap_zero
+#undef _std_malloc
+#define _std_malloc 1 /* use native malloc/free/realloc */
+#endif
+
+typedef unsigned char Vmuchar_t;
+typedef unsigned long Vmulong_t;
+
+typedef union _head_u Head_t;
+typedef union _body_u Body_t;
+typedef struct _block_s Block_t;
+typedef struct _seg_s Seg_t;
+typedef struct _pfobj_s Pfobj_t;
+
+#define NIL(t) ((t)0)
+#define reg register
+#if __STD_C
+#define NOTUSED(x) (void)(x)
+#else
+#define NOTUSED(x) (&x,1)
+#endif
+
+
+/* convert an address to an integral value */
+#define VLONG(addr) ((Vmulong_t)((Vmuchar_t*)((Vmulong_t)addr) - (Vmuchar_t*)0) )
+
+/* Round x up to a multiple of y. ROUND2 does powers-of-2 and ROUNDX does others */
+#define ROUND2(x,y) (((x) + ((y)-1)) & ~((y)-1))
+#define ROUNDX(x,y) ((((x) + ((y)-1)) / (y)) * (y))
+#define ROUND(x,y) (((y)&((y)-1)) ? ROUNDX((x),(y)) : ROUND2((x),(y)) )
+
+/* compute a value that is a common multiple of x and y */
+#define MULTIPLE(x,y) ((x)%(y) == 0 ? (x) : (y)%(x) == 0 ? (y) : (y)*(x))
+
+#define VM_abort 0x0001 /* abort() on assertion failure */
+#define VM_break 0x0002 /* try sbrk() block allocator first */
+#define VM_check 0x0004 /* enable detailed checks */
+#define VM_free 0x0008 /* disable addfreelist() */
+#define VM_keep 0x0010 /* disable free() */
+
+#if _UWIN
+#include <ast_windows.h>
+#endif
+
+#ifndef DEBUG
+#ifdef _BLD_DEBUG
+#define DEBUG 1
+#endif /*_BLD_DEBUG*/
+#endif /*DEBUG*/
+#if DEBUG
+extern void _vmmessage _ARG_((const char*, long, const char*, long));
+#define MESSAGE(s) _vmmessage(__FILE__,__LINE__,s,0)
+#define ABORT() (_Vmassert & VM_abort)
+#define CHECK() (_Vmassert & VM_check)
+#define ASSERT(p) ((p) ? 0 : (MESSAGE("Assertion failed"), ABORT() ? (abort(),0) : 0))
+#define COUNT(n) ((n) += 1)
+#else
+#define ABORT() (0)
+#define ASSERT(p)
+#define CHECK() (0)
+#define COUNT(n)
+#define MESSAGE(s) (0)
+#endif /*DEBUG*/
+
+#define VMPAGESIZE 8192
+#if _lib_getpagesize
+#define GETPAGESIZE(x) ((x) ? (x) : ((x)=getpagesize()) )
+#else
+#define GETPAGESIZE(x) ((x) = VMPAGESIZE)
+#endif
+
+/* Blocks are allocated such that their sizes are 0%(BITS+1)
+** This frees up enough low order bits to store state information
+*/
+#define BUSY (01) /* block is busy */
+#define PFREE (02) /* preceding block is free */
+#define JUNK (04) /* marked as freed but not yet processed */
+#define BITS (07) /* (BUSY|PFREE|JUNK) */
+#define ALIGNB (8) /* size must be a multiple of BITS+1 */
+
+#define ISBITS(w) ((w) & BITS)
+#define CLRBITS(w) ((w) &= ~BITS)
+#define CPYBITS(w,f) ((w) |= ((f)&BITS) )
+
+#define ISBUSY(w) ((w) & BUSY)
+#define SETBUSY(w) ((w) |= BUSY)
+#define CLRBUSY(w) ((w) &= ~BUSY)
+
+#define ISPFREE(w) ((w) & PFREE)
+#define SETPFREE(w) ((w) |= PFREE)
+#define CLRPFREE(w) ((w) &= ~PFREE)
+
+#define ISJUNK(w) ((w) & JUNK)
+#define SETJUNK(w) ((w) |= JUNK)
+#define CLRJUNK(w) ((w) &= ~JUNK)
+
+#define OFFSET(t,e) ((size_t)(&(((t*)0)->e)) )
+
+#define VMETHOD(vd) ((vd)->mode&VM_METHODS)
+
+/* lock and unlock regions during concurrent accesses */
+#define SETLOCK(vm,l) ((l) ? 0 : _vmlock((vm), 1) )
+#define CLRLOCK(vm,l) ((l) ? 0 : _vmlock((vm), 0) )
+
+/* local calls */
+#define KPVALLOC(vm,sz,func) (func((vm),(sz),1) )
+#define KPVRESIZE(vm,dt,sz,mv,func) (func((vm),(dt),(sz),(mv),1) )
+#define KPVFREE(vm,dt,func) (func((vm),(dt),1) )
+#define KPVADDR(vm,addr,func) (func((vm),(addr),1) )
+#define KPVSIZE(vm,addr,func) (func((vm),(addr),1) )
+#define KPVCOMPACT(vm,func) (func((vm),1) )
+#define KPVALIGN(vm,sz,al,func) (func((vm),(sz),(al),1) )
+
+/* ALIGN is chosen so that a block can store all primitive types.
+** It should also be a multiple of ALIGNB==(BITS+1) so the size field
+** of Block_t will always be 0%(BITS+1) as noted above.
+** Of paramount importance is the ALIGNA macro below. If the local compile
+** environment is strange enough that the below method does not calculate
+** ALIGNA right, then the code below should be commented out and ALIGNA
+** redefined to the appropriate requirement.
+*/
+union _align_u
+{ char c, *cp;
+ int i, *ip;
+ long l, *lp;
+ double d, *dp, ***dppp[8];
+ size_t s, *sp;
+ void(* fn)();
+ union _align_u* align;
+ Head_t* head;
+ Body_t* body;
+ Block_t* block;
+ Vmuchar_t a[ALIGNB];
+ _ast_fltmax_t ld, *ldp;
+ jmp_buf jmp;
+};
+struct _a_s
+{ char c;
+ union _align_u a;
+};
+#define ALIGNA (sizeof(struct _a_s) - sizeof(union _align_u))
+struct _align_s
+{ char data[MULTIPLE(ALIGNA,ALIGNB)];
+};
+#undef ALIGN /* bsd sys/param.h defines this */
+#define ALIGN sizeof(struct _align_s)
+
+/* make sure that the head of a block is a multiple of ALIGN */
+struct _head_s
+{ union
+ { Seg_t* seg; /* the containing segment */
+ Block_t* link; /* possible link list usage */
+ Pfobj_t* pf; /* profile structure pointer */
+ char* file; /* for file name in Vmdebug */
+ } seg;
+ union
+ { size_t size; /* size of data area in bytes */
+ Block_t* link; /* possible link list usage */
+ int line; /* for line number in Vmdebug */
+ } size;
+};
+#define HEADSIZE ROUND(sizeof(struct _head_s),ALIGN)
+union _head_u
+{ Vmuchar_t data[HEADSIZE]; /* to standardize size */
+ struct _head_s head;
+};
+
+/* now make sure that the body of a block is a multiple of ALIGN */
+struct _body_s
+{ Block_t* link; /* next in link list */
+ Block_t* left; /* left child in free tree */
+ Block_t* right; /* right child in free tree */
+ Block_t** self; /* self pointer when free */
+};
+#define BODYSIZE ROUND(sizeof(struct _body_s),ALIGN)
+
+union _body_u
+{ Vmuchar_t data[BODYSIZE]; /* to standardize size */
+ struct _body_s body;
+ Block_t* self[1];
+};
+
+/* After all the songs and dances, we should now have:
+** sizeof(Head_t)%ALIGN == 0
+** sizeof(Body_t)%ALIGN == 0
+** and sizeof(Block_t) = sizeof(Head_t)+sizeof(Body_t)
+*/
+struct _block_s
+{ Head_t head;
+ Body_t body;
+};
+
+/* requirements for smallest block type */
+struct _tiny_s
+{ Block_t* link;
+ Block_t* self;
+};
+#define TINYSIZE ROUND(sizeof(struct _tiny_s),ALIGN)
+#define S_TINY 1 /* # of tiny blocks */
+#define MAXTINY (S_TINY*ALIGN + TINYSIZE)
+#define TLEFT(b) ((b)->head.head.seg.link) /* instead of LEFT */
+#define TINIEST(b) (SIZE(b) == TINYSIZE) /* this type uses TLEFT */
+
+#define DIV(x,y) ((y) == 8 ? ((x)>>3) : (x)/(y) )
+#define INDEX(s) DIV((s)-TINYSIZE,ALIGN)
+
+/* small block types kept in separate caches for quick allocation */
+#define S_CACHE 6 /* # of types of small blocks to be cached */
+#define N_CACHE 32 /* on allocation, create this many at a time */
+#define MAXCACHE (S_CACHE*ALIGN + TINYSIZE)
+#define C_INDEX(s) (s < MAXCACHE ? INDEX(s) : S_CACHE)
+
+#define TINY(vd) ((vd)->tiny)
+#define CACHE(vd) ((vd)->cache)
+
+struct _vmdata_s /* core region data - could be in shared/persistent memory */
+{ unsigned int lock; /* lock status */
+ int mode; /* current mode for region */
+ size_t incr; /* allocate in multiple of this */
+ size_t pool; /* size of an elt in a Vmpool region */
+ Seg_t* seg; /* list of segments */
+ Block_t* free; /* most recent free block */
+ Block_t* wild; /* wilderness block */
+ Block_t* root; /* root of free tree */
+ Block_t* tiny[S_TINY]; /* small blocks */
+ Block_t* cache[S_CACHE+1]; /* delayed free blocks */
+};
+
+#include "vmalloc.h"
+
+#if !_PACKAGE_ast
+/* we don't use these here and they interfere with some local names */
+#undef malloc
+#undef free
+#undef realloc
+#endif
+
+/* segment structure */
+struct _seg_s
+{ Vmdata_t* vmdt; /* the data region holding this */
+ Seg_t* next; /* next segment */
+ Void_t* addr; /* starting segment address */
+ size_t extent; /* extent of segment */
+ Vmuchar_t* baddr; /* bottom of usable memory */
+ size_t size; /* allocable size */
+ Block_t* free; /* recent free blocks */
+ Block_t* last; /* Vmlast last-allocated block */
+};
+
+/* starting block of a segment */
+#define SEGBLOCK(s) ((Block_t*)(((Vmuchar_t*)(s)) + ROUND(sizeof(Seg_t),ALIGN)))
+
+/* short-hands for block data */
+#define SEG(b) ((b)->head.head.seg.seg)
+#define SEGLINK(b) ((b)->head.head.seg.link)
+#define SIZE(b) ((b)->head.head.size.size)
+#define SIZELINK(b) ((b)->head.head.size.link)
+#define LINK(b) ((b)->body.body.link)
+#define LEFT(b) ((b)->body.body.left)
+#define RIGHT(b) ((b)->body.body.right)
+
+#define DATA(b) ((Void_t*)((b)->body.data) )
+#define BLOCK(d) ((Block_t*)((char*)(d) - sizeof(Head_t)) )
+#define SELF(b) (b)->body.self[SIZE(b)/sizeof(Block_t*)-1]
+#define LAST(b) (*((Block_t**)(((char*)(b)) - sizeof(Block_t*)) ) )
+#define NEXT(b) ((Block_t*)((b)->body.data + SIZE(b)) )
+
+/* functions to manipulate link lists of elts of the same size */
+#define SETLINK(b) (RIGHT(b) = (b) )
+#define ISLINK(b) (RIGHT(b) == (b) )
+#define UNLINK(vd,b,i,t) \
+ ((((t) = LINK(b)) ? (LEFT(t) = LEFT(b)) : NIL(Block_t*) ), \
+ (((t) = LEFT(b)) ? (LINK(t) = LINK(b)) : (TINY(vd)[i] = LINK(b)) ) )
+
+/* delete a block from a link list or the free tree.
+** The test in the below macro is worth scratching your head a bit.
+** Even though tiny blocks (size < BODYSIZE) are kept in separate lists,
+** only the TINIEST ones require TLEFT(b) for the back link. Since this
+** destroys the SEG(b) pointer, it must be carefully restored in bestsearch().
+** Other tiny blocks have enough space to use the usual LEFT(b).
+** In this case, I have also carefully arranged so that RIGHT(b) and
+** SELF(b) can be overlapped and the test ISLINK() will go through.
+*/
+#define REMOVE(vd,b,i,t,func) \
+ ((!TINIEST(b) && ISLINK(b)) ? UNLINK((vd),(b),(i),(t)) : \
+ func((vd),SIZE(b),(b)) )
+
+/* see if a block is the wilderness block */
+#define SEGWILD(b) (((b)->body.data+SIZE(b)+sizeof(Head_t)) >= SEG(b)->baddr)
+#define VMWILD(vd,b) (((b)->body.data+SIZE(b)+sizeof(Head_t)) >= vd->seg->baddr)
+
+#define VMFLF(vm,fi,ln,fn) ((fi) = (vm)->file, (vm)->file = NIL(char*), \
+ (ln) = (vm)->line, (vm)->line = 0 , \
+ (fn) = (vm)->func, (vm)->func = NIL(Void_t*) )
+
+/* The lay-out of a Vmprofile block is this:
+** seg_ size ----data---- _pf_ size
+** _________ ____________ _________
+** seg_, size: header required by Vmbest.
+** data: actual data block.
+** _pf_: pointer to the corresponding Pfobj_t struct
+** size: the true size of the block.
+** So each block requires an extra Head_t.
+*/
+#define PF_EXTRA sizeof(Head_t)
+#define PFDATA(d) ((Head_t*)((Vmuchar_t*)(d)+(SIZE(BLOCK(d))&~BITS)-sizeof(Head_t)) )
+#define PFOBJ(d) (PFDATA(d)->head.seg.pf)
+#define PFSIZE(d) (PFDATA(d)->head.size.size)
+
+/* The lay-out of a block allocated by Vmdebug is this:
+** seg_ size file size seg_ magi ----data---- --magi-- magi line
+** --------- --------- --------- ------------ -------- ---------
+** seg_,size: header required by Vmbest management.
+** file: the file where it was created.
+** size: the true byte count of the block
+** seg_: should be the same as the previous seg_.
+** This allows the function vmregion() to work.
+** magi: magic bytes to detect overwrites.
+** data: the actual data block.
+** magi: more magic bytes.
+** line: the line number in the file where it was created.
+** So for each allocated block, we'll need 3 extra Head_t.
+*/
+
+/* convenient macros for accessing the above fields */
+#define DB_HEAD (2*sizeof(Head_t))
+#define DB_TAIL (2*sizeof(Head_t))
+#define DB_EXTRA (DB_HEAD+DB_TAIL)
+#define DBBLOCK(d) ((Block_t*)((Vmuchar_t*)(d) - 3*sizeof(Head_t)) )
+#define DBBSIZE(d) (SIZE(DBBLOCK(d)) & ~BITS)
+#define DBSEG(d) (((Head_t*)((Vmuchar_t*)(d) - sizeof(Head_t)))->head.seg.seg )
+#define DBSIZE(d) (((Head_t*)((Vmuchar_t*)(d) - 2*sizeof(Head_t)))->head.size.size )
+#define DBFILE(d) (((Head_t*)((Vmuchar_t*)(d) - 2*sizeof(Head_t)))->head.seg.file )
+#define DBLN(d) (((Head_t*)((Vmuchar_t*)DBBLOCK(d)+DBBSIZE(d)))->head.size.line )
+#define DBLINE(d) (DBLN(d) < 0 ? -DBLN(d) : DBLN(d))
+
+/* forward/backward translation for addresses between Vmbest and Vmdebug */
+#define DB2BEST(d) ((Vmuchar_t*)(d) - 2*sizeof(Head_t))
+#define DB2DEBUG(b) ((Vmuchar_t*)(b) + 2*sizeof(Head_t))
+
+/* set file and line number, note that DBLN > 0 so that DBISBAD will work */
+#define DBSETFL(d,f,l) (DBFILE(d) = (f), DBLN(d) = (f) ? (l) : 1)
+
+/* set and test the state of known to be corrupted */
+#define DBSETBAD(d) (DBLN(d) > 0 ? (DBLN(d) = -DBLN(d)) : -1)
+#define DBISBAD(d) (DBLN(d) <= 0)
+
+#define DB_MAGIC 0255 /* 10101101 */
+
+/* compute the bounds of the magic areas */
+#define DBHEAD(d,begp,endp) \
+ (((begp) = (Vmuchar_t*)(&DBSEG(d)) + sizeof(Seg_t*)), ((endp) = (d)) )
+#define DBTAIL(d,begp,endp) \
+ (((begp) = (Vmuchar_t*)(d)+DBSIZE(d)), ((endp) = (Vmuchar_t*)(&DBLN(d))) )
+
+
+/* external symbols for use inside vmalloc only */
+typedef Block_t* (*Vmsearch_f)_ARG_((Vmdata_t*, size_t, Block_t*));
+typedef struct _vmextern_s
+{ Block_t* (*vm_extend)_ARG_((Vmalloc_t*, size_t, Vmsearch_f ));
+ ssize_t (*vm_truncate)_ARG_((Vmalloc_t*, Seg_t*, size_t, int));
+ size_t vm_pagesize;
+ char* (*vm_strcpy)_ARG_((char*, const char*, int));
+ char* (*vm_itoa)_ARG_((Vmulong_t, int));
+ void (*vm_trace)_ARG_((Vmalloc_t*,
+ Vmuchar_t*, Vmuchar_t*, size_t, size_t));
+ void (*vm_pfclose)_ARG_((Vmalloc_t*));
+ unsigned int vm_lock;
+ int vm_assert;
+ int vm_options;
+} Vmextern_t;
+
+#define _Vmextend (_Vmextern.vm_extend)
+#define _Vmtruncate (_Vmextern.vm_truncate)
+#define _Vmpagesize (_Vmextern.vm_pagesize)
+#define _Vmstrcpy (_Vmextern.vm_strcpy)
+#define _Vmitoa (_Vmextern.vm_itoa)
+#define _Vmtrace (_Vmextern.vm_trace)
+#define _Vmpfclose (_Vmextern.vm_pfclose)
+#define _Vmlock (_Vmextern.vm_lock)
+#define _Vmassert (_Vmextern.vm_assert)
+#define _Vmoptions (_Vmextern.vm_options)
+
+#define VMOPTIONS() do { if (!_Vmoptions) { _vmoptions(); } } while (0)
+
+extern int _vmbestcheck _ARG_((Vmdata_t*, Block_t*));
+extern int _vmlock _ARG_((Vmalloc_t*, int));
+extern void _vmoptions _ARG_((void));
+
+_BEGIN_EXTERNS_
+
+extern Vmextern_t _Vmextern;
+
+#if _PACKAGE_ast
+
+#if _npt_getpagesize
+extern int getpagesize _ARG_((void));
+#endif
+#if _npt_sbrk
+extern int brk _ARG_(( void* ));
+extern Void_t* sbrk _ARG_(( ssize_t ));
+#endif
+
+#else
+
+#if _hdr_unistd
+#include <unistd.h>
+#else
+extern void abort _ARG_(( void ));
+extern ssize_t write _ARG_(( int, const void*, size_t ));
+extern int getpagesize _ARG_((void));
+extern Void_t* sbrk _ARG_((ssize_t));
+#endif
+
+#if !__STDC__ && !_hdr_stdlib
+extern size_t strlen _ARG_(( const char* ));
+extern char* strcpy _ARG_(( char*, const char* ));
+extern int strcmp _ARG_(( const char*, const char* ));
+extern int atexit _ARG_(( void(*)(void) ));
+extern char* getenv _ARG_(( const char* ));
+extern Void_t* memcpy _ARG_(( Void_t*, const Void_t*, size_t ));
+extern Void_t* memset _ARG_(( Void_t*, int, size_t ));
+#else
+#include <stdlib.h>
+#include <string.h>
+#endif
+
+/* for vmexit.c */
+extern int onexit _ARG_(( void(*)(void) ));
+extern void _exit _ARG_(( int ));
+extern void _cleanup _ARG_(( void ));
+
+#endif /*_PACKAGE_ast*/
+
+/* for vmdcsbrk.c */
+#if !_typ_ssize_t
+typedef int ssize_t;
+#endif
+
+_END_EXTERNS_
+
+#endif /* _VMHDR_H */
diff --git a/src/lib/libast/vmalloc/vmlast.c b/src/lib/libast/vmalloc/vmlast.c
new file mode 100644
index 0000000..31f70b7
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmlast.c
@@ -0,0 +1,431 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmlast(){}
+
+#else
+
+#include "vmhdr.h"
+
+/* Allocation with freeing and reallocing of last allocated block only.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+
+#if __STD_C
+static Void_t* lastalloc(Vmalloc_t* vm, size_t size, int local)
+#else
+static Void_t* lastalloc(vm, size, local)
+Vmalloc_t* vm;
+size_t size;
+int local;
+#endif
+{
+ Block_t *tp, *next;
+ Seg_t *seg, *last;
+ size_t s;
+ Vmdata_t *vd = vm->data;
+ size_t orgsize = size;
+
+ SETLOCK(vm, local);
+
+ size = size < ALIGN ? ALIGN : ROUND(size,ALIGN);
+ for(last = NIL(Seg_t*), seg = vd->seg; seg; last = seg, seg = seg->next)
+ { if(!(tp = seg->free) || (SIZE(tp)+sizeof(Head_t)) < size)
+ continue;
+ if(last)
+ { last->next = seg->next;
+ seg->next = vd->seg;
+ vd->seg = seg;
+ }
+ goto got_block;
+ }
+
+ /* there is no usable free space in region, try extending */
+ if((tp = (*_Vmextend)(vm,size,NIL(Vmsearch_f))) )
+ { seg = SEG(tp);
+ goto got_block;
+ }
+ else goto done;
+
+got_block:
+ if((s = SIZE(tp)) >= size)
+ { next = (Block_t*)((Vmuchar_t*)tp+size);
+ SIZE(next) = s - size;
+ SEG(next) = seg;
+ seg->free = next;
+ }
+ else seg->free = NIL(Block_t*);
+
+ vd->free = seg->last = tp;
+
+ if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
+ (*_Vmtrace)(vm, NIL(Vmuchar_t*), (Vmuchar_t*)tp, orgsize, 0);
+
+done:
+ CLRLOCK(vm, local);
+
+ return (Void_t*)tp;
+}
+
+#if __STD_C
+static int lastfree(Vmalloc_t* vm, reg Void_t* data, int local )
+#else
+static int lastfree(vm, data, local)
+Vmalloc_t* vm;
+Void_t* data;
+int local;
+#endif
+{
+ Seg_t *seg;
+ Block_t *fp;
+ size_t s;
+ Vmdata_t *vd = vm->data;
+
+ if(!data)
+ return 0;
+
+ SETLOCK(vm, local);
+
+ if(data != (Void_t*)vd->free)
+ data = NIL(Void_t*); /* signaling an error */
+ else
+ { seg = vd->seg;
+ if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
+ { if(seg->free )
+ s = (Vmuchar_t*)(seg->free) - (Vmuchar_t*)data;
+ else s = (Vmuchar_t*)BLOCK(seg->baddr) - (Vmuchar_t*)data;
+ (*_Vmtrace)(vm, (Vmuchar_t*)data, NIL(Vmuchar_t*), s, 0);
+ }
+
+ vd->free = NIL(Block_t*);
+ fp = (Block_t*)data;
+ SEG(fp) = seg;
+ SIZE(fp) = ((Vmuchar_t*)BLOCK(seg->baddr) - (Vmuchar_t*)data) - sizeof(Head_t);
+ seg->free = fp;
+ seg->last = NIL(Block_t*);
+ }
+
+ CLRLOCK(vm, local);
+
+ return data ? 0 : -1;
+}
+
+#if __STD_C
+static Void_t* lastresize(Vmalloc_t* vm, reg Void_t* data, size_t size, int type, int local)
+#else
+static Void_t* lastresize(vm, data, size, type, local )
+Vmalloc_t* vm;
+reg Void_t* data;
+size_t size;
+int type;
+int local;
+#endif
+{
+ Block_t *tp;
+ Seg_t *seg;
+ ssize_t s, ds;
+ Void_t *addr;
+ size_t oldsize = 0;
+ Void_t *orgdata = data;
+ size_t orgsize = size;
+ Vmdata_t *vd = vm->data;
+
+ if(!data)
+ { data = lastalloc(vm, size, local);
+ if(data && (type&VM_RSZERO) )
+ memset(data, 0, size);
+ return data;
+ }
+ if(size <= 0)
+ { (void)lastfree(vm, data, local);
+ return NIL(Void_t*);
+ }
+
+ SETLOCK(vm, local);
+
+ if(data == (Void_t*)vd->free)
+ seg = vd->seg;
+ else
+ { /* see if it was one of ours */
+ for(seg = vd->seg; seg; seg = seg->next)
+ if(data >= seg->addr && data < (Void_t*)seg->baddr)
+ break;
+ if(!seg || (VLONG(data)%ALIGN) != 0 ||
+ (seg->last && (Vmuchar_t*)data > (Vmuchar_t*)seg->last) )
+ { data = NIL(Void_t*);
+ goto done;
+ }
+ }
+
+ /* set 's' to be the current available space */
+ if(data != seg->last)
+ { if(seg->last && (Vmuchar_t*)data < (Vmuchar_t*)seg->last)
+ oldsize = (Vmuchar_t*)seg->last - (Vmuchar_t*)data;
+ else oldsize = (Vmuchar_t*)BLOCK(seg->baddr) - (Vmuchar_t*)data;
+ s = -1;
+ }
+ else
+ { s = (Vmuchar_t*)BLOCK(seg->baddr) - (Vmuchar_t*)data;
+ if(!(tp = seg->free) )
+ oldsize = s;
+ else
+ { oldsize = (Vmuchar_t*)tp - (Vmuchar_t*)data;
+ seg->free = NIL(Block_t*);
+ }
+ }
+
+ size = size < ALIGN ? ALIGN : ROUND(size,ALIGN);
+ if(s < 0 || (ssize_t)size > s)
+ { if(s >= 0) /* amount to extend */
+ { ds = size-s; ds = ROUND(ds,vd->incr);
+ addr = (*vm->disc->memoryf)(vm, seg->addr, seg->extent,
+ seg->extent+ds, vm->disc);
+ if(addr == seg->addr)
+ { s += ds;
+ seg->size += ds;
+ seg->extent += ds;
+ seg->baddr += ds;
+ SIZE(BLOCK(seg->baddr)) = BUSY;
+ }
+ else goto do_alloc;
+ }
+ else
+ { do_alloc:
+ if(!(type&(VM_RSMOVE|VM_RSCOPY)) )
+ data = NIL(Void_t*);
+ else
+ { tp = vd->free;
+ if(!(addr = KPVALLOC(vm,size,lastalloc)) )
+ { vd->free = tp;
+ data = NIL(Void_t*);
+ }
+ else
+ { if(type&VM_RSCOPY)
+ { ds = oldsize < size ? oldsize : size;
+ memcpy(addr, data, ds);
+ }
+
+ if(s >= 0 && seg != vd->seg)
+ { tp = (Block_t*)data;
+ SEG(tp) = seg;
+ SIZE(tp) = s - sizeof(Head_t);
+ seg->free = tp;
+ }
+
+ /* new block and size */
+ data = addr;
+ seg = vd->seg;
+ s = (Vmuchar_t*)BLOCK(seg->baddr) -
+ (Vmuchar_t*)data;
+ seg->free = NIL(Block_t*);
+ }
+ }
+ }
+ }
+
+ if(data)
+ { if(s >= (ssize_t)(size+sizeof(Head_t)) )
+ { tp = (Block_t*)((Vmuchar_t*)data + size);
+ SEG(tp) = seg;
+ SIZE(tp) = (s - size) - sizeof(Head_t);
+ seg->free = tp;
+ }
+
+ vd->free = seg->last = (Block_t*)data;
+
+ if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
+ (*_Vmtrace)(vm,(Vmuchar_t*)orgdata,(Vmuchar_t*)data,orgsize,0);
+
+ if((type&VM_RSZERO) && size > oldsize)
+ memset((Void_t*)((Vmuchar_t*)data + oldsize), 0, size-oldsize);
+ }
+
+done: CLRLOCK(vm, local);
+
+ return data;
+}
+
+
+#if __STD_C
+static long lastaddr(Vmalloc_t* vm, Void_t* addr, int local)
+#else
+static long lastaddr(vm, addr, local)
+Vmalloc_t* vm;
+Void_t* addr;
+int local;
+#endif
+{
+ long offset;
+ Vmdata_t *vd = vm->data;
+
+ SETLOCK(vm, local);
+
+ if(!vd->free || addr < (Void_t*)vd->free || addr >= (Void_t*)vd->seg->baddr)
+ offset = -1L;
+ else offset = (Vmuchar_t*)addr - (Vmuchar_t*)vd->free;
+
+ CLRLOCK(vm, local);
+
+ return offset;
+}
+
+#if __STD_C
+static long lastsize(Vmalloc_t* vm, Void_t* addr, int local)
+#else
+static long lastsize(vm, addr, local)
+Vmalloc_t* vm;
+Void_t* addr;
+int local;
+#endif
+{
+ long size;
+ Vmdata_t *vd = vm->data;
+
+ SETLOCK(vm, local);
+
+ if(!vd->free || addr != (Void_t*)vd->free )
+ size = -1L;
+ else if(vd->seg->free)
+ size = (Vmuchar_t*)vd->seg->free - (Vmuchar_t*)addr;
+ else size = (Vmuchar_t*)vd->seg->baddr - (Vmuchar_t*)addr - sizeof(Head_t);
+
+ CLRLOCK(vm, local);
+
+ return size;
+}
+
+#if __STD_C
+static int lastcompact(Vmalloc_t* vm, int local)
+#else
+static int lastcompact(vm, local)
+Vmalloc_t* vm;
+int local;
+#endif
+{
+ ssize_t s;
+ Block_t *fp;
+ Seg_t *seg, *next;
+ Vmdata_t *vd = vm->data;
+
+ SETLOCK(vm, local);
+
+ for(seg = vd->seg; seg; seg = next)
+ { next = seg->next;
+
+ if(!(fp = seg->free))
+ continue;
+
+ seg->free = NIL(Block_t*);
+ if(seg->size == (s = SIZE(fp)&~BITS))
+ s = seg->extent;
+ else s += sizeof(Head_t);
+
+ if((*_Vmtruncate)(vm,seg,s,1) == s)
+ seg->free = fp;
+ }
+
+ if((vd->mode&VM_TRACE) && _Vmtrace)
+ (*_Vmtrace)(vm,(Vmuchar_t*)0,(Vmuchar_t*)0,0,0);
+
+ CLRLOCK(vm, local);
+ return 0;
+}
+
+#if __STD_C
+static Void_t* lastalign(Vmalloc_t* vm, size_t size, size_t align, int local)
+#else
+static Void_t* lastalign(vm, size, align, local)
+Vmalloc_t* vm;
+size_t size;
+size_t align;
+int local;
+#endif
+{
+ Vmuchar_t *data;
+ Seg_t *seg;
+ Block_t *next;
+ size_t s, orgsize = size, orgalign = align;
+ Vmdata_t *vd = vm->data;
+
+ if(size <= 0 || align <= 0)
+ return NIL(Void_t*);
+
+ SETLOCK(vm, local);
+
+ size = size <= TINYSIZE ? TINYSIZE : ROUND(size,ALIGN);
+ align = MULTIPLE(align,ALIGN);
+
+ s = size + align;
+ if(!(data = (Vmuchar_t*)KPVALLOC(vm,s,lastalloc)) )
+ goto done;
+
+ /* find the segment containing this block */
+ for(seg = vd->seg; seg; seg = seg->next)
+ if(seg->last == (Block_t*)data)
+ break;
+ /**/ASSERT(seg);
+
+ /* get a suitably aligned address */
+ if((s = (size_t)(VLONG(data)%align)) != 0)
+ data += align-s; /**/ASSERT((VLONG(data)%align) == 0);
+
+ /* free the unused tail */
+ next = (Block_t*)(data+size);
+ if((s = (seg->baddr - (Vmuchar_t*)next)) >= sizeof(Block_t))
+ { SEG(next) = seg;
+ SIZE(next) = s - sizeof(Head_t);
+ seg->free = next;
+ }
+
+ vd->free = seg->last = (Block_t*)data;
+
+ if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
+ (*_Vmtrace)(vm,NIL(Vmuchar_t*),data,orgsize,orgalign);
+
+done:
+ CLRLOCK(vm, local);
+
+ return (Void_t*)data;
+}
+
+/* Public method for free-1 allocation */
+static Vmethod_t _Vmlast =
+{
+ lastalloc,
+ lastresize,
+ lastfree,
+ lastaddr,
+ lastsize,
+ lastcompact,
+ lastalign,
+ VM_MTLAST
+};
+
+__DEFINE__(Vmethod_t*,Vmlast,&_Vmlast);
+
+#ifdef NoF
+NoF(vmlast)
+#endif
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmmopen.c b/src/lib/libast/vmalloc/vmmopen.c
new file mode 100644
index 0000000..4523cae
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmmopen.c
@@ -0,0 +1,518 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmmapopen(){}
+
+#else
+
+#include "vmhdr.h"
+#include <sys/types.h>
+#include <string.h>
+#if _hdr_unistd
+#include <unistd.h>
+#endif
+
+#undef ALIGN /* some sys/param.h define this */
+
+#include <sys/mman.h> /* mmap() headers */
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <sys/shm.h> /* shm headers */
+#include <sys/ipc.h>
+
+#undef ALIGN
+#define ALIGN sizeof(struct _align_s)
+
+/* Create a region to allocate based on mmap() or shmget().
+** Both ways provide for share memory allocation.
+** mmap() also allows for allocating persistent data.
+**
+** Written by Kiem-Phong Vo (kpv@research.att.com)
+*/
+
+#define MM_INIT 001 /* initialization mode */
+
+#define MM_RELEASE 010 /* release share mem */
+#define MM_CLEANUP 020 /* clean up resources */
+
+/* magic word signaling region is being initialized */
+#define MM_LETMEDOIT ((unsigned int)(('N'<<24) | ('B'<<16) | ('&'<<8) | ('I')) )
+
+/* magic word signaling file/segment is ready */
+#define MM_MAGIC ((unsigned int)(('P'<<24) | ('&'<<16) | ('N'<<8) | ('8')) )
+
+/* default mimimum region size */
+#define MM_MINSIZE (64*_Vmpagesize)
+
+/* macros to get the data section and size */
+#define MMHEAD(file) ROUND(sizeof(Mmvm_t)+strlen(file), ALIGN)
+#define MMDATA(mmvm) ((Vmuchar_t*)(mmvm)->base + MMHEAD(mmvm->file))
+#define MMSIZE(mmvm) ((mmvm)->size - MMHEAD(mmvm->file))
+
+#ifdef S_IRUSR
+#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
+#else
+#define FILE_MODE 0644
+#endif
+
+/* to store key/value pairs for application */
+typedef struct _mmuser_s Mmuser_t;
+struct _mmuser_s
+{ Mmuser_t* next; /* link list */
+ int key; /* identifying key */
+ Void_t* val; /* associated value */
+};
+
+typedef struct _mmvm_s
+{ unsigned int magic; /* magic bytes */
+ Void_t* base; /* address to map to */
+ ssize_t size; /* total data size */
+ ssize_t busy; /* amount in use */
+ Mmuser_t* user; /* stored (key,val)'s */
+ int proj; /* project number */
+ char file[1];/* file name */
+} Mmvm_t;
+
+typedef struct _mmdisc_s
+{ Vmdisc_t disc; /* Vmalloc discipline */
+ int flag; /* various modes */
+ Mmvm_t* mmvm; /* shared memory data */
+ ssize_t size; /* desired file size */
+ int shmid; /* ID of the shared mem */
+ int proj; /* shm project ID */
+ char file[1];/* backing store/ftok() */
+} Mmdisc_t;
+
+#if DEBUG
+#include <stdio.h>
+#include <string.h>
+int _vmmdump(Vmalloc_t* vm, int fd)
+{
+ char mesg[1024];
+ Mmdisc_t *mmdc = (Mmdisc_t*)vm->disc;
+
+ fd = fd < 0 ? 2 : fd;
+ sprintf(mesg, "File: %s\n", mmdc->file ); write(fd, mesg, strlen(mesg));
+ sprintf(mesg, "Project: %10d\n", mmdc->proj); write(fd, mesg, strlen(mesg));
+ sprintf(mesg, "Memory: %#010lx\n", mmdc->mmvm); write(fd, mesg, strlen(mesg));
+ sprintf(mesg, "Size: %10d\n", mmdc->size); write(fd, mesg, strlen(mesg));
+ sprintf(mesg, "Shmid: %10d\n", mmdc->shmid); write(fd, mesg, strlen(mesg));
+
+ sprintf(mesg, "File header:\n"); write(fd, mesg, strlen(mesg));
+ sprintf(mesg, "Magic: %10d\n", mmdc->mmvm->magic); write(fd, mesg, strlen(mesg));
+ sprintf(mesg, "Base: %#010lx\n", mmdc->mmvm->base); write(fd, mesg, strlen(mesg));
+ sprintf(mesg, "Size: %10d\n", mmdc->mmvm->size); write(fd, mesg, strlen(mesg));
+ sprintf(mesg, "Busy: %10d\n", mmdc->mmvm->busy); write(fd, mesg, strlen(mesg));
+ return 0;
+}
+#endif /*DEBUG*/
+
+/* fix the mapped address for a region */
+static Mmvm_t* mmfix(Mmvm_t* mmvm, Mmdisc_t* mmdc, int fd)
+{
+ Void_t *base = mmvm->base;
+ ssize_t size = mmvm->size;
+
+ if(base != (Void_t*)mmvm) /* mmvm is not right yet */
+ { /**/ASSERT(!base || (base && (VLONG(base)%_Vmpagesize) == 0) );
+ if(mmdc->proj < 0)
+ { munmap((Void_t*)mmvm, size);
+ mmvm = (Mmvm_t*)mmap(base, size, (PROT_READ|PROT_WRITE),
+ (MAP_FIXED|MAP_SHARED), fd, (off_t)0 );
+ }
+ else
+ { shmdt((Void_t*)mmvm);
+ mmvm = (Mmvm_t*)shmat(mmdc->shmid, base, 0);
+ }
+ if(!mmvm || mmvm == (Mmvm_t*)(-1) )
+ mmvm = NIL(Mmvm_t*);
+ }
+
+ return mmvm;
+}
+
+/* initialize region data */
+static int mminit(Mmdisc_t* mmdc)
+{
+ struct shmid_ds shmds;
+ Void_t *base;
+ int try, k;
+ int fd = -1;
+ key_t key = -1;
+ ssize_t extent, size = 0;
+ Mmvm_t *mmvm = NIL(Mmvm_t*);
+ int rv = -1;
+
+ if(mmdc->mmvm) /* already done this */
+ return 0;
+
+ /* fixed size region so make it reasonably large */
+ if((size = mmdc->size) < MM_MINSIZE )
+ size = MM_MINSIZE;
+ size += MMHEAD(mmdc->file) + ALIGN;
+ size = ROUND(size, _Vmpagesize);
+
+ /* this op can happen simultaneously in different processes */
+ if((fd = open(mmdc->file, O_RDWR|O_CREAT, FILE_MODE)) < 0)
+ return -1;
+
+ /* get/create the initial segment of data */
+ if(mmdc->proj < 0 ) /* proj < 0 means doing mmap() */
+ { /* Note that the location being written to is always zero! */
+ if((extent = (ssize_t)lseek(fd, (off_t)0, SEEK_END)) < 0)
+ goto done;
+ if(extent < size) /* make the file size large enough */
+ if(lseek(fd, (off_t)size, 0) != (off_t)size || write(fd, "", 1) != 1 )
+ goto done;
+
+ /* map the file into memory */
+ mmvm = (Mmvm_t*)mmap(NIL(Void_t*), size, (PROT_READ|PROT_WRITE),
+ MAP_SHARED, fd, (off_t)0 );
+ }
+ else
+ { /* make the key and get/create an id for the share mem segment */
+ if((key = ftok(mmdc->file, mmdc->proj)) < 0 )
+ goto done;
+ if((mmdc->shmid = shmget(key, size, IPC_CREAT|FILE_MODE)) < 0 )
+ goto done;
+
+ /* map the data segment into memory */
+ mmvm = (Mmvm_t*)shmat(mmdc->shmid, NIL(Void_t*), 0);
+ }
+
+ if(!mmvm || mmvm == (Mmvm_t*)(-1) ) /* initial mapping failed */
+ goto done;
+
+ /* all processes compete for the chore to initialize data */
+ if(asocasint(&mmvm->magic, 0, MM_LETMEDOIT) == 0 ) /* lucky winner: us! */
+ { if(!(base = vmmaddress(size)) ) /* get a suitable base for the map */
+ base = (Void_t*)mmvm;
+ mmdc->flag |= MM_INIT;
+ mmvm->base = base;
+ mmvm->size = size;
+ mmvm->busy = 0;
+ mmvm->proj = mmdc->proj;
+ strcpy(mmvm->file, mmdc->file);
+ if(mmdc->proj < 0 ) /* flush to file */
+ msync((Void_t*)mmvm, MMHEAD(mmvm->file), MS_SYNC);
+
+ if(mmvm->base != (Void_t*)mmvm) /* not yet at the right address */
+ if(!(mmvm = mmfix(mmvm, mmdc, fd)) )
+ goto done;
+ rv = 0; /* success, return this value to indicate a new map */
+ }
+ else /* wait for someone else to finish initialization */
+ { /**/ASSERT(!(mmdc->flag&MM_INIT));
+ if(mmvm->magic != MM_LETMEDOIT && mmvm->magic != MM_MAGIC)
+ goto done;
+
+ for(try = 0, k = 0;; ASOLOOP(k) ) /* waiting */
+ { if(asocasint(&mmvm->magic, MM_MAGIC, MM_MAGIC) == MM_MAGIC )
+ break;
+ else if((try += 1) <= 0 ) /* too many tries */
+ goto done;
+ }
+
+ /* mapped the wrong memory */
+ if(mmvm->proj != mmdc->proj || strcmp(mmvm->file, mmdc->file) != 0 )
+ goto done;
+
+ if(mmvm->base != (Void_t*)mmvm) /* not yet at the right address */
+ if(!(mmvm = mmfix(mmvm, mmdc, fd)) )
+ goto done;
+ rv = 1; /* success, return this value to indicate a finished map */
+ }
+
+done: (void)close(fd);
+
+ if(rv >= 0 ) /* successful construction of region */
+ { /**/ASSERT(mmvm && mmvm != (Mmvm_t*)(-1));
+ mmdc->mmvm = mmvm;
+ }
+ else if(mmvm && mmvm != (Mmvm_t*)(-1)) /* error, remove map */
+ { if(mmdc->proj < 0)
+ (void)munmap((Void_t*)mmvm, size);
+ else (void)shmdt((Void_t*)mmvm);
+ }
+
+ return rv;
+}
+
+#if __STD_C /* end a file mapping */
+static int mmend(Mmdisc_t* mmdc)
+#else
+static int mmend(mmdc)
+Mmdisc_t* mmdc;
+#endif
+{
+ Mmvm_t *mmvm;
+ struct shmid_ds shmds;
+
+ if(!(mmvm = mmdc->mmvm) )
+ return 0;
+
+ if(mmdc->proj < 0 )
+ { (void)msync(mmvm->base, mmvm->size, MS_ASYNC);
+ if(mmdc->flag&MM_RELEASE)
+ { if(mmvm->base )
+ (void)munmap(mmvm->base, mmvm->size);
+ }
+ if(mmdc->flag&MM_CLEANUP)
+ (void)unlink(mmdc->file);
+ }
+ else
+ { if(mmdc->flag&MM_RELEASE)
+ { if(mmvm->base )
+ (void)shmdt(mmvm->base);
+ }
+ if(mmdc->flag&MM_CLEANUP)
+ { if(mmdc->shmid >= 0 )
+ (void)shmctl(mmdc->shmid, IPC_RMID, &shmds);
+ }
+ }
+
+ mmdc->mmvm = NIL(Mmvm_t*);
+ return 0;
+}
+
+#if __STD_C
+static Void_t* mmgetmem(Vmalloc_t* vm, Void_t* caddr,
+ size_t csize, size_t nsize, Vmdisc_t* disc)
+#else
+static Void_t* mmgetmem(vm, caddr, csize, nsize, disc)
+Vmalloc_t* vm;
+Void_t* caddr;
+size_t csize;
+size_t nsize;
+Vmdisc_t* disc;
+#endif
+{
+ Mmvm_t *mmvm;
+ Mmdisc_t *mmdc = (Mmdisc_t*)disc;
+
+ if(!(mmvm = mmdc->mmvm) ) /* bad data */
+ return NIL(Void_t*);
+
+ /* this region allows only a single busy block! */
+ if(caddr) /* resizing/freeing an existing block */
+ { if(caddr == MMDATA(mmvm) && nsize <= MMSIZE(mmvm) )
+ { mmvm->busy = nsize;
+ return MMDATA(mmvm);
+ }
+ else return NIL(Void_t*);
+ }
+ else /* requesting a new block */
+ { if(mmvm->busy == 0 )
+ { mmvm->busy = nsize;
+ return MMDATA(mmvm);
+ }
+ else return NIL(Void_t*);
+ }
+}
+
+#if __STD_C
+static int mmexcept(Vmalloc_t* vm, int type, Void_t* data, Vmdisc_t* disc)
+#else
+static int mmexcept(vm, type, data, disc)
+Vmalloc_t* vm;
+int type;
+Void_t* data;
+Vmdisc_t* disc;
+#endif
+{
+ int rv;
+ Void_t *base;
+ Vmdata_t *vd = vm->data;
+ Mmdisc_t *mmdc = (Mmdisc_t*)disc;
+
+ if(type == VM_OPEN)
+ { if(data) /* VM_OPEN event at start of vmopen() */
+ { if((rv = mminit(mmdc)) < 0 ) /* initialization failed */
+ return -1;
+ else if(rv == 0) /* just started a new map */
+ { /**/ASSERT(mmdc->flag&MM_INIT);
+ /**/ASSERT(mmdc->mmvm->magic == MM_LETMEDOIT);
+ return 0;
+ }
+ else /* an existing map was reconstructed */
+ { /**/ASSERT(!(mmdc->flag&MM_INIT));
+ /**/ASSERT(mmdc->mmvm->magic == MM_MAGIC);
+ *((Void_t**)data) = MMDATA(mmdc->mmvm);
+ return 1;
+ }
+ }
+ else return 0;
+ }
+ else if(type == VM_ENDOPEN) /* at end of vmopen() */
+ { if(mmdc->flag&MM_INIT) /* this is the initializing process! */
+ { /**/ASSERT(mmdc->mmvm->magic == MM_LETMEDOIT);
+ asocasint(&mmdc->mmvm->magic, MM_LETMEDOIT, MM_MAGIC);
+
+ if(mmdc->proj < 0) /* sync data to file now */
+ msync((Void_t*)mmdc->mmvm, MMHEAD(mmdc->file), MS_SYNC);
+ } /**/ASSERT(mmdc->mmvm->magic == MM_MAGIC);
+ return 0;
+ }
+ else if(type == VM_CLOSE)
+ return 1; /* tell vmclose not to free memory segments */
+ else if(type == VM_ENDCLOSE) /* this is the final closing event */
+ { (void)mmend(mmdc);
+ (void)vmfree(Vmheap, mmdc);
+ return 0; /* all done */
+ }
+ else return 0;
+}
+
+#if __STD_C
+Vmalloc_t* vmmopen(char* file, int proj, ssize_t size )
+#else
+Vmalloc_t* vmmopen(file, proj, size )
+char* file; /* file for key or data backing */
+int proj; /* project ID, < 0 doing mmap */
+ssize_t size; /* desired size for mem segment */
+#endif
+{
+ Vmalloc_t *vm;
+ Mmdisc_t *mmdc;
+
+ GETPAGESIZE(_Vmpagesize);
+
+ if(!file || !file[0] )
+ return NIL(Vmalloc_t*);
+
+ /* create discipline structure for getting memory from mmap */
+ if(!(mmdc = vmalloc(Vmheap, sizeof(Mmdisc_t)+strlen(file))) )
+ return NIL(Vmalloc_t*);
+ memset(mmdc, 0, sizeof(Mmdisc_t));
+ mmdc->disc.memoryf = mmgetmem;
+ mmdc->disc.exceptf = mmexcept;
+ mmdc->disc.round = _Vmpagesize; /* round request to this size */
+ mmdc->mmvm = NIL(Mmvm_t*);
+ mmdc->size = size;
+ mmdc->shmid = -1;
+ mmdc->flag = 0;
+ mmdc->proj = proj;
+ strcpy(mmdc->file, file);
+
+ /* now open the Vmalloc_t handle to return to application */
+ if(!(vm = vmopen(&mmdc->disc, Vmbest, VM_SHARE)) )
+ { (void)mmend(mmdc);
+ (void)vmfree(Vmheap, mmdc);
+ return NIL(Vmalloc_t*);
+ }
+ else
+ { /**/ASSERT(mmdc->mmvm && mmdc->mmvm->magic == MM_MAGIC);
+ return vm;
+ }
+}
+
+/* to store (key,value) data in the map */
+#if __STD_C
+Void_t* vmmvalue(Vmalloc_t* vm, int key, Void_t* val, int oper)
+#else
+Void_t* vmmvalue(vm, key, val, oper)
+Vmalloc_t* vm; /* a region based on vmmapopen */
+int key; /* key of data to be set */
+Void_t* val; /* data to be set */
+int oper; /* operation type */
+#endif
+{
+ Mmuser_t *u;
+ Vmdata_t *vd = vm->data;
+ Mmdisc_t *mmdc = (Mmdisc_t*)vm->disc;
+ Mmvm_t *mmvm = mmdc->mmvm;
+
+ /* check to see if operation is well-defined */
+ if(oper != VM_MMGET && oper != VM_MMSET && oper != VM_MMADD)
+ return NIL(Void_t*);
+
+ SETLOCK(vm, 0);
+
+ /* find the key */
+ for(u = mmvm->user; u; u = u->next)
+ if(u->key == key)
+ break;
+
+ if(!u && (oper == VM_MMSET || oper == VM_MMADD) )
+ { if((u = KPVALLOC(vm, sizeof(Mmuser_t), vm->meth.allocf)) )
+ { u->val = NIL(Void_t*);
+ u->key = key;
+ u->next = mmvm->user;
+ mmvm->user = u;
+ }
+ }
+
+ if(u) /* update data and set value to return */
+ { if(oper == VM_MMSET)
+ u->val = val;
+ else if(oper == VM_MMADD)
+ u->val = (Void_t*)((long)(u->val) + (long)(val));
+ val = u->val;
+ }
+ else val = NIL(Void_t*);
+
+ CLRLOCK(vm, 0);
+
+ return val;
+}
+
+void vmmrelease(Vmalloc_t* vm, int type)
+{
+ Mmdisc_t *mmdc = (Mmdisc_t*)vm->disc;
+
+ mmdc->flag |= MM_RELEASE;
+ if(type > 0)
+ mmdc->flag |= MM_CLEANUP;
+}
+
+/* suggest an address usable for mapping memory */
+Void_t* vmmaddress(size_t size)
+{
+#if !defined(_map_min) || !defined(_map_max) || !defined(_map_dir)
+ return NIL(Void_t*);
+#else
+ Void_t *avail;
+ static Vmuchar_t *min = (Vmuchar_t*)_map_min;
+ static Vmuchar_t *max = (Vmuchar_t*)_map_max;
+
+ GETPAGESIZE(_Vmpagesize);
+ size = ROUND(size, _Vmpagesize);
+
+ if(_map_dir == 0 || (min+size) > max)
+ avail = NIL(Void_t*);
+ else if(_map_dir > 0)
+ { avail = (Void_t*)min;
+ min += size;
+ }
+ else
+ { max -= size;
+ avail = (Void_t*)max;
+ }
+
+ return avail;
+#endif
+}
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmopen.c b/src/lib/libast/vmalloc/vmopen.c
new file mode 100644
index 0000000..5f6912f
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmopen.c
@@ -0,0 +1,180 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmopen(){}
+
+#else
+
+#include "vmhdr.h"
+
+/* Opening a new region of allocation.
+** Note that because of possible exotic memory types,
+** all region data must be stored within the space given
+** by the discipline.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+
+/* this structure lives in the top data segment of the region */
+typedef struct _vminit_s
+{ union
+ { Vmdata_t vd; /* root of usable data space */
+ Vmuchar_t a[ROUND(sizeof(Vmdata_t),ALIGN)];
+ } vd;
+ union
+ { Vmalloc_t vm; /* embedded region if needed */
+ Vmuchar_t a[ROUND(sizeof(Vmalloc_t),ALIGN)];
+ } vm;
+ union
+ { Seg_t seg; /* space for segment */
+ Vmuchar_t a[ROUND(sizeof(Seg_t),ALIGN)];
+ } seg;
+ Block_t block[16]; /* space for a few blocks */
+} Vminit_t;
+
+#if __STD_C
+Vmalloc_t* vmopen(Vmdisc_t* disc, Vmethod_t* meth, int mode)
+#else
+Vmalloc_t* vmopen(disc, meth, mode)
+Vmdisc_t* disc; /* discipline to get segments */
+Vmethod_t* meth; /* method to manage space */
+int mode; /* type of region */
+#endif
+{
+ Vmalloc_t *vm, *vmp, vmproto;
+ Vmdata_t *vd;
+ Vminit_t *init;
+ size_t algn, size, incr;
+ Block_t *bp, *np;
+ Seg_t *seg;
+ Vmuchar_t *addr;
+ int rv;
+
+ if(!meth || !disc || !disc->memoryf )
+ return NIL(Vmalloc_t*);
+
+ GETPAGESIZE(_Vmpagesize);
+
+ vmp = &vmproto; /* avoid memory allocation here! */
+ memset(vmp, 0, sizeof(Vmalloc_t));
+ memcpy(&vmp->meth, meth, sizeof(Vmethod_t));
+ vmp->disc = disc;
+
+ mode &= VM_FLAGS; /* start with user-settable flags */
+ size = 0;
+
+ if(disc->exceptf)
+ { addr = NIL(Vmuchar_t*);
+ if((rv = (*disc->exceptf)(vmp,VM_OPEN,(Void_t*)(&addr),disc)) < 0)
+ return NIL(Vmalloc_t*);
+ else if(rv == 0 )
+ { if(addr) /* vm itself is in memory from disc->memoryf */
+ mode |= VM_MEMORYF;
+ }
+ else if(rv > 0) /* the data section is being restored */
+ { if(!(init = (Vminit_t*)addr) )
+ return NIL(Vmalloc_t*);
+ size = -1; /* to tell that addr was not from disc->memoryf */
+ vd = &init->vd.vd; /**/ASSERT(VLONG(vd)%ALIGN == 0);
+ goto done;
+ }
+ }
+
+ /* make sure vd->incr is properly rounded and get initial memory */
+ incr = disc->round <= 0 ? _Vmpagesize : disc->round;
+ incr = MULTIPLE(incr,ALIGN);
+ size = ROUND(sizeof(Vminit_t),incr); /* get initial memory */
+ if(!(addr = (Vmuchar_t*)(*disc->memoryf)(vmp, NIL(Void_t*), 0, size, disc)) )
+ return NIL(Vmalloc_t*);
+ memset(addr, 0, size);
+
+ /* initialize region data */
+ algn = (size_t)(VLONG(addr)%ALIGN);
+ init = (Vminit_t*)(addr + (algn ? ALIGN-algn : 0)); /**/ASSERT(VLONG(init)%ALIGN == 0);
+ vd = &init->vd.vd; /**/ASSERT(VLONG(vd)%ALIGN == 0);
+ vd->mode = mode | meth->meth;
+ vd->incr = incr;
+ vd->pool = 0;
+ vd->free = vd->wild = NIL(Block_t*);
+
+ if(vd->mode&(VM_MTBEST|VM_MTDEBUG|VM_MTPROFILE))
+ { int k;
+ vd->root = NIL(Block_t*);
+ for(k = S_TINY-1; k >= 0; --k)
+ TINY(vd)[k] = NIL(Block_t*);
+ for(k = S_CACHE; k >= 0; --k)
+ CACHE(vd)[k] = NIL(Block_t*);
+ }
+
+ vd->seg = &init->seg.seg; /**/ ASSERT(VLONG(vd->seg)%ALIGN == 0);
+ seg = vd->seg;
+ seg->next = NIL(Seg_t*);
+ seg->vmdt = vd;
+ seg->addr = (Void_t*)addr;
+ seg->extent = size;
+ seg->baddr = addr + size;
+ seg->size = size; /* Note: this size is unusually large to mark seg as
+ the root segment and can be freed only at closing */
+ seg->free = NIL(Block_t*);
+
+ /* make a data block out of the remainder */
+ bp = SEGBLOCK(seg);
+ SEG(bp) = seg;
+ size = ((seg->baddr - (Vmuchar_t*)bp)/ALIGN) * ALIGN; /**/ ASSERT(size > 0);
+ SIZE(bp) = size - 2*sizeof(Head_t); /**/ASSERT(SIZE(bp) > 0 && (SIZE(bp)%ALIGN) == 0);
+ SELF(bp) = bp;
+ /**/ ASSERT(SIZE(bp)%ALIGN == 0);
+ /**/ ASSERT(VLONG(bp)%ALIGN == 0);
+
+ /* make a fake header for next block in case of noncontiguous segments */
+ np = NEXT(bp);
+ SEG(np) = seg;
+ SIZE(np) = BUSY|PFREE;
+
+ if(vd->mode&(VM_MTLAST|VM_MTPOOL))
+ seg->free = bp;
+ else vd->wild = bp;
+
+done: /* now make the region handle */
+ if(vd->mode&VM_MEMORYF)
+ vm = &init->vm.vm;
+ else if(!(vm = vmalloc(Vmheap, sizeof(Vmalloc_t))) )
+ { if(size > 0)
+ (void)(*disc->memoryf)(vmp, addr, size, 0, disc);
+ return NIL(Vmalloc_t*);
+ }
+ memcpy(vm, vmp, sizeof(Vmalloc_t));
+ vm->data = vd;
+
+ if(disc->exceptf) /* signaling that vmopen succeeded */
+ (void)(*disc->exceptf)(vm, VM_ENDOPEN, NIL(Void_t*), disc);
+
+ /* add to the linked list of regions */
+ _vmlock(NIL(Vmalloc_t*), 1);
+ vm->next = Vmheap->next; Vmheap->next = vm;
+ _vmlock(NIL(Vmalloc_t*), 0);
+
+ return vm;
+}
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmpool.c b/src/lib/libast/vmalloc/vmpool.c
new file mode 100644
index 0000000..2c65a66
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmpool.c
@@ -0,0 +1,316 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmpool(){}
+
+#else
+
+#include "vmhdr.h"
+
+#define POOLFREE 0x55555555L /* block free indicator */
+
+/* Method for pool allocation.
+** All elements in a pool have the same size.
+** The following fields of Vmdata_t are used as:
+** pool: size of a block.
+** free: list of free blocks.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+
+#if __STD_C
+static Void_t* poolalloc(Vmalloc_t* vm, reg size_t size, int local)
+#else
+static Void_t* poolalloc(vm, size, local )
+Vmalloc_t* vm;
+reg size_t size;
+int local;
+#endif
+{
+ reg Block_t *tp, *next;
+ reg size_t s;
+ reg Seg_t *seg;
+ reg Vmdata_t *vd = vm->data;
+
+ if(size <= 0)
+ return NIL(Void_t*);
+
+ if(size != vd->pool)
+ { if(vd->pool <= 0)
+ vd->pool = size;
+ else return NIL(Void_t*);
+ }
+
+ SETLOCK(vm, local);
+
+ if((tp = vd->free) ) /* there is a ready free block */
+ { vd->free = SEGLINK(tp);
+ goto done;
+ }
+
+ size = ROUND(size,ALIGN);
+
+ /* look thru all segments for a suitable free block */
+ for(tp = NIL(Block_t*), seg = vd->seg; seg; seg = seg->next)
+ { if((tp = seg->free) &&
+ (s = (SIZE(tp) & ~BITS) + sizeof(Head_t)) >= size )
+ goto got_blk;
+ }
+
+ if((tp = (*_Vmextend)(vm,ROUND(size,vd->incr),NIL(Vmsearch_f))) )
+ { s = (SIZE(tp) & ~BITS) + sizeof(Head_t);
+ seg = SEG(tp);
+ goto got_blk;
+ }
+ else goto done;
+
+got_blk: /* if get here, (tp, s, seg) must be well-defined */
+ next = (Block_t*)((Vmuchar_t*)tp+size);
+ if((s -= size) <= (size + sizeof(Head_t)) )
+ { for(; s >= size; s -= size)
+ { SIZE(next) = POOLFREE;
+ SEGLINK(next) = vd->free;
+ vd->free = next;
+ next = (Block_t*)((Vmuchar_t*)next + size);
+ }
+ seg->free = NIL(Block_t*);
+ }
+ else
+ { SIZE(next) = s - sizeof(Head_t);
+ SEG(next) = seg;
+ seg->free = next;
+ }
+
+done:
+ if(!local && (vd->mode&VM_TRACE) && _Vmtrace && tp)
+ (*_Vmtrace)(vm,NIL(Vmuchar_t*),(Vmuchar_t*)tp,vd->pool,0);
+
+ CLRLOCK(vm, local);
+
+ return (Void_t*)tp;
+}
+
+#if __STD_C
+static long pooladdr(Vmalloc_t* vm, reg Void_t* addr, int local)
+#else
+static long pooladdr(vm, addr, local)
+Vmalloc_t* vm;
+reg Void_t* addr;
+int local;
+#endif
+{
+ Block_t *bp, *tp;
+ Vmuchar_t *laddr, *baddr;
+ size_t size;
+ Seg_t *seg;
+ long offset;
+ Vmdata_t* vd = vm->data;
+
+ SETLOCK(vm, local);
+
+ offset = -1L;
+ for(seg = vd->seg; seg; seg = seg->next)
+ { laddr = (Vmuchar_t*)SEGBLOCK(seg);
+ baddr = seg->baddr-sizeof(Head_t);
+ if((Vmuchar_t*)addr < laddr || (Vmuchar_t*)addr >= baddr)
+ continue;
+
+ /* the block that has this address */
+ size = ROUND(vd->pool,ALIGN);
+ tp = (Block_t*)(laddr + (((Vmuchar_t*)addr-laddr)/size)*size );
+
+ /* see if this block has been freed */
+ if(SIZE(tp) == POOLFREE) /* may be a coincidence - make sure */
+ for(bp = vd->free; bp; bp = SEGLINK(bp))
+ if(bp == tp)
+ goto done;
+
+ offset = (Vmuchar_t*)addr - (Vmuchar_t*)tp;
+ goto done;
+ }
+
+done :
+ CLRLOCK(vm, local);
+
+ return offset;
+}
+
+#if __STD_C
+static int poolfree(reg Vmalloc_t* vm, reg Void_t* data, int local )
+#else
+static int poolfree(vm, data, local)
+Vmalloc_t* vm;
+Void_t* data;
+int local;
+#endif
+{
+ Block_t *bp;
+ Vmdata_t *vd = vm->data;
+
+ if(!data)
+ return 0;
+ if(vd->pool <= 0)
+ return -1;
+
+ SETLOCK(vm, local);
+
+ /**/ASSERT(KPVADDR(vm, data, pooladdr) == 0);
+ bp = (Block_t*)data;
+ SIZE(bp) = POOLFREE;
+ SEGLINK(bp) = vd->free;
+ vd->free = bp;
+
+ if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
+ (*_Vmtrace)(vm, (Vmuchar_t*)data, NIL(Vmuchar_t*), vd->pool, 0);
+
+ CLRLOCK(vm, local);
+
+ return 0;
+}
+
+#if __STD_C
+static Void_t* poolresize(Vmalloc_t* vm, Void_t* data, size_t size, int type, int local )
+#else
+static Void_t* poolresize(vm, data, size, type, local )
+Vmalloc_t* vm;
+Void_t* data;
+size_t size;
+int type;
+int local;
+#endif
+{
+ Vmdata_t *vd = vm->data;
+
+ NOTUSED(type);
+
+ if(!data)
+ { data = poolalloc(vm, size, local);
+ if(data && (type&VM_RSZERO) )
+ memset(data, 0, size);
+ return data;
+ }
+ if(size == 0)
+ { (void)poolfree(vm, data, local);
+ return NIL(Void_t*);
+ }
+ if(size != vd->pool)
+ return NIL(Void_t*);
+
+ SETLOCK(vm, local);
+
+ /**/ASSERT(KPVADDR(vm, data, pooladdr) == 0);
+
+ if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
+ (*_Vmtrace)(vm, (Vmuchar_t*)data, (Vmuchar_t*)data, size, 0);
+
+ CLRLOCK(vm, local);
+
+ return data;
+}
+
+#if __STD_C
+static long poolsize(Vmalloc_t* vm, Void_t* addr, int local)
+#else
+static long poolsize(vm, addr, local)
+Vmalloc_t* vm;
+Void_t* addr;
+int local;
+#endif
+{
+ return pooladdr(vm, addr, local) == 0 ? (long)vm->data->pool : -1L;
+}
+
+#if __STD_C
+static int poolcompact(Vmalloc_t* vm, int local)
+#else
+static int poolcompact(vm, local)
+Vmalloc_t* vm;
+int local;
+#endif
+{
+ ssize_t s;
+ Block_t *fp;
+ Seg_t *seg, *next;
+ Vmdata_t *vd = vm->data;
+
+ SETLOCK(vm, local);
+
+ for(seg = vd->seg; seg; seg = next)
+ { next = seg->next;
+
+ if(!(fp = seg->free))
+ continue;
+
+ seg->free = NIL(Block_t*);
+ if(seg->size == (s = SIZE(fp)&~BITS))
+ s = seg->extent;
+ else s += sizeof(Head_t);
+
+ if((*_Vmtruncate)(vm,seg,s,1) == s)
+ seg->free = fp;
+ }
+
+ if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
+ (*_Vmtrace)(vm, (Vmuchar_t*)0, (Vmuchar_t*)0, 0, 0);
+
+ CLRLOCK(vm, local);
+
+ return 0;
+}
+
+#if __STD_C
+static Void_t* poolalign(Vmalloc_t* vm, size_t size, size_t align, int local)
+#else
+static Void_t* poolalign(vm, size, align, local)
+Vmalloc_t* vm;
+size_t size;
+size_t align;
+int local;
+#endif
+{
+ NOTUSED(vm);
+ NOTUSED(size);
+ NOTUSED(align);
+ return NIL(Void_t*);
+}
+
+/* Public interface */
+static Vmethod_t _Vmpool =
+{
+ poolalloc,
+ poolresize,
+ poolfree,
+ pooladdr,
+ poolsize,
+ poolcompact,
+ poolalign,
+ VM_MTPOOL
+};
+
+__DEFINE__(Vmethod_t*,Vmpool,&_Vmpool);
+
+#ifdef NoF
+NoF(vmpool)
+#endif
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmprivate.c b/src/lib/libast/vmalloc/vmprivate.c
new file mode 100644
index 0000000..28f3f70
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmprivate.c
@@ -0,0 +1,292 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmprivate(){}
+
+#else
+
+#include "vmhdr.h"
+
+static char* Version = "\n@(#)$Id: Vmalloc (AT&T Labs - Research) 2011-08-08 $\0\n";
+
+
+/* Private code used in the vmalloc library
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+
+/* Get more memory for a region */
+#if __STD_C
+static Block_t* _vmextend(reg Vmalloc_t* vm, size_t size, Vmsearch_f searchf )
+#else
+static Block_t* _vmextend(vm, size, searchf )
+reg Vmalloc_t* vm; /* region to increase in size */
+size_t size; /* desired amount of space */
+Vmsearch_f searchf; /* tree search function */
+#endif
+{
+ reg size_t s;
+ reg Seg_t* seg;
+ reg Block_t *bp, *tp, *np;
+ reg Vmuchar_t* addr = (Vmuchar_t*)Version; /* shut compiler warning */
+ reg Vmdata_t* vd = vm->data;
+
+ GETPAGESIZE(_Vmpagesize);
+
+ if(vd->incr <= 0) /* this is just _Vmheap on the first call */
+ vd->incr = _Vmpagesize*sizeof(Void_t*);
+
+ /* Get slightly more for administrative data */
+ s = size + sizeof(Seg_t) + sizeof(Block_t) + sizeof(Head_t) + 2*ALIGN;
+ if(s <= size) /* size was too large and we have wrapped around */
+ return NIL(Block_t*);
+ if((size = ROUND(s,vd->incr)) < s)
+ return NIL(Block_t*);
+
+ /* increase the rounding factor to reduce # of future extensions */
+ if(size > 2*vd->incr && vm->disc->round < vd->incr)
+ vd->incr *= 2;
+
+ if(!(seg = vd->seg) ) /* there is no current segment */
+ addr = NIL(Vmuchar_t*);
+ else /* see if we can extend the current segment */
+ { addr = (Vmuchar_t*)(*vm->disc->memoryf)(vm,seg->addr,seg->extent,
+ seg->extent+size,vm->disc);
+ if(addr == (Vmuchar_t*)seg->addr)
+ addr += seg->extent; /* seg successfully extended */
+ else seg = NIL(Seg_t*); /* a new segment was created */
+ }
+
+ if(!addr) /* create a new segment */
+ { if(!(addr = (Vmuchar_t*)(*vm->disc->memoryf)(vm, NIL(Void_t*), 0, size, vm->disc)) )
+ { if(vm->disc->exceptf) /* announce that no more memory is available */
+ {
+ CLRLOCK(vm, 0);
+ (void)(*vm->disc->exceptf)(vm, VM_NOMEM, (Void_t*)size, vm->disc);
+ SETLOCK(vm, 0);
+ }
+ return NIL(Block_t*);
+ }
+ }
+
+ if(seg)
+ { /* extending current segment */
+ bp = BLOCK(seg->baddr);
+
+ if(vd->mode&(VM_MTBEST|VM_MTDEBUG|VM_MTPROFILE) )
+ { /**/ ASSERT((SIZE(bp)&~BITS) == 0);
+ /**/ ASSERT(SEG(bp) == seg);
+
+ if(!ISPFREE(SIZE(bp)) )
+ SIZE(bp) = size - sizeof(Head_t);
+ else
+ { /**/ ASSERT(searchf);
+ bp = LAST(bp);
+ if(bp == vd->wild)
+ vd->wild = NIL(Block_t*);
+ else REMOVE(vd,bp,INDEX(SIZE(bp)),tp,(*searchf));
+ SIZE(bp) += size;
+ }
+ }
+ else
+ { if(seg->free)
+ { bp = seg->free;
+ seg->free = NIL(Block_t*);
+ SIZE(bp) += size;
+ }
+ else
+ { SEG(bp) = seg;
+ SIZE(bp) = size - sizeof(Head_t);
+ }
+ }
+
+ seg->size += size;
+ seg->extent += size;
+ seg->baddr += size;
+ }
+ else
+ { /* creating a new segment */
+ reg Seg_t *sp, *lastsp;
+
+ if((s = (size_t)(VLONG(addr)%ALIGN)) != 0)
+ addr += ALIGN-s;
+
+ seg = (Seg_t*)addr;
+ seg->vmdt = vd;
+ seg->addr = (Void_t*)(addr - (s ? ALIGN-s : 0));
+ seg->extent = size;
+ seg->baddr = addr + size - (s ? 2*ALIGN : 0);
+ seg->free = NIL(Block_t*);
+ bp = SEGBLOCK(seg);
+ SEG(bp) = seg;
+ SIZE(bp) = seg->baddr - (Vmuchar_t*)bp - 2*sizeof(Head_t);
+
+ /* NOTE: for Vmbest, Vmdebug and Vmprofile the region's segment list
+ is reversely ordered by addresses. This is so that we can easily
+ check for the wild block.
+ */
+ lastsp = NIL(Seg_t*);
+ sp = vd->seg;
+ if(vd->mode&(VM_MTBEST|VM_MTDEBUG|VM_MTPROFILE))
+ for(; sp; lastsp = sp, sp = sp->next)
+ if(seg->addr > sp->addr)
+ break;
+ seg->next = sp;
+ if(lastsp)
+ lastsp->next = seg;
+ else vd->seg = seg;
+
+ seg->size = SIZE(bp);
+ }
+
+ /* make a fake header for possible segmented memory */
+ tp = NEXT(bp);
+ SEG(tp) = seg;
+ SIZE(tp) = BUSY;
+
+ /* see if the wild block is still wild */
+ if((tp = vd->wild) && (seg = SEG(tp)) != vd->seg)
+ { np = NEXT(tp);
+ CLRPFREE(SIZE(np));
+ if(vd->mode&(VM_MTBEST|VM_MTDEBUG|VM_MTPROFILE) )
+ { SIZE(tp) |= BUSY|JUNK;
+ LINK(tp) = CACHE(vd)[C_INDEX(SIZE(tp))];
+ CACHE(vd)[C_INDEX(SIZE(tp))] = tp;
+ }
+ else seg->free = tp;
+
+ vd->wild = NIL(Block_t*);
+ }
+
+ return bp;
+}
+
+/* Truncate a segment if possible */
+#if __STD_C
+static ssize_t _vmtruncate(Vmalloc_t* vm, Seg_t* seg, size_t size, int exact)
+#else
+static ssize_t _vmtruncate(vm, seg, size, exact)
+Vmalloc_t* vm; /* containing region */
+Seg_t* seg; /* the one to be truncated */
+size_t size; /* amount of free space */
+int exact;
+#endif
+{
+ reg Void_t* caddr;
+ reg Seg_t* last;
+ reg Vmdata_t* vd = vm->data;
+ reg Vmemory_f memoryf = vm->disc->memoryf;
+
+ caddr = seg->addr;
+
+ if(size < seg->size)
+ { reg ssize_t less;
+
+ if(exact)
+ less = size;
+ else /* keep truncated amount to discipline requirements */
+ { if((less = vm->disc->round) <= 0)
+ less = _Vmpagesize;
+ less = (size/less)*less;
+ less = (less/vd->incr)*vd->incr;
+ if(less > 0 && (ssize_t)size > less && (size-less) < sizeof(Block_t) )
+ less = less <= (ssize_t)vd->incr ? 0 : less - vd->incr;
+ }
+
+ if(less <= 0 ||
+ (*memoryf)(vm,caddr,seg->extent,seg->extent-less,vm->disc) != caddr)
+ return 0;
+
+ seg->extent -= less;
+ seg->size -= less;
+ seg->baddr -= less;
+ SEG(BLOCK(seg->baddr)) = seg;
+ SIZE(BLOCK(seg->baddr)) = BUSY;
+
+ return less;
+ }
+ else
+ { /* unlink segment from region */
+ if(seg == vd->seg)
+ { vd->seg = seg->next;
+ last = NIL(Seg_t*);
+ }
+ else
+ { for(last = vd->seg; last->next != seg; last = last->next)
+ ;
+ last->next = seg->next;
+ }
+
+ /* now delete it */
+ if((*memoryf)(vm,caddr,seg->extent,0,vm->disc) == caddr)
+ return size;
+
+ /* space reduction failed, reinsert segment */
+ if(last)
+ { seg->next = last->next;
+ last->next = seg;
+ }
+ else
+ { seg->next = vd->seg;
+ vd->seg = seg;
+ }
+ return 0;
+ }
+}
+
+int _vmlock(Vmalloc_t* vm, int locking)
+{
+ int k;
+
+ if(!vm) /* some sort of global locking */
+ { if(!locking) /* turn off lock */
+ asolock(&_Vmlock, 1, ASO_UNLOCK);
+ else asolock(&_Vmlock, 1, ASO_SPINLOCK);
+ }
+ else if(vm->data->mode&VM_SHARE)
+ { if(!locking) /* turning off the lock */
+ asolock(&vm->data->lock, 1, ASO_UNLOCK);
+ else asolock(&vm->data->lock, 1, ASO_SPINLOCK);
+ }
+ else
+ { if(!locking)
+ vm->data->lock = 0;
+ else vm->data->lock = 1;
+ }
+ return 0;
+}
+
+
+/* Externally visible names but local to library */
+Vmextern_t _Vmextern =
+{ _vmextend, /* _Vmextend */
+ _vmtruncate, /* _Vmtruncate */
+ 0, /* _Vmpagesize */
+ NIL(char*(*)_ARG_((char*,const char*,int))), /* _Vmstrcpy */
+ NIL(char*(*)_ARG_((Vmulong_t,int))), /* _Vmitoa */
+ NIL(void(*)_ARG_((Vmalloc_t*,
+ Vmuchar_t*,Vmuchar_t*,size_t,size_t))), /* _Vmtrace */
+ NIL(void(*)_ARG_((Vmalloc_t*))) /* _Vmpfclose */
+};
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmprofile.c b/src/lib/libast/vmalloc/vmprofile.c
new file mode 100644
index 0000000..43191ed
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmprofile.c
@@ -0,0 +1,709 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmprofile(){}
+
+#else
+
+#include "vmhdr.h"
+
+/* Method to profile space usage.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 03/23/94.
+*/
+
+#define PFHASH(pf) ((pf)->data.data.hash)
+#define PFVM(pf) ((pf)->data.data.vm)
+#define PFFILE(pf) ((pf)->data.data.fm.file)
+#define PFLINE(pf) ((pf)->line)
+#define PFNAME(pf) ((pf)->data.f)
+#define PFNALLOC(pf) ((pf)->data.data.nalloc)
+#define PFALLOC(pf) ((pf)->data.data.alloc)
+#define PFNFREE(pf) ((pf)->data.data.nfree)
+#define PFFREE(pf) ((pf)->data.data.free)
+#define PFREGION(pf) ((pf)->data.data.region)
+#define PFMAX(pf) ((pf)->data.data.fm.max)
+
+typedef struct _pfdata_s Pfdata_t;
+struct _pfdata_s
+{ Vmulong_t hash; /* hash value */
+ union
+ { char* file; /* file name */
+ Vmulong_t max; /* max busy space for region */
+ } fm;
+ Vmalloc_t* vm; /* region alloc from */
+ Pfobj_t* region; /* pointer to region record */
+ Vmulong_t nalloc; /* number of alloc calls */
+ Vmulong_t alloc; /* amount allocated */
+ Vmulong_t nfree; /* number of free calls */
+ Vmulong_t free; /* amount freed */
+};
+struct _pfobj_s
+{ Pfobj_t* next; /* next in linked list */
+ int line; /* line #, 0 for name holder */
+ union
+ {
+ Pfdata_t data;
+ char f[1]; /* actual file name */
+ } data;
+};
+
+static Pfobj_t** Pftable; /* hash table */
+#define PFTABLE 1019 /* table size */
+static Vmalloc_t* Vmpf; /* heap for our own use */
+
+#if __STD_C
+static Pfobj_t* pfsearch(Vmalloc_t* vm, char* file, int line)
+#else
+static Pfobj_t* pfsearch(vm, file, line)
+Vmalloc_t* vm; /* region allocating from */
+char* file; /* the file issuing the allocation request */
+int line; /* line number */
+#endif
+{
+ reg Pfobj_t *pf, *last;
+ reg Vmulong_t h;
+ reg int n;
+ reg char *cp;
+
+ if(!Vmpf && !(Vmpf = vmopen(Vmdcheap,Vmpool,0)) )
+ return NIL(Pfobj_t*);
+
+ /* make hash table; PFTABLE'th slot hold regions' records */
+ if(!Pftable)
+ { if(!(Pftable = (Pfobj_t**)vmalloc(Vmheap,(PFTABLE+1)*sizeof(Pfobj_t*))) )
+ return NIL(Pfobj_t*);
+ for(n = PFTABLE; n >= 0; --n)
+ Pftable[n] = NIL(Pfobj_t*);
+ }
+
+ /* see if it's there with a combined hash value of vm,file,line */
+ h = line + (((Vmulong_t)vm)>>4);
+ for(cp = file; *cp; ++cp)
+ h += (h<<7) + ((*cp)&0377) + 987654321L;
+ n = (int)(h%PFTABLE);
+ for(last = NIL(Pfobj_t*), pf = Pftable[n]; pf; last = pf, pf = pf->next)
+ if(PFLINE(pf) == line && PFVM(pf) == vm && strcmp(PFFILE(pf),file) == 0)
+ break;
+
+ /* insert if not there yet */
+ if(!pf)
+ { reg Pfobj_t* fn;
+ reg Pfobj_t* pfvm;
+ reg Vmulong_t hn;
+
+ /* first get/construct the file name slot */
+ hn = 0;
+ for(cp = file; *cp; ++cp)
+ hn += (hn<<7) + ((*cp)&0377) + 987654321L;
+ n = (int)(hn%PFTABLE);
+ for(fn = Pftable[n]; fn; fn = fn->next)
+ if(PFLINE(fn) < 0 && strcmp(PFNAME(fn),file) == 0)
+ break;
+ if(!fn)
+ { reg size_t s;
+ s = sizeof(Pfobj_t) - sizeof(Pfdata_t) + strlen(file) + 1;
+ if(!(fn = (Pfobj_t*)vmalloc(Vmheap,s)) )
+ return NIL(Pfobj_t*);
+ fn->next = Pftable[n];
+ Pftable[n] = fn;
+ PFLINE(fn) = -1;
+ strcpy(PFNAME(fn),file);
+ }
+
+ /* get region record; note that these are ordered by vm */
+ last = NIL(Pfobj_t*);
+ for(pfvm = Pftable[PFTABLE]; pfvm; last = pfvm, pfvm = pfvm->next)
+ if(vm >= PFVM(pfvm))
+ break;
+ if(!pfvm || PFVM(pfvm) > vm)
+ { if(!(pfvm = (Pfobj_t*)vmalloc(Vmpf,sizeof(Pfobj_t))) )
+ return NIL(Pfobj_t*);
+ if(last)
+ { pfvm->next = last->next;
+ last->next = pfvm;
+ }
+ else
+ { pfvm->next = Pftable[PFTABLE];
+ Pftable[PFTABLE] = pfvm;
+ }
+ PFNALLOC(pfvm) = PFALLOC(pfvm) = 0;
+ PFNFREE(pfvm) = PFFREE(pfvm) = 0;
+ PFMAX(pfvm) = 0;
+ PFVM(pfvm) = vm;
+ PFLINE(pfvm) = 0;
+ }
+
+ if(!(pf = (Pfobj_t*)vmalloc(Vmpf,sizeof(Pfobj_t))) )
+ return NIL(Pfobj_t*);
+ n = (int)(h%PFTABLE);
+ pf->next = Pftable[n];
+ Pftable[n] = pf;
+ PFLINE(pf) = line;
+ PFFILE(pf) = PFNAME(fn);
+ PFREGION(pf) = pfvm;
+ PFVM(pf) = vm;
+ PFNALLOC(pf) = 0;
+ PFALLOC(pf) = 0;
+ PFNFREE(pf) = 0;
+ PFFREE(pf) = 0;
+ PFHASH(pf) = h;
+ }
+ else if(last) /* do a move-to-front */
+ { last->next = pf->next;
+ pf->next = Pftable[n];
+ Pftable[n] = pf;
+ }
+
+ return pf;
+}
+
+#if __STD_C
+static void pfclose(Vmalloc_t* vm)
+#else
+static void pfclose(vm)
+Vmalloc_t* vm;
+#endif
+{
+ reg int n;
+ reg Pfobj_t *pf, *next, *last;
+
+ /* free all records related to region vm */
+ for(n = PFTABLE; n >= 0; --n)
+ { for(last = NIL(Pfobj_t*), pf = Pftable[n]; pf; )
+ { next = pf->next;
+
+ if(PFLINE(pf) >= 0 && PFVM(pf) == vm)
+ { if(last)
+ last->next = next;
+ else Pftable[n] = next;
+ vmfree(Vmpf,pf);
+ }
+ else last = pf;
+
+ pf = next;
+ }
+ }
+}
+
+#if __STD_C
+static void pfsetinfo(Vmalloc_t* vm, Vmuchar_t* data, size_t size, char* file, int line)
+#else
+static void pfsetinfo(vm, data, size, file, line)
+Vmalloc_t* vm;
+Vmuchar_t* data;
+size_t size;
+char* file;
+int line;
+#endif
+{
+ reg Pfobj_t* pf;
+ reg Vmulong_t s;
+
+ /* let vmclose knows that there are records for region vm */
+ _Vmpfclose = pfclose;
+
+ if(!file || line <= 0)
+ { file = "";
+ line = 0;
+ }
+
+ if((pf = pfsearch(vm,file,line)) )
+ { PFALLOC(pf) += size;
+ PFNALLOC(pf) += 1;
+ }
+ PFOBJ(data) = pf;
+ PFSIZE(data) = size;
+
+ if(pf)
+ { /* update region statistics */
+ pf = PFREGION(pf);
+ PFALLOC(pf) += size;
+ PFNALLOC(pf) += 1;
+ if((s = PFALLOC(pf) - PFFREE(pf)) > PFMAX(pf) )
+ PFMAX(pf) = s;
+ }
+}
+
+/* sort by file names and line numbers */
+#if __STD_C
+static Pfobj_t* pfsort(Pfobj_t* pf)
+#else
+static Pfobj_t* pfsort(pf)
+Pfobj_t* pf;
+#endif
+{
+ reg Pfobj_t *one, *two, *next;
+ reg int cmp;
+
+ if(!pf->next)
+ return pf;
+
+ /* partition to two equal size lists */
+ one = two = NIL(Pfobj_t*);
+ while(pf)
+ { next = pf->next;
+ pf->next = one;
+ one = pf;
+
+ if((pf = next) )
+ { next = pf->next;
+ pf->next = two;
+ two = pf;
+ pf = next;
+ }
+ }
+
+ /* sort and merge the lists */
+ one = pfsort(one);
+ two = pfsort(two);
+ for(pf = next = NIL(Pfobj_t*);; )
+ { /* make sure that the "<>" file comes first */
+ if(PFLINE(one) == 0 && PFLINE(two) == 0)
+ cmp = PFVM(one) > PFVM(two) ? 1 : -1;
+ else if(PFLINE(one) == 0)
+ cmp = -1;
+ else if(PFLINE(two) == 0)
+ cmp = 1;
+ else if((cmp = strcmp(PFFILE(one),PFFILE(two))) == 0)
+ { cmp = PFLINE(one) - PFLINE(two);
+ if(cmp == 0)
+ cmp = PFVM(one) > PFVM(two) ? 1 : -1;
+ }
+
+ if(cmp < 0)
+ { if(!pf)
+ pf = one;
+ else next->next = one;
+ next = one;
+ if(!(one = one->next) )
+ { if(two)
+ next->next = two;
+ return pf;
+ }
+ }
+ else
+ { if(!pf)
+ pf = two;
+ else next->next = two;
+ next = two;
+ if(!(two = two->next) )
+ { if(one)
+ next->next = one;
+ return pf;
+ }
+ }
+ }
+}
+
+#if __STD_C
+static char* pfsummary(char* buf, Vmulong_t na, Vmulong_t sa,
+ Vmulong_t nf, Vmulong_t sf, Vmulong_t max, Vmulong_t size)
+#else
+static char* pfsummary(buf, na, sa, nf, sf, max, size)
+char* buf;
+Vmulong_t na;
+Vmulong_t sa;
+Vmulong_t nf;
+Vmulong_t sf;
+Vmulong_t max;
+Vmulong_t size;
+#endif
+{
+ buf = (*_Vmstrcpy)(buf,"n_alloc", '=');
+ buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(na,-1), ':');
+ buf = (*_Vmstrcpy)(buf,"n_free", '=');
+ buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(nf,-1), ':');
+ buf = (*_Vmstrcpy)(buf,"s_alloc", '=');
+ buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(sa,-1), ':');
+ buf = (*_Vmstrcpy)(buf,"s_free", '=');
+ buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(sf,-1), ':');
+ if(max > 0)
+ { buf = (*_Vmstrcpy)(buf,"max_busy", '=');
+ buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(max,-1), ':');
+ buf = (*_Vmstrcpy)(buf,"extent", '=');
+ buf = (*_Vmstrcpy)(buf, (*_Vmitoa)(size,-1), ':');
+ }
+ *buf++ = '\n';
+
+ return buf;
+}
+
+/* print profile data */
+#if __STD_C
+int vmprofile(Vmalloc_t* vm, int fd)
+#else
+int vmprofile(vm, fd)
+Vmalloc_t* vm;
+int fd;
+#endif
+{
+ reg Pfobj_t *pf, *list, *next, *last;
+ reg int n;
+ reg Vmulong_t nalloc, alloc, nfree, free;
+ reg Seg_t *seg;
+ char buf[1024], *bufp, *endbuf;
+#define INITBUF() (bufp = buf, endbuf = buf+sizeof(buf)-128)
+#define CHKBUF() (bufp >= endbuf ? (write(fd,buf,bufp-buf), bufp=buf) : bufp)
+#define FLSBUF() (bufp > buf ? write(fd,buf,bufp-buf) : 0)
+
+ if(fd < 0)
+ return -1;
+
+ /* initialize functions from vmtrace.c that we use below */
+ if((n = vmtrace(-1)) >= 0)
+ vmtrace(n);
+
+ alloc = free = nalloc = nfree = 0;
+ list = NIL(Pfobj_t*);
+ for(n = PFTABLE-1; n >= 0; --n)
+ { for(pf = Pftable[n], last = NIL(Pfobj_t*); pf; )
+ { next = pf->next;
+
+ if(PFLINE(pf) < 0 || (vm && vm != PFVM(pf)) )
+ { last = pf;
+ goto next_pf;
+ }
+
+ /* remove from hash table */
+ if(last)
+ last->next = next;
+ else Pftable[n] = next;
+
+ /* put on output list */
+ pf->next = list;
+ list = pf;
+ nalloc += PFNALLOC(pf);
+ alloc += PFALLOC(pf);
+ nfree += PFNFREE(pf);
+ free += PFFREE(pf);
+
+ next_pf:
+ pf = next;
+ }
+ }
+
+ INITBUF();
+ bufp = (*_Vmstrcpy)(bufp,"ALLOCATION USAGE SUMMARY", ':');
+ bufp = pfsummary(bufp,nalloc,alloc,nfree,free,0,0);
+
+ /* print regions' summary data */
+ for(pf = Pftable[PFTABLE]; pf; pf = pf->next)
+ { if(vm && PFVM(pf) != vm)
+ continue;
+ alloc = 0;
+ for(seg = PFVM(pf)->data->seg; seg; seg = seg->next)
+ alloc += seg->extent;
+ bufp = (*_Vmstrcpy)(bufp,"region", '=');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(PFVM(pf)),0), ':');
+ bufp = pfsummary(bufp,PFNALLOC(pf),PFALLOC(pf),
+ PFNFREE(pf),PFFREE(pf),PFMAX(pf),alloc);
+ }
+
+ /* sort then output detailed profile */
+ list = pfsort(list);
+ for(pf = list; pf; )
+ { /* compute summary for file */
+ alloc = free = nalloc = nfree = 0;
+ for(last = pf; last; last = last->next)
+ { if(strcmp(PFFILE(last),PFFILE(pf)) != 0)
+ break;
+ nalloc += PFNALLOC(pf);
+ alloc += PFALLOC(last);
+ nfree += PFNFREE(last);
+ free += PFFREE(last);
+ }
+ CHKBUF();
+ bufp = (*_Vmstrcpy)(bufp,"file",'=');
+ bufp = (*_Vmstrcpy)(bufp,PFFILE(pf)[0] ? PFFILE(pf) : "<>" ,':');
+ bufp = pfsummary(bufp,nalloc,alloc,nfree,free,0,0);
+
+ while(pf != last) /* detailed data */
+ { CHKBUF();
+ bufp = (*_Vmstrcpy)(bufp,"\tline",'=');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(PFLINE(pf),-1), ':');
+ bufp = (*_Vmstrcpy)(bufp, "region", '=');
+ bufp = (*_Vmstrcpy)(bufp, (*_Vmitoa)(VLONG(PFVM(pf)),0), ':');
+ bufp = pfsummary(bufp,PFNALLOC(pf),PFALLOC(pf),
+ PFNFREE(pf),PFFREE(pf),0,0);
+
+ /* reinsert into hash table */
+ next = pf->next;
+ n = (int)(PFHASH(pf)%PFTABLE);
+ pf->next = Pftable[n];
+ Pftable[n] = pf;
+ pf = next;
+ }
+ }
+
+ FLSBUF();
+ return 0;
+}
+
+#if __STD_C
+static Void_t* pfalloc(Vmalloc_t* vm, size_t size, int local)
+#else
+static Void_t* pfalloc(vm, size, local)
+Vmalloc_t* vm;
+size_t size;
+int local;
+#endif
+{
+ reg size_t s;
+ reg Void_t *data;
+ reg char *file;
+ reg int line;
+ reg Void_t *func;
+ reg Vmdata_t *vd = vm->data;
+
+ VMFLF(vm,file,line,func);
+
+ SETLOCK(vm, local);
+
+ s = ROUND(size,ALIGN) + PF_EXTRA;
+ if((data = KPVALLOC(vm,s,(*(Vmbest->allocf))) ) )
+ { pfsetinfo(vm,(Vmuchar_t*)data,size,file,line);
+
+ if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
+ { vm->file = file; vm->line = line; vm->func = func;
+ (*_Vmtrace)(vm,NIL(Vmuchar_t*),(Vmuchar_t*)data,size,0);
+ }
+ }
+
+ CLRLOCK(vm, local);
+
+ return data;
+}
+
+#if __STD_C
+static int pffree(Vmalloc_t* vm, Void_t* data, int local)
+#else
+static int pffree(vm, data, local)
+Vmalloc_t* vm;
+Void_t* data;
+int local;
+#endif
+{
+ reg Pfobj_t *pf;
+ reg size_t s;
+ reg char *file;
+ reg int line, rv;
+ reg Void_t *func;
+ reg Vmdata_t *vd = vm->data;
+
+ VMFLF(vm,file,line,func);
+
+ if(!data)
+ return 0;
+
+ SETLOCK(vm,local);
+
+ /**/ASSERT(KPVADDR(vm, data, Vmbest->addrf) == 0 );
+ pf = PFOBJ(data);
+ s = PFSIZE(data);
+ if(pf)
+ { PFNFREE(pf) += 1;
+ PFFREE(pf) += s;
+ pf = PFREGION(pf);
+ PFNFREE(pf) += 1;
+ PFFREE(pf) += s;
+ }
+
+ if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
+ { vm->file = file; vm->line = line; vm->func = func;
+ (*_Vmtrace)(vm,(Vmuchar_t*)data,NIL(Vmuchar_t*),s,0);
+ }
+
+ rv = KPVFREE((vm), (Void_t*)data, (*Vmbest->freef));
+
+ CLRLOCK(vm, local);
+
+ return rv;
+}
+
+#if __STD_C
+static Void_t* pfresize(Vmalloc_t* vm, Void_t* data, size_t size, int type, int local)
+#else
+static Void_t* pfresize(vm, data, size, type, local)
+Vmalloc_t* vm;
+Void_t* data;
+size_t size;
+int type;
+int local;
+#endif
+{
+ reg Pfobj_t *pf;
+ reg size_t s, news;
+ reg Void_t *addr;
+ reg char *file;
+ reg int line;
+ reg Void_t *func;
+ reg size_t oldsize;
+ reg Vmdata_t *vd = vm->data;
+
+ if(!data)
+ { addr = pfalloc(vm, size, local);
+ if(addr && (type&VM_RSZERO) )
+ memset(addr, 0, size);
+ return addr;
+ }
+ if(size == 0)
+ { (void)pffree(vm, data, local);
+ return NIL(Void_t*);
+ }
+
+ VMFLF(vm,file,line,func);
+
+ SETLOCK(vm, local);
+
+ /**/ASSERT(KPVADDR(vm,data,Vmbest->addrf) == 0 );
+ pf = PFOBJ(data);
+ s = oldsize = PFSIZE(data);
+
+ news = ROUND(size,ALIGN) + PF_EXTRA;
+ if((addr = KPVRESIZE(vm,data,news,(type&~VM_RSZERO),Vmbest->resizef)) )
+ { if(pf)
+ { PFFREE(pf) += s;
+ PFNFREE(pf) += 1;
+ pf = PFREGION(pf);
+ PFFREE(pf) += s;
+ PFNFREE(pf) += 1;
+ pfsetinfo(vm,(Vmuchar_t*)addr,size,file,line);
+ }
+
+ if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
+ { vm->file = file; vm->line = line; vm->func = func;
+ (*_Vmtrace)(vm,(Vmuchar_t*)data,(Vmuchar_t*)addr,size,0);
+ }
+ }
+ else if(pf) /* reset old info */
+ { PFALLOC(pf) -= s;
+ PFNALLOC(pf) -= 1;
+ pf = PFREGION(pf);
+ PFALLOC(pf) -= s;
+ PFNALLOC(pf) -= 1;
+ file = PFFILE(pf);
+ line = PFLINE(pf);
+ pfsetinfo(vm,(Vmuchar_t*)data,s,file,line);
+ }
+
+ if(addr && (type&VM_RSZERO) && oldsize < size)
+ { reg Vmuchar_t *d = (Vmuchar_t*)addr+oldsize, *ed = (Vmuchar_t*)addr+size;
+ do { *d++ = 0; } while(d < ed);
+ }
+
+ CLRLOCK(vm, local);
+
+ return addr;
+}
+
+#if __STD_C
+static long pfsize(Vmalloc_t* vm, Void_t* addr, int local)
+#else
+static long pfsize(vm, addr, local)
+Vmalloc_t* vm;
+Void_t* addr;
+int local;
+#endif
+{
+ return (*Vmbest->addrf)(vm, addr, local) != 0 ? -1L : (long)PFSIZE(addr);
+}
+
+#if __STD_C
+static long pfaddr(Vmalloc_t* vm, Void_t* addr, int local)
+#else
+static long pfaddr(vm, addr, local)
+Vmalloc_t* vm;
+Void_t* addr;
+int local;
+#endif
+{
+ return (*Vmbest->addrf)(vm, addr, local);
+}
+
+#if __STD_C
+static int pfcompact(Vmalloc_t* vm, int local)
+#else
+static int pfcompact(vm, local)
+Vmalloc_t* vm;
+int local;
+#endif
+{
+ return (*Vmbest->compactf)(vm, local);
+}
+
+#if __STD_C
+static Void_t* pfalign(Vmalloc_t* vm, size_t size, size_t align, int local)
+#else
+static Void_t* pfalign(vm, size, align, local)
+Vmalloc_t* vm;
+size_t size;
+size_t align;
+int local;
+#endif
+{
+ reg size_t s;
+ reg Void_t *data;
+ reg char *file;
+ reg int line, inuse;
+ reg Void_t *func;
+ reg Vmdata_t *vd = vm->data;
+
+ VMFLF(vm,file,line,func);
+
+ SETLOCK(vm, local);
+
+ s = (size <= TINYSIZE ? TINYSIZE : ROUND(size,ALIGN)) + PF_EXTRA;
+ if((data = KPVALIGN(vm,s,align,Vmbest->alignf)) )
+ { pfsetinfo(vm,(Vmuchar_t*)data,size,file,line);
+
+ if(!local && (vd->mode&VM_TRACE) && _Vmtrace)
+ { vm->file = file; vm->line = line; vm->func = func;
+ (*_Vmtrace)(vm,NIL(Vmuchar_t*),(Vmuchar_t*)data,size,align);
+ }
+ }
+
+ CLRLOCK(vm, local);
+
+ return data;
+}
+
+static Vmethod_t _Vmprofile =
+{
+ pfalloc,
+ pfresize,
+ pffree,
+ pfaddr,
+ pfsize,
+ pfcompact,
+ pfalign,
+ VM_MTPROFILE
+};
+
+__DEFINE__(Vmethod_t*,Vmprofile,&_Vmprofile);
+
+#ifdef NoF
+NoF(vmprofile)
+#endif
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmregion.c b/src/lib/libast/vmalloc/vmregion.c
new file mode 100644
index 0000000..9aa1172
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmregion.c
@@ -0,0 +1,61 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmregion(){}
+
+#else
+
+#include "vmhdr.h"
+
+/* Return the containing region of an allocated piece of memory.
+** Beware: this only works with Vmbest, Vmdebug and Vmprofile.
+**
+** 10/31/2009: Add handling of shared/persistent memory regions.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+#if __STD_C
+Vmalloc_t* vmregion(Void_t* addr)
+#else
+Vmalloc_t* vmregion(addr)
+Void_t* addr;
+#endif
+{
+ Vmalloc_t *vm;
+ Vmdata_t *vd;
+
+ if(!addr)
+ return NIL(Vmalloc_t*);
+
+ vd = SEG(BLOCK(addr))->vmdt;
+
+ _vmlock(NIL(Vmalloc_t*), 1);
+ for(vm = Vmheap; vm; vm = vm->next)
+ if(vm->data == vd)
+ break;
+ _vmlock(NIL(Vmalloc_t*), 0);
+
+ return vm;
+}
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmsegment.c b/src/lib/libast/vmalloc/vmsegment.c
new file mode 100644
index 0000000..9cf658d
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmsegment.c
@@ -0,0 +1,58 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmsegment(){}
+
+#else
+
+#include "vmhdr.h"
+
+/* Get the segment containing this address
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 02/07/95
+*/
+
+#if __STD_C
+Void_t* vmsegment(Vmalloc_t* vm, Void_t* addr)
+#else
+Void_t* vmsegment(vm, addr)
+Vmalloc_t* vm; /* region */
+Void_t* addr; /* address */
+#endif
+{
+ Seg_t *seg;
+ Vmdata_t *vd = vm->data;
+
+ SETLOCK(vm, 0);
+
+ for(seg = vd->seg; seg; seg = seg->next)
+ if((Vmuchar_t*)addr >= (Vmuchar_t*)seg->addr &&
+ (Vmuchar_t*)addr < (Vmuchar_t*)seg->baddr )
+ break;
+
+ CLRLOCK(vm, 0);
+
+ return seg ? (Void_t*)seg->addr : NIL(Void_t*);
+}
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmset.c b/src/lib/libast/vmalloc/vmset.c
new file mode 100644
index 0000000..c437692
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmset.c
@@ -0,0 +1,62 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmset(){}
+
+#else
+
+#include "vmhdr.h"
+
+
+/* Set the control flags for a region.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+#if __STD_C
+int vmset(reg Vmalloc_t* vm, int flags, int on)
+#else
+int vmset(vm, flags, on)
+reg Vmalloc_t* vm; /* region being worked on */
+int flags; /* flags must be in VM_FLAGS */
+int on; /* !=0 if turning on, else turning off */
+#endif
+{
+ int mode;
+ Vmdata_t *vd = vm->data;
+
+ if(flags == 0 && on == 0)
+ return vd->mode;
+
+ SETLOCK(vm, 0);
+
+ mode = vd->mode;
+ if(on)
+ vd->mode |= (flags&VM_FLAGS);
+ else vd->mode &= ~(flags&VM_FLAGS);
+
+ CLRLOCK(vm, 0);
+
+ return mode;
+}
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmstat.c b/src/lib/libast/vmalloc/vmstat.c
new file mode 100644
index 0000000..4c6f6a4
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmstat.c
@@ -0,0 +1,145 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2012 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmstat(){}
+
+#else
+
+#include "vmhdr.h"
+
+/* Get statistics from a region.
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+
+#if __STD_C
+int vmstat(Vmalloc_t* vm, Vmstat_t* st)
+#else
+int vmstat(vm, st)
+Vmalloc_t* vm;
+Vmstat_t* st;
+#endif
+{
+ size_t s;
+ Seg_t *seg;
+ Block_t *b, *endb;
+ int local;
+ Vmdata_t *vd;
+ Void_t *d;
+
+ if(!st) /* just checking lock state of region */
+ return (vm ? vm : Vmregion)->data->lock;
+
+ memset(st, 0, sizeof(Vmstat_t));
+
+ if(!vm)
+ { /* getting data for malloc */
+#if ( !_std_malloc || !_BLD_ast ) && !_AST_std_malloc
+ extern int _mallocstat(Vmstat_t*);
+ return _mallocstat(st);
+#else
+ return -1;
+#endif
+ }
+
+ SETLOCK(vm, 0);
+
+ st->n_busy = st->n_free = 0;
+ st->s_busy = st->s_free = st->m_busy = st->m_free = 0;
+ st->n_seg = 0;
+ st->extent = 0;
+
+ vd = vm->data;
+ st->mode = vd->mode;
+ s = 0;
+ if(vd->mode&VM_MTLAST)
+ st->n_busy = 0;
+ else if((vd->mode&VM_MTPOOL) && (s = vd->pool) > 0)
+ { s = ROUND(s,ALIGN);
+ for(b = vd->free; b; b = SEGLINK(b))
+ st->n_free += 1;
+ }
+
+ for(seg = vd->seg; seg; seg = seg->next)
+ { st->n_seg += 1;
+ st->extent += seg->extent;
+
+ b = SEGBLOCK(seg);
+ endb = BLOCK(seg->baddr);
+
+ if(vd->mode&(VM_MTDEBUG|VM_MTBEST|VM_MTPROFILE))
+ { while(b < endb)
+ { s = SIZE(b)&~BITS;
+ if(ISJUNK(SIZE(b)) || !ISBUSY(SIZE(b)))
+ { if(s > st->m_free)
+ st->m_free = s;
+ st->s_free += s;
+ st->n_free += 1;
+ }
+ else /* get the real size */
+ { d = DATA(b);
+ if(vd->mode&VM_MTDEBUG)
+ s = DBSIZE(DB2DEBUG(d));
+ else if(vd->mode&VM_MTPROFILE)
+ s = PFSIZE(d);
+ if(s > st->m_busy)
+ st->m_busy = s;
+ st->s_busy += s;
+ st->n_busy += 1;
+ }
+
+ b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
+ }
+ /**/ASSERT(st->extent >= (st->s_busy + st->s_free));
+ }
+ else if(vd->mode&VM_MTLAST)
+ { if((s = seg->free ? (SIZE(seg->free) + sizeof(Head_t)) : 0) > 0)
+ { st->s_free += s;
+ st->n_free += 1;
+ }
+ if((s = ((char*)endb - (char*)b) - s) > 0)
+ { st->s_busy += s;
+ st->n_busy += 1;
+ }
+ }
+ else if((vd->mode&VM_MTPOOL) && s > 0)
+ { if(seg->free)
+ st->n_free += (SIZE(seg->free)+sizeof(Head_t))/s;
+ st->n_busy += ((seg->baddr - (Vmuchar_t*)b) - sizeof(Head_t))/s;
+ }
+ }
+
+ if((vd->mode&VM_MTPOOL) && s > 0)
+ { st->n_busy -= st->n_free;
+ if(st->n_busy > 0)
+ st->s_busy = (st->m_busy = vd->pool)*st->n_busy;
+ if(st->n_free > 0)
+ st->s_free = (st->m_free = vd->pool)*st->n_free;
+ }
+
+ CLRLOCK(vm, 0);
+
+ return 0;
+}
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmstrdup.c b/src/lib/libast/vmalloc/vmstrdup.c
new file mode 100644
index 0000000..2172f6e
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmstrdup.c
@@ -0,0 +1,48 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmstrdup(){}
+
+#else
+
+#include "vmhdr.h"
+
+/*
+ * return a copy of s using vmalloc
+ */
+
+#if __STD_C
+char* vmstrdup(Vmalloc_t* v, register const char* s)
+#else
+char* vmstrdup(v, s)
+Vmalloc_t* v;
+register char* s;
+#endif
+{
+ register char* t;
+ register size_t n;
+
+ return (s && (t = vmalloc(v, n = strlen(s) + 1))) ? (char*)memcpy(t, s, n) : (char*)0;
+}
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmtrace.c b/src/lib/libast/vmalloc/vmtrace.c
new file mode 100644
index 0000000..22edba3
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmtrace.c
@@ -0,0 +1,286 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmtrace(){}
+
+#else
+
+#include "vmhdr.h"
+
+/* Turn on tracing for regions
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com, 01/16/94.
+*/
+
+static int Trfile = -1;
+static char Trbuf[128];
+
+#if __STD_C
+static char* trstrcpy(char* to, const char* from, int endc)
+#else
+static char* trstrcpy(to, from, endc)
+char* to;
+const char* from;
+int endc;
+#endif
+{ reg int n;
+
+ n = strlen(from);
+ memcpy(to,from,n);
+ to += n;
+ if((*to = endc) )
+ to += 1;
+ return to;
+}
+
+/* convert a long value to an ascii representation */
+#if __STD_C
+static char* tritoa(Vmulong_t v, int type)
+#else
+static char* tritoa(v, type)
+Vmulong_t v; /* value to convert */
+int type; /* =0 base-16, >0: unsigned base-10, <0: signed base-10 */
+#endif
+{
+ char* s;
+
+ s = &Trbuf[sizeof(Trbuf) - 1];
+ *s-- = '\0';
+
+ if(type == 0) /* base-16 */
+ { reg char* digit = "0123456789abcdef";
+ do
+ { *s-- = digit[v&0xf];
+ v >>= 4;
+ } while(v);
+ }
+ else if(type > 0) /* unsigned base-10 */
+ { do
+ { *s-- = (char)('0' + (v%10));
+ v /= 10;
+ } while(v);
+ }
+ else /* signed base-10 */
+ { int sign = ((long)v < 0);
+ if(sign)
+ v = (Vmulong_t)(-((long)v));
+ do
+ { *s-- = (char)('0' + (v%10));
+ v /= 10;
+ } while(v);
+ if(sign)
+ *s-- = '-';
+ }
+
+ return s+1;
+}
+
+/* generate a trace of some call */
+#if __STD_C
+static void trtrace(Vmalloc_t* vm,
+ Vmuchar_t* oldaddr, Vmuchar_t* newaddr, size_t size, size_t align )
+#else
+static void trtrace(vm, oldaddr, newaddr, size, align)
+Vmalloc_t* vm; /* region call was made from */
+Vmuchar_t* oldaddr; /* old data address */
+Vmuchar_t* newaddr; /* new data address */
+size_t size; /* size of piece */
+size_t align; /* alignment */
+#endif
+{
+ char buf[1024], *bufp, *endbuf;
+ Vmdata_t* vd = vm->data;
+ const char* file = 0;
+ int line = 0;
+ const char* func = 0;
+ int comma;
+ int n;
+ int m;
+
+ int type;
+#define SLOP 64
+
+ if(oldaddr == (Vmuchar_t*)(-1)) /* printing busy blocks */
+ { type = 0;
+ oldaddr = NIL(Vmuchar_t*);
+ }
+ else
+ { type = vd->mode&VM_METHODS;
+ VMFLF(vm,file,line,func);
+ }
+
+ if(Trfile < 0)
+ return;
+
+ bufp = buf; endbuf = buf+sizeof(buf);
+ bufp = trstrcpy(bufp, tritoa(oldaddr ? VLONG(oldaddr) : 0L, 0), ':');
+ bufp = trstrcpy(bufp, tritoa(newaddr ? VLONG(newaddr) : 0L, 0), ':');
+ bufp = trstrcpy(bufp, tritoa((Vmulong_t)size, 1), ':');
+ bufp = trstrcpy(bufp, tritoa((Vmulong_t)align, 1), ':');
+ bufp = trstrcpy(bufp, tritoa(VLONG(vm), 0), ':');
+ if(type&VM_MTBEST)
+ bufp = trstrcpy(bufp, "b", ':');
+ else if(type&VM_MTLAST)
+ bufp = trstrcpy(bufp, "l", ':');
+ else if(type&VM_MTPOOL)
+ bufp = trstrcpy(bufp, "p", ':');
+ else if(type&VM_MTPROFILE)
+ bufp = trstrcpy(bufp, "s", ':');
+ else if(type&VM_MTDEBUG)
+ bufp = trstrcpy(bufp, "d", ':');
+ else bufp = trstrcpy(bufp, "u", ':');
+
+ comma = 0;
+ if(file && file[0] && line > 0)
+ { if((bufp + strlen(file) + SLOP) >= endbuf)
+ { char* f;
+ for(f = bufp + strlen(file); f > file; --f)
+ if(f[-1] == '/' || f[-1] == '\\')
+ break;
+ file = f;
+ }
+
+ bufp = trstrcpy(bufp, "file", '=');
+ n = endbuf - bufp - SLOP - 3;
+ m = strlen(file);
+ if(m > n)
+ { file += (m - n);
+ bufp = trstrcpy(bufp, "..", '.');
+ }
+ bufp = trstrcpy(bufp, file, ',');
+ bufp = trstrcpy(bufp, "line", '=');
+ bufp = trstrcpy(bufp, tritoa((Vmulong_t)line,1), 0);
+ comma = 1;
+ }
+ if(func)
+ { if(comma)
+ *bufp++ = ',';
+ bufp = trstrcpy(bufp, "func", '=');
+#if 1
+ bufp = trstrcpy(bufp, (const char*)func, 0);
+#else
+ bufp = trstrcpy(bufp, tritoa((Vmulong_t)func,0), 0);
+#endif
+ comma = 1;
+ }
+ if(comma)
+ *bufp++ = ':';
+
+ *bufp++ = '\n';
+ *bufp = '\0';
+
+ write(Trfile,buf,(bufp-buf));
+}
+
+#if __STD_C
+void _vmmessage(const char* s1, long n1, const char* s2, long n2)
+#else
+void _vmmessage(s1, n1, s2, n2)
+const char* s1;
+long n1;
+const char* s2;
+long n2;
+#endif
+{
+ char buf[1024], *bufp;
+
+ bufp = buf;
+ bufp = trstrcpy(bufp, "vmalloc", ':');
+ if (s1)
+ {
+ bufp = trstrcpy(bufp, s1, ':');
+ if (n1)
+ bufp = trstrcpy(bufp, tritoa(n1, 1), ':');
+ }
+ if (s2)
+ {
+ bufp = trstrcpy(bufp, s2, ':');
+ if (n2)
+ bufp = trstrcpy(bufp, tritoa(n2, 0), ':');
+ }
+
+ bufp = trstrcpy(bufp, tritoa((long)getpid(), 1), ':');
+
+ *bufp++ = '\n';
+ write(2,buf,(bufp-buf));
+}
+
+#if __STD_C
+int vmtrace(int file)
+#else
+int vmtrace(file)
+int file;
+#endif
+{
+ int fd;
+
+ _Vmstrcpy = trstrcpy;
+ _Vmitoa = tritoa;
+ _Vmtrace = trtrace;
+
+ fd = Trfile;
+ Trfile = file;
+ return fd;
+}
+
+#if __STD_C
+int vmtrbusy(Vmalloc_t* vm)
+#else
+int vmtrbusy(vm)
+Vmalloc_t* vm;
+#endif
+{
+ Seg_t* seg;
+ Vmdata_t* vd = vm->data;
+
+ if(Trfile < 0 || !(vd->mode&(VM_MTBEST|VM_MTDEBUG|VM_MTPROFILE)))
+ return -1;
+
+ for(seg = vd->seg; seg; seg = seg->next)
+ { Block_t *b, *endb;
+ Vmuchar_t* data;
+ size_t s;
+
+ for(b = SEGBLOCK(seg), endb = BLOCK(seg->baddr); b < endb; )
+ { if(ISJUNK(SIZE(b)) || !ISBUSY(SIZE(b)))
+ continue;
+
+ data = DATA(b);
+ if(vd->mode&VM_MTDEBUG)
+ { data = DB2DEBUG(data);
+ s = DBSIZE(data);
+ }
+ else if(vd->mode&VM_MTPROFILE)
+ s = PFSIZE(data);
+ else s = SIZE(b)&~BITS;
+
+ trtrace(vm, (Vmuchar_t*)(-1), data, s, 0);
+
+ b = (Block_t*)((Vmuchar_t*)DATA(b) + (SIZE(b)&~BITS) );
+ }
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/src/lib/libast/vmalloc/vmwalk.c b/src/lib/libast/vmalloc/vmwalk.c
new file mode 100644
index 0000000..d7a8e36
--- /dev/null
+++ b/src/lib/libast/vmalloc/vmwalk.c
@@ -0,0 +1,69 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#if defined(_UWIN) && defined(_BLD_ast)
+
+void _STUB_vmwalk(){}
+
+#else
+
+#include "vmhdr.h"
+
+/* Walks all segments created in region(s)
+**
+** Written by Kiem-Phong Vo, kpv@research.att.com (02/08/96)
+*/
+
+#if __STD_C
+int vmwalk(Vmalloc_t* vm, int(*segf)(Vmalloc_t*, Void_t*, size_t, Vmdisc_t*, Void_t*), Void_t* handle )
+#else
+int vmwalk(vm, segf, handle)
+Vmalloc_t* vm;
+int(* segf)(/* Vmalloc_t*, Void_t*, size_t, Vmdisc_t*, Void_t* */);
+Void_t* handle;
+#endif
+{
+ reg Seg_t *seg;
+ reg int rv = 0;
+
+ if(!vm)
+ { _vmlock(NIL(Vmalloc_t*), 1);
+ for(vm = Vmheap; vm; vm = vm->next)
+ { SETLOCK(vm, 0);
+ for(seg = vm->data->seg; seg; seg = seg->next)
+ if((rv = (*segf)(vm, seg->addr, seg->extent, vm->disc, handle)) < 0 )
+ break;
+ CLRLOCK(vm, 0);
+ }
+ _vmlock(NIL(Vmalloc_t*), 0);
+ }
+ else
+ { SETLOCK(vm, 0);
+ for(seg = vm->data->seg; seg; seg = seg->next)
+ if((rv = (*segf)(vm, seg->addr, seg->extent, vm->disc, handle)) < 0 )
+ break;
+ CLRLOCK(vm, 0);
+ }
+
+ return rv;
+}
+
+#endif