Compare commits

...
47 Commits
Author SHA1 Message Date
Erik Greenwald 1c8f9cc4b2 merge from head
svn:revision:22550
cvs:account:erikg
cvs:branch:AUTOCONF
2004-03-18 18:10:35 +00:00
Erik Greenwald 6a905d058c *** empty log message ***
svn:revision:22549
cvs:account:erikg
cvs:branch:AUTOCONF
2004-03-18 18:08:58 +00:00
Erik Greenwald f4eba2ca66 merge from head...
svn:revision:22548
cvs:branch:AUTOCONF
cvs:branch:autoconf-branch
cvs:account:erikg
2004-03-18 18:00:45 +00:00
Christopher Sean Morrison 5e4252ab4d testing
svn:revision:22546
cvs:account:morrison
cvs:branch:AUTOCONF
2004-03-18 15:37:16 +00:00
Erik Greenwald 346a7d2c4b cope with itcl changes...
svn:revision:22497
cvs:account:erikg
cvs:branch:AUTOCONF
2004-03-15 15:41:12 +00:00
Erik Greenwald 6d77cf0c2e merge from head
svn:revision:22491
cvs:branch:AUTOCONF
cvs:account:erikg
2004-03-15 14:08:06 +00:00
Erik Greenwald ef3b003957 autogenerated...
svn:revision:22485
cvs:account:erikg
cvs:branch:AUTOCONF
2004-03-15 12:19:49 +00:00
Erik Greenwald 348708a9d8 makefiles should be generated
svn:revision:22408
cvs:account:erikg
cvs:branch:AUTOCONF
2004-02-25 15:24:49 +00:00
Erik Greenwald 78870aea83 vers.c files are generated
svn:revision:22406
cvs:account:erikg
cvs:branch:AUTOCONF
2004-02-25 14:55:26 +00:00
Erik Greenwald 4ef40cd1ec vers.c fixes
svn:revision:22404
cvs:branch:AUTOCONF
cvs:account:erikg
2004-02-25 14:33:20 +00:00
Erik Greenwald 5caa6dc4f3 revived.
svn:revision:22398
cvs:account:erikg
cvs:branch:AUTOCONF
2004-02-24 19:58:08 +00:00
Erik Greenwald df8143b77e generated now...
svn:revision:22393
cvs:branch:AUTOCONF
cvs:branch:autoconf-branch
cvs:account:erikg
2004-02-12 20:07:05 +00:00
Erik Greenwald dc6d52862b generated now...
svn:revision:22392
cvs:account:erikg
cvs:branch:AUTOCONF
2004-02-12 20:00:38 +00:00
Erik Greenwald fbb3f5e3ea merge from HEAD
svn:revision:22391
cvs:account:erikg
cvs:branch:AUTOCONF
2004-02-12 19:51:36 +00:00
Erik Greenwald c4332180ff merge from HEAD
svn:revision:22391
cvs:branch:AUTOCONF
cvs:account:erikg
2004-02-12 19:45:35 +00:00
Erik Greenwald 95b573c3cf merge from HEAD
svn:revision:22391
cvs:branch:AUTOCONF
cvs:account:erikg
2004-02-12 19:37:13 +00:00
Erik Greenwald 970999e39f merge from HEAD
svn:revision:22390
cvs:branch:AUTOCONF
cvs:account:erikg
2004-02-12 19:22:15 +00:00
Erik Greenwald 59ed68a012 merge from HEAD
svn:revision:22389
cvs:branch:AUTOCONF
cvs:account:erikg
2004-02-12 19:03:03 +00:00
Erik Greenwald 5cabcb79b7 merge from HEAD
svn:revision:22388
cvs:branch:AUTOCONF
cvs:account:erikg
2004-02-12 18:55:46 +00:00
Erik Greenwald ce353f2b73 merge from HEAD
svn:revision:22388
cvs:branch:AUTOCONF
cvs:account:erikg
2004-02-12 18:50:43 +00:00
Erik Greenwald 76f4a36ee6 merge from HEAD
svn:revision:22387
cvs:branch:AUTOCONF
cvs:account:erikg
2004-02-12 18:39:33 +00:00
Erik Greenwald b1c4bfca7b new automake files
svn:revision:22298
cvs:branch:AUTOCONF
cvs:account:erikg
2003-12-29 15:45:18 +00:00
Erik Greenwald 09a79cf628 more normalization
svn:revision:22291
cvs:branch:AUTOCONF
cvs:account:erikg
2003-12-24 19:19:30 +00:00
Erik Greenwald 7b085f5e83 make dist fixes, part 2
svn:revision:22278
cvs:branch:AUTOCONF
cvs:account:erikg
2003-12-16 15:41:59 +00:00
Erik Greenwald 154eef9311 tcl fixes
svn:revision:22269
cvs:branch:AUTOCONF
cvs:account:erikg
2003-12-15 17:36:41 +00:00
Erik Greenwald 5a4f552d81 allow building and installing when builddir != srcdir (important for
multi-arch building from the same source tree)

svn:revision:22267
cvs:branch:AUTOCONF
cvs:account:erikg
2003-12-11 15:36:47 +00:00
Erik Greenwald 23fc2fab42 bee ess dee five point one
svn:revision:22253
cvs:branch:AUTOCONF
cvs:account:erikg
2003-12-08 21:10:07 +00:00
Erik Greenwald e56423fc33 adding more automake stuff
removed some files that are now generated

svn:revision:22247
cvs:branch:AUTOCONF
cvs:account:erikg
2003-12-04 19:20:00 +00:00
Erik Greenwald 18ce09bd52 updates from HEAD
svn:revision:22239
cvs:branch:AUTOCONF
cvs:account:erikg
2003-12-03 17:55:59 +00:00
Erik Greenwald 179e568177 updates from HEAD
svn:revision:22238
cvs:account:erikg
cvs:branch:AUTOCONF
2003-12-03 17:44:55 +00:00
Erik Greenwald f301acbcbe updates from HEAD, part 1
svn:revision:22237
cvs:branch:AUTOCONF
cvs:account:erikg
2003-12-03 16:25:43 +00:00
Erik Greenwald d474c3eaf5 muchos autoconf fixes, libtcl and libtk are now built with the rest of the
system, instead of trying to use the pre-installed versions

svn:revision:22235
cvs:branch:AUTOCONF
cvs:account:erikg
2003-12-02 19:33:55 +00:00
Erik Greenwald 1949ce0be3 starting merged autoconf of libtcl84
svn:revision:22217
cvs:branch:AUTOCONF
cvs:account:erikg
2003-11-14 19:30:20 +00:00
Erik Greenwald d90d3370e9 generated now
svn:revision:22213
cvs:account:erikg
cvs:branch:AUTOCONF
2003-11-07 16:41:50 +00:00
Erik Greenwald fac29f640c copied Copyright_2003_US_Army to stifle automake.
svn:revision:22211
cvs:account:erikg
cvs:branch:AUTOCONF
2003-11-07 15:54:18 +00:00
Christopher Sean Morrison e6f630c2e9 Import of initial port to Windows
svn:revision:21564
svn:revision:21565
cvs:account:morrison
cvs:branch:photonmap-branch
2002-09-26 04:01:00 +00:00
Robert Parker 096c109ece Import itcl3.2
svn:revision:19762
svn:revision:19763
cvs:account:bparker
cvs:branch:itcl3-2
2000-12-06 21:48:10 +00:00
Robert Parker e078a68d77 Import itcl3.2
svn:revision:19760
svn:revision:19761
cvs:account:bparker
cvs:branch:itcl3-2
2000-12-06 21:35:20 +00:00
Robert Parker 0287a35ffb Import tk8.3
svn:revision:19758
svn:revision:19759
cvs:account:bparker
cvs:branch:tk8-3
2000-12-06 21:34:21 +00:00
Robert Parker e77989c21b Import tcl8.3
svn:revision:19756
svn:revision:19757
cvs:account:bparker
cvs:branch:tcl8-3
2000-12-06 21:33:21 +00:00
Lee Butler 9c696591dd The html manuals for BRLCAD
svn:revision:15427
cvs:account:butler
cvs:branch:VendorARL
1998-06-30 17:38:07 +00:00
John Anderson bf843475ea libpng 1.0.2
svn:revision:15365
cvs:account:jra
cvs:branch:libpng
1998-06-24 20:00:14 +00:00
John Anderson e63f8fccee Initial inclusion of zlib (version 1.0.4).
svn:revision:15338
cvs:account:jra
cvs:branch:zlib
1998-06-24 13:19:59 +00:00
John Anderson 13e0bb1a11 Checkpoint
svn:revision:8061
cvs:account:jra
cvs:branch:unlabeled-1.1.1
1993-12-09 09:52:56 +00:00
John Anderson e83e56b866 Checkpoint
svn:revision:7885
cvs:account:jra
cvs:branch:unlabeled-1.1.1
1993-10-21 15:33:46 +00:00
John Anderson fab2420d37 Checkpoint (working version for just 3DFACE entities).
svn:revision:7884
cvs:account:jra
cvs:branch:unlabeled-1.1.1
1993-10-21 14:14:44 +00:00
Paul Tanenbaum 6b8c080c36 Attempt to add $Header$ to file.
svn:revision:5208
cvs:branch:unlabeled-1.1.1
cvs:account:pjt
1991-02-14 09:24:53 +00:00
1045 changed files with 0 additions and 293484 deletions
-14
View File
@@ -1,14 +0,0 @@
/*
* Top level Cakefile.
*
* This Cakefile serves the same purpose as the top level Makefile,
* ie, to run the "gen.sh" script with the given argument.
*
* $Header$
*/
%&:
/bin/sh gen.sh %
all&::
/bin/sh gen.sh
-1009
View File
File diff suppressed because it is too large Load Diff
-57
View File
@@ -1,57 +0,0 @@
/*
* C A K E F I L E . L I B
*
* Cakefile for building a single library archive.
* Symbol PRODUCTS should be name of a single library
*
* Author -
* Michael John Muuss
*
* Source -
* SECAD/VLD Computing Consortium, Bldg 394
* The U. S. Army Ballistic Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5066
*
* Distribution Status -
* Public Domain, Distribution Unlimitied.
*
* $Header$
*/
#ifndef PRODUCTS
# include "Symbol PRODUCTS required to make library"
#endif
#ifndef SRCDIR
# include "Symbol SRCDIR required"
#endif
#ifndef OBJ
# include "Symbol OBJ required"
#endif
#ifndef EXTRA_OBJ
# define EXTRA_OBJ /**/
#endif
#ifndef EXTRA_SETUP
# define EXTRA_SETUP /**/
#endif
PRODUCTS:: EXTRA_OBJ OBJ
rm -f PRODUCTS; EXTRA_SETUP
AR r PRODUCTS OBJ EXTRA_OBJ
RANLIB PRODUCTS
%.o&: SRCDIR,,%,o if exist ../SRCDIR/%.c
%9,,%,o&: ../%9/%.c [[cakeinclude -i INCDIR -s ../%9 ../%9/%.c]] \
if exist ../%9/%.c
CC CFLAGS -c ../%9/%.c
/* Override the modes for the library */
#undef BINDIR
#undef BINPERM
#define BINDIR LIBDIR
#define BINPERM LIBPERM
/* If RANLIB is specified, be sure it is run when installing libraries */
#define AFTERINSTALL RANLIB
-27
View File
@@ -1,27 +0,0 @@
/*
* C A K E F I L E . P R O G
*
* Like Cakefile.lib, this is the common part for making programs.
*
* Author -
* Michael John Muuss
*
* Source -
* SECAD/VLD Computing Consortium, Bldg 394
* The U. S. Army Ballistic Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5066
*
* Distribution Status -
* Public Domain, Distribution Unlimitied.
*
* $Header$
*/
/* Default rule */
everything&:: PRODUCTS
%.o: ../SRCDIR/%.c HDR_DEP if exist ../SRCDIR/%.c
CC CFLAGS -c ../SRCDIR/%.c
%.o: ../SRCDIR/%.f if exist ../SRCDIR/%.f
FC FFLAGS -c ../SRCDIR/%.f
-239
View File
@@ -1,239 +0,0 @@
/*
* C A K E F I L E . R U L E S
*/
/*
* Patterns to handle the installation and uninstallation
* of products, manuals, and manual stubs.
* This is complicated by the fact that not all directories
* will contain all three types of items.
*/
#define MAN_EXISTS {{ls ../SRCDIR|grep -s .MANSECTION'$'}}
#define STUB_EXISTS {{ls ../SRCDIR|grep -s .MANSECTION.stub'$'}}
#define ARG_EXISTS {{ARGS="%"; test '%' != "$ARGS" -o -f %}}
/* Format sources for printing on stdout */
print&: Cakefile.print \
[[SUB X X.print ../SRCDIR/''*.[h''MANSECTION] ]] \
[[SUB X X.nroff ../SRCDIR/''*.MANSECTION ]] \
[[SUB X ../SRCDIR/X''SRCSUFF.print FILES]]
%.print&: do-%.print if ARG_EXISTS
%.print&: if not ARG_EXISTS
do-%.print&:
@pr %
/*
*/
nroff&: do-nroff if MAN_EXISTS
nroff&: if not MAN_EXISTS
do-nroff&: [[SUB X X.nroff ../SRCDIR/''*.MANSECTION ]]
%.nroff&: ../SRCDIR/%
@nroff -Tlp -man ../SRCDIR/%
/*
* Typeset all the non-stub manual pages. Do them all at once,
* to prevent lots of extra header sheets on the printer
*
* do-typeset-a creates the file "troff.out" with the macros in it
* %.troff adds each manual page to "troff.out"
*/
typeset&: do-typeset if MAN_EXISTS
typeset&: if not MAN_EXISTS
do-typeset&: do-typeset-a troff.out
( TYPESET_MAN2 ) < troff.out
@rm -f troff.out
do-typeset-a&:
TYPESET_MAN0 TYPESET_MAN1 > troff.out
troff.out&: [[SUB X X.troff ../SRCDIR/''*.MANSECTION ]]
%.troff&: if ARG_EXISTS
TYPESET_MAN0 % >> troff.out
#define SRC_LIST `SUB X ../SRCDIR/X''SRCSUFF FILES`
lint&:
LINT LFLAGS -I''INCDIR SRC_LIST LLIBES > SRCDIR.lint
tags: [[echo SRC_LIST]]
ctags SRC_LIST
flow&: [[echo SRC_LIST]]
cflow -I''INCDIR SRC_LIST > SRCDIR.flow
xref&: [[echo SRC_LIST]]
cxref -c -s -w132 -I''INCDIR SRC_LIST > SRCDIR.xref
compare&: [[SUB X X.compare PRODUCTS]]
%.compare&: %
cmp BINDIR/% %
uninstall&: uninstall-prod uninstall-man uninstall-stub
#ifdef PRODUCTS
uninstall-prod&: [[SUB X X.uninstall-prod PRODUCTS]]
#else
uninstall-prod&:
#endif
%.uninstall-prod&:
rm -f BINDIR/% BINDIR/%.bak
uninstall-man&: do-uninstall-man if MAN_EXISTS
uninstall-man&: if not MAN_EXISTS
do-uninstall-man&: [[SUB ../SRCDIR/X X.uninstall-man ../SRCDIR/''*.MANSECTION]]
%.uninstall-man&:
rm -f MANDIR''MANSECTION/% MANDIR''MANSECTION/%.bak
uninstall-stub&: do-uninstall-stub if STUB_EXISTS
uninstall-stub&: if not STUB_EXISTS
do-uninstall-stub&: [[SUB ../SRCDIR/X.stub X.uninstall-stub ../SRCDIR/''*.stub]]
%.uninstall-stub&:
rm -f MANDIR''MANSECTION/% MANDIR''MANSECTION/%.bak
#if !defined(DONT_INSTALL)
install&: install-prod install-man install-stub inst-dist
install-nobak&: install-prod-nobak install-man install-stub inst-dist
#else
install&: inst-dist
install-nobak&: inst-dist
#endif
#if defined(PRODUCTS)
install-prod&: [[SUB X X.iprod PRODUCTS]]
install-prod-nobak&: [[SUB X X.iprod-nobak PRODUCTS]]
#else
install-prod&:
install-prod-nobak&:
#endif
/* Here is where we depend on having /bin/sh as the shell */
%.iprod&: %
@echo ......checking % 1>&2 ; \
if cmp -s BINDIR/% %; \
then exit 0; fi; \
mv -f BINDIR/% BINDIR/%.bak 2>/dev/null; \
if INS % BINDIR/%; \
then if test x''AFTERINSTALL != x'AFTERINSTALL'; \
then AFTERINSTALL BINDIR/%; fi; \
echo "++++++INSTALLED" BINDIR/% 1>&2; \
chmod BINPERM BINDIR/%; \
fi
%.iprod-nobak&: %
@echo ......checking % 1>&2 ; \
if cmp -s BINDIR/% %; \
then exit 0; fi; \
rm -f BINDIR/% 2>/dev/null; \
if INS % BINDIR/%; \
then if test x''AFTERINSTALL != x'AFTERINSTALL'; \
then AFTERINSTALL BINDIR/%; fi; \
echo "++++++INSTALLED" BINDIR/% 1>&2; \
chmod BINPERM BINDIR/%; \
fi
install-man&: do-install-man if MAN_EXISTS
install-man&: if not MAN_EXISTS
do-install-man&: [[SUB ../SRCDIR/X X.install-man ../SRCDIR/''*.MANSECTION ]]
%.install-man&: ../SRCDIR/%
@if cmp -s MANDIR''MANSECTION/% ../SRCDIR/%; \
then exit 0; fi; \
mv -f MANDIR''MANSECTION/% MANDIR''MANSECTION/%.bak 2>/dev/null; \
if INS ../SRCDIR/% MANDIR''MANSECTION/%; \
then echo "++++++INSTALLED" MANDIR''MANSECTION/% 1>&2; \
chmod MANPERM MANDIR''MANSECTION/%; \
fi
install-stub&: do-install-stub if STUB_EXISTS
install-stub&: if not STUB_EXISTS
do-install-stub&: [[SUB ../SRCDIR/X.stub X.install-stub ../SRCDIR/''*.stub]]
%.install-stub&: ../SRCDIR/%.stub
@if cmp -s MANDIR''MANSECTION/% ../SRCDIR/%.stub; \
then exit 0; fi; \
mv -f MANDIR''MANSECTION/% MANDIR''MANSECTION/%.bak 2>/dev/null; \
if INS ../SRCDIR/%.stub MANDIR''MANSECTION/%; \
then echo "++++++INSTALLED" MANDIR''MANSECTION/% 1>&2; \
chmod MANPERM MANDIR''MANSECTION/%; \
fi
/*
* Force installation of copies of all sources,
* whether configured in or not, into the distribution tree.
*/
#ifndef STATIC_PRODUCTS
# define STATIC_PRODUCTS /**/
#endif
#ifdef NFS
#define INSTALL_PATTERNS STATIC_PRODUCTS \
../SRCDIR/Cakefile ../SRCDIR/\\\\*.[hcsfyl] \
../SRCDIR/\\\\*.sh \
../SRCDIR/\\\\*.MANSECTION ../SRCDIR/\\\\*.MANSECTION.stub \
../SRCDIR/\\\\*.doc
#else
#define INSTALL_PATTERNS STATIC_PRODUCTS \
./Cakefile \\\\*.[hcsfyl] \\\\*.sh \
\\\\*.MANSECTION \\\\*.MANSECTION.stub \\\\*.doc
#endif
#define IS_MASTER {{test x''MASTERHOST = x`GETHOST`}}
inst-dist&: inst-dist-main if IS_MASTER
/* inst-dist is also called from "install", so say nothing if not master */
inst-dist&: if not IS_MASTER
inst-dist-main&: dist-clobber [[SUB X X.do-inst-dist INSTALL_PATTERNS]]
dist-clobber&:
-rm -fr DISTRIBUTION/SRCDIR
mkdir DISTRIBUTION/SRCDIR; chmod 775 DISTRIBUTION/SRCDIR
%.do-inst-dist&: %.inst-dist if ARG_EXISTS
%.do-inst-dist&: if not ARG_EXISTS
%.inst-dist&:
-INS % DISTRIBUTION/SRCDIR/.
#ifndef EXTRA_CLEAN
# define EXTRA_CLEAN /**/
#endif
/*
* clean remove all .o files and by-products
* noprod remove the final executables
* clobber perform clean & noprod
*/
clobber&: clean noprod
clean&:
-rm -f core *~ *.o EXTRA_CLEAN SRCDIR.out SRCDIR.err SRCDIR.xref SRCDIR.flow SRCDIR.lint
noprod&:
-rm -f PRODUCTS
#ifdef never
/*
* Insist that, by default, Cake work on making the products.
* THIS SHOULD BE THE LAST THING CAKE SEES!
* The double-colon marks this as the main target.
*/
"!MAINCAKE!"&:: PRODUCTS
#endif
-22
View File
@@ -1,22 +0,0 @@
This software was developed by and is proprietary to the United States
Government, and any use of the software without the written permission
of the Ballistic Research Laboratory is strictly prohibited. Any
unauthorized use of the software will be construed as an infringement of
the Government's rights and will subject the unauthorized user to
action(s) for infringement damages. (BRL MFR 380-15, Feb-88)
The terms and conditions for the use of this software are detailed
in your distribution agreement.
Please note that portions of this software and the associated databases
and images are Copyright (C) 1985, 1986, 1987, 1988, 1989 by the United
States Army. Unauthorized redistribution in any form is prohibited.
Recipients of this distribution are authorized unlimited use within
their corporation, organization, or agency.
There is no warranty or other guarantee of fitness for this software,
it is provided solely "as is". Bug reports or fixes must be sent
to BRL, which may or may not act on them.
The software in the "contributed" directory is Public Domain, Distribution
Unlimited. In addition, certain other modules in the BRL-CAD package
bear this designation. Files so marked are available for unlimited use.
-69
View File
@@ -1,69 +0,0 @@
#################################################################
# #
# Makefile #
# #
# The top-level Makefile for the BRL CAD Software Distribution #
# #
# This exists mostly as a convienience, so folks can #
# type "make install" and such like, and get the expected #
# results, even in the face of the rather complex mechanism. #
# Thus, we make Make into a simple front-end for gen.sh #
# #
# Author - #
# Michael John Muuss #
# #
# Source - #
# SECAD/VLD Computing Consortium, Bldg 394 #
# The U. S. Army Ballistic Research Laboratory #
# Aberdeen Proving Ground, Maryland 21005-5066 #
# #
# $Header$ #
# #
#################################################################
SHELL = /bin/sh
# Main rule (default):
all:
-@sh gen.sh all
help:
-@sh gen.sh help
benchmark:
-@sh gen.sh $@
depend:
-@sh gen.sh $@
install:
-@sh gen.sh $@
inst-man:
-@sh gen.sh $@
uninstall:
-@sh gen.sh $@
inst-dist:
-@sh gen.sh $@
clean:
-@sh gen.sh $@
noprod:
-@sh gen.sh $@
clobber:
-@sh gen.sh $@
lint:
-@sh gen.sh $@
ls:
-@sh gen.sh $@
print:
-@sh gen.sh $@
typeset:
-@sh gen.sh $@
checkin:
-@sh gen.sh $@
dist:
-@sh gen.sh $@
arch:
-@sh gen.sh $@
mkdir:
-@sh gen.sh $@
relink:
-@sh gen.sh $@
rmdir:
-@sh gen.sh $@
-451
View File
@@ -1,451 +0,0 @@
#################################################################
# #
# Makefile.defs #
# #
# This Makefile contains definitions common to most of the #
# software packages contained in this distribution. #
# Combined with Makefile.rules and a directory-specific #
# Makefile.loc to create full MAKE input. #
# #
# Each source directory contains a Makefile with these #
# contents: #
# #
#everything: #
# make $(MFLAGS) -$(MAKEFLAGS) \ #
# -f ../Makefile.defs -f Makefile.loc \ #
# -f ../Makefile.rules #
#.DEFAULT: #
# make $(MFLAGS) -$(MAKEFLAGS) \ #
# -f ../Makefile.defs -f Makefile.loc \ #
# -f ../Makefile.rules $@ #
# #
# so that the local rules and definitions for each directory #
# are combined with the common rules and definitions. #
# #
# Author - #
# Michael John Muuss #
# #
# Source - #
# SECAD/VLD Computing Consortium, Bldg 394 #
# The U. S. Army Ballistic Research Laboratory #
# Aberdeen Proving Ground, Maryland 21005 #
# #
# Acknowledgements - #
# This Makefile draws heavily on Doug Gwyn's #
# VLD Standard Makefile, and Doug Kingston's #
# MMDF Global Makefile. #
# #
# $Header$ #
# #
#################################################################
#################################################################
# #
# Operating System Definition and Compiler Flags #
# #
# Either "BSD" or "SYSV" *MUST* be defined #
# #
# Oddball compiler/loader directives should also go here #
# On parallel machines, if h/machine.h does not define #
# the PARALLEL flag, it should be done here. #
# #
#################################################################
#VAX#SYSTEM = -DBSD
#SYSV#SYSTEM = -DSYSV
#VLD#SYSTEM = -DSYSV -DVLDSYSV
# Silicon Graphics, -Zf if Weitek FP chip installed
#SGI#SYSTEM = -DSYSV -Zf
#SGI#SYSTEM = -DSYSV
#ALLIANT#SYSTEM = -DBSD -ce
#GOULD#SYSTEM = -DBSD -m 8
#XMP#SYSTEM = -DSYSV -DPARALLEL
#XMP2.1#SYSTEM = -DSYSV -DPARALLEL -holevel_0
#CRAY2#SYSTEM = -DSYSV -DPARALLEL -Dcray
# Sun3, select correct floating point flag, or -fswitch if unsure (slower)
#SUN3#SYSTEM = -DBSD -f68881
#SUN3#SYSTEM = -DBSD -ffpa
#SUN3#SYSTEM = -DBSD -fswitch
#PYRAMID#SYSTEM = -DBSD -Dvoid=int
#ULTRIX1#SYSTEM = -DBSD -Dvoid=int
#################################################################
# #
# System-Version information, for special handling within one #
# type of $SYSTEM. #
# #
# Currently meaningful settings are: #
# #
# SGI34 SGI release 3.4 and below, with EXCELAN TCP. #
# SGI35 SGI release 3.5 and above, with real TCP. #
# UNICOS20 Cray UNICOS 2.0, with TCP #
# SUN3 SUN UNIX version 3.2 or above #
# #
#################################################################
#SGI#SYSVERS = SGI34
#SGI#SYSVERS = SGI35
#4D#SYSVERS = 4D32
#XMP#SYSVERS = UNICOS20
#CRAY2#SYSVERS = UNICOS20
#SUN#SYSVERS = SUN3
#################################################################
# #
# Definitions specific to one portion of the CAD distribution, #
# but collected here for ease of configuration #
# #
#################################################################
#################################################################
# #
# Configuration for libpkg #
# #
#################################################################
#SGI34#LIBPKG_CONFIG = -I/usr/include/EXOS -DSGI_EXCELAN
#SGI35#LIBPKG_CONFIG = -I/usr/include/bsd -DBSD
#4D32#LIBPKG_CONFIG = -I/usr/include/bsd -DBSD
#XMP#LIBPKG_CONFIG = -I/usr/win-include -DBSD -DSHORT_IDENT -DCRAY
#CRAY2#LIBPKG_CONFIG = -I/usr/win-include -DBSD -DSHORT_IDENT -DCRAY
#################################################################
# #
# Configuration for remrt #
# #
#################################################################
#SGI34#REMRT_CONFIG = -I/usr/include/EXOS -DSGI_EXCELAN
#SGI35#REMRT_CONFIG = -I/usr/include/bsd -DBSD
#4D32#REMRT_CONFIG = -I/usr/include/bsd -DBSD
#XMP#REMRT_CONFIG = -I/usr/win-include -DBSD -DSHORT_IDENT -DCRAY
#CRAY2#REMRT_CONFIG = -I/usr/win-include -DBSD -DSHORT_IDENT -DCRAY
#################################################################
# #
# Configuration for rfbd #
# #
#################################################################
#SGI35#RFBD_CONFIG = -I/usr/include/bsd -DBSD
#4D32#RFBD_CONFIG = -I/usr/include/bsd -DBSD
#################################################################
# #
# Configuration for libfb #
# #
# Specify all OPTIONAL framebuffer interfaces to attach. #
# Select from: #
# if_remote Network access to remote display #
# if_adage Adage RDS-3000 ("Ikonas") #
# if_sgi SGI IRIS display #
# if_ptty AT&T 5620 w/special Moss layer #
# if_sun SUNView interface #
# if_ug Ultra Graphics device #
# if_rat Raster Technology One/80 (24-bit RGB) #
# if_4d SGI 4D/60T "clover" workstation
# #
# Edit all three LIBFB_* lines below similarly. #
# NOTES: #
# 1) When TCP exists and if_remote is desired, set #
# LIBFB_OBJS = if_remote.o pkg.o #
# to gain access to the PKG routines. #
# #
# 2) For SGI release 3.4 and below, but not 3.5 and above: #
# LIBFB_OBJS = if_remote.o ../libpkg/pkg.o sgiselect.o #
# #
# 3) For SGIs which have MC 68010 CPUs (not Turbos or #
# 30xx machines), be certain to uncomment -DMC_68010, #
# because the default is a 68020 #
# #
LIBFB_CFILES = if_remote.c \
if_ptty.c
#VAX# if_adage.c
#SGI# if_sgi.c
#SUN# if_sun.c
#4D32# if_4d.c
LIBFB_OBJS = if_remote.o pkg.o \
if_ptty.o
#VAX# if_adage.o
#SGI35# if_sgi.o
#SGI34# if_sgi.o sgiselect.o
#SUN# if_sun.o
#4D32# if_4d.o
LIBFB_CONFIG = -DIF_REMOTE \
-DIF_PTTY
#VAX# -DIF_ADAGE
#SGI# -DIF_SGI # -DMC_68010
#SUN# -DIF_SUN
#4D32# -DIF_4D
#USNA# -DIF_ADAGE -DGM256
# #
#################################################################
#################################################################
# #
# Configuration for librt #
# #
# Select one of: #
# timer42 4.2 BSD, 4.3 BSD (Berkeley UNIX) #
# timerunix Generic UNIX, System III, V, etc. #
# timer52brl For BRL's System 5-under-4.n BSD #
# timerhep Denelcor HEP #
# timercray Cray-X/MP UNICOS #
LIBRT_TIMER = timer42
#SYSV#LIBRT_TIMER = timerunix
#XMP#LIBRT_TIMER = timercray
# #
#################################################################
#################################################################
# #
# Configuration for RT #
# #
# Mostly useful for specification of multi-processing #
# versions of libc, etc. #
# #
#XMP#RT_CONFIG = -L/lib/multi -lu
#CRAY2#RT_CONFIG = -lmt
#4D32#RT_CONFIG = -lbsd
# #
#################################################################
#################################################################
# #
# Configuration for mged #
# #
# If you wish MGED usage logging, add #
# -DLOGFILE=/file/name to MGED_CONFIG #
# #
# At present, MGED operates on these types of #
# display hardware by default: #
# dm-plot any UNIX-plot filter #
# dm-tek Tektronix 4014 and family #
# dm-tek4109 Tektronix 4109 #
# and also supports these optional display devices: #
# dm-vg Vector General 3300 #
# dm-mg Megatek 7250 #
# dm-ir SGI IRIS 2400,3030 (uses lib -lgl2) #
# dm-sun SUN 3.2 Pixwin #
# dm-rat Raster Tech One/180,380 #
# dm-rat80 Raster Tech One/80 #
# dm-ps E&S Picture System 300 #
# dm-4d Silicon Graphics 4D/60T
# dm-mer Megatek Merlin 9200 [ Marginal ] #
# dm-sab Saber w/GOPS [ Marginal ] #
# #
# Specify all OPTIONAL display managers to attach. #
# #
#VAX#MGED_CFILES = dm-mg.c dm-vg.c
#VAX#MGED_OBJS = dm-mg.o dm-vg.o
#VAX#MGED_CONFIG = -DDM_MG -DDM_VG
#VAX#MGED_LIBES =
#
#4D32#MGED_CFILES = dm-4d.c
#4D32#MGED_OBJS = dm-4d.o
#4D32#MGED_CONFIG = -G 64 -DDM_4D
#4D32#MGED_LIBES = -lbsd -lgl
#
#SGI#MGED_CFILES = dm-ir.c
#SGI#MGED_OBJS = dm-ir.o
#SGI#MGED_CONFIG = -DDM_IR # -DMC_68010
#SGIXNS#MGED_CONFIG = -DDM_IR -DNONBLOCK # -DMC_68010
#SGI35#MGED_LIBES = -lbsd -lgl2
#SGI34#MGED_LIBES = ../libfb/sgiselect.o -lgl2
# #
#SUN#MGED_CFILES = dm-sun.c
#SUN#MGED_OBJS = dm-sun.o
#SUN#MGED_CONFIG = -DDM_SUNPW
#SUN#MGED_LIBES = -lsuntool -lsunwindow -lpixrect
# #
# Pick the right script for generating the version string: #
# Depends on differing behaviors of "echo" command #
# #
MGED_VERS = newvers.sh
#SYSV#MGED_VERS = newvers5.sh
#VLD#MGED_VERS = newversVLD.sh
# #
#################################################################
#################################################################
# #
# Paths for programs, libraries, etc #
# Defined here to provide "optimal managerial flexibility" #
# #
# Note: Don't add comments after a definition, #
# the extra white space can ruin some of the expansions. #
# #
#################################################################
CC = /bin/cc
#4D32#CC = /usr/bin/cc
#VLD#CC = /usr/5bin/cc
SHELL = /bin/sh
MAKE = /bin/make
# Makefiles to print
MAKEFILE = ../Makefile.defs ./Makefile.loc ../Makefile.rules ./Makefile
# Program to get name of current system
GETHOST = hostname
#SYSV#GETHOST = uname -n
#4D32#GETHOST = hostname
# If BSD42, use ranlib on archives. For SYSV, set to "echo" (except SGI).
RANLIB = ranlib
#SYSV#RANLIB = echo
#VLD#RANLIB = ranlib
#SGI#RANLIB = ranlib
#4D32#RANLIB = ar ts
# Place to install binary executable
BINDIR = /usr/brlcad/bin
#VLD#BINDIR = /vld/bin
# Place to install (and find) libraries
LIBDIR = /usr/brlcad/lib
#VLD#LIBDIR = /vld/lib
# Place to install daemons and other non-user-command type programs
ETCDIR = /usr/brlcad/etc
# Suffix for archives. Won't change for most UNIX machines, but...
ARCH_SUF = a
#XMP#ARCH_SUF = o
# For utilities that wish to USE our libraries, here are the popular ones:
LIBFB = ../libfb.'`sh ../mtype.sh`'/libfb.${ARCH_SUF}
LIBRT = ../librt.'`sh ../mtype.sh`'/librt.${ARCH_SUF}
LIBPLOT = ../libplot3.'`sh ../mtype.sh`'/libplot3.${ARCH_SUF}
LIBRLE = ../librle.'`sh ../mtype.sh`'/librle.${ARCH_SUF}
LIBPKG = ../libpkg.'`sh ../mtype.sh`'/libpkg.${ARCH_SUF}
LIBWDB = ../libwdb.'`sh ../mtype.sh`'/libwdb.${ARCH_SUF}
LIBSPL = ../libspl.'`sh ../mtype.sh`'/libspl.${ARCH_SUF}
LIBTERMLIB = -ltermlib
#XMP#LIBTERMLIB = -lcurses
LIBTERMIO = ../libtermio.'`sh ../mtype.sh`'/libtermio.${ARCH_SUF}
LIBCURSOR = ../libcursor.'`sh ../mtype.sh`'/libcursor.${ARCH_SUF}
LIBSYSV = ../libsysv.'`sh ../mtype.sh`'/libsysv.${ARCH_SUF}
#SYSV#LIBSYSV =
# For strictly serial machines, the Princeton malloc() in libmalloc
# uses address space and physical memory more efficiently than the
# Berkeley/CalTech malloc(), but with the same performance advantage.
# It works well on VAXen and Goulds and SGIs. Sadly, it does not work
# on the SUNs.
# For parallel machines, the vendor's malloc() typically needs to be
# used, to handle parallel stack frame expansion, etc. This is
# significant on the Cray and HEP, and perhaps others.
LIBMALLOC = ../libmalloc/libmalloc.${ARCH_SUF}
#SUN#LIBMALLOC = # Forced to use vendor malloc
#XMP#LIBMALLOC = # Forced to use vendor malloc
#CRAY2#LIBMALLOC = # Forced to use vendor malloc
# Directory within CAD Package for header files
INCDIR = ../h
# Directory where users can find installed copies of header files.
INCLUDE_DIR = /usr/include/brlcad
#VLD#INCLUDE_DIR = /vld/include
# Directory for Manual pages, when ${MANSECTION} appended
MANDIR = /usr/man/man
#SYSV#MANDIR = /usr/man/u_man/man
#VLD#MANDIR = /usr/5lib/man/local/man
# Permissions for files to be installed
BINPERM = 775
MANPERM = 664
LIBPERM = 664
DIRPERM = 775
# Compiler Flags
PROFILE =
CFLAGS = -O ${PROFILE} -I${INCDIR} ${SYSTEM} ${CONFIGDEFS}
#4D#CFLAGS = -O2 ${PROFILE} -I${INCDIR} ${SYSTEM} ${CONFIGDEFS}
# Loader Flags. Note that ${CC} is used to invoke the loader
LDFLAGS = ${SYSTEM} ${PROFILE}
#4D#LDFLAGS = -O2 ${SYSTEM} ${PROFILE}
# Lint Flags
LINT = lint
LFLAGS = -hbvxac ${SYSTEM} ${CONFIGDEFS}
#SYSV#LFLAGS = ${SYSTEM} ${CONFIGDEFS}
# Name of the object module archiver, for use with the loader.
AR = ar
#XMP#AR = ../cray-ar.sh
# Regular libraries. Everybody gets the math library; most need it.
LIBES = -lm
# Lint libraries
LLIBES = -lm
# Program to install executables
INS = cp
# Command string to typeset manual pages
# Usage is: ${TYPESET_MAN1} *.${MANSECTION} ${TYPESET_MAN2}
#
TYPESET_MAN1 = tbl /usr/lib/tmac/tmac.an
TYPESET_MAN2 = | /usr/5lib/troff -Ti300 | /usr/5bin/dimp -t | \
qpr -q im231
#TYPESET_MAN1 = tbl /usr/lib/tmac/tmac.an
#TYPESET_MAN2 = | /usr/5lib/troff -Ti10 | /usr/5bin/di10 -t | \
qpr -q im328-raw
#TYPESET_MAN1 = troff -man
#TYPESET_MAN2 =
#################################################################
# #
# Definition of master source machine, and master distribution #
# directory. Please don't change these values. #
# When the current host is == MASTERHOST, the "make install" #
# rules will also handle the distribution source management. #
# Even if you have lots of disk space, you don't want that #
# to happen. #
# #
#################################################################
MASTERHOST = brl-vgr
DISTRIBUTION = /m/dist
#################################################################
# #
# Variables that will be defined in xxx/Makefile.loc #
# #
#################################################################
# Full names of final products
PRODUCTS = product
# Names of local headers that contribute to product
HEADERS =
# Names of C source files that contribute to product
CFILES = cfiles.c
# Names of Shell files that contribute to product
SHFILES =
# Section of manual to install pages in.
# All the manual pages in a given directory MUST be in the same section.
MANSECTION = 99
# ASCII Test files: input, and expected output
TFILES =
# Any Configuration-specific definitions to pass to ${CC}, ie, -Dfoo=1
CONFIGDEFS =
# Name of directory that holds the sources
SRCDIR = xxx
# If special things (like ranlib) need doing after "make install",
# xxx/Makefile.loc should set AFTERINSTALL=${RANLIB}
AFTERINSTALL = echo
# #
#################################################################
-217
View File
@@ -1,217 +0,0 @@
#################################################################
# #
# Makefile.rules #
# #
# Author - #
# Michael John Muuss #
# #
# Source - #
# SECAD/VLD Computing Consortium, Bldg 394 #
# The U. S. Army Ballistic Research Laboratory #
# Aberdeen Proving Ground, Maryland 21005 #
# #
# $Header$ #
# #
#################################################################
# Define default list of targets to be made
all: ${PRODUCTS}
# Generic SCCS rule:
#.DEFAULT:
# $(GET) $(GFLAGS) -p s.$@ > $@
# touch $@
# This is how to make the product, but may not always apply (eg, libs).
# Also, this construct only works with the SysV make.
#${PRODUCTS}: $$@.o ${OBJS}
# $(CC) -o $@ ${LDFLAGS} $@.o ${OBJS} ${LIBES}
# size $@
# Format sources for printing on stdout.
# The invoker is responsible for diverting to their printer of choice.
print: ${MAKEFILE} ${HEADERS} ${CFILES} ${TFILES}
@pr ${MAKEFILE} ${HEADERS} ${CFILES} ${TFILES} *.${MANSECTION}
@nroff -Tlp -man *.${MANSECTION}
# Don't bother doing the stub pages
typeset:
${TYPESET_MAN1} *.${MANSECTION} ${TYPESET_MAN2}
lint: ${HEADERS} ${CFILES}
${LINT} ${LFLAGS} -I${INCDIR} ${CFILES} ${LLIBES} > ${SRCDIR}.lint
tags: ${HEADERS} ${CFILES}
ctags ${HEADERS} ${CFILES}
flow: ${HEADERS} ${CFILES}
cflow -I${INCDIR} ${CFILES} > ${SRCDIR}.flow
xref: ${HEADERS} ${CFILES}
cxref -c -s -w132 -I${INCDIR} ${CFILES} > ${SRCDIR}.xref
compare: all
for prod in ${PRODUCTS} ; \
do cmp ${BINDIR}/$$prod $$prod; \
done
uninstall: all
-@if test -n "${PRODUCTS}" ; \
then $(MAKE) $(MFLAGS) -$(MAKEFLAGS) uninst-prod ; \
fi
-@files=`echo *.${MANSECTION}` ; \
if test "$$files" != '*'.${MANSECTION} ; \
then $(MAKE) $(MFLAGS) -$(MAKEFLAGS) uninst-man ; \
fi
-@files=`echo *.${MANSECTION}.stub` ; \
if test "$$files" != '*'.${MANSECTION}.stub ; \
then $(MAKE) $(MFLAGS) -$(MAKEFLAGS) uninst-stub ; \
fi
uninst-prod:
-@for prod in ${PRODUCTS} ; \
do rm -f ${BINDIR}/$$prod ${BINDIR}/$$prod.bak 2>/dev/null; \
done
uninst-man:
-@for man in *.${MANSECTION} ; \
do rm -f ${MANDIR}${MANSECTION}/$$man \
${MANDIR}${MANSECTION}/$$man.bak 2>/dev/null ; \
done
uninst-stub:
-@for stub in *.${MANSECTION}.stub ; \
do man=`basename $$stub .stub`; \
rm -f ${MANDIR}${MANSECTION}/$$man \
${MANDIR}${MANSECTION}/$$man.bak 2>/dev/null ; \
done
# Handle all phases of final installation
install: all
-@if test -n "${PRODUCTS}" ; \
then $(MAKE) $(MFLAGS) -$(MAKEFLAGS) inst-prod ; \
fi
-@files=`echo *.${MANSECTION}` ; \
if test "$$files" != '*'.${MANSECTION} ; \
then $(MAKE) $(MFLAGS) -$(MAKEFLAGS) inst-man ; \
fi
-@files=`echo *.${MANSECTION}.stub` ; \
if test "$$files" != '*'.${MANSECTION}.stub ; \
then $(MAKE) $(MFLAGS) -$(MAKEFLAGS) inst-stub ; \
fi
-@sh -c "if test `${GETHOST}` = ${MASTERHOST} ; then $(MAKE) inst-dist; else exit 0 ; fi"
# Install all products
inst-prod: ${PRODUCTS}
-@for prod in ${PRODUCTS} ; \
do if cmp -s ${BINDIR}/$$prod $$prod; \
then echo $$prod unchanged; \
else mv -f ${BINDIR}/$$prod ${BINDIR}/$$prod.bak 2>/dev/null; \
${INS} $$prod ${BINDIR} && \
${AFTERINSTALL} ${BINDIR}/$$prod && \
echo "++++++INSTALLED" ${BINDIR}/$$prod && \
${AFTERINSTALL} ${BINDIR}/$$prod.bak && \
chmod ${BINPERM} ${BINDIR}/$$prod; \
fi \
done
# Install the actual manual pages
inst-man:
-@for man in *.${MANSECTION} ; \
do if cmp -s ${MANDIR}${MANSECTION}/$$man $$man; \
then echo $$man unchanged; \
else mv -f ${MANDIR}${MANSECTION}/$$man \
${MANDIR}${MANSECTION}/$$man.bak 2>/dev/null ; \
${INS} $$man ${MANDIR}${MANSECTION} && \
echo "++++++INSTALLED" ${MANDIR}${MANSECTION}/$$man && \
chmod ${MANPERM} ${MANDIR}${MANSECTION}/$$man; \
fi \
done
# Install the "stub" manual pages, which just source some other page
inst-stub:
-@for stub in *.${MANSECTION}.stub ; \
do man=`basename $$stub .stub`; \
if cmp -s ${MANDIR}${MANSECTION}/$$man $$stub; \
then echo $$man unchanged; \
else mv -f ${MANDIR}${MANSECTION}/$$man \
${MANDIR}${MANSECTION}/$$man.bak 2>/dev/null ; \
${INS} $$stub ${MANDIR}${MANSECTION}/$$man && \
echo "++++++INSTALLED" ${MANDIR}${MANSECTION}/$$man && \
chmod ${MANPERM} ${MANDIR}${MANSECTION}/$$man; \
fi \
done
# It might be better to say ${HEADERS} ${CFILES} ${SFILES},
# but that would miss routines that were not configured in a particular system.
inst-dist:
-rm -fr ${DISTRIBUTION}/${SRCDIR}/*
-${INS} ./Makefile.loc Makefile *.[hcfs] ${SHFILES} \
*.${MANSECTION} *.${MANSECTION}.stub \
*.doc \
${DISTRIBUTION}/${SRCDIR}/.
# running "make clobber" or "make clean noprod" will remove all binary files.
# "clean" is intended to remove .o files and by-products.
# "noprod" is intended to remove the final executables.
# Either can be used without the other, depending on the effect desired.
clobber: clean noprod
clean:
-rm -f core *~ *.o \
${SRCDIR}.out ${SRCDIR}.err ${SRCDIR}.xref \
${SRCDIR}.flow ${SRCDIR}.lint
noprod:
-rm -f ${PRODUCTS}
#
# Automaticly build #include dependencies.
#
# This code can't be simply replaced by the 4.3 BSD "cc -M".
#
# The convention for writing #include directives is:
# #include "./file" gives file in current directory
# #include "/file" gives file at absolute path
# #include "file" gives file in ${INCDIR}
# #include <file> leaves to CPP
#
# Note that there MUST be a SPACE after the "#include" in order to
# be seen; this allows conditional includes (if needed) to be indicated
# by a #include TAB, so as to not cause trouble.
depend:
-@if test -n "${CFILES}" ; \
then $(MAKE) $(MFLAGS) -$(MAKEFLAGS) do-depend ; \
fi
do-depend:
cd ../${SRCDIR}; \
mv -f Makefile.loc Makefile.bak; \
cp Makefile.bak Makefile.loc; \
chmod 664 Makefile.loc; \
for k in ${CFILES}; do \
i=`basename $$k .c`; \
echo $$i.o: ../${SRCDIR}/$$k >>makedep; \
grep '^#include ' /dev/null ../${SRCDIR}/$$k | sed \
-e 's,^../'${SRCDIR}'/,,' \
-e 's,c:[^"]*"\./\([^"]*\)".*,o: \1,' \
-e 's,c:[^"]*"/\([^"]*\)".*,o: /\1,' \
-e 's,c:[^"]*"\([^"]*\)".*,o: '${INCDIR}'/\1,' \
-e '/debug.h/d' \
-e '/c:[^<]*<\(.*\)>/d' \
>>makedep; \
echo ' $$(CC) $$(CFLAGS) -c ../'${SRCDIR}/$$k >>makedep; \
done; \
echo '# DO NOT DELETE THIS LINE -- make depend uses it' >>Makefile.loc; \
echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile.loc; \
echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep; \
echo '$$r makedep' >>eddep; \
echo 'w' >>eddep; \
ed - Makefile.loc < eddep; \
rm eddep makedep; \
echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile.loc; \
echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile.loc; \
echo '# see make depend above' >> Makefile.loc
-193
View File
@@ -1,193 +0,0 @@
.\" $Header$
.TL
README
.sp
The Ballistic Research Laboratory CAD Package
.br
Release 3.5
.br
(29-May-1989)
.RT
.IP "VERSION"
.sp
This document is printed from the README file in the BRL-CAD distribution.
The version in the printed manuals are usually somewhat older
than the version on the actual distribution tape.
When attempting to
install the software, please refer to the documentation
versions actually contained on the distribution tape.
.sp
.IP CONTENTS
.sp
This README file exists only to provide you a brief roadmap to
the contents of the BRL-CAD distribution tape.
The information on how to read the tape,
install and operate the software,
and perform the benchmark tests have become sufficiently large
that they are now each a standalone document.
.sp
Please note that
this distribution package does \fInot\fR include
the various military-specific model
analysis tools such as GIFT, SAR, SLAVE, VAST, etc., nor does it
include any military databases.
If you desire to have access to this material,
please contact Keith Applin at (301)-278-6647.
.sp
.IP "INSTALLATION"
.sp
To install the BRL-CAD Package see the instructions in doc/install.doc.
This file includes directions on the best way to read the distribution
tape,
as well as details on how to configure and install the software.
This file also includes directions on how to compile and run
the benchmark tests.
.sp
.IP "BENCHMARK"
.sp
See the paper in doc/benchmark.doc for information on
analyzing the results of the benchmark tests.
Comparisons between various different computers are listed.
.sp
.IP "BACKGROUND MATERIAL"
.sp
For overview information on the whole package, consult
the overview paper in the file papers/overview, and
the brlcad(1) manual page in the file util/brlcad.1.
For a discussion of the significance of this software,
read the paper "Understanding the Preparation and Analysis of Solid
Models", included in the file papers/solid-models.
.sp
.IP "DISTRIBUTION DETAILS"
.sp
This section is included in the README file for two purposes.
First, we wish to remind you of the terms of this limited distribution.
Second, if you have obtained a copy of the printed documentation, and now
wish to obtain a copy of the software, the procedures are listed here.
.sp
To obtain a copy of the distribution, you should send the authors:
.sp
1) Enough magnetic tape for 20 Mbytes of data. Standard nine-track
half-inch magtape is the strongly preferred format, and can be written
at either 1600 or 6250 bpi, in TAR format with 10k byte records. For
sites with no half-inch tape drives, Silicon Graphics and SUN tape
cartridges can also be accommodated, using QIC-24 format.
.sp
2) A letter indicating:
.sp
.nf
-- Who you are
-- What the BRL-CAD package is to be used for
-- The equipment and operating system(s) you plan on using
-- That you agree to the conditions listed below.
.fi
.sp
It is vital that your letter include a sentence acknowledging your
agreement to the conditions, such as "We agree to the
conditions of the distribution listed in your letter".
This software is an unpublished work that is not generally available to the
public, except through the terms of this limited distribution.
The United States Department of the Army grants a royalty-free,
nonexclusive, nontransferable license and right to use,
free of charge, with the following terms and conditions:
.sp
1. The BRL-CAD package source files will not be disclosed to third
parties. BRL needs to know who has what, and what it is being used for.
.sp
2. BRL will be credited should the software be used in a product or written
about in any publication. BRL will be referenced as the original
source in any advertisements.
.sp
3. The software is provided "as is", without warranty by BRL.
In no event shall BRL be liable for any loss or for any indirect,
special, punitive, exemplary, incidental, or consequential damages
arising from use, possession, or performance of the software.
.sp
4. When bugs or problems are found, you will make a reasonable effort
to report them back to BRL.
.sp
5. Before using the software at additional sites, or for permission to
use this work as part of a commercial package, you agree to first obtain
authorization from BRL.
.sp
6. You will own full rights to any databases or images you create with this
package.
.sp
All requests from US citizens, or from US government agencies should be
sent to:
.sp
.nf
.ne 1i
Ballistic Research Lab
Attn: Mike Muuss
APG, MD 21005-5066
.fi
.sp
If you are not a US citizen (regardless of any affiliation with a
US industry), or if you represent a foreign-owned or foreign-controlled
industry, you must send your letter and tape through your Ambassador to
the United States in Washington DC. Have your Ambassador submit the
request to:
.sp
.nf
.ne 1i
Army Headquarters
Attn: DAMI-FL
Washington, DC 20310
.fi
.sp
Because distribution tapes are written by various members of the
development team in their spare time, and because of vagaries in
the supply of printed manuals, the turnaround time for responding
to distribution requests varies from 1 to 12 weeks.
.sp
.ne 1i
.IP "COMMUNICATION"
.sp
You are invited to participate in the DARPA InterNet (aka "ARPANET")
electronic mailing list on the BRL-CAD software, which is called
.sp .5
.ti +1i
<CAD @ BRL.MIL>.
.sp .5
Bug reports and discussions of new features
are the main topics; volume of messages has been light (so far).
Direct your bug reports to this address. Request a subscription by
sending to
.sp .5
.ti +1i
<CAD-REQUEST @ BRL.MIL>.
.sp .5
If you find bugs, please report your experiences via E-mail.
While BRL makes no
offer of support, we are most interested in hearing about your
experiences.
.sp
.IP "FUTURE EVENTS"
.sp
It is expected that new releases of this software will be issued
between once and twice a year.
Information about new releases will be routinely provided
by both paper and electronic mail
to recipients of this software.
If your address changes, please let us
know, so we can update our records.
.sp
The BRL-CAD Symposium '88 was a big success.
If you would be interested in attending the Symposium in '89,
and especially if you would like to make a presentation, please
contact Keith Applin <Keith@BRL.MIL>, or call 301-278-6647.
.sp
.KS
.nf
Best Wishes,
-Mike Muuss
.sp
Leader, Advanced Computer Systems Team
U.S. Army Ballistic Research Laboratory
APG, MD. 21005-5066
USA
.sp
ArpaNet: <Mike @ BRL.MIL>
.KE
.fi
-38
View File
@@ -1,38 +0,0 @@
/*
* bench/Cakefile
*/
#define SRCDIR bench
#define PRODUCTS pixcmp
#define SRCSUFF .c
#define MANSECTION 9
#define FILES pixcmp
#include "../Cakefile.defs"
/* These programs are not really for system-wide installation */
#define DONT_INSTALL 1
#ifdef NFS
/* Pick up any shell scripts needed */
%.sh: if exist ../SRCDIR/%.sh
rm -f %.sh
ln ../SRCDIR/%.sh %.sh
#endif
#include "../Cakefile.prog"
clobber&: xxclober
@echo "About to wipe out all pictures and binary files in this directory"
@echo "Send SIGINT (typ. ^C) within 3 seconds to abort"
@sleep 5
rm -f *.log.* *.pix.* # old versions
rm -f *.log *.pix # last try
#define clobber xxclober /* rename "clobber" in Cakefile.rules */
pixcmp: OBJ
CC LDFLAGS -o pixcmp OBJ
#include "../Cakefile.rules"
-148
View File
@@ -1,148 +0,0 @@
#!/bin/sh
# A Shell script to test LGT
# @(#)$Header$ (BRL)
# Ensure /bin/sh
export PATH || (echo "This isn't sh."; sh $0 $*; kill $$)
eval `machinetype.sh -b` # sets MACHINE, UNIXTYPE, HAS_TCP
if test -f ../.lgt.$MACHINE/lgt
then
LGT=../.lgt.$MACHINE/lgt
DB=../.db.$MACHINE
else
if test -f ../lgt/lgt
then
LGT=../lgt/lgt
DB=../db
else
echo "Can't find LGT"
exit 1
fi
fi
CMP=./pixcmp
if test ! -f $CMP
then
cake pixcmp
fi
# Alliant NFS hack
if test x${MACHINE} = xfx
then
cp ${LGT} /tmp/lgt
cp ${CMP} /tmp/pixcmp
LGT=/tmp/lgt
CMP=/tmp/pixcmp
fi
# This test of LGT assumes a "live" framebuffer here.
if test x$FB_FILE = x
then
echo "Environment variable FB_FILE must be set to a real framebuffer"
echo "for this test of LGT to operate correctly."
exit 1
fi
# Run the first set of tests
${LGT} ${DB}/lgt-test.g all.g << EOF
# read light source data base
v ../db/lgt-test.ldb
# read material data base
w ../db/lgt-test.mdb
# force display window to be 512x512 pixels, should cause 8-to-1 zoom
T 512
# clear frame buffer
E
# set maximum bounces to 20
K 20
# turn hidden-line drawing off
k 0
# configure grid: 64 rays across
G 64 0 0 0.0
# turn perspective off
p 0
# change background to mauve
b 111 66 66
# read key frame
j ../db/lgt-test.key
# display view #3
R
# save image in file
H lgt3a.pix
# change frame buffer to disk file
o lgt3b.pix
# save a script of previous commands, to produce the "b" version.
S script3
# disable reading of key frame file
j
# change frame buffer back to default
o
# configure grid: 2.45 mm cells, centered about model origin, view size 225 mm
G 2.45 1 1 225.0
# change background to firebrick
b 142 35 35
# force frame buffer size to be 455 pixels across, should cause 4-to-1 zoom
T 455
# set automatic perspective at 0.25
p 0.25
# set anti-aliasing over-sampling factor to 2
A 2
# set maximum bounces to 20
K 20
# display view #1
R
# save image in file
H lgt1a.pix
# change frame buffer to disk file
o lgt1b.pix
# save a script
S script1
# change frame buffer back to default
o
# turn off anti-aliasing
A 1
# revert to auto-sizing of frame buffer
T 0
# set automatic perspective at 0.25
p 0.25
# select hidden-line drawing, reverse video
k 2
# configure grid: 128 rays across, centered at model RPP, view size 225mm
G 128 0 0 225.0
# display view #2
R
# save image in file
H lgt2a.pix
# change frame buffer to disk file
o lgt2b.pix
# save a script
S script2
# change frame buffer back to default
o
# bye
q
EOF
if test $? = 0
then :;
else echo "Abnormal lgt exit"; exit 1
fi
# Run the second set of tests. The scripts were created above.
./script1 < /dev/null &&
./script2 < /dev/null &&
./script3 < /dev/null || { echo "Script test failed."; exit 1; }
for i in 1 2 3
do
if ${CMP} ../pix/lgt${i}.pix lgt${i}a.pix
then :;
else echo "Test $i A failed."; exit 1
fi
if ${CMP} ../pix/lgt${i}.pix lgt${i}b.pix
then :;
else echo "Test $i B failed."; exit 1
fi
done
echo "Tested OK."
-65
View File
@@ -1,65 +0,0 @@
#!/bin/sh
# A Shell script to extract the benchmark statistics, and build an
# entry suitable for the tables in doc/benchmark.doc.
# Note well that the command-line args may have embedded spaces.
# Mike Muuss & Susan Muuss, 11-Sept-88.
# @(#)$Header$ (BRL)
# Ensure /bin/sh
export PATH || (sh $0 $*; kill $$)
NAME=$0
if test "x$1" = x
then
echo "Usage: $NAME hostname [note1] [note2]"
exit 1
fi
# Save three args, because arg list will be reused below.
# They may have embedded spaces in them.
HOST="$1"
NOTE1="$2"
NOTE2="$3"
NEW_FILES="moss.log world.log star.log bldg391.log m35.log"
REF_FILES="../pix/moss.log ../pix/world.log ../pix/star.log \
../pix/bldg391.log ../pix/m35.log"
# Use TR to convert newlines to tabs.
VGRREF=`grep RTFM $REF_FILES | \
sed -n -e 's/^.*= *//' -e 's/ rays.*//p' | \
tr '\012' '\011' `
CURVALS=`grep RTFM $NEW_FILES | \
sed -n -e 's/^.*= *//' -e 's/ rays.*//p' | \
tr '\012' '\011' `
RATIO_LIST=""
# Trick: Force args $1 through $5 to the numbers in $CURVALS
# This should be "set -- $CURVALS", but 4.2BSD /bin/sh can't handle it,
# and CURVALS are all positive (ie, no leading dashes), so this is safe.
set $CURVALS
while test $# != 5
do echo "${NAME}: Warning, only $# times found, using zeros"
CURVALS="$CURVALS 0"
set $CURVALS
done
for ref in $VGRREF
do
cur=$1
shift
RATIO=`echo "2k $cur $ref / p" | dc`
# Note: append new value and a trail TAB to existing list.
RATIO_LIST="${RATIO_LIST}$RATIO "
done
# The number of plus signs must be one less than the number of elements.
MEAN_ABS=`echo 2k $CURVALS ++++ 5/ p | dc`
MEAN_REL=`echo 2k $RATIO_LIST ++++ 5/ p | dc`
# Note: Both RATIO_LIST and CURVALS have an extra trailing tab.
# The question mark is for the mean field
echo "Abs ${HOST} ${CURVALS}${MEAN_ABS} $NOTE1"
echo "*vgr ${HOST} ${RATIO_LIST}${MEAN_REL} $NOTE2"
-124
View File
@@ -1,124 +0,0 @@
/*
* P I X C M P . C
*
* Compute the difference between two .pix files.
* To establish context, a monochrome image is produced when there
* are no differences; otherwise the channels that differ are
* highlighted on differing pixels.
*
* This routine operates on a pixel-by-pixel basis, and thus
* is independent of the resolution of the image.
*
* Author -
* Charles M. Kennedy
* Michael John Muuss
*
* Source -
* SECAD/VLD Computing Consortium, Bldg 394
* The U. S. Army Ballistic Research Laboratory
* Aberdeen Proving Ground, Maryland 21005
*
* Copyright Notice -
* This software is Copyright (C) 1988 by the United States Army.
* All rights reserved.
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
long matching;
long off1;
long offmany;
char usage[] = "Usage: pixcmp f1.pix f2.pix\n";
main(argc, argv)
char **argv;
{
register FILE *f1, *f2;
if( argc != 3 ) {
fprintf(stderr, "%s", usage);
exit(0);
}
if( strcmp( argv[1], "-" ) == 0 )
f1 = stdin;
else if( (f1 = fopen( argv[1], "r" ) ) == NULL ) {
perror( argv[1] );
exit(1);
}
if( strcmp( argv[2], "-" ) == 0 )
f2 = stdin;
else if( (f2 = fopen( argv[2], "r" ) ) == NULL ) {
perror( argv[2] );
exit(1);
}
while(1) {
register int r1, g1, b1;
int r2, g2, b2;
r1 = fgetc( f1 );
g1 = fgetc( f1 );
b1 = fgetc( f1 );
r2 = fgetc( f2 );
g2 = fgetc( f2 );
b2 = fgetc( f2 );
if( feof(f1) || feof(f2) ) break;
if( r1 != r2 || g1 != g2 || b1 != b2 ) {
register int i;
/* Highlight differing channels */
if( r1 != r2 ) {
if( (i = r1 - r2) < 0 ) i = -i;
if( i > 1 ) {
offmany++;
} else {
off1++;
}
} else {
matching++;
}
if( g1 != g2 ) {
if( (i = g1 - g2) < 0 ) i = -i;
if( i > 1 ) {
offmany++;
} else {
off1++;
}
} else {
matching++;
}
if( b1 != b2 ) {
if( (i = b1 - b2) < 0 ) i = -i;
if( i > 1 ) {
offmany++;
} else {
off1++;
}
} else {
matching++;
}
} else {
/* Common case: equal. Give B&W NTSC average */
matching += 3;
}
}
fprintf(stderr,
"pixcmp bytes: %7d matching, %7d off by 1, %7d off by many\n",
matching, off1, offmany );
/* If files were of different lengths, that is an error */
if( feof(f1) != feof(f2) )
exit(2);
/* If any pixels were off by more than +/- 1, that is an error */
if( offmany)
exit(1);
/* Success! */
exit(0);
}
-15
View File
@@ -1,15 +0,0 @@
#!/bin/sh
# WARNING THIS IS A REAL CPU HOG
../rt/rt -p90 -f1024 -H3 -M $*\
-o cube.pix\
../db/cube.g\
'all.g' \
2> cube.log\
<<EOF
6.847580140e+03
3.699276190e+03 3.032924070e+03 3.658674860e+03
-5.735762590e-01 8.191521640e-01 0.000000000e+00 0.000000000e+00
-3.461885920e-01 -2.424037690e-01 9.063078880e-01 0.000000000e+00
7.424040310e-01 5.198366640e-01 4.226181980e-01 0.000000000e+00
0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00
EOF
-46
View File
@@ -1,46 +0,0 @@
#!/bin/sh
# A Shell script to re-check the most recent results of the benchmark
# @(#)$Header$ (BRL)
# Ensure /bin/sh
export PATH || (echo "This isn't sh."; sh $0 $*; kill $$)
eval `machinetype.sh -b` # sets MACHINE, UNIXTYPE, HAS_TCP
if test -f ../.util.$MACHINE/pixdiff
then
PIXDIFF=../.util.$MACHINE/pixdiff
PIX_FB=../.util.$MACHINE/pix-fb
else
if test -f ../util/pixdiff
then
PIXDIFF=../util/pixdiff
PIX_FB=../util/pix-fb
else
echo "Can't find pixdiff"
exit 1
fi
fi
# Alliant NFS hack
if test x${MACHINE} = xfx
then
cp ${PIXDIFF} /tmp/pixdiff
cp ${PIX_FB} /tmp/pix-fb
PIXDIFF=/tmp/pixdiff
PIX_FB=/tmp/pix-fb
fi
echo +++++ moss.pix
${PIXDIFF} ../pix/moss.pix moss.pix | ${PIX_FB}
echo +++++ world.pix
${PIXDIFF} ../pix/world.pix world.pix | ${PIX_FB}
echo +++++ star.pix
${PIXDIFF} ../pix/star.pix star.pix | ${PIX_FB}
echo +++++ bldg391.pix
${PIXDIFF} ../pix/bldg391.pix bldg391.pix | ${PIX_FB}
echo +++++ m35.pix
${PIXDIFF} ../pix/m35.pix m35.pix | ${PIX_FB}
-177
View File
@@ -1,177 +0,0 @@
#!/bin/sh
# A Shell script to run the BRL-CAD Benchmark Test
# @(#)$Header$ (BRL)
# Ensure /bin/sh
export PATH || (echo "This isn't sh."; sh $0 $*; kill $$)
eval `machinetype.sh -b` # sets MACHINE, UNIXTYPE, HAS_TCP
if test -f ../.rt.$MACHINE/rt
then
RT=../.rt.$MACHINE/rt
DB=../.db.$MACHINE
else
if test -f ../rt/rt
then
RT=../rt/rt
DB=../db
else
echo "Can't find RT"
exit 1
fi
fi
CMP=./pixcmp
if test ! -f $CMP
then
cake pixcmp
fi
# Alliant NFS hack
if test x${MACHINE} = xfx
then
cp ${RT} /tmp/rt
cp ${CMP} /tmp/pixcmp
RT=/tmp/rt
CMP=/tmp/pixcmp
fi
# Run the tests
echo +++++ moss
if test -f moss.pix; then mv -f moss.pix moss.pix.$$; fi
if test -f moss.log; then mv -f moss.log moss.log.$$; fi
time $RT -B -M -s512 $* \
-o moss.pix \
$DB/moss.g all.g \
2> moss.log \
<< EOF
viewsize 1.572026215e+02;
eye_pt 6.379990387e+01 3.271768951e+01 3.366661453e+01;
viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00
0.000000000e+00 -3.461886346e-01 -2.424038798e-01 9.063078165e-01
0.000000000e+00 7.424039245e-01 5.198368430e-01 4.226182699e-01
0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00
1.000000000e+00 ;
start 0;
end;
EOF
${CMP} ../pix/moss.pix moss.pix
if test $? = 0
then
echo moss.pix: answers are RIGHT
else
echo moss.pix: WRONG WRONG WRONG WRONG WRONG WRONG
fi
echo +++++ world
if test -f world.pix; then mv -f world.pix world.pix.$$; fi
if test -f world.log; then mv -f world.log world.log.$$; fi
time $RT -B -M -s512 $* \
-o world.pix \
$DB/world.g all.g \
2> world.log \
<< EOF
viewsize 1.572026215e+02;
eye_pt 6.379990387e+01 3.271768951e+01 3.366661453e+01;
viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00
0.000000000e+00 -3.461886346e-01 -2.424038798e-01 9.063078165e-01
0.000000000e+00 7.424039245e-01 5.198368430e-01 4.226182699e-01
0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00
1.000000000e+00 ;
start 0;
end;
EOF
${CMP} ../pix/world.pix world.pix
if test $? = 0
then
echo world.pix: answers are RIGHT
else
echo world.pix: WRONG WRONG WRONG WRONG WRONG WRONG
fi
echo +++++ star
if test -f star.pix; then mv -f star.pix star.pix.$$; fi
if test -f star.log; then mv -f star.log star.log.$$; fi
time $RT -B -M -s512 $* \
-o star.pix \
$DB/star.g all \
2> star.log \
<<EOF
viewsize 2.500000000e+05;
eye_pt 2.102677960e+05 8.455500000e+04 2.934714650e+04;
viewrot -6.733560560e-01 6.130643360e-01 4.132114880e-01 0.000000000e+00
5.539599410e-01 4.823888300e-02 8.311441420e-01 0.000000000e+00
4.896120540e-01 7.885590550e-01 -3.720948210e-01 0.000000000e+00
0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00 ;
start 0;
end;
EOF
${CMP} ../pix/star.pix star.pix
if test $? = 0
then
echo star.pix: answers are RIGHT
else
echo star.pix: WRONG WRONG WRONG WRONG WRONG WRONG
fi
echo +++++ bldg391
if test -f bldg391.pix; then mv -f bldg391.pix bldg391.pix.$$; fi
if test -f bldg391.log; then mv -f bldg391.log bldg391.log.$$; fi
time $RT -B -M -s512 $* \
-o bldg391.pix \
$DB/bldg391.g all.g \
2> bldg391.log \
<<EOF
viewsize 1.800000000e+03;
eye_pt 6.345012207e+02 8.633251343e+02 8.310771484e+02;
viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00
0.000000000e+00 -3.461886346e-01 -2.424038798e-01 9.063078165e-01
0.000000000e+00 7.424039245e-01 5.198368430e-01 4.226182699e-01
0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00
1.000000000e+00 ;
start 0;
end;
EOF
${CMP} ../pix/bldg391.pix bldg391.pix
if test $? = 0
then
echo bldg391.pix: answers are RIGHT
else
echo bldg391.pix: WRONG WRONG WRONG WRONG WRONG WRONG
fi
echo +++++ m35
if test -f m35.pix; then mv -f m35.pix m35.pix.$$; fi
if test -f m35.log; then mv -f m35.log m35.log.$$; fi
time $RT -B -M -s512 $* \
-o m35.pix \
$DB/m35.g all.g \
2> m35.log \
<< EOF
viewsize 6.787387985e+03;
eye_pt 3.974533127e+03 1.503320754e+03 2.874633221e+03;
viewrot -5.527838919e-01 8.332423558e-01 1.171090926e-02 0.000000000e+00
-4.815587087e-01 -3.308784486e-01 8.115544728e-01 0.000000000e+00
6.800964482e-01 4.429747496e-01 5.841593895e-01 0.000000000e+00
0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00 ;
start 0;
end;
EOF
${CMP} ../pix/m35.pix m35.pix
if test $? = 0
then
echo m35.pix: answers are RIGHT
else
echo m35.pix: WRONG WRONG WRONG WRONG WRONG WRONG
fi
echo
echo Testing complete, check times against reference files in ../pix/.
if test x$UNIXTYPE = xBSD
then HOST=`hostname`
else HOST=`uname -n`
fi
sh ../bench/perf.sh "$HOST" "`date`" "$*" >> summary
-118
View File
@@ -1,118 +0,0 @@
#!/bin/sh
# A Shell script to run the BRL-CAD Benchmark Test,
# with output going to the current framebuffer, rather than a file.
# @(#)$Header$ (BRL)
# Ensure /bin/sh
export PATH || (echo "This isn't sh."; sh $0 $*; kill $$)
eval `machinetype.sh -b` # sets MACHINE, UNIXTYPE, HAS_TCP
if test -f ../.rt.$MACHINE/rt
then
RT=../.rt.$MACHINE/rt
DB=../.db.$MACHINE
else
if test -f ../rt/rt
then
RT=../rt/rt
DB=../db
else
echo "Can't find RT"
exit 1
fi
fi
CMP=./pixcmp
if test ! -f $CMP
then
cake pixcmp
fi
# Alliant NFS hack
if test x${MACHINE} = xfx
then
cp ${RT} /tmp/rt
cp ${CMP} /tmp/pixcmp
RT=/tmp/rt
CMP=/tmp/pixcmp
fi
# Run the tests
echo +++++ moss
time $RT -B -M -s512 $* \
$DB/moss.g all.g \
<< EOF
viewsize 1.572026215e+02;
eye_pt 6.379990387e+01 3.271768951e+01 3.366661453e+01;
viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00
0.000000000e+00 -3.461886346e-01 -2.424038798e-01 9.063078165e-01
0.000000000e+00 7.424039245e-01 5.198368430e-01 4.226182699e-01
0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00
1.000000000e+00 ;
start 0;
end;
EOF
echo +++++ world
time $RT -B -M -s512 $* \
$DB/world.g all.g \
<< EOF
viewsize 1.572026215e+02;
eye_pt 6.379990387e+01 3.271768951e+01 3.366661453e+01;
viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00
0.000000000e+00 -3.461886346e-01 -2.424038798e-01 9.063078165e-01
0.000000000e+00 7.424039245e-01 5.198368430e-01 4.226182699e-01
0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00
1.000000000e+00 ;
start 0;
end;
EOF
echo +++++ star
time $RT -B -M -s512 $* \
$DB/star.g all \
<<EOF
viewsize 2.500000000e+05;
eye_pt 2.102677960e+05 8.455500000e+04 2.934714650e+04;
viewrot -6.733560560e-01 6.130643360e-01 4.132114880e-01 0.000000000e+00
5.539599410e-01 4.823888300e-02 8.311441420e-01 0.000000000e+00
4.896120540e-01 7.885590550e-01 -3.720948210e-01 0.000000000e+00
0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00 ;
start 0;
end;
EOF
echo +++++ bldg391
time $RT -B -M -s512 $* \
$DB/bldg391.g all.g \
<<EOF
viewsize 1.800000000e+03;
eye_pt 6.345012207e+02 8.633251343e+02 8.310771484e+02;
viewrot -5.735764503e-01 8.191520572e-01 0.000000000e+00
0.000000000e+00 -3.461886346e-01 -2.424038798e-01 9.063078165e-01
0.000000000e+00 7.424039245e-01 5.198368430e-01 4.226182699e-01
0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00
1.000000000e+00 ;
start 0;
end;
EOF
echo +++++ m35
time $RT -B -M -s512 $* \
$DB/m35.g all.g \
<< EOF
viewsize 6.787387985e+03;
eye_pt 3.974533127e+03 1.503320754e+03 2.874633221e+03;
viewrot -5.527838919e-01 8.332423558e-01 1.171090926e-02 0.000000000e+00
-4.815587087e-01 -3.308784486e-01 8.115544728e-01 0.000000000e+00
6.800964482e-01 4.429747496e-01 5.841593895e-01 0.000000000e+00
0.000000000e+00 0.000000000e+00 0.000000000e+00 1.000000000e+00 ;
start 0;
end;
EOF
-52
View File
@@ -1,52 +0,0 @@
/*
burst/Cakefile
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
$Header$ (BRL)
*/
#define CONFIGDEFS LGT_CONFIG -I. /* -DDEBUG */
#define SRCDIR burst
#define PRODUCTS burst
#define SRCSUFF .c
#define MANSECTION 1
#define FILES burst error fb glob grid gridrotate idents\
paint plot prnt trie ui\
Hm HmGetc HmGlob Sc Tc
#include "../Cakefile.defs"
#include "../Cakefile.prog"
/* Explicit composition of each product */
PRODUCTS: OBJ
CC LDFLAGS -o burst OBJ LIB_PRE''LIBRT RT_LIBES LIB_PRE''LIBFB LIBTERMLIB LIBES -ltermlib -lm
all&: PRODUCTS
test&: all tfiles/ktank.g
./burst -b < tfiles/ktank.in
@if test $? -ne 0 \
then echo "Test failed."; exit 1 \
fi
diff tfiles/ktank.burst tfiles/ktank.burst.bak
@if test $? -ne 0 \
then echo "Test failed."; exit 1 \
fi
diff tfiles/ktank.shotlines tfiles/ktank.shotlines.bak
@if test $? -ne 0 \
then echo "Test failed."; exit 1 \
fi
@echo "Tested OK."
untest&:
rm -f tfiles/ktank.burst tfiles/ktank.shotlines tfiles/ktank.plot \
tfiles/ktank.pix tfiles/ktank.g tfiles/ktank.log
tfiles/ktank.g:
asc2g < tfiles/ktank.asc > tfiles/ktank.g
#include "../Cakefile.rules"
-1389
View File
File diff suppressed because it is too large Load Diff
-325
View File
@@ -1,325 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
$Header$ (BRL)
*/
/**
<Hm.h> -- MUVES "Hm" (hierarchical menu) package definitions
**/
#ifndef Hm_H_INCLUDE
#define Hm_H_INCLUDE
/**
This software and documentation is derived in part from the
menuhit(9.3) manual pages (not source code) in AT&T 9th Edition
UNIX, Version 1 Programmer's Manual.
The Hm package provides a pop-up menu implementation which uses
a terminal-independent screen management facility (Sc package)
to simulate the necessary graphics using the ASCII character set.
Only a few keyboard characters are required to control the menus,
but when possible, as with DMD terminals running a MYX terminal
emulator, the menus can be controlled with the mouse.
**/
/**
Each menu is defined by the following structure:
typedef struct
{
HmItem *item;
HmItem *(*generator)();
short prevtop;
short prevhit;
bool sticky;
}
HmMenu;
A menu can be built as an array of HmItem's, pointed to by item,
or with a generator function. If item is (HmItem *) 0, the
generator field is assumed to be valid. The generator function
is passed an integer parameter, and must return the pointer to
an HmItem in a static area (the result is only needed until the
next call). The n's are guaranteed to start at 0 and increase
by 1 each invocation until generator returns (HmItem *) 0.
Prevtop will contain the index of the menu item which appeared
at the top of the menu the last time it was displayed. Prevhit
will contain the index of the last item traversed (indices begin
at 0). If sticky is true, the menu will hang around after an
entry is selected so that another entry may be chosen and the
menu must be exited explicitly with the appropriate key-stroke
or equivalent mouse operation. Otherwise, the menu will exit
after selection of an item (and any actions resulting from that
selection such as submenus have finished). WARNING: if a menu
is to be used more than once during recursive calls to HmHit,
there needs to be distinct copies (allocated storage) since the
item field is filled in by the generator function, and the
prevtop and prevhit fields should be private to the current
invocation of HmHit.
**/
struct HmMenu;
typedef struct
{
char *text; /* menu item string */
char *help; /* help string */
struct HmMenu *next; /* sub-menu pointer or NULL */
void (*dfn)();
void (*bfn)();
void (*hfn)();
long data;
}
HmItem;
/**
Menu items are defined by the following structure:
typedef struct
{
char *text;
char *help;
HmMenu *next;
void (*dfn)();
void (*bfn)();
void (*hfn)();
long data;
}
HmItem;
The text field will be displayed as the name of the item.
Characters with the 0200 bit set are regarded as fill characters.
For example, the string "\240X" will appear in the menu as a
right-justified X (040 is the ASCII space character). Menu
strings without fill characters are drawn centered in the menu.
Whether generated statically or dynamically, the list of HmItem's
must be terminated by a NULL text field. The help string will be
displayed when the user presses the help key. If next is not
equal to (HmMenu *) 0, it is assumed to point to a submenu,
"dfn()" if non-zero is called just before the submenu is invoked,
and "bfn()" likewise just afterwards. These functions are passed
the current menu item. If the menu item is selected and next is
0, "hfn()" is called (if non-zero), also with the current menu
item. The "data" field is reserved for the user to pass
information between these functions and the calling routine.
**/
typedef struct HmMenu
{
HmItem *item; /* List of menu items or 0. */
HmItem *(*generator)();/* If item == 0, generates items. */
short prevtop; /* Top entry currently visable */
short prevhit; /* Offset from top of last select */
bool sticky; /* If true, menu stays around after SELECT,
and until QUIT. */
}
HmMenu;
/* Structure used internally for screen management. These are stacked
dynamically with calls to HmHit() such that the head of the chain
is the current menu, and the end of the chain such that next is
0, is the top-level menu.
*/
typedef struct HmWin
{
struct HmWin *next; /* Parent of this menu. */
HmMenu *menup; /* Address of menu data structure. */
int menux; /* Position on screen where top-left */
int menuy; /* corner of menu will be displayed. */
int width; /* Width of menu, not including border. */
int height; /* Number of menu entries. */
int *dirty; /* Dynamically allocated bitmap. ON bits
mean character needs a redraw. */
}
HmWindow;
/**
bool HmInit( int x, int y, int maxvis )
HmInit() must be called before any other routines in the
Hm package to initialize the screen position of the top-left
corner of the top-level menu to x and y and to set the
maximum number of menu entries which will be visable at one
time to maxvis. If the number of entries in a menu exceeds
maxvis, the menu will scroll to accommodate them. The values
of x, y and maxvis are stored in these external variables:
int HmLftMenu
int HmTopMenu
int HmMaxVis
If this routine is not called, default parameters will be used.
HmInit() also opens "/dev/tty" for input and stores it's file
descriptor in HmTtyFd and associated stream handle in HmTtyFp.
int HmTtyFd
FILE *HmTtyFp
This routine returns true or false on success or failure to open
"/dev/tty".
**/
#if __STDC__
extern bool HmInit( int x, int y, int maxvis );
#else
extern bool HmInit();
#endif
extern FILE *HmTtyFp;
extern int HmLftMenu;
extern int HmTopMenu;
extern int HmMaxVis;
extern int HmLastMaxVis;
extern int HmTtyFd;
/**
HmItem *HmHit( HmMenu *menup )
HmHit() presents the user with a menu specified by HmMenu
pointer menup and returns a pointer to the selected HmItem
or 0 if nothing was selected. The menu is presented to
the user with the item corresponding to prevhit (current
item) highlighted. If a menu has not been accessed yet,
prevhit will be set to the first item. The user may move
the cursor to the item below the current one by pressing the
'd' key, or move up by pressing the 'u'. If the user
presses 'h', the help message for the current item will be
displayed until another key is struck. To select an item,
the user presses the space bar. An actual selection has
been made when the selected item does not have a submenu,
otherwise, it may be termed a traversal of that item.
Traversing an item does change the value of prevhit, but
is not final as the submenu can be exited by the user
pressing 'q', before selecting an item. In case the screen
becomes disturbed (i.e. by the output of another process),
holding down the <control> key and striking an 'l' will
re-display all of the menus.
Both the help and warning (non-fatal error) messages will
be displayed in the one-line window at HmYCOMMO. For
instance, if the user hits any keys other than the ones
mentioned above, an error message will appear in this
window. Also, a one-line window is reserved for application
prompts at HmYPROMPT. The prompt window is cleared just
prior to blocking on user input, and the message window
is cleared when the user provides input (strikes a key).
If a menu has more items than can be displayed at once,
the corners of the menu will indicate this as follows:
'+' means the adjacent displayed item is the actual first
(or last if a bottom corner) item in the menu.
'v' means that the entry displayed in the previous line
is not the last, and the menu can be scrolled upwards.
'^' means that the entry displayed on the next line is
not actually the first, and the menu can be scrolled
downwards.
Attempting to move the cursor below the bottom entry of
the menu will cause the menu to scroll half a page or
until the entries run out, which ever comes first. If
there are no entries to scroll the terminal will beep.
The analagous holds true for attempting to move upward
past the top entry of the menu. If a DMD terminal with
MYX running is used, a special cursor will appear, and
the user may use the mouse rather than the keyboard as
follows: Clicking button 1 of the mouse while the
cursor is outside the "current menu", will cause the
terminal to beep. If the cursor is on an item, that item
will be made "current". If on the "current" item, that
item will be selected. If on the top border of the
current menu, that menu will scroll down if possible, and
if not, that menu will exit. If on the bottom border,
that menu will scroll upward if possible and beep if not.
**/
#if __STDC__
extern HmItem *HmHit( HmMenu *menup );
#else
extern HmItem *HmHit();
#endif
/**
void HmRedraw( void )
HmRedraw() will force the entire set of active menus to
be redrawn on the next call to HmHit(). This is useful
when an application interferes with the portion of the
screen used by the Hm package (from HmTopMenu to HmYCOMMO).
**/
#if __STDC__
extern void HmRedraw( void );
#else
extern void HmRedraw();
#endif
/**
void HmError( char *string )
HmError() will display string on line HmYCOMMO.
**/
#if __STDC__
extern void HmError( char *str );
#else
extern void HmError();
#endif
#define HmYCOMMO (HmTopMenu+HmMaxVis+HmHGTBORDER)
#define HmYPROMPT (HmYCOMMO+1)
#define HmXPROMPT 1
#define HmYBORDER (HmYPROMPT+1)
/**
int HmGetchar( void )
int HmUngetchar( int c )
HmGetchar() and HmUngetchar() are used by the Hm package to
read a character from the keyboard and to stuff one character
back on the input stream. They may be both be supplied by
the application if the default behavior is not desirable.
HmGetchar() returns the next character on the standard input.
This command will block until input is available.
HmUngetchar() inserts the character c on the standard input.
An EOF will be returned if this is not possible or c is
equal to EOF. In general, this is guaranteed to work for one
character assuming that something has already been read with
HmGetchar() and the input stream is buffered.
**/
#if __STDC__
extern int HmGetchar( void );
extern int HmUngetchar( int c );
#else
extern int HmGetchar();
extern int HmUngetchar();
#endif
/**
void HmTtySet( void )
void HmTtyReset( void )
HmTtySet() and HmTtyReset() set/restore the terminal modes for
the menus to work properly. These are mainly internal routines
which are called from HmHit(), but are provided in case an
escape from the program is provided by the application or job
control is enabled in the underlying shell, in which case,
these routines can be called from a menu function or signal
handler.
**/
extern void HmTtySet();
extern void HmTtyReset();
#define HmMAXLINE 132
#define HmHGTBORDER 2
#endif /* Hm_H_INCLUDE */
-36
View File
@@ -1,36 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
$Header$ (BRL)
*/
#if ! defined( lint )
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#include "./burst.h"
#include "./Hm.h"
/*LINTLIBRARY*/
int
#if __STDC__
HmGetchar( void )
#else
HmGetchar()
#endif
{ int c;
while( (c = getc( HmTtyFp )) == EOF )
;
return c;
}
int
#if __STDC__
HmUngetchar( int c )
#else
HmUngetchar( c )
#endif
{
return ungetc( c, HmTtyFp );
}
-19
View File
@@ -1,19 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
$Header$ (BRL)
*/
/*LINTLIBRARY*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
FILE *HmTtyFp = NULL; /* read keyboard, not stdin */
int HmLftMenu = 1; /* default top-level menu position */
int HmTopMenu = 1;
int HmMaxVis = 10; /* default maximum menu items displayed */
int HmLastMaxVis = 10; /* track changes in above parameter */
int HmTtyFd; /* read keyboard, not stdin */
-22
View File
@@ -1,22 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
$Header$ (BRL)
*/
/* Emulate MUVES Mm package using malloc. */
#if __STDC__
extern char *malloc( unsigned n );
extern char *strcpy( char *s1, char *s2 );
#else
extern char *malloc();
extern char *strcpy();
#endif
#define MmAllo( typ ) (typ *) malloc( sizeof(typ) )
#define MmFree( typ, ptr ) free( (char *) ptr )
#define MmVAllo( ct, typ ) (typ *) malloc( (ct)*sizeof(typ) )
#define MmVFree( ct, typ, ptr ) free( (char *) ptr )
#define MmStrDup( str ) strcpy( malloc( strlen(str)+1 ), str )
#define MmStrFree( str ) free( str )
-452
View File
@@ -1,452 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
$Header$ (BRL)
*/
/*LINTLIBRARY*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#ifdef BSD
#include <strings.h>
#endif
#ifdef SYSV
#include <string.h>
#endif
#ifndef cray
#if defined( VLDSYSV )
#include <sys/_ioctl.h>
#else
#include <sys/ioctl.h>
#define _winsize winsize /* For compatibility with _ioctl.h. */
#endif
#endif
#include "./Sc.h"
/* Externals from termlib(3). */
#if _STDC_
extern char *tgoto( char *cm, int destcol, int destline );
extern char *tgetstr( char *id, char **area );
extern int tgetent( char *bp, char *name );
#else
extern char *tgoto();
extern char *tgetstr();
extern int tgetent();
#endif
/* Externals from the C library. */
#if _STDC_
extern char *getenv( char *s );
extern char *strncpy( char *a, char *b, int n );
#else
extern char *getenv();
extern char *strncpy();
#endif
static FILE *out_fp; /* Output stream. */
static char tstrings[ScTCAPSIZ]; /* Individual TCS. */
static char *tstr_addr = tstrings; /* Used by tgetstr(). */
static int fd_stdout = 1;
/* This is a global buffer for the terminal capabilities entry. */
char ScTermcap[ScTCAPSIZ];
/* This is a global buffer for the name of the terminal. */
char ScTermname[ScTERMSIZ] = "UNKNOWN";
/* Individual terminal control strings (TCS). */
char *ScBC, /* Backspace character. */
*ScPC, /* Padding character. */
*ScUP, /* Cursor up one line. */
*ScCS, /* Change scrolling region. */
*ScSO, /* Begin standout mode. */
*ScSE, /* End standout mode. */
*ScCE, /* Clear to end of line. */
*ScCL, /* Clear display and home cursor. */
*ScHO, /* Home cursor. */
*ScCM, /* Screen-relative cursor motion. */
*ScTI, /* Initialize terminal. */
*ScAL, /* Insert line. */
*ScDL, /* Delete line. */
*ScSR, /* Scroll text down. */
*ScSF; /* Scroll text up. */
/* Individual terminal parameters. */
int ScLI, /* Number of lines on screen. */
ScCO; /* Number of columns on screen. */
/*
static void ScLoadTP( void )
Get the terminal parameters.
*/
static void
#if _STDC_
ScLoadTP( void )
#else
ScLoadTP()
#endif
{
#ifdef TIOCGWINSZ
/* Get window size for DMD layers support. */
struct _winsize window;
if( ioctl( fd_stdout, TIOCGWINSZ, &window ) == 0
&& window.ws_row != 0 && window.ws_col != 0
)
{
ScLI = (int) window.ws_row;
ScCO = (int) window.ws_col;
}
else
#endif
{
ScLI = tgetnum( "li" );
ScCO = tgetnum( "co" );
}
return;
}
/*
static void ScLoadTCS( void )
Get the terminal control strings.
*/
static void
#if _STDC_
ScLoadTCS( void )
#else
ScLoadTCS()
#endif
{;
ScCS = tgetstr( "cs", &tstr_addr );
ScSE = tgetstr( "se", &tstr_addr );
ScSO = tgetstr( "so", &tstr_addr );
ScCE = tgetstr( "ce", &tstr_addr );
ScCL = tgetstr( "cl", &tstr_addr );
ScHO = tgetstr( "ho", &tstr_addr );
ScCM = tgetstr( "cm", &tstr_addr );
ScBC = tgetstr( "bc", &tstr_addr );
ScPC = tgetstr( "pc", &tstr_addr );
ScUP = tgetstr( "up", &tstr_addr );
ScTI = tgetstr( "ti", &tstr_addr );
ScAL = tgetstr( "al", &tstr_addr );
ScDL = tgetstr( "dl", &tstr_addr );
ScSR = tgetstr( "sr", &tstr_addr );
ScSF = tgetstr( "sf", &tstr_addr );
return;
}
/*
int PutChr( char c )
This function prevents the default "PutChr" from being pulled in
from the termcap library (-ltermlib). DO NOT change its name or
STDOUT will be assumed as the output stream for terminal control.
Some applications might want to open "/dev/tty" so that they can
use STDOUT for something else.
*/
int
#if _STDC_
PutChr( char c )
#else
PutChr( c )
char c;
#endif
{
return putc( c, out_fp );
}
/*
bool ScInit( FILE *fp )
ScInit() must be invoked before any other function in the Sc package.
Stream fp must be open for writing and all terminal control sequences
will be sent to fp, giving the application the option of using STDOUT
for other things. Besides setting the output stream, ScInit() does
the following:
Initializes the terminal. Fills terminal name and capabilities
into external buffers. Gets terminal control strings into external
variables. Gets individual terminal parameters into external
variables. Returns "true" for success, "false" for failure and
prints appropriate diagnostics on STDERR if $TERM is not set or
there is a problem in retrieving the corresponding termcap entry.
*/
bool
#if _STDC_
ScInit( FILE *fp )
#else
ScInit( fp )
FILE *fp;
#endif
{ char *term; /* Name of terminal from environment. */
out_fp = fp;
fd_stdout = fileno( out_fp );
if( (term = getenv( "TERM" )) == NULL )
{
(void) fprintf( stderr, "TERM not set or exported!\n" );
return false;
}
(void) strncpy( ScTermname, term, ScTERMSIZ-1 );
/* Get terminal entry. */
switch( tgetent( ScTermcap, term ) )
{
case -1 :
(void) fprintf( stderr, "Can't open termcap file!\n" );
return false;
case 0 :
(void) fprintf( stderr,
"Terminal type not in termcap file!\n"
);
return false;
}
/* Get individual terminal parameters and control strings. */
ScLoadTP();
ScLoadTCS();
tputs( ScTI, 1, PutChr ); /* Initialize terminal. */
return true; /* All is well. */
}
/*
bool ScClrEOL( void )
Clear from the cursor to the end of that line.
*/
bool
#if _STDC_
ScClrEOL( void )
#else
ScClrEOL()
#endif
{
if( ScCE == NULL )
return false;
tputs( ScCE, 1, PutChr );
return true;
}
/*
bool ScClrScrlReg( void )
Reset the scrolling region to the entire screen.
*/
bool
#if _STDC_
ScClrScrlReg( void )
#else
ScClrScrlReg()
#endif
{
if( ScCS == NULL )
return false;
tputs( tgoto( ScCS, ScLI-1, 0 ), 1, PutChr );
return true;
}
/*
bool ScClrStandout( void )
End standout mode.
*/
bool
#if _STDC_
ScClrStandout( void )
#else
ScClrStandout()
#endif
{
if( ScSE == NULL )
return false;
tputs( ScSE, 1, PutChr );
return true;
}
/* bool ScClrText( void )
Clear the screen and "home" the cursor.
*/
bool
#if _STDC_
ScClrText( void )
#else
ScClrText()
#endif
{
if( ScCL == NULL )
return false;
tputs( ScCL, ScLI, PutChr );
return true;
}
/*
bool ScInsertLn( void )
Insert a the line under the cursor.
*/
bool
#if _STDC_
ScInsertLn( void )
#else
ScInsertLn()
#endif
{
if( ScAL == NULL )
return false;
tputs( ScAL, 1, PutChr );
return true;
}
/*
bool ScDeleteLn( void )
Delete the line under the cursor.
*/
bool
#if _STDC_
ScDeleteLn( void )
#else
ScDeleteLn()
#endif
{
if( ScDL == NULL )
return false;
tputs( ScDL, 1, PutChr );
return true;
}
/*
bool ScDnScroll( void )
Scroll backward 1 line.
*/
bool
#if _STDC_
ScDnScroll( void )
#else
ScDnScroll()
#endif
{
if( ScSR == NULL )
return false;
tputs( ScSR, 1, PutChr );
return true;
}
/*
bool ScHmCursor( void )
Move the cursor to the top-left corner of the screen.
*/
bool
#if _STDC_
ScHmCursor( void )
#else
ScHmCursor()
#endif
{
if( ScHO == NULL )
return false;
tputs( ScHO, 1, PutChr );
return true;
}
/*
bool ScMvCursor( int x, int y )
Move the cursor to screen coordinates x, y (for column and row,
respectively).
*/
bool
#if _STDC_
ScMvCursor( int x, int y )
#else
ScMvCursor( x, y )
int x, y;
#endif
{
if( ScCM == NULL )
return false;
--x; --y; /* Tgoto() adds 1 to each coordinate!? */
tputs( tgoto( ScCM, x, y ), 1, PutChr );
return true;
}
/*
bool ScSetScrlReg( int top, int btm )
Set the scrolling region to be from "top" line to "btm" line,
inclusive.
*/
bool
#if _STDC_
ScSetScrlReg( int top, int btm )
#else
ScSetScrlReg( top, btm )
int top, btm;
#endif
{
if( ScCS == NULL )
return false;
tputs( tgoto( ScCS, btm-1, top-1 ), 1, PutChr );
return true;
}
/*
bool ScSetStandout( void )
Begin standout mode.
*/
bool
#if _STDC_
ScSetStandout( void )
#else
ScSetStandout()
#endif
{
if( ScSO == NULL )
return false;
tputs( ScSO, 1, PutChr );
return true;
}
/*
bool ScUpScroll( void )
Scroll text forward 1 line.
*/
bool
#if _STDC_
ScUpScroll( void )
#else
ScUpScroll()
#endif
{
if( ScSF == NULL )
return false;
tputs( ScSF, 1, PutChr );
return true;
}
-173
View File
@@ -1,173 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
$Header$ (BRL)
*/
/**
<Sc.h> -- MUVES "Sc" (Screen manager) package definitions
**/
/**
The Sc package provides an interface to the termcap library
(termlib(3)) for doing cursor movement, character attribute,
and other low-level screen management operations. It is
intended for use in building terminal-independent full-screen
user interfaces. Do to its use of the tgoto() termlib(3)
routine, programs that use this package should turn off TAB3
in the terminal handler.
**/
#ifndef Sc_H_INCLUDE
#define Sc_H_INCLUDE
#include "burst.h"
/**
bool ScInit( FILE *fp )
ScInit() must be invoked before any other function in the Sc
package. Stream fp must be open for writing and all terminal
control sequences will be sent to fp, giving the application
the option of using STDOUT for other things. Besides setting
the output stream, ScInit() does the following:
Initializes the terminal.
Fills terminal name and capabilities into these externals:
char ScTermname[ScTERMSIZ] (terminal name from $TERM)
char ScTermcap[ScTCAPSIZ] (terminal capabilities entry)
Gets terminal control strings into external variables (here
are some that don't have individual functions to output them,
the ones that DO are below):
char *ScBC (backspace character)
char *ScPC (padding character)
char *ScUP (move the cursor up one line)
char *ScTI (initialize the terminal)
Gets individual terminal parameters into these externals:
int ScLI (number of lines on screen)
int ScCO (number of columns on screen)
Returns "true" for success, "false" for failure and prints
appropriate diagnostics on STDERR if $TERM is not set or
there is a problem in retrieving the corresponding termcap
entry.
**/
#if _STDC_
extern bool ScInit( FILE *fp );
#else
extern bool ScInit();
#endif
/**
Below are functions paired with terminal control strings that
they output to the stream specified with ScInit(). It is not
recommended that the control strings be used directly, but it
may be useful in certain applications to check their value;
if ScInit() has not been invoked or the corresponding terminal
capability does not exist, its control string will be NULL,
AND the function will return "false". Otherwise, they will
return "true" (assuming that it worked). There is no way to
be sure of this.
char *ScCE (clear from under the cursor to end of line)
bool ScClrEOL( void )
char *ScCS (change scrolling region)
bool ScClrScrlReg( void )
char *ScSE (end standout mode)
bool ScClrStandout( void )
char *ScCL (clear screen, and home cursor)
bool ScClrText( void )
char *ScAL (insert a line under the cursor)
bool ScInsertLn( void )
char *ScDL (delete the line under the cursor)
bool ScDeleteLn( void )
char *ScSR (scroll text backwards 1 line)
bool ScDnScroll( void )
char *ScHO (move cursor to top-left corner of screen)
bool ScHmCursor( void )
char *ScCM (move cursor to column and row <x,y>)
bool ScMvCursor( x, y )
char *ScCS (set scrolling region from top to btm incl.)
bool ScSetScrlReg( top, btm )
char *ScSO (begin standout mode)
bool ScSetStandout( void )
char *ScSF (scroll text forwards 1 line)
bool ScUpScroll( void )
**/
extern char *ScBC;
extern char *ScPC;
extern char *ScUP;
extern char *ScCS;
extern char *ScSO;
extern char *ScSE;
extern char *ScCE;
extern char *ScCL;
extern char *ScHO;
extern char *ScCM;
extern char *ScTI;
extern char *ScDL;
extern char *ScSR;
extern char *ScSF;
extern int ScLI;
extern int ScCO;
#if _STDC_
extern bool ScClrEOL( void );
extern bool ScClrScrlReg( void );
extern bool ScClrStandout( void );
extern bool ScClrText( void );
extern bool ScDeleteLn( void );
extern bool ScDnScroll( void );
extern bool ScHmCursor( void );
extern bool ScInsertLn( void );
extern bool ScMvCursor( int x, int y );
extern bool ScSetScrlReg( int top, int btm );
extern bool ScSetStandout( void );
extern bool ScUpScroll( void );
#else
extern bool ScClrEOL();
extern bool ScClrScrlReg();
extern bool ScClrStandout();
extern bool ScClrText();
extern bool ScDeleteLn();
extern bool ScDnScroll();
extern bool ScHmCursor();
extern bool ScInsertLn();
extern bool ScMvCursor();
extern bool ScSetScrlReg();
extern bool ScSetStandout();
extern bool ScUpScroll();
#endif
#define ScTCAPSIZ 1024
#define ScTERMSIZ 80
extern char ScTermcap[];
extern char ScTermname[];
#endif /* Sc_H_INCLUDE */
-384
View File
@@ -1,384 +0,0 @@
/*
SCCS id: %Z% %M% %I%
Modified: %G% at %U%
Retrieved: %H% at %T%
SCCS archive: %P%
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
*/
/*LINTLIBRARY*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
static char sccsTag[] = "%Z% %M% %I%, modified %G% at %U%, archive %P%";
#endif
#include <stdio.h>
#include <fcntl.h>
#ifdef SYSV
/**#ifndef TANDEM /* USG derivatives */
#include <termio.h>
#include <memory.h>
#ifndef _NFILE
#define _NFILE 32
#endif _NFILE
static struct termio save_tio[_NFILE], curr_tio[_NFILE];
#endif SYSV
#ifdef BSD
#include <sys/ioctl.h>
#ifndef _NFILE
#define _NFILE 32
#endif _NFILE
/****#ifdef TANDEM /* 7th Edition derivatives */
#define TCSETA TIOCSETP
#define TCGETA TIOCGETP
#ifndef XTABS
#define XTABS (TAB1 | TAB2)
#endif XTABS
static struct sgttyb save_tio[_NFILE], curr_tio[_NFILE];
#endif BSD
void TcSaveTty(), TcResetTty();
void TcSetCbreak(), TcClrCbreak();
void TcSetRaw(), TcClrRaw();
void TcSetEcho(), TcClrEcho();
void TcSetTabs(), TcClrTabs();
void TcSetHUPCL();
void TcClrCRNL();
void prnt_Tio();
static void copy_Tio();
/*
void TcClrCbreak( int fd )
Clear CBREAK mode, for file descriptor "fd".
*/
void
#if _STDC_
TcClrCbreak( int fd )
#else
TcClrCbreak( fd )
int fd;
#endif
{
#ifdef BSD
curr_tio[fd].sg_flags &= ~CBREAK; /* CBREAK mode OFF. */
#else
curr_tio[fd].c_lflag |= ICANON; /* Canonical input ON. */
#ifndef CRAY2
curr_tio[fd].c_cc[VEOF] = 4; /* defaults! */
curr_tio[fd].c_cc[VEOL] = 0; /* best we can do.... */
#endif
#endif
(void) ioctl( fd, TCSETA, &curr_tio[fd] );
return;
}
/*
void TcSetCbreak( int fd )
Set CBREAK mode, "fd".
*/
void
#if _STDC_
TcSetCbreak( int fd )
#else
TcSetCbreak( fd )
int fd;
#endif
{
#ifdef BSD
curr_tio[fd].sg_flags |= CBREAK; /* CBREAK mode ON. */
#else
curr_tio[fd].c_lflag &= ~ICANON; /* Canonical input OFF. */
#ifndef CRAY2
curr_tio[fd].c_cc[VMIN] = 1;
curr_tio[fd].c_cc[VTIME] = 0;
#endif
#endif
(void) ioctl( fd, TCSETA, &curr_tio[fd] );
return;
}
/*
void TcClrRaw( int fd )
Set cooked mode, "fd".
*/
void
clr_Raw( fd )
int fd;
{
#ifdef BSD
curr_tio[fd].sg_flags &= ~RAW; /* Raw mode OFF. */
#else
curr_tio[fd].c_lflag |= ICANON; /* Canonical input ON. */
#ifndef CRAY2
curr_tio[fd].c_lflag |= ISIG; /* Signals ON. */
curr_tio[fd].c_cc[VEOF] = 4; /* defaults! */
curr_tio[fd].c_cc[VEOL] = 0; /* best we can do.... */
#endif
#endif
(void) ioctl( fd, TCSETA, &curr_tio[fd] );
return;
}
/*
void TcSetRaw( int fd )
Set raw mode, "fd".
*/
void
#if _STDC_
TcSetRaw( int fd )
#else
TcSetRaw( fd )
int fd;
#endif
{
#ifdef BSD
curr_tio[fd].sg_flags |= RAW; /* Raw mode ON. */
#else
curr_tio[fd].c_lflag &= ~ICANON; /* Canonical input OFF. */
#ifndef CRAY2
curr_tio[fd].c_lflag &= ~ISIG; /* Signals OFF. */
curr_tio[fd].c_cc[VMIN] = 1;
curr_tio[fd].c_cc[VTIME] = 0;
#endif
#endif
(void) ioctl( fd, TCSETA, &curr_tio[fd] );
return;
}
/*
void TcSetEcho( int fd )
Set echo mode, "fd".
*/
void
#if _STDC_
TcSetEcho( int fd )
#else
TcSetEcho( fd )
int fd;
#endif
{
#ifdef BSD
curr_tio[fd].sg_flags |= ECHO; /* Echo mode ON. */
#else
curr_tio[fd].c_lflag |= ECHO; /* Echo mode ON. */
#endif
(void) ioctl( fd, TCSETA, &curr_tio[fd] );
return;
}
/*
void TcClrEcho( int fd )
Clear echo mode, "fd".
*/
void
#if _STDC_
TcClrEcho( int fd )
#else
TcClrEcho( fd )
int fd;
#endif
{
#ifdef BSD
curr_tio[fd].sg_flags &= ~ECHO; /* Echo mode OFF. */
#else
curr_tio[fd].c_lflag &= ~ECHO; /* Echo mode OFF. */
#endif
(void) ioctl( fd, TCSETA, &curr_tio[fd] );
return;
}
/*
void TcSetTabs( int fd )
Turn on tab expansion, "fd".
*/
void
#if _STDC_
TcSetTabs( int fd )
#else
TcSetTabs( fd )
int fd;
#endif
{
#ifdef BSD
curr_tio[fd].sg_flags |= XTABS; /* Tab expansion ON. */
#else
#ifndef CRAY2
curr_tio[fd].c_oflag |= TAB3; /* Tab expansion ON. */
#endif
#endif
(void) ioctl( fd, TCSETA, &curr_tio[fd] );
return;
}
/*
void TcClrTabs( int fd )
Turn off tab expansion, "fd".
*/
void
#if _STDC_
TcClrTabs( int fd )
#else
TcClrTabs( fd )
int fd;
#endif
{
#ifdef BSD
curr_tio[fd].sg_flags &= ~XTABS; /* Tab expans. OFF. */
#else
#ifndef CRAY2
curr_tio[fd].c_oflag &= ~TAB3; /* Tab expans. OFF. */
#endif
#endif
(void) ioctl( fd, TCSETA, &curr_tio[fd] );
return;
}
/*
void TcSetHUPCL( int fd )
Turn on "Hang up on last close", "fd".
*/
void
#if _STDC_
TcSetHUPCL( int fd )
#else
TcSetHUPCL( fd )
int fd;
#endif
{
#ifndef CRAY2
#ifdef BSD
(void) ioctl( fd, TIOCHPCL, NULL );
#else
curr_tio[fd].c_cflag |= HUPCL;
(void) ioctl( fd, TCSETA, &curr_tio[fd] );
#endif
#endif
return;
}
/*
void TcClrCRNL( int fd )
Turn off CR/LF mapping, "fd".
*/
void
#if _STDC_
TcClrCRNL( int fd )
#else
TcClrCRNL( fd )
#endif
{
#ifdef BSD
curr_tio[fd].sg_flags &= ~CRMOD;
#else
#ifndef CRAY2
curr_tio[fd].c_oflag &= ~(ONLCR|OCRNL);
curr_tio[fd].c_iflag &= ~(ICRNL|INLCR);
#endif
#endif
(void) ioctl( fd, TCSETA, &curr_tio[fd] );
}
/*
void TcSaveTty( int fd )
Get and save terminal parameters, "fd".
*/
void
#if _STDC_
TcSaveTty( int fd )
#else
TcSaveTty( fd )
int fd;
#endif
{
(void) ioctl( fd, TCGETA, &save_tio[fd] );
copy_Tio( &curr_tio[fd], &save_tio[fd] );
return;
}
/*
void TcResetTty( int fd )
Set the terminal back to the mode that the user had last time
TcSaveTty() was called for "fd".
*/
void
#if _STDC_
TcResetTty( int fd )
#else
TcResetTty( fd )
int fd;
#endif
{
(void) ioctl( fd, TCSETA, &save_tio[fd] ); /* Write setting. */
return;
}
/* c o p y _ T i o ( ) */
static void
copy_Tio( to, from )
#ifdef BSD
struct sgttyb *to, *from;
#else
struct termio *to, *from;
#endif
{
#ifdef BSD
(void) bcopy( (char *)from, (char*)to, sizeof(struct sgttyb) );
#else
(void) memcpy( (char *) to, (char *) from, (int) sizeof(struct termio) );
#endif
return;
}
/* p r n t _ T i o ( ) */
void
prnt_Tio( msg, tio_ptr )
char *msg;
#ifdef BSD
struct sgttyb *tio_ptr;
#else
struct termio *tio_ptr;
#endif
{ register int i;
(void) fprintf( stderr, "%s :\n\r", msg );
#ifdef BSD
(void) fprintf( stderr, "\tsg_ispeed=%d\n\r", (int) tio_ptr->sg_ispeed );
(void) fprintf( stderr, "\tsg_ospeed=%d\n\r", (int) tio_ptr->sg_ospeed );
(void) fprintf( stderr, "\tsg_erase='%c'\n\r", tio_ptr->sg_erase );
(void) fprintf( stderr, "\tsg_kill='%c'\n\r", tio_ptr->sg_kill );
(void) fprintf( stderr, "\tsg_flags=0x%x\n\r", tio_ptr->sg_flags );
#else
(void) fprintf( stderr, "\tc_iflag=0x%x\n\r", tio_ptr->c_iflag );
(void) fprintf( stderr, "\tc_oflag=0x%x\n\r", tio_ptr->c_oflag );
(void) fprintf( stderr, "\tc_cflag=0x%x\n\r", tio_ptr->c_cflag );
(void) fprintf( stderr, "\tc_lflag=0x%x\n\r", tio_ptr->c_lflag );
(void) fprintf( stderr, "\tc_line=%c\n\r", tio_ptr->c_line );
for( i = 0; i < NCC; ++i )
{
(void) fprintf( stderr,
"\tc_cc[%d]=0%o\n\r",
i,
tio_ptr->c_cc[i]
);
}
#endif
return;
}
-93
View File
@@ -1,93 +0,0 @@
/*
SCCS id: %Z% %M% %I%
Modified: %G% at %U%
Retrieved: %H% at %T%
SCCS archive: %P%
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
*/
/**
<Tc.h> -- MUVES "Tc" (terminal control) package definitions
**/
/**
The Tc package provides an interface to the terminal handler
for controlling I/O processing.
**/
#ifndef Tc_H_INCLUDE
#define Tc_H_INCLUDE
/**
All of these functions take effect on the stream specified
by fd. Fd is assumed to be open. This enables the application
to control several terminal-style devices at once.
void TcSaveTty( int fd )
Saves the current terminal modes. This function should be
called once at the beginning of the program to save the user's
settings so that they can be restored via TcResetTty() when the
program exits, is suspended via job control, or for whatever
reason wishes to revert to the default terminal handler settings.
void TcResetTty( int fd ) restore the terminal modes
void TcClrCRNL( int fd ) turn off CR to NL mapping
void TcClrCbreak( int fd ) turn off cbreak mode
void TcClrEcho( int fd ) turn off echo mode
void TcClrRaw( int fd ) turn off raw mode
void TcClrTabs( int fd ) turn off tab expansion
void TcSetCbreak( int fd ) turn on cbreak mode
void TcSetEcho( int fd ) turn on echo mode
void TcSetHUPCL( int fd ) turn on "hang up on next close"
void TcSetRaw( int fd ) turn on raw mode
void TcSetTabs( int fd ) turn on tab expansion
**/
#if _STDC_
extern void TcClrCRNL( int fd );
extern void TcClrCbreak( int fd );
extern void TcClrEcho( int fd );
extern void TcClrRaw( int fd );
extern void TcClrTabs( int fd );
extern void TcResetTty( int fd );
extern void TcSaveTty( int fd );
extern void TcSetCbreak( int fd );
extern void TcSetEcho( int fd );
extern void TcSetHUPCL( int fd );
extern void TcSetRaw( int fd );
extern void TcSetTabs( int fd );
#else
extern void TcClrCRNL();
extern void TcClrCbreak();
extern void TcClrEcho();
extern void TcClrRaw();
extern void TcClrTabs();
extern void TcResetTty();
extern void TcSaveTty();
extern void TcSetCbreak();
extern void TcSetEcho();
extern void TcSetHUPCL();
extern void TcSetRaw();
extern void TcSetTabs();
#endif
#endif /* Tc_H_INCLUDE */
-35
View File
@@ -1,35 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
$Header$
*/
#define NUL '\000'
#define SOH '\001'
#define STX '\002'
#define INTR '\003'
#define EOT '\004'
#define ACK '\006'
#define BEL '\007'
#define BS '\010'
#define HT '\011'
#define LF '\012'
#define FF '\014'
#define CR '\015'
#define DLE '\020'
#define DC1 '\021'
#define DC2 '\022'
#define DC3 '\023'
#define DC4 '\024'
#define KILL '\025'
#define CAN '\030'
#define ESC '\033'
#define GS '\035'
#define RS '\036'
#define US '\037'
#define SP '\040'
#define DEL '\177'
#define Ctrl(chr) ((int)chr&037)
-267
View File
@@ -1,267 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#ifndef DEBUG
#define NDEBUG
#define STATIC static
#else
#define STATIC
#endif
#include <assert.h>
#include <stdio.h>
#include <signal.h>
#include "./burst.h"
#include "./trie.h"
#include "./ascii.h"
#include "./extern.h"
#define DEBUG_BURST 0 /* 1 enables debugging for this module */
/*
bool getCommand( char *name, char *buf, int len, FILE *fp )
Read next command line into buf and stuff the command name into name
from input stream fp. buf must be at least len bytes long.
RETURN: true for success
false for end of file
*/
STATIC bool
#if STD_C
getCommand( char *name, char *buf, int len, FILE *fp )
#else
getCommand( name, buf, len, fp )
char *name;
char *buf;
int len;
FILE *fp;
#endif
{
assert( name != NULL );
assert( buf != NULL );
assert( fp != NULL );
while( fgets( buf, len, fp ) != NULL )
{
if( buf[0] != CHAR_COMMENT )
{
if( sscanf( buf, "%s", name ) == 1 )
{
buf[strlen(buf)-1] = NUL; /* clobber newline */
return true;
}
else /* Skip over blank lines. */
continue;
}
else
{ /* Generate comment command. */
(void) strcpy( name, CMD_COMMENT );
return true;
}
}
return false; /* EOF */
}
/*
void setupSigs( void )
Initialize all signal handlers.
*/
STATIC void
#if STD_C
setupSigs( void )
#else
setupSigs()
#endif
{ register int i;
for( i = 0; i < NSIG; i++ )
switch( i )
{
case SIGINT :
if( (norml_sig = signal( i, SIG_IGN )) == SIG_IGN )
abort_sig = SIG_IGN;
else
{
norml_sig = intr_sig;
abort_sig = abort_RT;
(void) signal( i, norml_sig );
}
break;
#if defined( BSD )
case SIGCHLD :
#else
case SIGCLD :
#endif
break; /* leave SIGCLD alone */
case SIGPIPE :
(void) signal( i, SIG_IGN );
break;
case SIGQUIT :
break;
#if ! defined( SYSV )
#if ! defined( SIGTSTP )
#define SIGTSTP 18
#endif
case SIGTSTP :
break;
#endif
}
return;
}
/*
int parsArgv( int argc, char **argv )
Parse program command line.
*/
STATIC int
#if STD_C
parsArgv( int argc, char **argv )
#else
parsArgv( argc, argv )
int argc;
char **argv;
#endif
{ register int c;
extern int optind;
extern char *optarg;
/* Parse options. */
while( (c = getopt( argc, argv, "b" )) != EOF )
{
switch( c )
{
case 'b' :
tty = false;
break;
case '?' :
return 0;
}
}
return true;
}
/*
void readBatchInput( FILE *fp )
Read and execute commands from input stream fp.
*/
void
#if STD_C
readBatchInput( FILE *fp )
#else
readBatchInput( fp )
FILE *fp;
#endif
{
assert( fp != (FILE *) NULL );
batchmode = true;
while( getCommand( cmdname, cmdbuf, LNBUFSZ, fp ) )
{ Func *cmdfunc;
if( (cmdfunc = getTrie( cmdname, cmdtrie )) == NULL )
{ register int i, len = strlen( cmdname );
rt_log( "ERROR -- command syntax:\n" );
rt_log( "\t%s\n", cmdbuf );
rt_log( "\t" );
for( i = 0; i < len; i++ )
rt_log( " " );
rt_log( "^\n" );
}
else
if( strcmp( cmdname, CMD_COMMENT ) == 0 )
{ /* special handling for comments */
cmdptr = cmdbuf;
cmdbuf[strlen(cmdbuf)-1] = '\0'; /* clobber newline */
(*cmdfunc)( (HmItem *) 0 );
}
else
{ /* Advance pointer past nul at end of
command name. */
cmdptr = cmdbuf + strlen( cmdname ) + 1;
(*cmdfunc)( (HmItem *) 0 );
}
}
batchmode = false;
return;
}
/*
int main( int argc, char *argv[] )
*/
int
#if STD_C
main( int argc, char *argv[] )
#else
main( argc, argv )
int argc;
char *argv[];
#endif
{
#if ! defined( BSD ) && ! defined( sgi )
setvbuf( stderr, (char *) NULL, _IOLBF, BUFSIZ );
#endif
if( tmpnam( tmpfname ) == NULL
|| (tmpfp = fopen( tmpfname, "w" )) == (FILE *) NULL
)
{
perror( tmpfname );
(void) fprintf( stderr,
"Write access denied for file (%s).\n",
tmpfname );
goto death;
}
if( ! parsArgv( argc, argv ) )
{
prntUsage();
goto clean;
}
setupSigs();
if( ! initUi() ) /* must be called before any output is produced */
goto clean;
#if DEBUG_BURST
prntTrie( cmdtrie, 0 );
#endif
assert( airids.i_next == NULL );
assert( armorids.i_next == NULL );
assert( critids.i_next == NULL );
if( ! isatty( 0 ) || ! tty )
readBatchInput( stdin );
if( tty )
(void) HmHit( mainhmenu );
exitCleanly( EXIT_SUCCESS );
clean: (void) unlink( tmpfname );
death: return EXIT_FAILURE;
}
/*
void exitCleanly( int code )
Should be only exit from program after success of initUi().
*/
void
#if STD_C
exitCleanly( int code )
#else
exitCleanly( code )
int code;
#endif
{
if( tty )
closeUi(); /* keep screen straight */
(void) fclose( tmpfp );
if( unlink( tmpfname ) == -1 )
locPerror( tmpfname );
exit( code );
}
-84
View File
@@ -1,84 +0,0 @@
Shotline file output format from burst program:
record type: 1
description: header line for each aspect
ICD reference: Line Number 1, Figure 19.
format: '1',2(1x,f8.4),5(1x,f7.2),1x,6a
data: attack azimuth in degrees
attack elevation in degrees
shotline separation
maximum Y'-coordinate of target
minimum Y'-coordinate of target
maximum Z'-coordinate of target
minimum Z'-coordinate of target
units (mm,cm,inches,feet,meters)
record type: 2
description: information about shotline
format: '2',2(1x,f8.3)
data: horizontal coordinate of shotline in grid plane (Y')
vertical coordinate of shotline in grid plane (Z')
record type: 3
description: information about component intersected by shotline
format: '3',1x,f8.2,1x,f7.3,1x,f7.2,1x,i4,2(1x,f8.2),1x,i2,2(1x,f7.2)
data: X'-coordinate of intersection with component
sine of fallback angle of component exit normal
rotation angle in degrees of exit normal
component code number
normal thickness of component
line-of-sight thickness of component
space code following component
obliquity angle at entry to component in degrees
obliquity angle at exit from component in degrees
Burst Point Library output format from burst program:
record type: 1
description: header line for each aspect
ICD reference: Line Number 1, Figure 20.
format: '1',2(1x,f8.4),1x,f5.2,1x,f10.2,1x,6a,1x,f9.6
data: attack azimuth in degrees
attack elevation in degrees
burst distance
projected area associated with burst point
units (mm,cm,inches,feet,meters)
solid angle of each ray in steradians
record type: 2
description: information about shotline
ICD reference: Line Number 2, Figure 20.
format: '2',2(1x,f8.3) [format of record type '4' compatible]
data: horizontal coordinate of shotline in grid plane (Y')
vertical coordinate of shotline in grid plane (Z')
record type: 3
description: information about component intersected by shotline
ICD reference: Line Number 3, Figure 20.
format: '3',2(1x,f8.2),1x,i4,1x,i2,1x,f7.3,1x,f7.2,1x,f7.3
data: X'-coordinate of intersection with component
line-of-sight thickness of component
component code number
space code
sine of fallback angle of component exit normal
rotation angle in degrees of component exit normal
cosine of obliquity angle at entry to component
record type: 4
description: information about burst ray
ICD reference: Line Number 19, Figure 20.
format: '4',2(1x,f8.3),1x,i6 [format of record type '2' compatible]
data: ray azimuth angle WRT shotline in radians
sine of ray elevation angle WRT shotline
sequential ray number for this burst point
record type: 5
description: information about component intersected by burst ray
ICD reference: Line Number 20, Figure 20.
format: '5',1x,f10.3,2(1x,f9.3),2(1x,i4),1x,f6.3
data: distance to first contact with component from burst point
line-of-sight thickness of component
normal thickness of component
space code
component code number
cosine of obliquity angle at entry
-271
View File
@@ -1,271 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
$Header$ (BRL)
*/
#ifndef INCL_BURST
#define INCL_BURST
/* Some useful stuff from Doug Gwyn's std.h. */
/* Extended data types */
typedef int bool; /* Boolean data */
#define false 0
#define true 1
/* ANSI C definitions */
/* Defense against some silly systems defining __STDC__ to random things. */
#ifdef STD_C
#undef STD_C
#endif
#ifdef __STDC__
#if __STDC__ > 0
#define STD_C __STDC__ /* use this instead of __STDC__ */
#endif
#endif
#if STD_C
typedef void *pointer; /* generic pointer */
#else
typedef char *pointer; /* generic pointer */
#define const /* nothing */ /* ANSI C type qualifier */
/* There really is no substitute for the following, but these might work: */
#define signed /* nothing */ /* ANSI C type specifier */
#define volatile /* nothing */ /* ANSI C type qualifier */
#endif
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
#ifndef EXIT_FAILURE
#define EXIT_FAILURE 1
#endif
#define DEGRAD 57.2957795130823208767981548141051703324054724665642
/* allow for SGI screw-up, the single-precision math libraries */
#if defined( sgi ) && ! defined( mips )
#define SINGLE_PRECISION 1
#else
#define SINGLE_PRECISION 0
#endif
/* allow for SGI screw-up, winclose() dumps core on some systems */
#if defined(SGI4D_Rel2)
#define SGI_WINCLOSE_BUG 1
#else
#define SGI_WINCLOSE_BUG 0
#endif
/* allow for BSD screw-up, declaring signal handlers as 'int' functions */
#if STD_C || (defined(SYSV) && ! defined(cray))
#define STD_SIGNAL_DECLS 1
#else
#define STD_SIGNAL_DECLS 0
#endif
/* menu configuration */
#define MENU_LFT 1
#define MENU_TOP 2
#define MENU_MAXVISITEMS 10
/* prompt line configuration */
#define PROMPT_X HmXPROMPT
#define PROMPT_Y HmYPROMPT
/* banner (border) configuration */
#define BORDER_CHR '_'
#define BORDER_Y (PROMPT_Y+1)
/* grid offset printing window */
#define GRID_X 55 /* where grid indices are printed */
#define GRID_Y BORDER_Y
/* scroll region configuration */
#define SCROLL_TOP (BORDER_Y+1)
#define SCROLL_BTM (ScLI-1) /* bottom line causes scroll */
/* timer (cpu statistics) window configuration */
#define TIMER_X 1
#define TIMER_Y 1
/* buffer sizes */
#define LNBUFSZ 133 /* buffer for one-line messages */
#define MAXDEVWID 1024 /* maximum width of frame buffer */
#define CHAR_COMMENT '#'
#define CMD_COMMENT "comment"
/* default parameters */
#define DFL_AZIMUTH 0.0
#define DFL_BARRIERS 100
#define DFL_BDIST 0.0
#define DFL_CELLSIZE 101.6
#define DFL_CONEANGLE (45.0/DEGRAD)
#define DFL_DEFLECT false
#define DFL_DITHER false
#define DFL_ELEVATION 0.0
#define DFL_NRAYS 200
#define DFL_OVERLAPS true
#define DFL_RIPLEVELS 1
#define DFL_UNITS U_MILLIMETERS
/* firing mode bit definitions */
#define ASNBIT(w,b) (w = (b))
#define SETBIT(w,b) (w |= (b))
#define CLRBIT(w,b) (w &= ~(b))
#define TSTBIT(w,b) ((w)&(b))
#define FM_GRID 0 /* generate grid of shotlines */
#define FM_DFLT FM_GRID
#define FM_PART (1) /* bit 0: ON = partial envelope, OFF = full */
#define FM_SHOT (1<<1) /* bit 1: ON = discrete shots, OFF = gridding */
#define FM_FILE (1<<2) /* bit 2: ON = file input, OFF = direct input */
#define FM_3DIM (1<<3) /* bit 3: ON = 3-D coords., OFF = 2-D coords */
#define FM_BURST (1<<4) /* bit 4: ON = discrete burst points, OFF = shots */
/* flags for notify() */
#define NOTIFY_APPEND 1
#define NOTIFY_DELETE 2
#define NOTIFY_ERASE 4
#define NOTIFY_DELIM ':'
#define PB_ASPECT_INIT '1'
#define PB_CELL_IDENT '2'
#define PB_RAY_INTERSECT '3'
#define PB_RAY_HEADER '4'
#define PB_REGION_HEADER '5'
#define PS_ASPECT_INIT '1'
#define PS_CELL_IDENT '2'
#define PS_SHOT_INTERSECT '3'
#define TITLE_LEN 72
#define TIMER_LEN 72
#define U_INCHES 0
#define U_FEET 1
#define U_MILLIMETERS 2
#define U_CENTIMETERS 3
#define U_METERS 4
#define U_BAD -1
#define UNITS_INCHES "inches"
#define UNITS_FEET "feet"
#define UNITS_MILLIMETERS "millimeters"
#define UNITS_CENTIMETERS "centimeters"
#define UNITS_METERS "meters"
/* white space in input tokens */
#define WHITESPACE " \t"
/* colors for UNIX plot files */
#define R_GRID 255 /* grid - yellow */
#define G_GRID 255
#define B_GRID 0
#define R_BURST 255 /* burst cone - red */
#define G_BURST 0
#define B_BURST 0
#define R_OUTAIR 100 /* outside air - light blue */
#define G_OUTAIR 100
#define B_OUTAIR 255
#define R_INAIR 100 /* inside air - light green */
#define G_INAIR 255
#define B_INAIR 100
#define R_COMP 0 /* component (default) - blue */
#define G_COMP 0
#define B_COMP 255
#define R_CRIT 255 /* critical component (default) - purple */
#define G_CRIT 0
#define B_CRIT 255
#define C_MAIN 0
#define C_CRIT 1
#define TWO_PI 6.28318530717958647692528676655900576839433879875022
#define COS_TOL 0.01
#define LOS_TOL 0.1
#define VEC_TOL 0.001
#define OVERLAP_TOL 0.25 /* thinner overlaps not reported */
#define EXIT_AIR 9 /* exit air is called 09 air */
#define OUTSIDE_AIR 1 /* outside air is called 01 air */
#define Air(rp) ((rp)->reg_aircode > 0)
#define DiffAir(rp,sp) ((rp)->reg_aircode != (sp)->reg_aircode)
#define SameAir(rp,sp) ((rp)->reg_aircode == (sp)->reg_aircode)
#define SameCmp(rp,sp) ((rp)->reg_regionid == (sp)->reg_regionid)
#define OutsideAir(rp) ((rp)->reg_aircode == OUTSIDE_AIR)
#define InsideAir(rp) (Air(rp)&& !OutsideAir(rp))
#define Check_Iflip( _pp, _normal, _rdir )\
{ fastf_t f;\
if( _pp->pt_inflip )\
{\
ScaleVec( _normal, -1.0 );\
_pp->pt_inflip = 0;\
}\
f = Dot( _rdir, _normal );\
if( f >= 0.0 )\
{\
ScaleVec( _normal, -1.0 );\
rt_log( "Fixed flipped entry normal\n" );\
}\
}
#define Check_Oflip( _pp, _normal, _rdir )\
{ fastf_t f;\
if( _pp->pt_outflip )\
{\
ScaleVec( _normal, -1.0 );\
_pp->pt_outflip = 0;\
}\
f = Dot( _rdir, _normal );\
if( f <= 0.0 )\
{\
ScaleVec( _normal, -1.0 );\
rt_log( "Fixed flipped exit normal\n" );\
}\
}
#define Malloc_Bomb( _bytes_ ) \
rt_log( "\"%s\"(%d) : allocation of %d bytes failed.\n",\
__FILE__, __LINE__, _bytes_ )
#define Swap_Doubles( a_, b_ ) \
{ fastf_t f_ = a_; \
a_ = b_; \
b_ = f_; \
}
#define Toggle(f) (f) = !(f)
typedef struct ids Ids;
struct ids
{
short i_lower;
short i_upper;
Ids *i_next;
};
#define IDS_NULL (Ids *) 0
typedef struct colors Colors;
struct colors
{
short c_lower;
short c_upper;
unsigned char c_rgb[3];
Colors *c_next;
};
#define COLORS_NULL (Colors *) 0
typedef struct pt_queue Pt_Queue;
struct pt_queue
{
struct partition *q_part;
Pt_Queue *q_next;
};
#define PT_Q_NULL (Pt_Queue *) 0
#endif /* INCL_BURST */
-117
View File
@@ -1,117 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
/*
* E R R O R
*
* Ray Tracing library and Framebuffer library, error handling routines.
*
* Functions -
* rt_bomb Called upon fatal RT library error.
* rt_log Called to log RT library events.
* fb_log Called to log FB library events.
*
* Idea originated by Mike John Muuss
*/
#include <stdio.h>
#include <varargs.h>
#include "./Sc.h"
#include "./extern.h"
/*
* R T _ B O M B
*
* Abort the RT library
*/
void
rt_bomb(str)
char *str;
{
rt_log( "%s (librt.a) : Fatal error, aborting!\n", str );
(void) fflush( stdout );
(void) abort(); /* Should dump. */
exit(12);
}
/*
* R T _ L O G
*
* Log an RT library event
*/
/* VARARGS */
void
rt_log( va_alist )
va_dcl
{ register char *format; /* picked up by va_arg() */
va_list ap;
va_start( ap );
format = va_arg( ap, char * );
if( tty && (errfile[0] == '\0' || ! strcmp( errfile, "/dev/tty" )) )
{
TcClrTabs( HmTtyFd );
if( ScDL != NULL )
{
(void) ScMvCursor( 1, SCROLL_TOP );
(void) ScDeleteLn();
(void) ScMvCursor( 1, SCROLL_BTM );
(void) ScClrEOL();
(void) vprintf( format, ap );
}
else
if( ScSetScrlReg( SCROLL_TOP, SCROLL_BTM+1 ) )
{ char buf[LNBUFSZ];
char *p;
(void) ScMvCursor( 1, SCROLL_BTM+1 );
(void) ScClrEOL();
/* Work around for problem with vprintf(): it doesn't
cause the screen to scroll, don't know why. */
(void) vsprintf( buf, format, ap );
/* Newline will cause double scroll. */
p = buf+strlen(buf)-1;
if( *p == '\n' )
*p = '\0'; /* clobber newline */
(void) puts( buf );
/*(void) vprintf( format, ap );*/
(void) ScMvCursor( 1, SCROLL_BTM+1 );
(void) ScClrScrlReg();
}
else
{
(void) fprintf( stderr,
"%s %s %s %s!\n",
"This terminal has no delete line",
"or scrolling region capability,",
"please dump it somewhere and get",
"a real terminal"
);
exit( 1 );
}
(void) fflush( stdout );
}
else
{
(void) vfprintf( stderr, format, ap );
}
va_end( ap );
}
/*
* F B _ L O G
*
* Log an FB library event
*/
/* VARARGS */
void
fb_log( va_alist )
va_dcl
{
(void) rt_log( va_alist );
return;
}
-213
View File
@@ -1,213 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
$Header$ (BRL)
*/
#include <string.h>
#include "machine.h"
#include "fb.h"
#include "./burst.h"
#include "./trie.h"
#include "./Hm.h"
/* External functions from C library. */
#ifdef __STDC__
#include <stdlib.h>
extern pointer sbrk( int );
#else
extern char *fgets();
extern char *getenv();
extern char *malloc();
extern char *tmpnam();
extern pointer sbrk();
#endif
#ifdef SYSV
extern long lrand48();
#else
extern long random();
#endif
/* External variables from termlib. */
extern char *CS, *DL;
extern int CO, LI;
/* External functions from application. */
extern Colors *findColors();
extern Func *getTrie();
extern Trie *addTrie();
extern bool closFbDevice();
extern bool imageInit();
extern bool initUi();
extern bool openFbDevice();
extern bool findIdents();
extern bool readColors();
extern bool readIdents();
extern int notify();
extern int round();
extern void closeUi();
extern void colorPartition();
extern void exitCleanly();
extern void freeIdents();
extern void gridInit();
extern void gridModel();
extern void gridToFb();
extern void locPerror();
extern void logCmd();
extern void paintCellFb();
extern void paintGridFb();
extern void paintSpallFb();
extern void plotGrid();
extern void plotInit();
extern void plotPartition();
extern void plotRay();
extern void prntAspectInit();
extern void prntBurstHdr();
extern void prntCellIdent();
extern void prntFiringCoords();
extern void prntFusingComp();
extern void prntGridOffsets();
extern void prntIdents();
extern void prntPhantom();
extern void prntRayHeader();
extern void prntRayIntersect();
extern void prntScr();
extern void prntTimer();
extern void prompt();
extern void readCmdFile();
extern void rt_log();
extern void warning();
#if STD_SIGNAL_DECLS
extern void (*norml_sig)(), (*abort_sig)();
extern void abort_RT();
extern void intr_sig();
#else
extern int (*norml_sig)(), (*abort_sig)();
extern int abort_RT();
extern int intr_sig();
#endif
extern Colors colorids;
extern FBIO *fbiop;
extern FILE *burstfp;
extern FILE *gridfp;
extern FILE *histfp;
extern FILE *outfp;
extern FILE *plotfp;
extern FILE *shotfp;
extern FILE *shotlnfp;
extern FILE *tmpfp;
extern HmMenu *mainhmenu;
extern Ids airids;
extern Ids armorids;
extern Ids critids;
extern RGBpixel *pixgrid;
extern RGBpixel pixaxis;
extern RGBpixel pixbkgr;
extern RGBpixel pixbhit;
extern RGBpixel pixblack;
extern RGBpixel pixcrit;
extern RGBpixel pixghit;
extern RGBpixel pixmiss;
extern RGBpixel pixtarg;
extern Trie *cmdtrie;
extern bool batchmode;
extern bool cantwarhead;
extern bool deflectcone;
extern bool dithercells;
extern bool fatalerror;
extern bool groundburst;
extern bool reportoverlaps;
extern bool reqburstair;
extern bool shotburst;
extern bool tty;
extern bool userinterrupt;
extern char airfile[];
extern char armorfile[];
extern char burstfile[];
extern char cmdbuf[];
extern char cmdname[];
extern char colorfile[];
extern char critfile[];
extern char errfile[];
extern char fbfile[];
extern char gedfile[];
extern char gridfile[];
extern char histfile[];
extern char objects[];
extern char outfile[];
extern char plotfile[];
extern char scrbuf[];
extern char scriptfile[];
extern char shotfile[];
extern char shotlnfile[];
extern char title[];
extern char timer[];
extern char tmpfname[];
extern char *cmdptr;
extern char **template;
extern fastf_t bdist;
extern fastf_t burstpoint[];
extern fastf_t cellsz;
extern fastf_t conehfangle;
extern fastf_t fire[];
extern fastf_t griddn;
extern fastf_t gridlf;
extern fastf_t gridrt;
extern fastf_t gridup;
extern fastf_t gridhor[];
extern fastf_t gridsoff[];
extern fastf_t gridver[];
extern fastf_t grndbk;
extern fastf_t grndht;
extern fastf_t grndfr;
extern fastf_t grndlf;
extern fastf_t grndrt;
extern fastf_t modlcntr[];
extern fastf_t modldn;
extern fastf_t modllf;
extern fastf_t modlrt;
extern fastf_t modlup;
extern fastf_t pitch;
extern fastf_t raysolidangle;
extern fastf_t standoff;
extern fastf_t unitconv;
extern fastf_t viewazim;
extern fastf_t viewelev;
extern fastf_t viewsize;
extern fastf_t yaw;
extern fastf_t xaxis[];
extern fastf_t zaxis[];
extern fastf_t negzaxis[];
extern int co;
extern int devhgt;
extern int devwid;
extern int firemode;
extern int gridsz;
extern int gridxfin;
extern int gridyfin;
extern int gridxorg;
extern int gridyorg;
extern int gridheight;
extern int gridwidth;
extern int li;
extern int nbarriers;
extern int noverlaps;
extern int nprocessors;
extern int nriplevels;
extern int nspallrays;
extern int units;
extern int zoom;
extern struct rt_i *rtip;
-136
View File
@@ -1,136 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include "fb.h"
#include "./burst.h"
#include "./ascii.h"
#include "./extern.h"
bool
imageInit()
{ bool needopen = false;
static char lastfbfile[LNBUFSZ]={0}; /* last fbfile */
devwid = 512;
devhgt = 512;
if( fbfile[0] == NUL )
return true;
zoom = devwid / gridsz - 1;
while( zoom < 3 && devwid < MAXDEVWID )
{
devwid *= 2;
devhgt *= 2;
zoom = devwid / gridsz;
}
if( zoom * gridsz == devwid )
zoom--;
if( zoom < 1 )
zoom = 1;
/* Determine whether it is necessary to open fbfile. */
if( fbiop == FBIO_NULL || fb_getwidth( fbiop ) != devwid )
needopen = true; /* not currently open or size changed */
else
if( lastfbfile[0] != NUL && strcmp( fbfile, lastfbfile ) != 0 )
needopen = true; /* name changed */
(void) strcpy( lastfbfile, fbfile );
if( needopen )
{
if( ! openFbDevice( fbfile ) )
return false;
paintGridFb();
}
else
if( !(firemode & FM_SHOT) || (firemode & FM_FILE) )
paintGridFb();
return true;
}
/* openFbDevice( char *devname )
Must be called after gridInit() so that gridsz is setup.
*/
bool
openFbDevice( devname )
char *devname;
{ bool ret = true;
notify( "Opening frame buffer", NOTIFY_APPEND );
if( zoom < 1 )
{
prntScr( "Device is too small to display image." );
ret = false;
goto safe_exit;
}
if( ( (fbiop != FBIO_NULL && fb_getwidth( fbiop ) != devwid)
|| pixgrid == NULL
)
&& (pixgrid = (RGBpixel *) malloc( sizeof(RGBpixel)*devwid ))
== (RGBpixel *) NULL )
{
prntScr( "Memory allocation of %d bytes failed.",
sizeof(RGBpixel)*devwid );
ret = false;
goto safe_exit;
}
(void) memset( (char *) pixgrid, NUL, sizeof(RGBpixel)*devwid );
if( fbiop != FBIO_NULL )
{
#if SGI_WINCLOSE_BUG
if( strncmp( fbiop->if_name, "/dev/sgi", 8 ) == 0 )
{
prntScr( "IRIS can't change window size." );
ret = false;
goto safe_exit;
}
else
#endif
if( ! closFbDevice() )
{
ret = false;
goto safe_exit;
}
}
if( (fbiop = fb_open( devname, devwid, devhgt )) == NULL )
{
ret = false;
goto safe_exit;
}
else
if( fb_clear( fbiop, pixblack ) == -1
|| notify( "Zooming", NOTIFY_APPEND ),
fb_zoom( fbiop, 1, 1 ) == -1
|| notify( "Windowing", NOTIFY_DELETE ),
fb_window( fbiop, devwid/2, devhgt/2 ) == -1
)
{
ret = false;
goto safe_exit;
}
safe_exit : notify( NULL, NOTIFY_DELETE );
return ret;
}
bool
closFbDevice()
{ int ret;
notify( "Closing frame buffer", NOTIFY_APPEND );
if( fb_close( fbiop ) == -1 )
ret = false;
else
{
ret = true;
fbiop = FBIO_NULL;
}
notify( NULL, NOTIFY_DELETE );
return ret;
}
-159
View File
@@ -1,159 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#include "machine.h"
#include "vmath.h"
#include "fb.h"
#include "raytrace.h"
#include "./burst.h"
#include "./extern.h"
Colors colorids; /* ident range to color mappings for plots */
FBIO *fbiop = NULL; /* frame buffer specific access from libfb */
FILE *burstfp = NULL; /* input stream for burst point locations */
FILE *gridfp = NULL; /* grid file output stream (2-d shots) */
FILE *histfp = NULL; /* histogram output stream (statistics) */
FILE *outfp = NULL; /* burst point library output stream */
FILE *plotfp = NULL; /* 3-D UNIX plot stream (debugging) */
FILE *shotfp = NULL; /* input stream for shot positions */
FILE *shotlnfp = NULL; /* shotline file output stream */
FILE *tmpfp = NULL; /* temporary file output stream for logging input */
HmMenu *mainhmenu;
Ids airids; /* burst air idents */
Ids armorids; /* burst armor idents */
Ids critids; /* critical component idents */
RGBpixel *pixgrid;
RGBpixel pixaxis = { 255, 0, 0 }; /* grid axis */
RGBpixel pixbhit = { 200, 255, 200 }; /* burst ray hit non-critical comps */
RGBpixel pixbkgr = { 150, 100, 255 }; /* outside grid */
RGBpixel pixblack = { 0, 0, 0 }; /* black */
RGBpixel pixcrit = { 255, 200, 200 }; /* burst ray hit critical component */
RGBpixel pixghit = { 255, 0, 255 }; /* ground burst */
RGBpixel pixmiss = { 200, 200, 200 }; /* shot missed target */
RGBpixel pixtarg = { 255, 255, 255 }; /* shot hit target */
Trie *cmdtrie = NULL;
bool batchmode = false; /* are we processing batch input now */
bool cantwarhead = false; /* pitch or yaw will be applied to warhead */
bool deflectcone = DFL_DEFLECT; /* cone axis deflects towards normal */
bool dithercells = DFL_DITHER; /* if true, randomize shot within cell */
bool fatalerror; /* must abort ray tracing */
bool groundburst = false; /* if true, burst on imaginary ground */
bool reportoverlaps = DFL_OVERLAPS;
/* if true, overlaps are reported */
bool reqburstair = true; /* if true, burst air required for shotburst */
bool shotburst = false; /* if true, burst along shotline */
bool tty = true; /* if true, full screen display is used */
bool userinterrupt; /* has the ray trace been interrupted */
char airfile[LNBUFSZ]={0}; /* input file name for burst air ids */
char armorfile[LNBUFSZ]={0}; /* input file name for burst armor ids */
char burstfile[LNBUFSZ]={0}; /* input file name for burst points */
char cmdbuf[LNBUFSZ];
char cmdname[LNBUFSZ];
char colorfile[LNBUFSZ]={0}; /* ident range-to-color file name */
char critfile[LNBUFSZ]={0}; /* input file for critical components */
char errfile[LNBUFSZ]={0}; /* errors/diagnostics log file name */
char fbfile[LNBUFSZ]={0}; /* frame buffer image file name */
char gedfile[LNBUFSZ]={0}; /* MGED data base file name */
char gridfile[LNBUFSZ]={0}; /* saved grid (2-d shots) file name */
char histfile[LNBUFSZ]={0}; /* histogram file name (statistics) */
char objects[LNBUFSZ]={0}; /* list of objects from MGED file */
char outfile[LNBUFSZ]={0}; /* burst point library output file name */
char plotfile[LNBUFSZ]={0}; /* 3-D UNIX plot file name (debugging) */
char scrbuf[LNBUFSZ]; /* scratch buffer for temporary use */
char scriptfile[LNBUFSZ]={0}; /* shell script file name */
char shotfile[LNBUFSZ]; /* input file of firing coordinates */
char shotlnfile[LNBUFSZ]={0}; /* shotline output file name */
char title[TITLE_LEN]; /* title of MGED target description */
char timer[TIMER_LEN]; /* CPU usage statistics */
char tmpfname[TIMER_LEN]; /* temporary file for logging input */
char *cmdptr;
fastf_t bdist = DFL_BDIST;
/* fusing distance for warhead */
fastf_t burstpoint[3]; /* explicit burst point coordinates */
fastf_t cellsz = DFL_CELLSIZE;
/* shotline separation */
fastf_t conehfangle = DFL_CONEANGLE;
/* spall cone half angle */
fastf_t fire[3]; /* explicit firing coordinates (2-D or 3-D) */
fastf_t griddn; /* distance in model coordinates from origin to
bottom border of grid */
fastf_t gridlf; /* distance to left border */
fastf_t gridrt; /* distance to right border */
fastf_t gridup; /* distance to top border */
fastf_t gridhor[3]; /* horizontal grid direction cosines */
fastf_t gridsoff[3]; /* origin of grid translated by stand-off */
fastf_t gridver[3]; /* vertical grid direction cosines */
fastf_t grndbk = 0.0; /* distance to back border of ground plane (-X) */
fastf_t grndht = 0.0; /* distance of ground plane below target origin (-Z) */
fastf_t grndfr = 0.0; /* distance to front border of ground plane (+X) */
fastf_t grndlf = 0.0; /* distance to left border of ground plane (+Y) */
fastf_t grndrt = 0.0; /* distance to right border of ground plane (-Y) */
fastf_t modlcntr[3]; /* centroid of target's bounding RPP */
fastf_t modldn = 0.0; /* distance in model coordinates from origin to bottom
extent of projection of model in grid plane */
fastf_t modllf = 0.0; /* distance to left extent */
fastf_t modlrt = 0.0; /* distance to right extent */
fastf_t modlup = 0.0; /* distance to top extent */
fastf_t raysolidangle; /* solid angle per spall sampling ray */
fastf_t standoff; /* distance from model origin to grid */
fastf_t unitconv = 1.0; /* units conversion factor (mm to "units") */
fastf_t viewazim = DFL_AZIMUTH;
/* degrees from X-axis to firing position */
fastf_t viewelev = DFL_ELEVATION;
/* degrees from XY-plane to firing position */
/* These are the angles and fusing distance used to specify the path of
the canted warhead in Bob Wilson's simulation.
*/
fastf_t pitch = 0.0; /* elevation above path of main penetrator */
fastf_t yaw = 0.0; /* deviation right of path of main penetrator */
/* useful vectors */
fastf_t xaxis[3] = { 1.0, 0.0, 0.0 };
fastf_t zaxis[3] = { 0.0, 0.0, 1.0 };
fastf_t negzaxis[3] = { 0.0, 0.0, -1.0 };
int co; /* columns of text displayable on video screen */
int devwid; /* width in pixels of frame buffer window */
int devhgt; /* height in pixels of frame buffer window */
int firemode = FM_DFLT; /* mode of specifying shots */
int gridsz = 512;
int gridxfin;
int gridyfin;
int gridxorg;
int gridyorg;
int gridwidth; /* Grid width in cells. */
int gridheight; /* Grid height in cells. */
int li; /* lines of text displayable on video screen */
int nbarriers = DFL_BARRIERS;
/* no. of barriers allowed to critical comp */
int noverlaps = 0; /* no. of overlaps encountered in this view */
int nprocessors; /* no. of processors running concurrently */
int nriplevels = DFL_RIPLEVELS;
/* no. of levels of ripping (0 = no ripping) */
int nspallrays = DFL_NRAYS;
/* no. of spall rays at each burst point */
int units = DFL_UNITS; /* target units (default is millimeters) */
int zoom = 1; /* magnification factor on frame buffer */
struct rt_i *rtip = RTI_NULL; /* model specific access from librt */
/* signal handlers */
#if STD_SIGNAL_DECLS
void (*norml_sig)(); /* active during interactive operation */
void (*abort_sig)(); /* active during ray tracing only */
#else
int (*norml_sig)();
int (*abort_sig)();
#endif
-1629
View File
File diff suppressed because it is too large Load Diff
-60
View File
@@ -1,60 +0,0 @@
/*
Author: Jeff Hanes
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
Modified: Gary S. Moss (Added roll rotation.)
*/
#ifndef lint
static char RCSid[] = "$Header$ (BRL)";
#endif
#include <math.h>
#include "machine.h"
#include "./vecmath.h"
void gridRotate();
/*
void gridRotate( fastf_t azim, fastf_t elev, fastf_t roll,
register fastf_t *des_H, register fastf_t *des_V )
Creates the unit vectors H and V which are the horizontal
and vertical components of the grid in target coordinates.
The vectors are found from the azimuth and elivation of the
viewing angle according to a simplification of the rotation
matrix from grid coordinates to target coordinates.
To see that the vectors are, indeed, unit vectors, recall
the trigonometric relation:
sin( A )^2 + cos( A )^2 = 1 .
*/
void
gridRotate( azim, elev, roll, des_H, des_V )
fastf_t azim, elev, roll;
register fastf_t *des_H, *des_V;
{ fastf_t sn_azm = sin( azim );
fastf_t cs_azm = cos( azim );
fastf_t sn_elv = sin( elev );
des_H[0] = -sn_azm;
des_H[1] = cs_azm;
des_H[2] = 0.0;
des_V[0] = -sn_elv*cs_azm;
des_V[1] = -sn_elv*sn_azm;
des_V[2] = cos( elev );
if( roll != 0.0 )
{ fastf_t tmp_V[3], tmp_H[3], prime_V[3];
fastf_t sn_roll = sin( roll );
fastf_t cs_roll = cos( roll );
Scale2Vec( des_V, cs_roll, tmp_V );
Scale2Vec( des_H, sn_roll, tmp_H );
Add2Vec( tmp_V, tmp_H, prime_V );
Scale2Vec( des_V, -sn_roll, tmp_V );
Scale2Vec( des_H, cs_roll, tmp_H );
Add2Vec( tmp_V, tmp_H, des_H );
CopyVec( des_V, prime_V );
}
return;
}
-152
View File
@@ -1,152 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#ifndef DEBUG
#define NDEBUG
#define STATIC static
#else
#define STATIC
#endif
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "./burst.h"
#include "./vecmath.h"
#define DEBUG_IDENTS false
bool
findIdents( ident, idp )
int ident;
register Ids *idp;
{
#if DEBUG_IDENTS
rt_log( "findIdents(%d)\n", ident );
#endif
for( idp = idp->i_next ; idp != IDS_NULL; idp = idp->i_next )
{
#if DEBUG_IDENTS
rt_log( "lower=%d, upper=%d\n", (int) idp->i_lower,
(int) idp->i_upper );
#endif
if( ident >= (int) idp->i_lower
&& ident <= (int) idp->i_upper
)
return true;
}
#if DEBUG_IDENTS
rt_log( "returned false\n" );
#endif
return false;
}
Colors *
findColors( ident, colp )
int ident;
register Colors *colp;
{
for( colp = colp->c_next; colp != COLORS_NULL; colp = colp->c_next )
{
if( ident >= (int) colp->c_lower
&& ident <= (int) colp->c_upper
)
return colp;
}
return COLORS_NULL;
}
/*
void freeIdents( register Ids *idp )
Free up linked list, except for the head node.
*/
STATIC void
freeIdents( idp )
register Ids *idp;
{
if( idp->i_next == NULL )
return; /* finished */
freeIdents( idp->i_next );
free( (char *) idp->i_next );
}
bool
readIdents( idlist, fp )
Ids *idlist;
FILE *fp;
{ char input_buf[BUFSIZ];
int lower, upper;
register Ids *idp;
freeIdents( idlist ); /* free old list if it exists */
for( idp = idlist;
fgets( input_buf, BUFSIZ, fp ) != NULL;
)
{ char *token;
token = strtok( input_buf, ",-:; \t" );
if( token == NULL || sscanf( token, "%d", &lower ) < 1 )
continue;
token = strtok( NULL, " \t" );
if( token == NULL || sscanf( token, "%d", &upper ) < 1 )
upper = lower;
if( (idp->i_next = (Ids *) malloc( sizeof(Ids) )) == NULL )
{
Malloc_Bomb( sizeof(Ids) );
return false;
}
idp = idp->i_next;
idp->i_lower = lower;
idp->i_upper = upper;
}
idp->i_next = NULL;
return true;
}
bool
readColors( colorlist, fp )
Colors *colorlist;
FILE *fp;
{ char input_buf[BUFSIZ];
int lower, upper;
int rgb[3];
register Colors *colp;
for( colp = colorlist;
fgets( input_buf, BUFSIZ, fp ) != NULL;
)
{ int items;
if( (items =
sscanf( input_buf,
"%d %d %d %d %d\n",
&lower, &upper, &rgb[0], &rgb[1], &rgb[2]
)) < 5
)
{
if( items == EOF )
break;
else
{
rt_log( "readColors(): only %d items read\n",
items );
continue;
}
}
if( (colp->c_next = (Colors *) malloc( sizeof(Colors) ))
== NULL )
{
Malloc_Bomb( sizeof(Colors) );
return false;
}
colp = colp->c_next;
colp->c_lower = lower;
colp->c_upper = upper;
CopyVec( colp->c_rgb, rgb );
}
colp->c_next = NULL;
return true;
}
-214
View File
@@ -1,214 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#ifndef DEBUG
#define NDEBUG
#define STATIC static
#else
#define STATIC
#endif
#include <assert.h>
#include <stdio.h>
#include "machine.h"
#include "vmath.h"
#include "raytrace.h"
#include "fb.h"
#include "./vecmath.h"
#include "./extern.h"
#define DEBUG_CELLFB 0
#define DEBUG_SPALLFB 0
/* Offset frame buffer coordinates to center of cell from grid lines. */
#define CenterCell(b) (b += round( (fastf_t) zoom / 2.0 ))
/* Compare one RGB pixel to another. */
#define SAMERGB(a,b) ((a)[RED] == (b)[RED] &&\
(a)[GRN] == (b)[GRN] &&\
(a)[BLU] == (b)[BLU])
static RGBpixel pixbuf[MAXDEVWID];
static int gridxmargin;
static int gridymargin;
/*
fastf_t abs( fastf_t a )
Returns the absolute value of 'a'. Useful when a macro would
cause side-effects or redundant computation.
*/
STATIC fastf_t
abs( a )
fastf_t a;
{
return Abs( a );
}
void
gridToFb( gx, gy, fxp, fyp )
int gx, gy;
int *fxp, *fyp;
{
/* map grid offsets to frame buffer coordinates */
*fxp = (gx - gridxorg)*zoom + gridxmargin;
*fyp = (gy - gridyorg)*zoom + gridymargin;
return;
}
void
paintGridFb()
{ register int gx, gy;
register int fx, fy;
int fxbeg, fybeg;
int fxfin, fyfin;
int fxorg, fyorg;
int fgridwid;
if( fb_clear( fbiop, pixbkgr ) == -1 )
return;
gridxmargin = (devwid - (gridwidth*zoom)) / 2.0;
gridymargin = (devhgt - (gridheight*zoom)) / 2.0;
gridToFb( gridxorg, gridyorg, &fxbeg, &fybeg );
gridToFb( gridxfin+1, gridyfin+1, &fxfin, &fyfin );
gridToFb( 0, 0, &fxorg, &fyorg );
CenterCell( fxorg ); /* center of cell */
CenterCell( fyorg );
if( zoom == 1 )
{
fgridwid = gridwidth + 2;
fxfin++;
}
else
fgridwid = gridwidth * zoom + 1;
/* draw vertical lines */
for( fx = 1; fx < fgridwid; fx++ )
COPYRGB( pixbuf[fx], pixbkgr );
for( fx = fxbeg; fx <= fxfin; fx += zoom )
COPYRGB( pixbuf[fx-fxbeg], pixgrid[0] );
for( fy = fybeg; fy <= fyfin; fy++ )
(void) fb_write( fbiop, fxbeg, fy, pixbuf, fgridwid );
for( fy = 0; fy < devwid; fy++ )
(void) fb_write( fbiop, fxorg, fy, pixaxis, 1 );
/* draw horizontal lines */
if( zoom > 1 )
for( fy = fybeg; fy <= fyfin; fy += zoom )
(void) fb_write( fbiop,
fxbeg, fy, pixgrid, fgridwid ); for( fx = 0; fx < devwid; fx++ )
COPYRGB( pixbuf[fx], pixaxis );
(void) fb_write( fbiop, 0, fyorg, pixbuf, devwid );
return;
}
void
paintCellFb( ap, pixpaint, pixexpendable )
register struct application *ap;
RGBpixel *pixpaint;
RGBpixel *pixexpendable;
{ int gx, gy;
register int gyfin, gxfin;
register int gxorg, gyorg;
register int x, y;
int cnt;
#if DEBUG_CELLFB
rt_log( "paintCellFb: expendable {%d,%d,%d}\n",
(*pixexpendable)[RED],
(*pixexpendable)[GRN],
(*pixexpendable)[BLU] );
#endif
gridToFb( ap->a_x, ap->a_y, &gx, &gy );
gxorg = gx+1;
gyorg = gy+1;
gxfin = zoom == 1 ? gx+zoom+1 : gx+zoom;
gyfin = zoom == 1 ? gy+zoom+1 : gy+zoom;
cnt = gxfin - gxorg;
for( y = gyorg; y < gyfin; y++ )
{
if( zoom != 1 && (y - gy) % zoom == 0 )
continue;
RES_ACQUIRE( &rt_g.res_stats );
(void) fb_read( fbiop, gxorg, y, pixbuf, cnt );
RES_RELEASE( &rt_g.res_stats );
for( x = gxorg; x < gxfin; x++ )
{
if( SAMERGB( pixbuf[x-gxorg], *pixexpendable )
)
{
#if DEBUG_CELLFB
rt_log( "Clobbering:<%d,%d>{%d,%d,%d}\n",
x, y,
(pixbuf[x-gxorg])[RED],
(pixbuf[x-gxorg])[GRN],
(pixbuf[x-gxorg])[BLU] );
#endif
COPYRGB( pixbuf[x-gxorg], *pixpaint );
}
#if DEBUG_CELLFB
else
rt_log( "Preserving:<%d,%d>{%d,%d,%d}\n",
x, y,
(pixbuf[x-gxorg])[RED],
(pixbuf[x-gxorg])[GRN],
(pixbuf[x-gxorg])[BLU] );
#endif
}
RES_ACQUIRE( &rt_g.res_stats );
(void) fb_write( fbiop, gxorg, y, pixbuf, cnt );
RES_RELEASE( &rt_g.res_stats );
#if DEBUG_CELLFB
rt_log( "paintCellFb: fb_write(%d,%d)\n", x, y );
#endif
}
return;
}
void
paintSpallFb( ap )
register struct application *ap;
{ RGBpixel pixel;
int x, y;
int err;
fastf_t celldist;
#if DEBUG_SPALLFB
rt_log( "paintSpallFb: a_x=%d a_y=%d a_cumlen=%g cellsz=%g zoom=%d\n",
ap->a_x, ap->a_y, ap->a_cumlen, cellsz, zoom );
#endif
pixel[RED] = ap->a_color[RED] * 255;
pixel[GRN] = ap->a_color[GRN] * 255;
pixel[BLU] = ap->a_color[BLU] * 255;
gridToFb( ap->a_x, ap->a_y, &x, &y );
CenterCell( x ); /* center of cell */
CenterCell( y );
celldist = ap->a_cumlen/cellsz * zoom;
x = round( x + Dot( ap->a_ray.r_dir, gridhor ) * celldist );
y = round( y + Dot( ap->a_ray.r_dir, gridver ) * celldist );
RES_ACQUIRE( &rt_g.res_stats );
err = fb_write( fbiop, x, y, pixel, 1 );
RES_RELEASE( &rt_g.res_stats );
#if DEBUG_SPALLFB
rt_log( "paintSpallFb:gridhor=<%g,%g,%g> gridver=<%g,%g,%g>\n",
gridhor[X], gridhor[Y], gridhor[Z],
gridver[X], gridver[Y], gridver[Z] );
rt_log( "paintSpallFb:fb_write(x=%d,y=%d,pixel={%d,%d,%d})\n",
x, y,
(int) pixel[RED],
(int) pixel[GRN],
(int) pixel[BLU]
);
#endif
if( err == -1 )
rt_log( "Write failed to pixel <%d,%d> from cell <%d,%d>.\n",
x, y, ap->a_x, ap->a_y );
return;
}
-91
View File
@@ -1,91 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#include <math.h>
#include "machine.h"
#include "vmath.h"
#include "raytrace.h"
#include "./vecmath.h"
#include "./burst.h"
#include "./extern.h"
void
plotInit()
{ int x1, y1, z1, x2, y2, z2;
if( plotfp == NULL )
return;
x1 = (int) rtip->mdl_min[X] - 1;
y1 = (int) rtip->mdl_min[Y] - 1;
z1 = (int) rtip->mdl_min[Z] - 1;
x2 = (int) rtip->mdl_max[X] + 1;
y2 = (int) rtip->mdl_max[Y] + 1;
z2 = (int) rtip->mdl_max[Z] + 1;
pl_3space( plotfp, x1, y1, z1, x2, y2, z2 );
return;
}
void
plotGrid( r_pt )
register fastf_t *r_pt;
{
if( plotfp == NULL )
return;
pl_color( plotfp, R_GRID, G_GRID, B_GRID );
pl_3point( plotfp, (int) r_pt[X], (int) r_pt[Y], (int) r_pt[Z] );
return;
}
void
plotRay( rayp )
register struct xray *rayp;
{ int endpoint[3];
if( plotfp == NULL )
return;
VJOIN1( endpoint, rayp->r_pt, cellsz, rayp->r_dir );
RES_ACQUIRE( &rt_g.res_syscall );
pl_color( plotfp, R_BURST, G_BURST, B_BURST );
#if 0
pl_3line( plotfp,
(int) rayp->r_pt[X],
(int) rayp->r_pt[Y],
(int) rayp->r_pt[Z],
endpoint[X],
endpoint[Y],
endpoint[Z]
);
#else
pl_3point( plotfp, (int) endpoint[X], (int) endpoint[Y], (int) endpoint[Z] );
#endif
RES_RELEASE( &rt_g.res_syscall );
return;
}
void
plotPartition( ihitp, ohitp, rayp, regp )
struct hit *ihitp;
register struct hit *ohitp ;
register struct xray *rayp;
struct region *regp;
{
if( plotfp == NULL )
return;
RES_ACQUIRE( &rt_g.res_syscall );
pl_3line( plotfp,
(int) ihitp->hit_point[X],
(int) ihitp->hit_point[Y],
(int) ihitp->hit_point[Z],
(int) ohitp->hit_point[X],
(int) ohitp->hit_point[Y],
(int) ohitp->hit_point[Z]
);
RES_RELEASE( &rt_g.res_syscall );
return;
}
-965
View File
@@ -1,965 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#ifndef DEBUG
#define NDEBUG
#define STATIC static
#else
#define STATIC
#endif
#include <assert.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include "./Sc.h"
#include "machine.h"
#include "vmath.h"
#include "raytrace.h"
#include "./vecmath.h"
#include "./ascii.h"
#include "./extern.h"
#define MAX_COLS 128
#define PHANTOM_ARMOR 111
STATIC fastf_t getNormThickness();
int
doMore( linesp )
int *linesp;
{ register int ret = true;
if( ! tty )
return true;
TcSaveTty( HmTtyFd );
TcSetRaw( HmTtyFd );
TcClrEcho( HmTtyFd );
ScSetStandout();
prompt( "-- More -- " );
ScClrStandout();
(void) fflush( stdout );
switch( HmGetchar() )
{
case 'q' :
case 'n' :
ret = false;
break;
case LF :
case CR :
*linesp = 1;
break;
default :
*linesp = (PROMPT_Y-SCROLL_TOP);
break;
}
TcResetTty( HmTtyFd );
return ret;
}
STATIC int
f_Nerror( ap )
struct application *ap;
{
rt_log( "Couldn't compute thickness or exit point%s.\n",
"along normal direction" );
V_Print( "\tpnt", ap->a_ray.r_pt, rt_log );
V_Print( "\tdir", ap->a_ray.r_dir, rt_log );
ap->a_rbeam = 0.0;
return 0;
}
/* f_Normal()
Shooting from surface of object along reversed entry normal to
compute exit point along normal direction and normal thickness.
Thickness returned in "a_rbeam".
*/
STATIC int
f_Normal( ap, pt_headp )
struct application *ap;
struct partition *pt_headp;
{ register struct partition *pp = pt_headp->pt_forw;
register struct partition *cp;
register struct hit *ohitp;
for( cp = pp->pt_forw;
cp != pt_headp && SameCmp( pp->pt_regionp, cp->pt_regionp );
cp = cp->pt_forw
)
;
ohitp = cp->pt_back->pt_outhit;
ap->a_rbeam = ohitp->hit_dist - pp->pt_inhit->hit_dist;
#ifdef DEBUG
rt_log( "f_Normal: thickness=%g dout=%g din=%g\n",
ap->a_rbeam*unitconv, ohitp->hit_dist, pp->pt_inhit->hit_dist );
#endif
return 1;
}
#include <errno.h>
/* These aren't defined in BSD errno.h. */
extern int errno;
extern int sys_nerr;
extern char *sys_errlist[];
void
locPerror( msg )
char *msg;
{
if( errno > 0 && errno < sys_nerr )
rt_log( "%s: %s\n", msg, sys_errlist[errno] );
else
rt_log( "BUG: errno not set, shouldn't call perror.\n" );
return;
}
int
notify( str, mode )
char *str;
int mode;
{ register int i;
static int lastlen = -1;
register int len;
static char buf[LNBUFSZ] = { 0 };
register char *p;
if( ! tty )
return false;
switch( mode )
{
case NOTIFY_APPEND :
p = buf + lastlen;
break;
case NOTIFY_DELETE :
for( p = buf+lastlen; p > buf && *p != NOTIFY_DELIM; p-- )
;
break;
case NOTIFY_ERASE :
p = buf;
break;
}
if( str != NULL )
{
if( p > buf )
*p++ = NOTIFY_DELIM;
(void) strcpy( p, str );
}
else
*p = NUL;
(void) ScMvCursor( PROMPT_X, PROMPT_Y );
len = strlen( buf );
if( len > 0 )
{
(void) ScSetStandout();
(void) fputs( buf, stdout );
(void) ScClrStandout();
}
/* Blank out remainder of previous command. */
for( i = len; i < lastlen; i++ )
(void) putchar( ' ' );
(void) ScMvCursor( PROMPT_X, PROMPT_Y );
(void) fflush( stdout );
lastlen = len;
return true;
}
/*
void prntAspectInit( void )
Burst Point Library and Shotline file: header record for each view.
Ref. Figure 20., Line Number 1 and Figure 19., Line Number 1 of ICD.
*/
void
prntAspectInit()
{ fastf_t projarea; /* projected area */
/* Convert to user units before squaring cell size. */
projarea = cellsz*unitconv;
projarea *= projarea;
if( outfile[0] != NUL
&& fprintf(outfp,
"%c % 8.4f % 8.4f % 5.2f % 10.2f %-6s % 9.6f\n",
PB_ASPECT_INIT,
viewazim*DEGRAD, /* attack azimuth in degrees */
viewelev*DEGRAD, /* attack elevation in degrees */
bdist*unitconv, /* BDIST */
projarea, /* projected area associated with burst pt. */
units == U_INCHES ? "inches" :
units == U_FEET ? "feet" :
units == U_MILLIMETERS ? "mm" :
units == U_CENTIMETERS ? "cm" :
units == U_METERS ? "meters" : "units?",
raysolidangle
) < 0
)
{
rt_log( "Write failed to file (%s)!\n", outfile );
locPerror( "fprintf" );
exitCleanly( 1 );
}
if( shotlnfile[0] != NUL
&& fprintf(shotlnfp,
"%c % 8.4f % 8.4f % 7.2f % 7.2f %7.2f %7.2f %7.2f %-6s\n",
PS_ASPECT_INIT,
viewazim*DEGRAD, /* attack azimuth in degrees */
viewelev*DEGRAD, /* attack elevation in degrees */
cellsz*unitconv, /* shotline separation */
modlrt*unitconv, /* maximum Y'-coordinate of target */
modllf*unitconv, /* minimum Y'-coordinate of target */
modlup*unitconv, /* maximum Z'-coordinate of target */
modldn*unitconv, /* minimum Z'-coordinate of target */
units == U_INCHES ? "inches" :
units == U_FEET ? "feet" :
units == U_MILLIMETERS ? "mm" :
units == U_CENTIMETERS ? "cm" :
units == U_METERS ? "meters" : "units?"
) < 0
)
{
rt_log( "Write failed to file (%s)!\n", shotlnfile );
locPerror( "fprintf" );
exitCleanly( 1 );
}
return;
}
/*
void prntCellIdent( struct application *ap )
Burst Point Library and Shotline file: information about shotline.
Ref. Figure 20., Line Number 2 and Figure 19., Line Number 2 of ICD.
NOTE: field width of first 2 floats compatible with PB_RAY_HEADER
record.
*/
void
prntCellIdent( ap )
register struct application *ap;
{
if( outfile[0] != NUL
&& fprintf(outfp,
"%c % 8.3f % 8.3f\n",
PB_CELL_IDENT,
ap->a_uvec[X]*unitconv,
/* horizontal coordinate of shotline (Y') */
ap->a_uvec[Y]*unitconv
/* vertical coordinate of shotline (Z') */
) < 0
)
{
rt_log( "Write failed to file (%s)!\n", outfile );
locPerror( "fprintf" );
exitCleanly( 1 );
}
if( shotlnfile[0] != NUL
&& fprintf(shotlnfp,
"%c % 8.3f % 8.3f\n",
PS_CELL_IDENT,
ap->a_uvec[X]*unitconv,
/* horizontal coordinate of shotline (Y') */
ap->a_uvec[Y]*unitconv
/* vertical coordinate of shotline (Z') */
) < 0
)
{
rt_log( "Write failed to file (%s)!\n", shotlnfile );
locPerror( "fprintf" );
exitCleanly( 1 );
}
return;
}
/*
void prntSeg( struct application *ap, struct partition *cpp, int space )
Burst Point Library and Shotline file: information about each component
hit along path of main penetrator (shotline).
Ref. Figure 20., Line Number 3 and Figure 19., Line Number 2 of ICD.
*/
void
prntSeg( ap, cpp, space )
register struct application *ap;
register struct partition *cpp; /* component partition */
int space;
{ fastf_t icosobliquity; /* cosine of obliquity at entry */
fastf_t ocosobliquity; /* cosine of obliquity at exit */
fastf_t entryangle; /* obliquity angle at entry */
fastf_t exitangle; /* obliquity angle at exit */
fastf_t los; /* line-of-sight thickness */
fastf_t normthickness; /* normal thickness */
fastf_t rotangle; /* rotation angle */
fastf_t sinfbangle; /* sine of fall back angle */
register struct hit *ihitp;
register struct hit *ohitp;
register struct soltab *istp;
register struct soltab *ostp;
/* fill in entry hit point and normal */
istp = cpp->pt_inseg->seg_stp;
ihitp = cpp->pt_inhit;
RT_HIT_NORM( ihitp, istp, &(ap->a_ray) );
/* check for flipped normal and fix */
if( cpp->pt_inflip )
{
ScaleVec( ihitp->hit_normal, -1.0 );
cpp->pt_inflip = 0;
}
fixed_entry_normal:
/* This *should* give negative of desired result, but make sure. */
icosobliquity = Dot( ap->a_ray.r_dir, ihitp->hit_normal );
if( icosobliquity < 0.0 )
icosobliquity = -icosobliquity;
else
{
#ifdef DEBUG
rt_log( "prntSeg: fixed flipped entry normal.\n" );
rt_log( "cosine of angle of obliquity is %12.9f\n",
icosobliquity );
rt_log( "\tregion name '%s' solid name '%s'\n",
cpp->pt_regionp->reg_name,
istp->st_name );
#endif
ScaleVec( ihitp->hit_normal, -1.0 );
goto fixed_entry_normal;
}
/* fill in exit hit point and normal */
ostp = cpp->pt_outseg->seg_stp;
ohitp = cpp->pt_outhit;
RT_HIT_NORM( ohitp, ostp, &(ap->a_ray) );
/* check for flipped normal and fix */
if( cpp->pt_outflip )
{
ScaleVec( ohitp->hit_normal, -1.0 );
cpp->pt_outflip = 0;
}
fixed_exit_normal:
/* This *should* give negative of desired result, but make sure. */
ocosobliquity = Dot( ap->a_ray.r_dir, ohitp->hit_normal );
if( ocosobliquity < 0.0 )
ocosobliquity = -ocosobliquity;
else
{
#ifdef DEBUG
rt_log( "prntSeg: fixed flipped exit normal.\n" );
rt_log( "cosine of angle of obliquity is %12.9f\n",
ocosobliquity );
rt_log( "\tregion name '%s' solid name '%s'\n",
cpp->pt_regionp->reg_name,
ostp->st_name );
#endif
ScaleVec( ohitp->hit_normal, -1.0 );
goto fixed_exit_normal;
}
if( ohitp->hit_normal[Y] == 0.0 && ohitp->hit_normal[X] == 0.0 )
rotangle = 0.0;
else
{
rotangle = atan2( ohitp->hit_normal[Y], ohitp->hit_normal[X] );
rotangle *= DEGRAD; /* convert to degrees */
if( rotangle < 0.0 )
rotangle += 360.0;
}
sinfbangle = Dot( ohitp->hit_normal, zaxis );
los = (cpp->pt_outhit->hit_dist-ihitp->hit_dist)*unitconv;
#ifdef DEBUG
rt_log( "prntSeg: los=%g dout=%g din=%g\n",
los, cpp->pt_outhit->hit_dist, ihitp->hit_dist );
#endif
if( outfile[0] != NUL
&& fprintf( outfp,
"%c % 8.2f % 8.2f %4d %2d % 7.3f % 7.2f % 7.3f\n",
PB_RAY_INTERSECT,
(standoff-ihitp->hit_dist)*unitconv,
/* X'-coordinate of intersection */
los, /* LOS thickness of component */
cpp->pt_regionp->reg_regionid,
/* component code number */
space, /* space code */
sinfbangle, /* sine of fallback angle at exit */
rotangle, /* rotation angle in degrees at exit */
icosobliquity /* cosine of obliquity angle at entry */
) < 0
)
{
rt_log( "Write failed to file (%s)!\n", outfile );
locPerror( "fprintf" );
exitCleanly( 1 );
}
if( shotlnfile[0] == NUL )
return;
entryangle = AproxEq( icosobliquity, 1.0, COS_TOL ) ?
0.0 : acos( icosobliquity ) * DEGRAD;
if( (normthickness =
getNormThickness( ap, cpp, icosobliquity )) <= 0.0
&& fatalerror )
{
rt_log( "Couldn't compute normal thickness.\n" );
rt_log( "\tshotline coordinates <%g,%g>\n",
ap->a_uvec[X]*unitconv,
ap->a_uvec[Y]*unitconv
);
rt_log( "\tregion name '%s' solid name '%s'\n",
cpp->pt_regionp->reg_name,
istp->st_name );
return;
}
exitangle = AproxEq( ocosobliquity, 1.0, COS_TOL ) ?
0.0 : acos( ocosobliquity ) * DEGRAD;
if( fprintf( shotlnfp,
"%c % 8.2f % 7.3f % 7.2f %4d % 8.2f % 8.2f %2d % 7.2f % 7.2f\n",
PS_SHOT_INTERSECT,
(standoff-ihitp->hit_dist)*unitconv,
/* X'-coordinate of intersection */
sinfbangle, /* sine of fallback angle at exit */
rotangle, /* rotation angle in degrees at exit */
cpp->pt_regionp->reg_regionid,
/* component code number */
normthickness*unitconv,
/* normal thickness of component */
los, /* LOS thickness of component */
space, /* space code */
entryangle, /* entry obliquity angle in degrees */
exitangle /* exit obliquity angle in degrees */
) < 0
)
{
rt_log( "Write failed to file (%s)!\n", shotlnfile );
locPerror( "fprintf" );
exitCleanly( 1 );
}
return;
}
/*
void prntRayHeader( fastf_t *raydir, fastf_t *shotdir, unsigned rayno )
Burst Point Library: information about burst ray. All angles are
WRT the shotline coordinate system, represented by X', Y' and Z'.
Ref. Figure 20., Line Number 19 of ICD.
NOTE: field width of first 2 floats compatible with PB_CELL_IDENT
record.
*/
void
prntRayHeader( raydir, shotdir, rayno )
fastf_t *raydir; /* burst ray direction vector */
fastf_t *shotdir; /* shotline direction vector */
unsigned rayno; /* ray number for this burst point */
{ double cosxr; /* cosine of angle between X' and raydir */
double cosyr; /* cosine of angle between Y' and raydir */
fastf_t azim; /* ray azim in radians */
fastf_t sinelev; /* sine of ray elevation */
if( outfile[0] == NUL )
return;
cosxr = -Dot( shotdir, raydir ); /* shotdir is reverse of X' */
cosyr = Dot( gridhor, raydir );
if( cosyr == 0.0 && cosxr == 0.0 )
azim = 0.0;
else
azim = atan2( cosyr, cosxr );
sinelev = Dot( gridver, raydir );
if( fprintf( outfp,
"%c % 8.3f % 8.3f % 6u\n",
PB_RAY_HEADER,
azim, /* ray azimuth angle WRT shotline (radians). */
sinelev, /* sine of ray elevation angle WRT shotline. */
rayno
) < 0
)
{
rt_log( "Write failed to file (%s)!\n", outfile );
locPerror( "fprintf" );
exitCleanly( 1 );
}
return;
}
/*
void prntRegionHdr( struct application *ap, struct partition *pt_headp,
struct partition *pp )
Burst Point Libary: intersection along burst ray.
Ref. Figure 20., Line Number 20 of ICD.
*/
void
prntRegionHdr( ap, pt_headp, pp )
struct application *ap;
struct partition *pt_headp;
struct partition *pp;
{ fastf_t cosobliquity;
fastf_t normthickness;
register struct hit *ihitp = pp->pt_inhit;
register struct hit *ohitp = pp->pt_outhit;
register struct region *regp = pp->pt_regionp;
register struct soltab *stp = pp->pt_inseg->seg_stp;
register struct xray *rayp = &ap->a_ray;
/* fill in entry/exit normals and hit points */
RT_HIT_NORM( ihitp, stp, rayp );
Check_Iflip( pp, ihitp->hit_normal, rayp->r_dir );
stp = pp->pt_outseg->seg_stp;
RT_HIT_NORM( ohitp, stp, rayp );
Check_Oflip( pp, ohitp->hit_normal, rayp->r_dir );
/* calculate cosine of obliquity angle */
fixed_normal:
cosobliquity = Dot( ap->a_ray.r_dir, ihitp->hit_normal );
if( cosobliquity < 0.0 )
cosobliquity = -cosobliquity;
else
{
#if DEBUG
rt_log( "prntRegionHdr: fixed flipped entry normal.\n" );
rt_log( "region name '%s'\n", regp->reg_name );
#endif
ScaleVec( ihitp->hit_normal, -1.0 );
goto fixed_normal;
}
#if DEBUG
if( cosobliquity - COS_TOL > 1.0 )
{
rt_log( "cosobliquity=%12.8f\n", cosobliquity );
rt_log( "normal=<%g,%g,%g>\n",
ihitp->hit_normal[X],
ihitp->hit_normal[Y],
ihitp->hit_normal[Z]
);
rt_log( "ray direction=<%g,%g,%g>\n",
ap->a_ray.r_dir[X],
ap->a_ray.r_dir[Y],
ap->a_ray.r_dir[Z]
);
rt_log( "region name '%s'\n", regp->reg_name );
}
#endif
if( outfile[0] == NUL )
return;
/* Now we must find normal thickness through component. */
normthickness = getNormThickness( ap, pp, cosobliquity );
RES_ACQUIRE( &rt_g.res_syscall ); /* lock */
if( fprintf( outfp,
"%c % 10.3f % 9.3f % 9.3f %4d %4d % 6.3f\n",
PB_REGION_HEADER,
ihitp->hit_dist*unitconv, /* distance from burst pt. */
(ohitp->hit_dist - ihitp->hit_dist)*unitconv, /* LOS */
normthickness*unitconv, /* normal thickness */
pp->pt_forw == pt_headp ?
EXIT_AIR : pp->pt_forw->pt_regionp->reg_aircode,
regp->reg_regionid,
cosobliquity
) < 0
)
{
RES_RELEASE( &rt_g.res_syscall ); /* unlock */
rt_log( "Write failed to file (%s)!\n", outfile );
locPerror( "fprintf" );
exitCleanly( 1 );
}
RES_RELEASE( &rt_g.res_syscall ); /* unlock */
return;
}
/*
fastf_t getNormThickness( struct application *ap, struct partition *pp,
fast_t cosobliquity )
Given a partition structure with entry hit point and normal filled in,
the current application structure and the cosine of the obliquity at
entry to the component, return the normal thickness through the
component at the given hit point.
*/
STATIC fastf_t
getNormThickness( ap, pp, cosobliquity )
register struct application *ap;
register struct partition *pp;
fastf_t cosobliquity;
{
if( AproxEq( cosobliquity, 1.0, COS_TOL ) )
{ /* Trajectory was normal to surface, so no need
to shoot another ray. */
fastf_t thickness = pp->pt_outhit->hit_dist -
pp->pt_inhit->hit_dist;
#ifdef DEBUG
rt_log( "getNormThickness: using existing partitions.\n" );
rt_log( "\tthickness=%g dout=%g din=%g\n",
thickness*unitconv,
pp->pt_outhit->hit_dist, pp->pt_inhit->hit_dist );
#endif
return thickness;
}
else
{ /* need to shoot ray */
struct application a_thick;
register struct hit *ihitp = pp->pt_inhit;
register struct region *regp = pp->pt_regionp;
a_thick = *ap;
a_thick.a_hit = f_Normal;
a_thick.a_miss = f_Nerror;
a_thick.a_level++;
a_thick.a_uptr = regp->reg_name;
a_thick.a_user = regp->reg_regionid;
a_thick.a_purpose = "normal thickness";
CopyVec( a_thick.a_ray.r_pt, ihitp->hit_point );
#ifdef DEBUG
rt_log( "getNormThickness: ray tracing.\n" );
#endif
Scale2Vec( ihitp->hit_normal, -1.0, a_thick.a_ray.r_dir );
if( rt_shootray( &a_thick ) == -1 && fatalerror )
{ /* Fatal error in application routine. */
rt_log( "Fatal error: raytracing aborted.\n" );
return 0.0;
}
return a_thick.a_rbeam;
}
/*NOTREACHED*/
}
/*
void prntShieldComp( struct application *ap, struct partition *pt_headp,
Pt_Queue *qp )
*/
void
prntShieldComp( ap, pt_headp, qp )
struct application *ap;
struct partition *pt_headp;
register Pt_Queue *qp;
{
if( outfile[0] == NUL )
return;
if( qp == PT_Q_NULL )
return;
prntShieldComp( ap, pt_headp, qp->q_next );
prntRegionHdr( ap, pt_headp, qp->q_part );
return;
}
void
prntColors( colorp, str )
register Colors *colorp;
char *str;
{
rt_log( "%s:\n", str );
for( colorp = colorp->c_next;
colorp != COLORS_NULL;
colorp = colorp->c_next )
{
rt_log( "\t%d..%d\t%d,%d,%d\n",
(int)colorp->c_lower,
(int)colorp->c_upper,
(int)colorp->c_rgb[0],
(int)colorp->c_rgb[1],
(int)colorp->c_rgb[2]
);
}
return;
}
/*
void prntFiringCoords( register fastf_t *vec )
If the user has asked for grid coordinates to be saved, write
them to the output stream 'gridfp'.
*/
void
prntFiringCoords( vec )
register fastf_t *vec;
{
if( gridfile[0] == '\0' )
return;
assert( gridfp != (FILE *) NULL );
if( fprintf( gridfp, "%7.2f %7.2f\n", vec[X]*unitconv, vec[Y]*unitconv )
< 0 )
{
rt_log( "Write failed to file (%s)!\n", gridfile );
locPerror( "fprintf" );
exitCleanly( 1 );
}
return;
}
void
prntGridOffsets( x, y )
int x, y;
{
if( ! tty )
return;
(void) ScMvCursor( GRID_X, GRID_Y );
(void) printf( "[% 4d:% 4d,% 4d:% 4d]",
x, gridxfin, y, gridyfin
);
(void) fflush( stdout );
return;
}
void
prntIdents( idp, str )
register Ids *idp;
char *str;
{
rt_log( "%s:\n", str );
for( idp = idp->i_next ; idp != IDS_NULL; idp = idp->i_next )
{
if( idp->i_lower == idp->i_upper )
rt_log( "\t%d\n", (int) idp->i_lower );
else
rt_log( "\t%d..%d\n",
(int)idp->i_lower,
(int)idp->i_upper
);
}
return;
}
/**/
void
prntPagedMenu( menu )
register char **menu;
{ register int done = false;
int lines = (PROMPT_Y-SCROLL_TOP);
if( ! tty )
{
for( ; *menu != NULL; menu++ )
rt_log( "%s\n", *menu );
return;
}
for( ; *menu != NULL && ! done; )
{
for( ; lines > 0 && *menu != NULL; menu++, --lines )
rt_log( "%-*s\n", co, *menu );
if( *menu != NULL )
done = ! doMore( &lines );
prompt( "" );
}
(void) fflush( stdout );
return;
}
/*
void prntPhantom( struct hit *hitp, int space, fastf_t los )
Output "phantom armor" pseudo component. This component has no
surface normal or thickness, so many zero fields are used for
conformity with the normal component output formats.
*/
/*ARGSUSED*/
void
prntPhantom( hitp, space, los )
struct hit *hitp; /* ptr. to phantom's intersection information */
int space; /* space code behind phantom */
fastf_t los; /* LOS of space */
{
if( outfile[0] != NUL
&& fprintf( outfp,
"%c % 8.2f % 8.2f %4d %2d % 7.3f % 7.3f % 7.3f\n",
PB_RAY_INTERSECT,
(standoff-hitp->hit_dist)*unitconv,
/* X'-coordinate of intersection */
0.0, /* LOS thickness of component */
PHANTOM_ARMOR, /* component code number */
space, /* space code */
0.0, /* sine of fallback angle */
0.0, /* rotation angle (degrees) */
0.0 /* cosine of obliquity angle at entry */
) < 0
)
{
rt_log( "Write failed to file!\n", outfile );
locPerror( "fprintf" );
exitCleanly( 1 );
}
if( shotlnfile[0] != NUL
&& fprintf( shotlnfp,
"%c % 8.2f % 7.3f % 7.3f %4d % 8.2f % 8.2f %2d % 7.2f % 7.2f\n",
PS_SHOT_INTERSECT,
(standoff-hitp->hit_dist)*unitconv,
/* X'-coordinate of intersection */
0.0, /* sine of fallback angle */
0.0, /* rotation angle in degrees */
PHANTOM_ARMOR, /* component code number */
0.0, /* normal thickness of component */
0.0, /* LOS thickness of component */
space, /* space code */
0.0, /* entry obliquity angle in degrees */
0.0 /* exit obliquity angle in degrees */
) < 0
)
{
rt_log( "Write failed to file (%s)!\n", shotlnfile );
locPerror( "fprintf" );
exitCleanly( 1 );
}
return;
}
#include <varargs.h>
/* VARARGS */
void
prntScr( va_alist )
va_dcl
{ register char *format; /* picked up by va_arg() */
va_list ap;
va_start( ap );
format = va_arg( ap, char * );
if( tty )
{
TcClrTabs( HmTtyFd );
if( ScDL != NULL )
{
(void) ScMvCursor( 1, SCROLL_TOP );
(void) ScDeleteLn();
(void) ScMvCursor( 1, SCROLL_BTM );
(void) ScClrEOL();
(void) vprintf( format, ap );
}
else
if( ScSetScrlReg( SCROLL_TOP, SCROLL_BTM+1 ) )
{ char buf[LNBUFSZ];
(void) ScMvCursor( 1, SCROLL_BTM+1 );
(void) ScClrEOL();
/* Work around for problem with vprintf(): it doesn't
cause the screen to scroll, don't know why. */
(void) vsprintf( buf, format, ap );
(void) puts( buf );
/*(void) vprintf( format, ap );*/
(void) ScMvCursor( 1, SCROLL_BTM+1 );
(void) ScClrScrlReg();
}
else
{
(void) vprintf( format, ap );
(void) fputs( "\n", stdout );
}
(void) fflush( stdout );
}
else
{
(void) vfprintf( stderr, format, ap );
(void) fputs( "\n", stderr );
}
va_end( ap );
return;
}
/*
void prntTimer( char *str )
*/
void
prntTimer( str )
char *str;
{
(void) rt_read_timer( timer, TIMER_LEN-1 );
if( tty )
{
(void) ScMvCursor( TIMER_X, TIMER_Y );
if( str == NULL )
(void) printf( "%s", timer );
else
(void) printf( "%s:\t%s", str, timer );
(void) ScClrEOL();
(void) fflush( stdout );
}
else
rt_log( "%s:\t%s\n", str == NULL ? "(null)" : str, timer );
return;
}
void
prntTitle( title )
char *title;
{
if( ! tty || rt_g.debug )
rt_log( "%s\n", title == NULL ? "(null)" : title );
return;
}
static char *usage[] =
{
"Usage: burst [-b]",
"\tThe -b option suppresses the screen display (for batch jobs).",
NULL
};
void
prntUsage()
{ register char **p = usage;
while( *p != NULL )
(void) fprintf( stderr, "%s\n", *p++ );
return;
}
void
prompt( str )
char *str;
{
(void) ScMvCursor( PROMPT_X, PROMPT_Y );
if( str == (char *) NULL )
(void) ScClrEOL();
else
{
(void) ScSetStandout();
(void) fputs( str, stdout );
(void) ScClrStandout();
}
(void) fflush( stdout );
return;
}
int
qAdd( pp, qpp )
struct partition *pp;
Pt_Queue **qpp;
{ Pt_Queue *newq;
RES_ACQUIRE( &rt_g.res_syscall );
if( (newq = (Pt_Queue *) malloc( sizeof(Pt_Queue) )) == PT_Q_NULL )
{
Malloc_Bomb( sizeof(Pt_Queue) );
RES_RELEASE( &rt_g.res_syscall );
return 0;
}
RES_RELEASE( &rt_g.res_syscall );
newq->q_next = *qpp;
newq->q_part = pp;
*qpp = newq;
return 1;
}
void
qFree( qp )
Pt_Queue *qp;
{
if( qp == PT_Q_NULL )
return;
qFree( qp->q_next );
RES_ACQUIRE( &rt_g.res_syscall );
free( (char *) qp );
RES_RELEASE( &rt_g.res_syscall );
return;
}
void
warning( str )
char *str;
{
if( tty )
HmError( str );
else
prntScr( str );
return;
}
-468
View File
@@ -1,468 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#ifndef DEBUG
#define NDEBUG
#define STATIC static
#else
#define STATIC
#endif
#include <assert.h>
#include <stdio.h>
#include "./burst.h"
#include "./trie.h"
#include "./ascii.h"
#include "./extern.h"
STATIC Func *matchTrie();
/*
Trie *addTrie( char *name, Trie **triepp )
Insert the name in the trie specified by triepp, if it
doesn't already exist there.
Return pointer to leaf node associated with name.
*/
Trie *
addTrie( name, triepp )
register char *name;
register Trie **triepp;
{ register Trie *curp;
if( *name == NUL )
{ /* End of name, see if name already exists. */
if( *triepp == TRIE_NULL )
{ /* Name does not exist, make leaf node. */
NewTrie( *triepp );
(*triepp)->l.t_altr = (*triepp)->l.t_next
= TRIE_NULL;
(*triepp)->l.t_func = FUNC_NULL;
}
else
if( (*triepp)->n.t_next != TRIE_NULL )
/* Name is subset of another name. */
return addTrie( name, &(*triepp)->n.t_altr );
/* else -- Name already inserted, so do nothing. */
return *triepp;
}
/* Find matching letter, this level. */
for( curp = *triepp;
curp != TRIE_NULL && *name != curp->n.t_char;
curp = curp->n.t_altr
)
;
if( curp == TRIE_NULL )
{ /* No Match, this level, so create new alternate. */
curp = *triepp;
NewTrie( *triepp );
(*triepp)->n.t_altr = curp;
(*triepp)->n.t_char = *name;
(*triepp)->n.t_next = TRIE_NULL;
return addTrie( ++name, &(*triepp)->n.t_next );
}
else
/* Found matching character. */
return addTrie( ++name, &curp->n.t_next );
}
Func *
getTrie( name, triep )
register char *name;
register Trie *triep;
{ register Trie *curp;
/* Traverse next links to end of region name. */
for( ; triep != TRIE_NULL; triep = triep->n.t_next )
{
curp = triep;
if( *name == NUL )
{ /* End of user-typed name. */
if( triep->n.t_altr != TRIE_NULL )
/* Ambiguous at this point. */
return FUNC_NULL;
else /* Complete next character. */
{
*name++ = triep->n.t_char;
*name = NUL;
}
}
else
if( *name == '*' )
return matchTrie( triep );
else /* Not at end of user-typed name yet, traverse
alternate list to find current letter.
*/
{
for( ;
triep != TRIE_NULL
&& *name != triep->n.t_char;
triep = triep->n.t_altr
)
;
if( triep == TRIE_NULL )
/* Non-existant name, truncate bad part. */
{
*name = NUL;
return FUNC_NULL;
}
else
name++;
}
}
/* Clobber key-stroke, and return it. */
--name;
*name = NUL;
return curp->l.t_func;
}
#define MAX_TRIE_LEVEL (32*16)
STATIC Func *
matchTrie( triep )
register Trie *triep;
{ Func *func;
if( triep == TRIE_NULL )
func = FUNC_NULL;
else
if( triep->n.t_altr != TRIE_NULL )
func = FUNC_NULL; /* Ambiguous root, no match. */
else
if( triep->n.t_next == TRIE_NULL )
func = triep->l.t_func; /* At leaf node, return datum. */
else /* Keep going to leaf. */
func = matchTrie( triep->n.t_next );
return func;
}
void
prntTrie( triep, level )
Trie *triep;
int level;
{ register Trie *tp = triep;
static char name_buf[MAX_TRIE_LEVEL+1], *namep;
#if DEBUG_TRIE
rt_log( "prntTrie(triep=0x%x,level=%d)\n", triep, level );
#endif
if( tp == TRIE_NULL )
return;
if( tp->n.t_altr != TRIE_NULL )
prntTrie( tp->n.t_altr, level );
if( level == 0 )
namep = name_buf;
*namep = tp->n.t_char;
if( tp->n.t_next == TRIE_NULL )
{
/* At end of name, so print it out. */
*namep = NUL;
rt_log( "%s\n", name_buf );
}
else
{
namep++;
prntTrie( tp->n.t_next, level+1 );
namep--;
}
return;
}
int
writeTrie( triep, level, fp )
Trie *triep;
int level;
FILE *fp;
{ register Trie *tp = triep;
static char name_buf[MAX_TRIE_LEVEL+1], *namep;
if( tp == TRIE_NULL )
return 1;
if( tp->n.t_altr != TRIE_NULL )
(void) writeTrie( tp->n.t_altr, level, fp );
if( level == 0 )
namep = name_buf;
*namep = tp->n.t_char;
if( tp->n.t_next == TRIE_NULL )
{
/* At end of name, so print it out. */
*namep = NUL;
(void) fprintf( fp, "%s\n", name_buf );
}
else
{
namep++;
(void) writeTrie( tp->n.t_next, level+1, fp );
namep--;
}
return 1;
}
int
readTrie( fp, triepp )
FILE *fp;
Trie **triepp;
{ static char name_buf[MAX_TRIE_LEVEL+1];
while( fgets( name_buf, MAX_TRIE_LEVEL, fp ) != NULL )
{
name_buf[strlen(name_buf)-1] = '\0'; /* Clobber new-line. */
(void) addTrie( name_buf, triepp );
}
return 1;
}
void
ring_Bell()
{
(void) putchar( BEL );
return;
}
char *
char_To_String( i )
int i;
{ static char buf[4];
if( i >= SP && i < DEL )
{
buf[0] = i;
buf[1] = NUL;
}
else
if( i >= NUL && i < SP )
{
buf[0] = '^';
buf[1] = i + 64;
buf[2] = NUL;
}
else
if( i == DEL )
return "DL";
else
return "EOF";
return buf;
}
#if false
/*
Func *getFuncNm( char *inbuf, int bufsz, char *msg, Trie **triepp )
TENEX-style name completion.
Returns a function pointer.
*/
Func *
getFuncNm( inbuf, bufsz, msg, triepp )
char *inbuf;
int bufsz;
char *msg;
Trie **triepp;
{ static char buffer[BUFSIZ];
register char *p = buffer;
register int c;
Func *funcp;
if( tty )
{
save_Tty( 0 );
set_Raw( 0 );
clr_Echo( 0 );
}
prompt( msg );
*p = NUL;
do
{
(void) fflush( stdout );
c = hm_getchar();
switch( c )
{
case SP :
{
if( *triepp == TRIE_NULL
|| (funcp = getTrie( buffer, *triepp ))
== FUNC_NULL
)
(void) putchar( BEL );
for( ; p > buffer; p-- )
(void) putchar( BS );
(void) printf( "%s", buffer );
(void) ClrEOL();
(void) fflush( stdout );
p += strlen( buffer );
break;
}
case Ctrl('A') : /* Cursor to beginning of line. */
if( p == buffer )
{
ring_Bell();
break;
}
for( ; p > buffer; p-- )
(void) putchar( BS );
break;
case Ctrl('B') :
case BS : /* Move cursor back one character. */
if( p == buffer )
{
ring_Bell();
break;
}
(void) putchar( BS );
--p;
break;
case Ctrl('D') : /* Delete character under cursor. */
{ register char *q = p;
if( *p == NUL )
{
ring_Bell();
break;
}
for( ; *q != NUL; ++q )
{
*q = *(q+1);
(void) putchar( *q != NUL ? *q : SP );
}
for( ; q > p; --q )
(void) putchar( BS );
break;
}
case Ctrl('E') : /* Cursor to end of line. */
if( *p == NUL )
{
ring_Bell();
break;
}
(void) printf( "%s", p );
p += strlen( p );
break;
case Ctrl('F') : /* Cursor forward one character. */
if( *p == NUL || p-buffer >= bufsz-2 )
{
ring_Bell();
break;
}
(void) putchar( *p++ );
break;
case Ctrl('G') : /* Abort input. */
ring_Bell();
notify( "Aborted.", NOTIFY_APPEND );
goto clean_return;
case Ctrl('K') : /* Erase from cursor to end of line. */
if( *p == NUL )
{
ring_Bell();
break;
}
ClrEOL();
*p = NUL;
break;
case Ctrl('P') : /* Yank previous contents of "inbuf". */
{ register int len = strlen( inbuf );
if( (p + len) - buffer >= BUFSIZ )
{
ring_Bell();
break;
}
(void) strncpy( p, inbuf, bufsz );
(void) printf( "%s", p );
p += len;
break;
}
case Ctrl('U') : /* Erase from start of line to cursor. */
if( p == buffer )
{
ring_Bell();
break;
}
for( ; p > buffer; --p )
{ register char *q = p;
(void) putchar( BS );
for( ; *(q-1) != NUL; ++q )
{
*(q-1) = *q;
(void) putchar( *q != NUL ? *q : SP );
}
for( ; q > p; --q )
(void) putchar( BS );
}
break;
case Ctrl('R') : /* Print line, cursor doesn't move. */
{ register int i;
if( buffer[0] == NUL )
break;
for( i = p - buffer; i > 0; i-- )
(void) putchar( BS );
(void) printf( "%s", buffer );
for( i = strlen( buffer ) - (p - buffer); i > 0; i-- )
(void) putchar( BS );
break;
}
case DEL : /* Delete character behind cursor. */
{ register char *q = p;
if( p == buffer )
{
ring_Bell();
break;
}
(void) putchar( BS );
for( ; *(q-1) != NUL; ++q )
{
*(q-1) = *q;
(void) putchar( *q != NUL ? *q : SP );
}
for( ; q > p; --q )
(void) putchar( BS );
p--;
break;
}
case CR :
case LF :
case EOF :
if( *triepp == TRIE_NULL
|| (funcp = getTrie( buffer, *triepp ))
== FUNC_NULL
)
{
(void) putchar( BEL );
break;
}
else
{
(void) strncpy( inbuf, buffer, bufsz );
notify( NULL, NOTIFY_DELETE );
goto clean_return;
}
case Ctrl('V') :
/* Escape character, do not process next char. */
c = hm_getchar();
/* Fall through to default case! */
default : /* Insert character at cursor. */
{ register char *q = p;
register int len = strlen( p );
/* Scroll characters forward. */
if( c >= NUL && c < SP )
(void) printf( "%s", char_To_String( c ) );
else
(void) putchar( c );
for( ; len >= 0; len--, q++ )
(void) putchar( *q == NUL ? SP : *q );
for( ; q > p; q-- )
{
(void) putchar( BS );
*q = *(q-1);
}
*p++ = c;
break;
}
} /* End switch. */
}
while( strlen( buffer ) < BUFSIZ);
ring_Bell();
notify( "Buffer full.", NOTIFY_APPEND );
clean_return :
prompt( "" );
if( tty )
reset_Tty( 0 );
return funcp;
}
#endif
-48
View File
@@ -1,48 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
$Header$ (BRL)
*/
#ifndef INCL_TRIE
#define INCL_TRIE
#ifdef FUNC_NULL
#undef FUNC_NULL
#endif
#define FUNC_NULL ((Func *) NULL)
#define TRIE_NULL ((Trie *) NULL)
/* Datum for trie leaves. */
typedef void Func();
/* Trie tree node. */
typedef union trie Trie;
union trie
{
struct /* Internal nodes: datum is current letter. */
{
int t_char; /* Current letter. */
Trie *t_altr; /* Alternate letter node link. */
Trie *t_next; /* Next letter node link. */
}
n;
struct /* Leaf nodes: datum is function ptr. */
{
Func *t_func; /* Function pointer. */
Trie *t_altr; /* Alternate letter node link. */
Trie *t_next; /* Next letter node link. */
}
l;
};
#define NewTrie( p ) \
if( ((p) = (Trie *) malloc( sizeof(Trie) )) == TRIE_NULL )\
{\
Malloc_Bomb(sizeof(Trie));\
return TRIE_NULL;\
}
extern Trie *cmd_trie;
#endif /* INCL_TRIE */
-1625
View File
File diff suppressed because it is too large Load Diff
-100
View File
@@ -1,100 +0,0 @@
/*
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
$Header$
*/
#ifndef _POLY9
#include <math.h>
#endif
#ifndef Abs
#define Abs( a ) ((a) > 0 ? (a) : -(a))
#endif
#define AbsDotProd( A, B ) (Abs( Dot( A, B ) ))
#define AddVec( A, B ) { (A)[X] += (B)[X]; \
(A)[Y] += (B)[Y]; \
(A)[Z] += (B)[Z]; }
#define Add2Vec( A, B, C ) { (C)[X] = (A)[X]+(B)[X]; \
(C)[Y] = (A)[Y]+(B)[Y]; \
(C)[Z] = (A)[Z]+(B)[Z]; }
#define AproxEq( a, b, e ) (Abs( (a)-(b) ) < (e))
#define AproxEqVec( A, B, e ) ( AproxEq((A)[X],(B)[X],(e)) && \
AproxEq((A)[Y],(B)[Y],(e)) && \
AproxEq((A)[Z],(B)[Z],(e)) )
#define CopyVec( A, B ) { (A)[X] = (B)[X]; \
(A)[Y] = (B)[Y]; \
(A)[Z] = (B)[Z]; }
#define CrossProd( A, B, C ) { (C)[X] = (A)[Y]*(B)[Z]-(A)[Z]*(B)[Y]; \
(C)[Y] = (A)[Z]*(B)[X]-(A)[X]*(B)[Z]; \
(C)[Z] = (A)[X]*(B)[Y]-(A)[Y]*(B)[X]; }
#define DEGRAD 57.2957795130823208767981548141051703324054724665642
/* degrees per radian */
#define DiffVec( A, B ) { (A)[X] -= (B)[X]; \
(A)[Y] -= (B)[Y]; \
(A)[Z] -= (B)[Z]; }
#define Diff2Vec( A, B, C ) { (C)[X] = (A)[X]-(B)[X]; \
(C)[Y] = (A)[Y]-(B)[Y]; \
(C)[Z] = (A)[Z]-(B)[Z]; }
#define Dist3d( A, B ) (sqrt( Sqr((A)[X]-(B)[X])+\
Sqr((A)[Y]-(B)[Y])+\
Sqr((A)[Z]-(B)[Z]))\
)
#define DivideVec( A, S ) { (A)[X] /= (S); \
(A)[Y] /= (S); \
(A)[Z] /= (S); }
#define Dot( A, B ) ((A)[X]*(B)[X]+(A)[Y]*(B)[Y]+(A)[Z]*(B)[Z])
#ifndef EPSILON
#define EPSILON 0.000001
#endif
#define Expand_Vec_Int( V ) (int)(V)[X], (int)(V)[Y], (int)(V)[Z]
#define LOG10E 0.43429448190325182765112891891660508229439700580367
/* log of e to the base 10 */
#define Mag( A ) sqrt( AbsDotProd(A,A) )
#define Mag3(a1,a2,a3) (sqrt(Sqr(a1)+Sqr(a2)+Sqr(a3)))
#ifndef Min
#define Min( a, b ) ((a) < (b) ? (a) : (b))
#define Max( a, b ) ((a) > (b) ? (a) : (b))
#endif
#define MinMax( m, M, a ) { m = Min( m, a ); M = Max( M, a ); }
#define MinMaxVec( A, B, C ) { (A)[X] = Min( (A)[X], (C)[X] ); \
(A)[Y] = Min( (A)[Y], (C)[Y] ); \
(A)[Z] = Min( (A)[Z], (C)[Z] ); \
(B)[X] = Max( (B)[X], (C)[X] ); \
(B)[Y] = Max( (B)[Y], (C)[Y] ); \
(B)[Z] = Max( (B)[Z], (C)[Z] ); }
#define NearZero( a ) ((a) < EPSILON && (a) > -EPSILON)
#define NonZeroVec( V ) (!NearZero((V)[X]) || !NearZero((V)[Y])|| !NearZero((V)[Z]))
#define PI 3.14159265358979323846264338327950288419716939937511
/* ratio of circumf. to diam. */
#define RelDist3d( A, B ) (Sqr((A)[X]-(B)[X])+\
Sqr((A)[Y]-(B)[Y])+\
Sqr((A)[Z]-(B)[Z]))
#define ScaleVec( A, s ) { (A)[X] *= (s); \
(A)[Y] *= (s); \
(A)[Z] *= (s); }
#define Scale2Vec( A, s, B ) { (B)[X] = (A)[X] * (s); \
(B)[Y] = (A)[Y] * (s); \
(B)[Z] = (A)[Z] * (s); }
#define Sqr(a) ((a)*(a))
#define TWO_PI 6.28318530717958647692528676655900576839433879875022
/* Scale vector 'a' to have magnitude 'l'. */
#define V_Length( a, l ) \
{ double f, m; \
if( (m=Mag(a)) == 0.0 ) \
rt_log( "Magnitude is zero!\n" ); \
else \
{ \
f = (l)/m; \
(a)[X] *= f; (a)[Y] *= f; (a)[Z] *= f; \
} \
}
#define V_Print(a,b,func) \
func( "%s\t<%12.6f,%12.6f,%12.6f>\n", a, (b)[0], (b)[1], (b)[2] )
#ifndef X
#define X 0
#define Y 1
#define Z 2
#endif
-43
View File
@@ -1,43 +0,0 @@
Cake copying permission notice Copyright (C) 1987 Zoltan Somogyi
Cake is distributed in the hope that it will be useful, but without any
warranty. No author or distributor accepts responsibility to anyone for
the consequences of using it or for whether it serves any particular purpose
or works at all, unless he/she says so in writing.
Everyone is granted permission to copy, modify and redistribute Cake
under the following conditions:
Permission is granted to anyone to make or distribute verbatim copies
of Cake source code as received, in any medium, provided that all
copyright notices and permission and nonwarranty notices are preserved,
and that the distributor grants the recipient permission for further
redistribution as permitted by this document, and gives him/her and
points out to him/her an exact copy of this document to inform him/her
of his/her rights.
Permission is granted to distribute modified versions of Cake source
code, or of portions of it, under the above conditions, provided also
that all changed files carry prominent notices stating who last changed
them and that all the Cake-derived material, including everything
packaged together with it and not independently usable, is distributed
under the conditions stated in this document.
Permission is granted to distribute Cake in compiled or executable form
under the same conditions applying for source code, provided that either
A it is accompanied by the corresponding machine-readable source
code, or
B it is accompanied by a written offer, with no time limit, to
give anyone a machine-readable copy of the corresponding source
code in return for reimbursement of the cost of distribution.
This written offer must permit verbatim duplication by anyone.
C it is distributed by someone who received only the executable
form, and is accompanied by a copy of the written offer of
source code which he/she received along with it.
In other words, you are welcome to use, share and improve Cake.
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
This copyright notice was adapted from the one supplied with GNU Emacs.
-100
View File
@@ -1,100 +0,0 @@
# Makefile for Cake
#
#$Header$
SHELL=/bin/sh
# -DATT for SystemV, -DBSD for Berkeley, done by machinetype.sh
#
# For Apollo, may need to add -Tbsd4.3
COPTS = -DCAKEDEBUG -DYYDEBUG -DCAREFUL -D`machinetype.sh -a`
BINDIR=/usr/brlcad/bin
#LDFLAGS=-k 64k
HDR = cake.h conf.h port.h
SRC = act.c chase.c entry.c error.c expand.c file.c \
list.c main.c make.c mem.c pat.c print.c proc.c \
sym.c sys.c table.c test.c trail.c
OBJ = act.o chase.o entry.o error.o expand.o file.o \
list.o main.o make.o mem.o pat.o print.o proc.o \
sym.o sys.o table.o test.o trail.o
GEN = cake_g.y cake_s.l
GHDR = cake_g.h
GSRC = cake_g.c cake_s.c
GOBJ = cake_g.o cake_s.o
CFLAGS= $(COPTS)
cake: $(OBJ) $(GOBJ)
$(CC) $(LDFLAGS) $(CFLAGS) -o cake $(OBJ) $(GOBJ)
# -/bin/rm fake
# ln cake fake
all: cake lint tags
install: cake
-if test -f $(BINDIR)/cake; then \
mv -f $(BINDIR)/cake $(BINDIR)/cake.bak; fi
mv cake $(BINDIR)/cake
$(OBJ): $(HDR)
$(GOBJ): $(HDR)
cake_g.c: cake_g.y
yacc -dv cake_g.y
mv -f y.tab.h cake_g.h
mv -f y.tab.c cake_g.c
mv -f y.output cake_g.t
cake_s.c: cake_s.l
lex cake_s.l
mv -f lex.yy.c cake_s.c
var: $(SRC) $(GSRC)
var -DATT $(COPTS) $(SRC) $(GSRC) > Var
plint: $(SRC) $(GSRC)
lint -acpx $(COPTS) $(SRC) $(GSRC) > Lint_errs
ulint: $(SRC) $(GSRC)
lint -v $(COPTS) $(SRC) $(GSRC) > Lint_errs
lint: $(SRC) $(GSRC)
lint -v $(COPTS) $(SRC) $(GSRC) > Lint_errs
@gred yy Lint_errs
@gred malloc Lint_errs
@gred strcpy Lint_errs
@gred strcat Lint_errs
@gred printf Lint_errs
@gred flsbuf Lint_errs
@gred setbuf Lint_errs
@gred rcs_id Lint_errs
@gred longjmp Lint_errs
@gred sbrk Lint_errs
cchk: $(SRC)
cchk $(SRC) > Cchk_errs
tags: $(SRC) $(GSRC)
ctags $(SRC) $(GSRC)
cxref: $(SRC)
cxref -C $(SRC) > Cxref
ssize:
ssize $(SRC) $(GEN)
asize:
ssize $(SRC) $(GEN) $(GSRC)
clean:
/bin/rm -f cake_g.h cake_g.t \
Make_errs Lint_errs Cchk_errs core \
$(OBJ) $(GOBJ) $(GSRC)
gclean:
/bin/rm -f $(GSRC) $(GHDR)
clobber: clean
/bin/rm -f cake fake
-121
View File
@@ -1,121 +0,0 @@
This is the root directory of the cake distribution.
This directory contains the sources for the cake command itself.
Its subdirectories contain sources for commands used by the standard
cakefiles (Aux), diffs for a modified version of the lex driver (Lex),
"standard" cakefiles (Lib), manuals and a paper on cake (Man), and
commands implemented by scripts (Script). Each subdirectory contains
its own README file; you should have a look at them. The rest of this
file is just for the cake source.
Cake was developed on a 3240 under 4.2BSD Unix, with an early version
on a Pyramid 90x (in the Berkeley universe). It has been tested on a
VAX-11/780 under 4.3BSD, on a Sun under SunOS 3.4, and on an ELXSI 6400
under both 4.2BSD and System V. It should also be portable to other
configurations. Its parameters are concentrated in the Makefile and
in conf.h, but you should have a look at Lex/README *before* you run
"make install".
Makefile:
The four make variables you should have a look at and maybe change
are DEST, COPTS, CFLAGS, and LDFLAGS. DEST and CFLAGS should be
self-explanatory. LDFLAGS as it is just sets the max stack size
on the 3240 (a segmented non-paged machine) - on other machines
an empy LDFLAGS should do just fine. The macros you can choose from
for COPTS are:
ATT is for AT&T variants of Unix. Cake has not been tested extensively
for these, but it has been in use for a while now on an Elxsi 6400
running Enix, a System V port. Defining ATT shortens variable names
to ensure that all are unique in the first six characters (see port.h)
and that no two variable names differ only in case. This effect depends
on the C preprocessor being able to handle long case-sensitive variable
names, even if the compiler/loader can't handle them. Defining ATT makes
cake call System V system calls instead of Berkeley ones, and does a few
other things as well. It may or may not work for System III.
CAKEDEBUG, when defined, enables cake to output debugging information
of various kinds, either on abnormal termination or in response to
debugging options (see main.c). The option -Y requires YYDEBUG
to debug the parser actions.
CAREFUL is a safety feature. It prevents cake from removing user files,
even when its semantics call for it (see the -G option). It moves files
to /tmp instead. This can slow cake down, so if you think it is not
necessary (e.g. because you have used cake long enough to be confident
that it will not delete files it should not delete or because you do
frequent backups) you should not define CAREFUL.
EXTRACHECK is another safety feature - it enables extra internal
consistency checks. These are fairly cheap, so you may keep them
unless you are hurting for CPU time. The one specific instance you
may want to delete is the one in mem.c which checks the aligment
of malloc returns.
If you are concerned about memory usage, you may want to define MEMUSED,
without which cake never free()s space. However, the opportunities for
savings are minimal (really!); and you should also keep in mind that
cake has never been tested with MEMUSED.
conf.h:
Cast should be a type to which all kinds of pointers can be converted
forward and back without loss. On most machines int will do.
SLIB is the directory containing the "standard" systemwide library
(which is in the Lib subdirectory in the distribution), while ULIB
is the suffix (after $HOME) of people's own cake library.
CPP is the command to invoke the C preprocessor.
STATS_FILE is the name of the file in which each invocation of cake
puts statistics. If you don't define STATS_FILE, cake does not keep
any stats. If you do, the stats are reported (nicely formatted)
by Script/{cs,ccs}.
Cake parses and execs normal (non-script) actions by itself if they
don't contain any chars from the macro METACHARS. If they do, cake
calls SYSTEM_CMD, while it calls SCRIPT_CMD for scripts. The arg
to SYSTEM_CMD is the command itself, while the arg to SCRIPT_CMD
is the name of a file (in /tmp) which contains the script. To convert
to the Bourne shell, change csh to sh and delete the -f flags.
For other shells, you will have to find out how to get equivalent
behaviour, but keep in mind that Unix restricts you to zero or one
arguments.
For ATT systems, TIMERES is the resulotion of the times() system call,
but this is used only for stats.
GENESIS is just a time() value used internally for time when there is
none applicable. It doesn't really matter what it is, as long as it
precedes all valid values.
CHASEROOT is also a name used only internally - it too could be anything
as long as it does not conflict with real filenames.
The other macros in conf.h define the (maximum) sizes of various kinds
of things. You need to check only CHARSETSIZE, which should be 512 for
9-bit byte systems. You should enlarge the others when somebody gets
a bounds exceeded message.
Conditions:
The copying conditions for the cake distribution are in the file
COPYING. It is patterned after the copying conditions of GNU,
in particular GNU Emacs. Basically, you can do anything with it
except prevent other people from getting access to it. This
means that you can't sell it. For the reasons for these conditions,
read Stallman's GNU manifesto.
Author:
Zoltan Somogyi
Department of Computer Science
University of Melbourne
Parkville, 3052 Victoria, Australia
UUCP: {uunet,mcvax,ukc}!munnari.oz!zs
ARPA: zs%munnari.oz@uunet.uu.net
CSNET: zs%munnari.oz@australia
-671
View File
@@ -1,671 +0,0 @@
/*
** Module to execute Cake actions.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
/*
** Update the node by executing the attached actions.
** Actually, all the buddies will be updated, and
** no action will be executed unless it is necessary.
**
** The level of a file is one greater than the level of its
** parent in the chase graph; the level of !MAINCAKE! is 0.
** This controls the printing of messages about the primary
** targets.
*/
update(node, level, force_exec)
reg Node *node;
reg int level;
reg bool force_exec;
{
extern get_utime();
extern save_novol();
extern bool diff_novol();
extern Wait carry_out();
extern char *list_names();
reg Node *bnode, *onode;
reg List *ptr, *ptr1;
reg bool oksofar, needact, mayskip;
reg List *errnodes;
Wait code;
put_trail("update", "start");
cdebug("hunting %s at level %d\n", node->n_name, level);
/* force printing of "up-to-date" messages */
if (level == 0 && is_ok(node))
node->n_kind = n_CANDO;
if (off_node(node, nf_ERR) && is_ok(node))
{
cdebug("everything a-ok, nothing to do\n");
if (level == 1)
{
if (on_node(node, nf_ORIG))
{
printf("cake: target %s has no ancestors\n", node->n_name);
node->n_kind = n_NOWAY;
}
or (! xflag)
printf("cake: %s is up to date\n", node->n_name);
}
put_trail("update", "finish");
return;
}
#ifdef CAKEDEBUG
if (cakedebug)
{
printf("level %d starting update of\n", level);
print_node(node);
}
#endif
if (on_node(node, nf_ERR))
{
trace_errs(node);
return;
}
errnodes = NULL;
/* skip the actions if they are useless or not needed */
oksofar = TRUE;
needact = FALSE;
mayskip = FALSE;
for_list (ptr, node->n_new)
{
bnode = (Node *) ldata(ptr);
if (on_node(bnode, nf_ERR))
{
oksofar = FALSE;
errnodes = addtail(errnodes, bnode);
}
else
{
if (off_node(bnode, nf_EXIST) || bnode->n_rtime < bnode->n_utime)
needact = TRUE;
if (on_node(bnode, nf_DEPNONVOL))
mayskip = TRUE;
}
}
if (! oksofar)
{
cdebug("error in buddies\n");
if (vflag && strdiff(node->n_name, CHASEROOT))
{
sprintf(scratchbuf, "cannot proceed with update of %s because of problems with %s %s",
node->n_name, (length(errnodes) == 1)? "buddy": "buddies", list_names(errnodes));
add_error(node, new_name(scratchbuf), errnodes, TRUE);
trace_errs(node);
}
goto endit;
}
if (! needact)
{
cdebug("no need for actions\n");
if (strdiff(node->n_name, CHASEROOT))
printf("cake: %s is up to date\n", node->n_name);
goto endit;
}
/* update all ancestors of all buddies */
for_list (ptr, node->n_new)
{
bnode = (Node *) ldata(ptr);
for_list (ptr1, bnode->n_old)
{
onode = (Node *) ldata(ptr1);
update(onode, level+1, force_exec);
if (on_node(onode, nf_ERR) || ! is_ok(onode))
{
oksofar = FALSE;
errnodes = addtail(errnodes, onode);
}
}
}
/* skip the actions if any ancestors are missing */
if (! oksofar)
{
cdebug("error in prerequisites\n");
if (vflag && strdiff(node->n_name, CHASEROOT))
{
sprintf(scratchbuf, "cannot proceed with update of %s because of problems with %s %s",
node->n_name, (length(errnodes) == 1)? "ancestor": "ancestors", list_names(errnodes));
add_error(node, new_name(scratchbuf), errnodes, TRUE);
trace_errs(node);
}
goto endit;
}
/* skip the actions; node is a missing base file */
if (is_noway(node))
{
cdebug("error in planning\n");
trace_errs(node);
goto endit;
}
/* find any NOWAY buddies; these may have n_old == [] */
for_list (ptr, node->n_new)
{
bnode = (Node *) ldata(ptr);
if (is_noway(bnode))
{
oksofar = FALSE;
errnodes = addtail(errnodes, bnode);
}
}
/* skip the actions if there are any NOWAY buddies */
if (! oksofar)
{
cdebug("error in buddy planning\n");
sprintf(scratchbuf, "dare not update %s because of possible effects on %s %s", node->n_name,
(length(errnodes) == 1)? "buddy": "buddies", list_names(errnodes));
add_error(node, new_name(scratchbuf), LNULL, TRUE);
trace_errs(node);
goto endit;
}
/* reevaluate the necessity to act in the light of the */
/* actions taken to update possibly nonvolatile ancestors */
if (mayskip)
{
needact = FALSE; /* assume so for the moment */
cdebug("deciding whether to skip\n");
for_list (ptr, node->n_new)
{
bnode = (Node *) ldata(ptr);
if (on_node(bnode, nf_DEPNONVOL))
{
cdebug("considering %s\n", bnode->n_name);
get_utime(bnode, FALSE);
}
if (off_node(bnode, nf_EXIST) || bnode->n_rtime < bnode->n_utime)
{
cdebug("%s needs action\n", bnode->n_name);
needact = TRUE;
}
}
}
if (! needact)
{
cdebug("no need for actions after all\n");
if (strdiff(node->n_name, CHASEROOT))
printf("cake: %s is up to date\n", node->n_name);
goto endit;
}
if (tflag)
{
/* instead of action just touch the targets */
for_list (ptr, node->n_new)
{
bnode = (Node *) ldata(ptr);
if (on_node(bnode, nf_PSEUDO))
continue;
if (rflag)
cake_utimes(bnode, bnode->n_utime);
else
cake_utimes(bnode, GENESIS);
printf("touch %s\n", bnode->n_name);
}
}
else
{
/* prepare for actions */
for_list (ptr, node->n_new)
{
bnode = (Node *) ldata(ptr);
if (on_node(bnode, nf_NONVOL))
save_novol(bnode);
}
/* execute actions */
code = carry_out(node, force_exec);
if (code.w_status != 0)
{
oksofar = FALSE;
sprintf(scratchbuf, "error in actions for %s", node->n_name);
for_list (ptr, node->n_new)
{
bnode = (Node *) ldata(ptr);
add_error(bnode, new_name(scratchbuf), LNULL, TRUE);
}
if (! xflag)
{
if (code.w_termsig == 0)
printf("*** Error code %d\n", code.w_retcode);
else
printf("*** Termination code %d\n", code.w_termsig);
}
cake_error(node);
goto endit;
}
/* clean up after actions */
for_list (ptr, node->n_new)
{
bnode = (Node *) ldata(ptr);
if (on_node(bnode, nf_NONVOL) && ! diff_novol(bnode))
node_resetstat(bnode);
or (rflag)
node_setstat(bnode);
else
node_stat(bnode);
}
}
endit:
cdebug("update level %d finished\n", level);
for_list (ptr, node->n_new)
{
bnode = (Node *) ldata(ptr);
if (oksofar)
{
if (on_node(bnode, nf_EXIST) || on_node(bnode, nf_PSEUDO) || nflag)
bnode->n_kind = n_OK;
else
{
set_node(bnode, nf_ERR);
if (length(node->n_act) == 0)
sprintf(scratchbuf, "no actions to make %s with", bnode->n_name);
else
sprintf(scratchbuf, "action did not create %s", bnode->n_name);
add_error(bnode, new_name(scratchbuf), LNULL, TRUE);
trace_errs(bnode);
}
}
#ifdef CAKEDEBUG
if (cakedebug)
print_node(bnode);
#endif
}
put_trail("update", "finish");
}
/*
** Execute the plan prepared by chase.c
** Prevent the deletion of the primary targets by cleanup.
*/
execute(root)
reg Node *root;
{
reg List *ptr;
reg Node *target;
#ifdef CAKEDEBUG
if (cakedebug) { /* BRL */
cdebug("execute plan:\n");
print_node(root);
}
#endif
for_list (ptr, root->n_old)
{
target = (Node *) ldata(ptr);
set_node(target, nf_NODELETE);
}
update(root, 0, FALSE);
}
/*
** Carry out the specified actions and return the exit code.
** Note that an empty list of actions is perfectly acceptable.
*/
#define START_SCRIPT "{"
#define FINISH_SCRIPT "}"
Wait
carry_out(node, force_exec)
reg Node *node;
reg bool force_exec;
{
extern char *expand_cmds();
extern Wait action();
reg List *ptr;
reg Act *act;
reg Node *bnode;
Wait code;
#ifdef CAKEDEBUG
if (cakedebug) { /* BRL */
cdebug("carry_out plan:\n");
print_node(node);
}
#endif
if (Gflag && ! nflag)
{
for_list (ptr, node->n_new)
{
bnode = (Node *) ldata(ptr);
if (on_node(bnode, nf_EXIST))
{
cdebug("removing %s for -G\n", bnode->n_name);
cake_remove(bnode->n_name);
}
}
}
for_list (ptr, node->n_act)
{
act = (Act *) ldata(ptr);
if (nflag)
{
if (off_act(act, af_MINUSN) && ! force_exec)
show_act(act->a_str, (char *) NULL);
else
{
reset_act(act, af_SILENT);
printf("executing ...\n");
code = action(act, node);
printf("... done\n");
if (code.w_status != 0)
return code;
}
continue;
}
code = action(act, node);
if (code.w_status != 0)
return code;
}
code.w_status = 0;
return code;
}
/*
** Execute the given command and return its status,
** modified by flags and prefixes.
*/
Wait
action(act, node)
reg Act *act;
reg Node *node;
{
extern int cake_proc();
extern Wait cake_wait();
Wait code;
reg A_kind type;
reg int pid;
reg char *after;
if( cakedebug ) { /* BRL */
cdebug("action(): ", act->a_str, node);
print_act(act);
cdebug("\n");
}
if( act->a_str == NULL || strlen(act->a_str) <= 0 ) { /* BRL */
printf("NOTE: Null action skipped\n");
code.w_status = 0;
return(code);
}
put_trail("action", "start");
after = expand_cmds(act->a_str);
if (! (on_act(act, af_SILENT) || sflag))
show_act(act->a_str, after);
act->a_str = after;
if (on_act(act, af_SCRIPT))
type = Script;
or (on_act(act, af_SYSTEM))
type = System;
else
type = Exec;
pid = cake_proc(act->a_str, type, (char *) NULL, node, (int (*)()) NULL, (List *) NULL);
code = cake_wait(pid);
if (on_act(act, af_IGNORE) || iflag)
code.w_status = 0;
if (code.w_status != 0 && ! kflag)
exit_cake(FALSE);
put_trail("action", "finish");
return code;
}
/*
** Print an action in the format specified by the options.
** The two args are the action before and after expansion.
** The second may be NULL, in which case show_act does the
** expansion itself.
*/
show_act(before, after)
reg char *before;
reg char *after;
{
extern char *squeeze();
reg char *form;
if (bflag)
form = before;
or (after != NULL)
form = after;
else
form = expand_cmds(before);
if (wflag)
printf("%s", form);
else
printf("%s", squeeze(form));
}
/*
** Reduce the width of the given command string
** by squeezing out extra spaces and tabs.
*/
char *
squeeze(cmd)
reg char *cmd;
{
char buf[MAXSIZE];
reg char *s;
reg int i, oldi;
reg bool inquotes;
reg bool insingle;
reg bool indouble;
reg bool lastblank;
s = cmd;
i = 0;
lastblank = FALSE;
while (*s != '\0')
{
while (*s != '\0' && (*s == ' ' || *s == '\t'))
s++;
if (lastblank && (*s == '\n' || *s == '\r' || *s == '\f'))
i--;
oldi = i;
inquotes = FALSE;
for (; *s != '\0' && ((*s != ' ' && *s != '\t') || inquotes); s++)
{
if (*s == '\\')
{
buf[i++] = *s;
if (s[1] != '\0')
buf[i++] = *++s;
}
else
{
if (*s == '"' && ! (inquotes && insingle))
{
inquotes = ! inquotes;
indouble = TRUE;
insingle = FALSE;
}
or (*s == '\'' && ! (inquotes && indouble))
{
inquotes = ! inquotes;
insingle = TRUE;
indouble = FALSE;
}
buf[i++] = *s;
}
}
if (i == oldi || buf[i-1] == '\n' || buf[i-1] == '\r' || buf[i-1] == '\f')
lastblank = FALSE;
else
{
lastblank = TRUE;
buf[i++] = ' ';
}
}
buf[i] = '\0';
if (i >= MAXSIZE)
{
fprintf(stderr, "cake internal error: command '%s' too long\n", buf);
exit_cake(FALSE);
}
while (buf[i-1] == ' ' || buf[i-1] == '\t')
buf[--i] = '\0';
return new_name(buf);
}
/*
** Clean up after an error or interrupt.
*/
cake_error(node)
reg Node *node;
{
reg List *ptr, *ptr1;
reg Node *bnode, *onode;
for_list (ptr, node->n_new)
{
bnode = (Node *) ldata(ptr);
for_list (ptr1, bnode->n_old)
{
onode = (Node *) ldata(ptr1);
set_node(onode, nf_NODELETE);
}
if (on_node(bnode, nf_EXIST) && off_node(bnode, nf_PRECIOUS))
cake_remove(bnode->n_name);
}
}
/*
** Clean up after all the fuss.
*/
cleanup()
{
extern List *get_allnodes();
reg List *ptr, *ptr1;
reg List *nodes;
reg Node *node, *onode;
cdebug("cleanup:\n");
if (nflag)
return;
nodes = get_allnodes();
for_list (ptr, nodes)
{
node = (Node *) ldata(ptr);
cdebug("considering %s: ", node->n_name);
if (off_node(node, nf_EXIST))
{
cdebug("nonexistent\n");
continue;
}
if (on_node(node, nf_ERR) || is_noway(node))
{
cdebug("errors or noway\n");
continue;
}
if (! dflag && off_node(node, nf_REDUNDANT))
{
cdebug("no flag\n");
continue;
}
/* file exists and OK, shall we delete it ? */
/* not if we thought earlier it need it */
if (on_node(node, nf_NODELETE))
{
cdebug("nodelete flag\n");
continue;
}
/* not if it cannot be regenerated at all */
if (length(node->n_act) == 0)
{
cdebug("nonregenerable\n");
continue;
}
/* not if it cannot be regenerated as is */
if ((node->n_utime < node->n_rtime) && off_node(node, nf_NEWFILE))
{
cdebug("nonregenerable as is\n");
continue;
}
/* or if its ancestors are not all OK */
for_list (ptr1, node->n_old)
{
onode = (Node *) ldata(ptr1);
if (! is_ok(onode))
{
cdebug("ancestor not ok\n");
goto nextnode;
}
}
cdebug("DELETED\n");
cake_remove(node->n_name);
nextnode: ;
}
}
-137
View File
@@ -1,137 +0,0 @@
/*
** Cake definitions.
**
** $Header$
*/
#include <sys/types.h>
#include <stdio.h>
#include "std.h"
#include "conf.h"
#include "wait.h"
#include "list.h"
#include "table.h"
#define nf_NONVOL 0x0001
#define nf_PRECIOUS 0x0002
#define nf_PSEUDO 0x0004
#define nf_REDUNDANT 0x0008
#define nf_WHEN 0x0010
#define nf_DEPNONVOL 0x0020
#define nf_NODELETE 0x0040
#define nf_NEWFILE 0x0080
#define nf_EXIST 0x0100
#define nf_BUSY 0x0200
#define nf_ERR 0x0400
#define nf_TRACED 0x0800
#define nf_WARNED 0x1000
#define nf_ORIG 0x2000
#define af_SILENT 0x0001
#define af_IGNORE 0x0002
#define af_MINUSN 0x0004
#define af_SYSTEM 0x0008
#define af_SCRIPT 0x0010
/* type of internal patterns */
typedef struct s_pat
{
char *p_str;
short p_flag;
short p_cmd;
} Pat;
/* type of internal actions */
typedef struct s_act
{
char *a_str;
short a_flag;
} Act;
/* kinds of actions */
typedef enum
{
Exec, System, Script
} A_kind;
/* kinds of tests */
typedef enum
{
t_TRUE, t_FALSE, t_AND, t_OR, t_NOT,
t_CMD, t_MATCH, t_LIST, t_EXIST, t_CANDO, t_OK
} T_kind;
/* type of tests */
typedef struct s_test
{
T_kind t_kind;
Pat *t_pat;
List *t_list; /* of Pat(L), char(M) */
char *t_cmd;
struct s_test *t_left;
struct s_test *t_right;
} Test;
/* type of substitution variables */
typedef struct s_var
{
char *v_val;
bool v_bound;
} Var;
#define NOVAR 10
#define MAXVAR 11
/* type of substitution environments */
typedef Var Env[MAXVAR];
/* type of entries */
typedef struct s_entry
{
char *e_file;
List *e_new; /* of Pat */
List *e_old; /* of Pat */
List *e_when; /* of Pat */
List *e_act; /* of Act */
Test *e_cond;
bool e_dblc;
} Entry;
typedef enum
{
n_OK, n_CANDO, n_NOWAY
} N_kind;
/* type of nodes in the dependency graph */
typedef struct s_node
{
char *n_name; /* name of the node */
N_kind n_kind; /* current status of the chase */
int n_flag; /* the applicable nf_[A-Z]* */
time_t n_rtime; /* Real modify time if exist */
time_t n_stime; /* Saved copy of n_rtime */
time_t n_utime; /* last ancestor Update time */
List *n_new; /* left side or rule, of Node */
List *n_old; /* right side of rule, of Node */
List *n_when; /* starred right side, of Pat */
List *n_act; /* the actions, of Act */
#if 0 /* N must be 1 for the time being */
int n_pid; /* current update process */
char *n_file; /* name of output file */
#endif
char *n_msg; /* error message, if nf_ERR */
List *n_badguys; /* error causes, if nf_ERR */
} Node;
typedef struct s_proc
{
int pr_pid;
bool pr_run;
Wait pr_stat;
int (*pr_func)();
List *pr_args;
Node *pr_node;
} Proc;
#include "extern.h"
#include "macro.h"
-202
View File
@@ -1,202 +0,0 @@
%{
/*
** Grammar for Cakefiles
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
#include <ctype.h>
extern List *set_flag();
extern int yylineno;
extern char *yyfile;
%}
%start file
%union
{
int Uint;
char *Ustr;
List *Ulist;
Entry *Uent;
Test *Utest;
Act *Uact;
Pat *Upat;
}
%token NL EMPTYLINE
%token NONVOL PRECIOUS REDUNDANT PSEUDO WHEN
%token IF IN MATCH EXIST CANDO OK
%token LPAREN RPAREN
%token <Ustr> COLON PAT PATCMD TESTCMD
%token <Uact> BEGIN_ACT ACT END_ACT
%token GARBAGE
%left OR
%left AND
%left NOT
%type <Uent> rule
%type <Utest> cond test
%type <Upat> basepat
%type <Uact> act
%type <Uint> flag flag_el
%type <Ulist> pat
%type <Ulist> rule_l ACT_el act_el pat_el pat_l
%%
/**********************************************************************/
/* Entries */
file : empty_el ent_esl empty_el
;
entry : rule_l act_el
{ new_entry($1, $2); }
;
rule : pat_l COLON pat_el cond NL
{ $$ = make_dep($1, $3, $4, new_name(yyfile), $2); }
;
cond : IF test
{ $$ = $2; }
| /* empty */
{ $$ = (Test *) NULL; }
;
test : basepat IN pat_l
{ $$ = make_test_l($1, $3); }
| basepat MATCH basepat
{ $$ = make_test_m($1, (Pat *) NULL, $3);}
| basepat MATCH basepat basepat
{ $$ = make_test_m($1, $3, $4); }
| EXIST basepat
{ $$ = make_test_s(t_EXIST, $2); }
| CANDO basepat
{ $$ = make_test_s(t_CANDO, $2); }
| OK basepat
{ $$ = make_test_s(t_OK, $2); }
| TESTCMD
{ $$ = make_test_c($1); }
| test AND test
{ $$ = make_test_b(t_AND, $1, $3);}
| test OR test
{ $$ = make_test_b(t_OR, $1, $3); }
| NOT test
{ $$ = make_test_u(t_NOT, $2); }
| LPAREN test RPAREN
{ $$ = $2; }
;
act : ACT
{ $$ = $1; }
| BEGIN_ACT ACT_el END_ACT
{ $$ = prep_script($1, $2, $3); }
;
basepat : PAT
{ $$ = make_pat($1, FALSE, 0); }
| PATCMD
{ $$ = make_pat($1, TRUE, 0); }
;
pat : basepat flag_el
{ $$ = set_flag(makelist($1), $2);}
| LPAREN pat_l RPAREN flag_el
{ $$ = set_flag($2, $4); }
;
flag : NONVOL
{ $$ = nf_NONVOL; }
| PRECIOUS
{ $$ = nf_PRECIOUS; }
| REDUNDANT
{ $$ = nf_REDUNDANT; }
| PSEUDO
{ $$ = nf_PSEUDO; }
| WHEN
{ $$ = nf_WHEN; }
;
/* From here on, the grammar is JUNK */
/**********************************************************************/
/* Lists */
ent_esl : entry
| ent_esl empty_l entry
;
rule_l : rule
{ $$ = makelist($1); }
| rule_l rule
{ $$ = addtail($1, $2); }
;
ACT_el : /* empty */
{ $$ = makelist0(); }
| ACT_el ACT
{ $$ = addtail($1, $2); }
;
act_el : /* empty */
{ $$ = makelist0(); }
| act_el act
{ $$ = addtail($1, $2); }
;
pat_el : /* empty */
{ $$ = makelist0(); }
| pat_l
{ $$ = $1; }
;
pat_l : pat
{ $$ = $1; }
| pat_l pat
{ $$ = addlist($1, $2); }
;
flag_el : /* empty */
{ $$ = 0; }
| flag_el flag
{ $$ = $1 | $2; }
;
empty_el: /* empty */
| empty_l
;
empty_l : EMPTYLINE
| empty_l EMPTYLINE
;
%%
yyerror(s)
char *s;
{
extern int yyleng;
extern char yytext[];
char buf[80];
if (yychar <= 0)
{
sprintf(buf, "premature EOF");
yylineno--;
}
or (yytext[0] == '\n' || yytext[0] == '\f')
sprintf(buf, "%s at end of line", s);
or (isprint(yytext[0]))
sprintf(buf, "%s at symbol %s", s, yytext);
else
sprintf(buf, "%s at \\%o", s, yytext[0]);
if (cakedebug)
printf("%s, %d: %s, token %d\n", yyfile, yylineno, buf, yychar);
else
printf("%s, %d: %s\n", yyfile, yylineno, buf);
}
-371
View File
@@ -1,371 +0,0 @@
%{
/*
** Scanner for Cake
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
#include "cake_g.h"
#include <ctype.h>
#ifdef CAKEDEBUG
#define ret(x) if (lexdebug) printf("lex: x\n"); return x
#else
#define ret(x) return x
#endif
/* YYLMAX must be defined here; it can't be defined in conf.h */
#undef YYLMAX
#define YYLMAX MAXLEXBUF
#define LATE_CATCH
#define LATE_RECOVERY printf("cake: token '%s' is too long\n", yytext); \
exit(1);
#define LBRACE '{'
#define RBRACE '}'
extern char *yysquare();
extern char *yycurly();
extern int lexdebug;
char *yyfile = "no input file";
bool afterifdef = FALSE;
%}
%a 2500
%o 5000
%start edge middle
pat [a-zA-Z_0-9/%+-.,]
sp [ \t]
nl [\n\f]
nonl [^\n\f]
enonl ({nonl}|\\{nl})
%%
"if" { BEGIN middle; ret(IF); }
"and" { BEGIN middle; ret(AND); }
"or" { BEGIN middle; ret(OR); }
"not" { BEGIN middle; ret(NOT); }
"in" { BEGIN middle; ret(IN); }
"match" { BEGIN middle; ret(MATCH); }
"exist" { BEGIN middle; ret(EXIST); }
"cando" { BEGIN middle; ret(CANDO); }
"ok" { BEGIN middle; ret(OK); }
"(" { BEGIN middle; ret(LPAREN); }
")" { BEGIN middle; ret(RPAREN); }
"@" { BEGIN middle; ret(NONVOL); }
"!" { BEGIN middle; ret(PRECIOUS); }
"&" { BEGIN middle; ret(PSEUDO); }
"^" { BEGIN middle; ret(REDUNDANT); }
"*" { BEGIN middle; ret(WHEN); }
":" |
"::" {
BEGIN middle;
yylval.Ustr = new_name(yytext);
ret(COLON);
}
({pat}|\\{nonl})+ {
BEGIN middle;
yylval.Ustr = new_name(yytext);
ret(PAT);
}
\"([^"]|\\\")*\" {
BEGIN middle;
/* strip off quotes */
yytext[yyleng-1] = '\0';
yylval.Ustr = new_name(yytext+1);
ret(PAT);
}
"[[" {
BEGIN middle;
yylval.Ustr = yysquare();
ret(PATCMD);
}
"{{" {
BEGIN middle;
yylval.Ustr = yycurly();
ret(TESTCMD);
}
<middle>({sp}|\\{nl})* { BEGIN middle; }
<edge>[@!+-]*"{"{enonl}*{nl} |
<edge>[@!+-]*"}"{enonl}*{nl} |
<edge>{sp}+{enonl}+{nl} {
BEGIN edge;
afterifdef = FALSE;
yylval.Uact = prep_act(yytext);
/* comment out check_actlen if */
/* have a lex driver with CATCH */
check_actlen();
/* braces around ret ARE needed */
/* as ret expands to an if stmt */
if (yylval.Uact->a_str[0] == LBRACE)
{
ret(BEGIN_ACT);
}
or (yylval.Uact->a_str[0] == RBRACE)
{
ret(END_ACT);
}
else
{
ret(ACT);
}
}
<edge>"set"{nonl}*{nl} {
BEGIN edge;
if (lexdebug)
printf("set line\n");
yyset(yytext);
}
<edge>#{nonl}*{nl} {
BEGIN edge;
if (lexdebug)
printf("hash line\n");
yyhash(yytext);
if (! afterifdef)
ret(EMPTYLINE);
}
<edge>{sp}*{nl} {
BEGIN edge;
if (lexdebug)
printf("empty line\n");
if (! afterifdef)
ret(EMPTYLINE);
}
<middle>{nl} {
BEGIN edge;
afterifdef = FALSE;
ret(NL);
}
{nonl} { BEGIN middle; ret(GARBAGE); }
"$"{nonl}*{nl} { BEGIN edge; }
%%
yyinit()
{
BEGIN edge;
}
yywrap()
{
return 1;
}
yyset(text)
reg char text[];
{
reg char *s;
int setc;
char *setv[MAXARGS];
for (s = text+4; *s != '\0' && isspace(*s); s++)
;
setc = parse_args(s, setv);
process_args(setv, &setc, 0);
if (setc > 0)
printf("cake: non-options on parameter line ignored\n");
}
yyhash(text)
reg char text[];
{
reg char *oldfile = yyfile;
reg char *s, *t;
afterifdef = TRUE; /* assume so until proven otherwise */
if (sscanf(text+1, "%d", &yylineno) != 1)
return;
text[strlen(text)-1] = '\0'; /* clobber the newline */
for (s = text; *s != '\0' && *s != '"' && !isalpha(*s); s++)
;
if (*s == '\0')
return;
if (*s != '"')
yyfile = new_name(s);
else
{
for (t = s+strlen(s)-1; t != s && *t != '"'; t--)
;
if (t != s)
*t = '\0';
yyfile = new_name(s+1);
}
if (yyfile != oldfile)
{
afterifdef = FALSE;
return;
}
}
/*
** Read in a PATCMD, which is [[.*PATCMD?.*]]
** (or a matched set of double brackets with other stuff.
** Note that PATCMD cannot be described by a REAL regular
** expression; the one above cheats by using recursion.
** yysquare returns the PATCMD brackets and all.
*/
char *
yysquare()
{
char buf[MAXSIZE];
reg int c, c1;
reg int i;
reg int n; /* number of outstanding levels */
n = 1;
i = 0;
buf[i++] = '[';
buf[i++] = '[';
for (c = input(); c != '\0' && c != '\n' && c != '\f'; c = input())
{
buf[i++] = c;
if (c == ']')
{
if ((c1 = input()) != ']')
{
/* for the next iteration */
unput(c1);
continue;
}
buf[i++] = c1;
if (--n > 0)
continue;
buf[i] = '\0';
if (strlen(buf) >= MAXSIZE)
{
fprintf(stderr, "cake internal error: buffer overflow in yysquare\n");
exit_cake(FALSE);
}
if (lexdebug)
printf("yysquare: %s\n", buf);
fflush(stdout);
return new_name(buf);
}
or (c == '[')
{
if ((c1 = input()) != '[')
{
/* for the next iteration */
unput(c1);
continue;
}
buf[i++] = c1;
n++;
}
or (c == '\\')
{
/* don't check next char */
if ((c1 = input()) != '\0')
buf[i++] = c1;
}
}
if (c == '\0')
fprintf(stderr, "%s, %d: premature EOF\n", yyfile, yylineno);
else
fprintf(stderr, "%s, %d: unescaped newline inside a command\n", yyfile, yylineno);
exit_cake(FALSE);
return("--error--"); /* BRL */
}
/*
** Read in a TESTCMD, which is {{.*}}. Strip the brackets.
*/
char *
yycurly()
{
char buf[MAXSIZE];
reg int c, c1;
reg int i;
i = 0;
for (c = input(); c != '\0' && c != '\n' && c != '\f'; c = input())
{
buf[i++] = c;
if (c == RBRACE)
{
if ((c1 = input()) != RBRACE)
{
/* for the next iteration */
unput(c1);
continue;
}
/* overwrite first RBRACE */
buf[--i] = '\0';
if (strlen(buf) >= MAXSIZE)
{
fprintf(stderr, "cake internal error: buffer overflow in yycurly\n");
exit_cake(FALSE);
}
if (lexdebug)
printf("yycurly: %s\n", buf);
fflush(stdout);
return new_name(buf);
}
or (c == '\\')
{
/* don't check next char */
if ((c1 = input()) != '\0')
buf[i++] = c1;
}
}
if (c == '\0')
fprintf(stderr, "%s, %d: premature EOF\n", yyfile, yylineno);
else
fprintf(stderr, "%s, %d: unescaped newline inside a command\n", yyfile, yylineno);
exit_cake(FALSE);
return("--error--"); /* BRL */
}
check_actlen()
{
if (strlen(yytext) >= YYLMAX)
{
printf("cake: action '%s' too long\n", yytext);
exit_cake(FALSE);
}
}
-579
View File
@@ -1,579 +0,0 @@
/*
** Module to chase Cake dependencies.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
/*
** The main chasing function. It checks all entries to see
** if they describe a dependency of the name. If the second arg
** is not NULL, it is taken as a fixed choice (by another do_chase)
** as to which entry will actually be used to generate the name.
**
** The kinds of nodes returned by do_chase are as follows.
** OK means that no action is needed to update the name.
** CANDO means that the action is known and there is no reason
** why it shouldn't succeed. NOWAY is set when neither of those
** conditions is satisfied. nf_ERR means that some error has
** occurred; nf_ERR nodes are never touched again; except for
** printing the error messages themselves. (NOWAY nodes *are*
** touched by act.c to update as many ancestors as possible.)
**
** Whenever nf_ERR is not set, do_chase sets the utime field,
** and the rtime field as well if the file exists.
*/
do_chase(node, picked)
reg Node *node;
reg Entry *picked;
{
extern get_utime();
extern time_t cake_gettime();
extern Node *chase();
extern Node *chase_node();
extern time_t pick_time();
extern bool match();
extern bool eval();
extern Entry *ground_entry();
extern Test *deref_test();
extern deref_entry();
extern List *entries;
extern char *list_names();
Env env;
reg List *ptr, *ptr1, *ptr2;
reg Node *newnode, *onode;
reg Entry *entry, *newentry;
reg Pat *pat;
reg List *entry_anay, *entry_ayea; /* of Entry */
reg List *miss_anay, *miss_ayea; /* of Node */
reg List *pot_entry; /* of Entry */
reg List *pot_pat; /* of Pat */
reg List *probe_old; /* of Node */
reg bool found, missing;
reg bool singleton, orphan;
put_trail("do_chase", "start");
cdebug("chasing %s\n", node->n_name);
if (off_node(node, nf_EXIST))
set_node(node, nf_NEWFILE);
/* find all entries which could generate this name */
pot_entry = makelist0();
pot_pat = makelist0();
for_list (ptr, entries)
{
entry = (Entry *) ldata(ptr);
/* try everything on the left side of the entry */
for_list (ptr1, entry->e_new)
{
pat = (Pat *) ldata(ptr1);
if (match(env, node->n_name, pat))
{
if ((newentry = ground_entry(env, entry)) == (Entry *) NULL)
{
sprintf(scratchbuf, "cannot perform substitutions on entry for %s",
node->n_name);
add_error(node, new_name(scratchbuf), LNULL, TRUE);
goto end;
}
#ifdef CAKEDEBUG
if (entrydebug)
{
printf("Applicable entry\n");
print_entry(newentry);
}
#endif
addtail(pot_entry, newentry); /* na */
addtail(pot_pat, pat); /* na */
break;
}
}
}
cdebug("%s: %d potentials\n", node->n_name, length(pot_entry));
/* find out which tests are satisfied */
entry_anay = makelist0();
entry_ayea = makelist0();
for_2list (ptr1, ptr2, pot_entry, pot_pat)
{
entry = (Entry *) ldata(ptr1);
pat = (Pat *) ldata(ptr2);
for_list (ptr, entry->e_when)
{
reg Node *whennode;
reg Pat *whenpat;
whenpat = (Pat *) ldata(ptr);
whennode = chase(whenpat->p_str, whenpat->p_flag, (Entry *) NULL);
if (off_node(whennode, nf_ERR))
{
if (is_ok(whennode))
continue;
if (nflag && off_node(whennode, nf_WARNED))
{
printf("cake -n: warning, need to make %s to find dependencies\n",
whenpat->p_str);
set_node(whennode, nf_WARNED);
}
update(whennode, 100, TRUE);
}
if (on_node(whennode, nf_ERR) || ! is_ok(whennode))
{
sprintf(scratchbuf, "cannot find out if entry applies to %s",
node->n_name);
add_error(node, new_name(scratchbuf), makelist(whennode), TRUE);
return;
}
}
#ifdef CAKEDEBUG
if (entrydebug)
{
printf("about to test condition\n");
print_entry(entry);
}
#endif
entry->e_cond = deref_test(entry->e_cond);
if (! eval(node, entry->e_cond, env))
{
cdebug("condition FALSE\n");
continue;
}
/* here we know that this entry applies */
deref_entry(env, entry);
if (Lflag)
{
for_list (ptr, entry->e_old)
{
reg Pat *opat;
opat = (Pat *) ldata(ptr);
if (streq(node->n_name, opat->p_str))
{
cdebug("found loop in entry at %s\n", node->n_name);
continue;
}
}
}
node->n_flag |= pat->p_flag;
if (length(entry->e_act) == 0)
addtail(entry_anay, entry); /* no assigment */
else
addtail(entry_ayea, entry); /* no assigment */
}
if (on_node(node, nf_ERR))
return;
cdebug("%s: no action: %d, with actions: %d\n",
node->n_name, length(entry_anay), length(entry_ayea));
/* All entries considered from now on are ground */
/* see if the file is an original */
if (length(entry_anay) == 0 && length(entry_ayea) == 0)
{
if (off_node(node, nf_EXIST))
{
cdebug("%s: noway\n", node->n_name);
node->n_kind = n_NOWAY;
node->n_utime = GENESIS;
sprintf(scratchbuf, "base file %s does not exist", node->n_name);
add_error(node, new_name(scratchbuf), LNULL, FALSE);
goto end;
}
set_node(node, nf_ORIG);
cdebug("%s: orig ok\n", node->n_name);
node->n_kind = n_OK;
node->n_utime = node->n_rtime;
goto end;
}
/* see to actionless dependencies */
missing = FALSE;
miss_anay = NULL;
for_list (ptr, entry_anay)
{
entry = (Entry *) ldata(ptr);
for_list (ptr1, entry->e_old)
{
pat = (Pat *) ldata(ptr1);
newnode = chase(pat->p_str, pat->p_flag, (Entry *) NULL);
if (on_node(newnode, nf_ERR) || is_noway(newnode))
{
missing = TRUE;
miss_anay = addtail(miss_anay, newnode);
}
addtail(node->n_old, newnode); /* na */
}
}
cdebug("%s: unconditional dependencies, %s\n",
node->n_name, missing? "some missing": "all there");
/*
** If necessary, choose a feasible action dependency.
** However, if there is only one, select it even if
** it is not feasible.
*/
found = FALSE;
miss_ayea = NULL;
if (picked == (Entry *) NULL)
{
singleton = (length(entry_ayea) == 1);
orphan = (length(entry_ayea) == 0);
for_list (ptr, entry_ayea)
{
entry = (Entry *) ldata(ptr);
/* first copy of this code, with chase */
found = TRUE; /* assume it for the moment */
probe_old = makelist0();
for_list (ptr1, entry->e_old)
{
pat = (Pat *) ldata(ptr1);
newnode = chase(pat->p_str, pat->p_flag, (Entry *) NULL);
if (on_node(newnode, nf_ERR) || is_noway(newnode))
{
found = FALSE;
miss_ayea = addtail(miss_ayea, newnode);
if (! singleton)
break;
}
addtail(probe_old, newnode); /* na */
}
if (found)
break;
}
}
else
{
singleton = TRUE;
orphan = FALSE;
cdebug("%s: was given generator\n", node->n_name);
entry = picked;
/* second copy of this code, with chase_node */
found = TRUE; /* assume it for the moment */
probe_old = makelist0();
for_list (ptr1, entry->e_old)
{
pat = (Pat *) ldata(ptr1);
newnode = chase_node(pat->p_str);
if (on_node(newnode, nf_ERR) || is_noway(newnode))
{
found = FALSE;
miss_ayea = addtail(miss_ayea, newnode);
if (! singleton)
break;
}
addtail(probe_old, newnode); /* na */
}
}
if (found)
{
/* we have found an applicable entry */
cdebug("%s: found feasible generator\n", node->n_name);
addlist(node->n_old, probe_old); /* na */
node->n_act = entry->e_act;
if (picked == (Entry *) NULL)
set_buddies(node, entry);
picked = entry;
}
or (singleton)
{
/* we have only one (inapplicable) entry */
/* so we shall make do as best we can */
cdebug("%s: found single infeasible generator\n", node->n_name);
addlist(node->n_old, probe_old); /* na */
node->n_act = entry->e_act;
if (picked == (Entry *) NULL)
set_buddies(node, entry);
picked = entry;
}
or (orphan && on_node(node, nf_PSEUDO))
{
/* no entry is needed, act as we had one */
found = TRUE;
cdebug("%s: no generator, no problem\n", node->n_name);
node->n_act = makelist0();
}
else
{
cdebug("%s: no feasible generator\n", node->n_name);
node->n_act = makelist0();
}
if (length(node->n_act) > 0 && length(picked->e_old) == 0)
node->n_utime = cake_gettime();
else
get_utime(node, TRUE);
for_list (ptr, node->n_old)
{
newnode = (Node *) ldata(ptr);
if (on_node(newnode, nf_NONVOL))
set_node(node, nf_DEPNONVOL);
}
if (missing)
{
node->n_kind = n_NOWAY;
sprintf(scratchbuf, "%s is missing the prerequisite%s %s",
node->n_name, length(miss_anay)==1? "": "s", list_names(miss_anay));
add_error(node, new_name(scratchbuf), miss_anay, FALSE);
}
or (! found)
{
node->n_kind = n_NOWAY;
if (miss_ayea == (List *) NULL)
sprintf(scratchbuf, "%s has no applicable entries with actions\n",
node->n_name);
else
sprintf(scratchbuf, "%s is missing the ancestor%s %s",
node->n_name, length(miss_ayea)==1? "": "s", list_names(miss_ayea));
add_error(node, new_name(scratchbuf), miss_ayea, FALSE);
}
or (on_node(node, nf_EXIST) && node->n_utime <= node->n_rtime)
node->n_kind = n_OK;
or (on_node(node, nf_PSEUDO) && length(node->n_act) == 0)
{
node->n_kind = n_OK;
for_list (ptr, node->n_old)
{
onode = (Node *) ldata(ptr);
if (is_cando(onode))
node->n_kind = n_CANDO;
}
}
else
node->n_kind = n_CANDO;
end:
#ifdef CAKEDEBUG
if (cakedebug)
{
printf("chase exit\n");
print_node(node);
}
#endif
put_trail("do_chase", "finish");
}
/*
** Calculate the "update time" of the given node. The second arg
** tells us whether we should set a flag for nonvolatile ancestors.
*/
get_utime(node, planning)
reg Node *node;
reg bool planning;
{
extern time_t get_youngest(), cake_gettime();
reg time_t youngest;
if ((youngest = get_youngest(node, planning)) == GENESIS)
node->n_utime = cake_gettime();
else
node->n_utime = youngest;
}
/*
** Return the time of update of the youngest dependent.
*/
time_t
get_youngest(node, planning)
reg Node *node;
reg bool planning;
{
reg List *ptr;
reg Node *onode;
reg time_t youngest, picked_time;
reg List *errnodes;
youngest = GENESIS;
errnodes = NULL;
for_list (ptr, node->n_old)
{
onode = (Node *) ldata(ptr);
if (on_node(onode, nf_ERR))
errnodes = addtail(errnodes, onode);
else
{
if ((picked_time = pick_time(onode, planning)) > youngest)
youngest = picked_time;
}
}
if (errnodes != (List *) NULL)
{
sprintf(scratchbuf, "don't know what to do with %s because of problems with %s",
node->n_name, list_names(errnodes));
add_error(node, new_name(scratchbuf), errnodes, TRUE);
}
return youngest;
}
/*
** Take care of the names mentioned alongside node's
** on the left hand side of the given ground entry.
**
** If a node exists for one of these names we know that
** a producer must have been chosen for it, and we know that
** it is not this rule (if it were, then the caller would not
** have done anything about buddies). This is an inconsistency.
*/
set_buddies(node, entry)
reg Node *node;
reg Entry *entry;
{
extern Node *chase_node();
reg List *list;
reg List *ptr;
reg Node *newnode;
reg Pat *pat;
reg List *errnodes;
put_trail("set_buddies", "start");
list = makelist(node);
errnodes = NULL;
for_list (ptr, entry->e_new)
{
pat = (Pat *) ldata(ptr);
if (streq(pat->p_str, node->n_name))
continue;
if ((newnode = chase_node(pat->p_str)) != (Node *) NULL)
errnodes = addtail(errnodes, newnode);
else
{
newnode = chase(pat->p_str, pat->p_flag, entry);
addtail(list, newnode); /* no assigment */
}
}
for_list (ptr, list)
{
newnode = (Node *) ldata(ptr);
newnode->n_new = list;
if (errnodes != (List *) NULL)
{
sprintf(scratchbuf, "cannot update %s because of interference with %s %s",
newnode->n_name, (length(errnodes) == 1)? "buddy": "buddies",
list_names(errnodes));
add_error(node, new_name(scratchbuf), errnodes, TRUE);
}
}
put_trail("set_buddies", "finish");
}
/*
** Pick the appropriate time to use in decisions
** about dependencies. The algorithms differ in the
** twp phases: in the execution phase real times
** override any calculated times.
*/
time_t
pick_time(node, planning)
reg Node *node;
reg bool planning;
{
if (off_node(node, nf_EXIST))
return node->n_utime;
if (planning)
return max(node->n_rtime, node->n_utime);
return node->n_rtime;
}
/*
** Chase down the ancestors of the given name.
** Return the node describing the dependency graph.
**
** Note that this is merely an interface function,
** serving to cache previous results and to detect cycles.
*/
char *goal_stack[MAXGSTACK];
int goal_stackp = 0;
Node *
chase(name, flag, picked)
reg char *name;
reg bool flag;
reg Entry *picked;
{
extern Table node_tab;
extern do_chase();
extern char *find_circle();
reg Node *node;
if ((node = (Node *) lookup_table(node_tab, name)) == NULL)
{
node = make_node(name);
if (goal_stackp >= MAXGSTACK)
{
printf("cake: dependency nesting level %d too deep\n", goal_stackp);
exit_cake(FALSE);
}
goal_stack[goal_stackp++] = name;
#ifdef CAKEDEBUG
cdebug("stack[%d] = %s\n", goal_stackp-1, goal_stack[goal_stackp-1]);
#endif
set_node(node, nf_BUSY);
insert_table(node_tab, node);
do_chase(node, picked);
--goal_stackp;
reset_node(node, nf_BUSY);
}
else
{
cdebug("Using cache for %s\n", name);
if (on_node(node, nf_BUSY))
{
node->n_flag |= flag;
sprintf(scratchbuf, "%s depends upon itself %s", node->n_name,
find_circle(node->n_name));
add_error(node, new_name(scratchbuf), LNULL, TRUE);
put_trail("chase", "finish");
return node;
}
}
node->n_flag |= flag;
put_trail("chase", "finish");
return node;
}
-65
View File
@@ -1,65 +0,0 @@
/*
** Cake configuration parameters.
**
** $Header$
*/
/* type used when type is not known */
typedef int Cast;
/* location of the systemwide cake library */
/*#define SLIB "/u/pgrad/zs/lib/cake" **BRL*/
#define SLIB "/usr/brlcad/lib/cake"
/* suffix (after $HOME) of personal libraries */
#define ULIB "/lib/cake"
/* command to invoke the C preprocessor */
#define CPP "/lib/cpp"
/* If C preprocessor needs options, define them here. For example, GNU CPP */
#if 0
# define CPP_OPTIONS "-traditional"
#endif
/* location of the statistics file - if not defined, no stats kept */
/*#define STATS_FILE "/u/pgrad/zs/lib/cake_stats" **BRL*/
#define STATS_FILE "/usr/brlcad/lib/cake_stats"
/* characters always requiring shell attention */
#define METACHARS "*?!&|;<>()[]{}'`\"%$~#"
/* default command to execute non-script shell actions */
#define SYSTEM_CMD "/bin/csh -cf"
/* default command to execute shell scripts */
#define SCRIPT_CMD "/bin/csh -f"
/* System V compatibility */
#ifdef ATT
/* the resolution of the times(2) system call */
#ifdef exlsi
#define TIMERES 100
#else
#define TIMERES 60
#endif
#include "port.h"
#define vfork() fork()
#define index(s, c) strchr(s, c)
#define rindex(s, c) strrchr(s, c)
#endif
#define MAXARGS 128 /* BRL, was 64 */
#define MAXGSTACK 128
#define MAXARGSIZE 128
#define MAXPATSIZE 4096 /* BRL, was 512 */
#define MAXLEXBUF 4096 /* BRL, was 2048 */
#define MAXSIZE 4096 /* BRL, was 2048 */
#define MAXSCRIPT 16384
#define MAXNEST 8
#define SIZE 97 /* size of tables */
#define CHARSETSIZE 256
#define GENESIS (time_t) 42 /* something distinctive */
#define CHASEROOT "!MAINCAKE!"
-559
View File
@@ -1,559 +0,0 @@
/*
** Module to record and process Cake dependency entries.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
#include <ctype.h>
List *entries;
Entry *main_entry;
extern Test *ground_test();
#define ground_pat(env, pat) make_pat(ground(env, pat->p_str), pat->p_cmd, pat->p_flag);
#define ground_act(env, act) make_act(ground(env, act->a_str), act->a_flag);
/*
** Initialise ALL data structures about entries.
*/
init_entry()
{
entries = makelist0();
main_entry = (Entry *) NULL;
}
/*
** Deposit an entry just read in.
*/
new_entry(deps, acts)
reg List *deps; /* of Entry */
reg List *acts; /* of Pat */
{
reg List *ptr;
reg Entry *entry;
for_list (ptr, deps)
{
entry = (Entry *) ldata(ptr);
entry->e_act = acts;
addtail(entries, entry); /* no assignment */
}
}
/*
** Prepare entries for matches against their left hand sides.
** This essentially means dereferencing any command patterns.
** Another minor correction is also done here: if -n is given
** then we set nf_PRECIOUS so no file is deleted.
*/
prep_entries()
{
extern List *break_pat();
reg List *ptr, *ptr1;
reg Entry *entry;
reg Pat *pat;
reg List *newnew;
for_list (ptr, entries)
{
entry = (Entry *) ldata(ptr);
newnew = makelist0();
for_list (ptr1, entry->e_new)
{
pat = (Pat *) ldata(ptr1);
if (on_pat(pat, nf_WHEN))
{
printf("cake: inappropriate flag '*' after target %s ignored\n",
pat->p_str);
reset_pat(pat, nf_WHEN);
}
if (nflag)
set_pat(pat, nf_PRECIOUS);
if (! pat->p_cmd)
addtail(newnew, pat); /* na */
else
{
deref(pat, TRUE);
addlist(newnew, break_pat(pat));/* na */
}
}
entry->e_new = newnew;
for_list (ptr1, entry->e_old)
{
pat = (Pat *) ldata(ptr1);
if (pat->p_cmd && on_pat(pat, nf_WHEN))
{
printf("cake: inappropriate flag '*' after command source %s ignored\n",
pat->p_str);
reset_pat(pat, nf_WHEN);
}
}
#ifdef CAKEDEBUG
if (entrydebug)
{
printf("prepared entry:\n");
print_entry(entry);
}
#endif
}
}
/*
** Enter the last (main) entry. This entry has a distinguished
** left hand side consisting of the sole pattern CHASEROOT.
** This is the pattern which cake tries to make up-to-date.
** If there were nonoption arguments on the command line,
** CHASEROOT is made to depend on them; otherwise the left hand
** side of the first concrete entry is used, as in make.
** However, if the first concrete entry is in an included file,
** we keep looking, unless it had a double colon.
*/
final_entry(argc, argv)
reg int argc;
reg char *argv[];
{
extern bool hasvars();
reg List *ptr, *ptr1;
reg Entry *entry, *foundentry;
reg Pat *pat;
reg bool found_main, found_incl;
reg int i;
main_entry = make(Entry);
main_entry->e_new = makelist(make_pat(CHASEROOT, FALSE, nf_PSEUDO|nf_NODELETE));
main_entry->e_old = makelist0();
main_entry->e_cond = (Test *) NULL;
main_entry->e_act = makelist0();
cdebug("target count %d\n", argc-1);
if (argc > 1)
{
for (i = 1; i < argc; i++)
{
cdebug("target %s\n", argv[i]);
addtail(main_entry->e_old, make_pat(argv[i], FALSE, 0)); /* na */
}
}
else
{
/* find the first entry without variables */
found_main = FALSE;
found_incl = FALSE;
for_list (ptr, entries)
{
entry = (Entry *) ldata(ptr);
for_list (ptr1, entry->e_new)
{
pat = (Pat *) ldata(ptr1);
if (hasvars(pat->p_str))
goto nextentry;
}
if (streq(entry->e_file, cakefile) || entry->e_dblc)
{
found_main = TRUE;
foundentry = entry;
break;
}
or (! found_incl)
{
found_incl = TRUE;
foundentry = entry;
}
nextentry: ;
}
if (! found_main && ! found_incl)
{
printf("cake: no entries without variables\n");
printf("cake: don't know what cake to bake\n");
exit(1);
}
/* update everything on its left side */
for_list (ptr, foundentry->e_new)
{
pat = (Pat *) ldata(ptr);
addtail(main_entry->e_old, pat); /* na */
}
}
addtail(entries, main_entry); /* no assigment */
}
/*
** Return a new entry which is a ground version of the one passed.
** Process '*' flags and set up e_when accordingly.
*/
Entry *
ground_entry(env, entry)
Env env;
reg Entry *entry;
{
extern do_when();
extern List *break_pat();
extern char *ground();
reg List *ptr;
reg Entry *newentry;
reg Pat *pat, *newpat;
reg Act *act, *newact;
put_trail("ground_entry", "start");
newentry = make(Entry);
newentry->e_new = makelist0();
newentry->e_old = makelist0();
newentry->e_act = makelist0();
newentry->e_when = makelist0();
for_list (ptr, entry->e_new)
{
/* prep_entries made these patterns command free */
pat = (Pat *) ldata(ptr);
newpat = ground_pat(env, pat);
do_when(newentry, newpat);
addtail(newentry->e_new, newpat); /* na */
}
for_list (ptr, entry->e_old)
{
pat = (Pat *) ldata(ptr);
newpat = ground_pat(env, pat);
do_when(newentry, newpat);
addtail(newentry->e_old, newpat); /* na */
}
for_list (ptr, entry->e_act)
{
act = (Act *) ldata(ptr);
newact = ground_act(env, act);
addtail(newentry->e_act, newact); /* na */
}
newentry->e_cond = ground_test(env, entry->e_cond);
put_trail("ground_entry", "finish");
return newentry;
}
/*
** Look after '*' (when) flags.
*/
do_when(entry, pat)
reg Entry *entry;
reg Pat *pat;
{
if (on_pat(pat, nf_WHEN))
{
reset_pat(pat, nf_WHEN);
entry->e_when = addtail(entry->e_when, pat);
}
}
/*
** Ground a test.
*/
Test *
ground_test(env, test)
Env env;
reg Test *test;
{
extern char *ground();
reg List *ptr;
reg Pat *pat, *newpat;
reg Test *newtest;
if (test == (Test *) NULL)
return test;
put_trail("ground_test", "start");
switch (test->t_kind)
{
when t_TRUE:
case t_FALSE: put_trail("ground_test", "finish");
return test;
when t_AND:
case t_OR: put_trail("ground_test", "finish");
return make_test_b(test->t_kind,
ground_test(env, test->t_left), ground_test(env, test->t_right));
when t_NOT: put_trail("ground_test", "finish");
return make_test_u(test->t_kind, ground_test(env, test->t_left));
when t_CMD: put_trail("ground_test", "finish");
return make_test_c(ground(env, test->t_cmd));
when t_MATCH: pat = ground_pat(env, test->t_pat);
newtest = make_test_mm(pat);
for_list (ptr, test->t_list)
{
pat = (Pat *) ldata(ptr);
newpat = ground_pat(env, pat);
addtail(newtest->t_list, newpat); /* na */
}
put_trail("ground_test", "finish");
return newtest;
when t_LIST: pat = ground_pat(env, test->t_pat);
newtest = make_test_l(pat, makelist0());
for_list (ptr, test->t_list)
{
pat = (Pat *) ldata(ptr);
newpat = ground_pat(env, pat);
addtail(newtest->t_list, newpat); /* na */
}
put_trail("ground_test", "finish");
return newtest;
when t_EXIST: newpat = ground_pat(env, test->t_pat);
put_trail("ground_test", "finish");
return make_test_s(t_EXIST, newpat);
when t_CANDO: newpat = ground_pat(env, test->t_pat);
put_trail("ground_test", "finish");
return make_test_s(t_CANDO, newpat);
when t_OK: newpat = ground_pat(env, test->t_pat);
put_trail("ground_test", "finish");
return make_test_s(t_OK, newpat);
otherwise: printf("cake internal error: bad test type %x in ground_test\n", test->t_kind);
put_trail("ground_test", "finish");
return (Test *) NULL;
}
put_trail("ground_test", "finish");
return (Test *) NULL;
}
/*
** Dereference all command patterns in the given entry.
*/
deref_entry(env, entry)
Env env;
reg Entry *entry;
{
reg List *ptr, *ptr1;
reg List *newlist;
reg List *patlist;
reg Pat *pat, *oldpat, *newpat;
newlist = makelist0();
for_list (ptr, entry->e_old)
{
pat = (Pat *) ldata(ptr);
if (! pat->p_cmd)
addtail(newlist, pat); /* na */
else
{
deref(pat, TRUE);
patlist = break_pat(pat);
for_list (ptr1, patlist)
{
oldpat = (Pat *) ldata(ptr1);
newpat = make_pat(ground(env, oldpat->p_str), FALSE, 0);
do_when(entry, newpat);
addtail(newlist, newpat); /* na */
}
}
}
entry->e_old = newlist;
}
/*
** Dereference a test.
*/
Test *
deref_test(test)
reg Test *test;
{
extern char *expand_cmds();
reg List *ptr;
reg List *newlist;
reg Pat *pat;
if (test == (Test *) NULL)
return test;
put_trail("deref_test", "start");
switch (test->t_kind)
{
when t_TRUE:
case t_FALSE: put_trail("deref_test", "finish");
return test;
when t_AND:
case t_OR: test->t_left = deref_test(test->t_left);
test->t_right = deref_test(test->t_right);
put_trail("deref_test", "finish");
return test;
when t_NOT: test->t_left = deref_test(test->t_left);
put_trail("deref_test", "finish");
return test;
when t_CMD: test->t_cmd = expand_cmds(test->t_cmd);
put_trail("deref_test", "finish");
return test;
when t_MATCH: deref(test->t_pat, FALSE);
for_list (ptr, test->t_list)
{
pat = (Pat *) ldata(ptr);
deref(pat, FALSE);
}
put_trail("deref_test", "finish");
return test;
when t_LIST: deref(test->t_pat, FALSE);
newlist = makelist0();
for_list (ptr, test->t_list)
{
pat = (Pat *) ldata(ptr);
if (! pat->p_cmd)
addtail(newlist, pat); /* na */
else
{
deref(pat, TRUE);
addlist(newlist, break_pat(pat)); /* na */
}
}
test->t_list = newlist;
put_trail("deref_test", "finish");
return test;
when t_EXIST: deref(test->t_pat, FALSE);
put_trail("deref_test", "finish");
return test;
when t_CANDO: deref(test->t_pat, FALSE);
put_trail("deref_test", "finish");
return test;
when t_OK: deref(test->t_pat, FALSE);
put_trail("deref_test", "finish");
return test;
otherwise: printf("cake internal error: bad test type %x in deref_test\n", test->t_kind);
put_trail("deref_test", "finish");
return (Test *) NULL;
}
put_trail("deref_test", "finish");
return (Test *) NULL;
}
Act *
prep_act(text)
reg char *text;
{
reg Act *act;
reg char *s;
act = make(Act);
act->a_flag = 0;
/* strip trailing space - there is at least the newline */
for (s = text+strlen(text)-1; isspace(*s); s--)
*s = '\0';
/* put just the newline back */
strcat(s, "\n");
/* strip spaces before flags */
for (s = text; isspace(*s); s++)
;
/* process the flags */
for (; *s != '\0'; s++)
if (*s == '@')
set_act(act, af_SILENT);
or (*s == '!')
set_act(act, af_SYSTEM);
or (*s == '-')
set_act(act, af_IGNORE);
or (*s == '+')
set_act(act, af_MINUSN);
else
break;
/* strip spaces after flags */
for (; isspace(*s); s++)
;
act->a_str = new_name(s);
return act;
}
Act *
prep_script(first_act, middle_act, last_act)
reg Act *first_act, *last_act;
reg List *middle_act;
{
reg List *ptr;
reg Act *act;
reg char *s;
char buf[MAXSCRIPT];
buf[0] = '\0';
/* handle the first action */
for (s = first_act->a_str+1; *s == ' ' || *s == '\t'; s++)
;
if (strdiff(s, "\n"))
strcat(buf, s);
/* handle the middle actions, if any */
for_list (ptr, middle_act)
{
act = (Act *) ldata(ptr);
strcat(buf, act->a_str);
}
/* handle the last action as the first */
for (s = last_act->a_str+1; *s == ' ' || *s == '\t'; s++)
;
if (strdiff(s, "\n"))
strcat(buf, s);
/* check for overflow */
if (strlen(buf) > MAXSCRIPT)
{
printf("cake: script too long\n");
printf("%s", buf);
exit_cake(FALSE);
}
first_act->a_str = new_name(buf);
set_act(first_act, af_SCRIPT);
return first_act;
}
-134
View File
@@ -1,134 +0,0 @@
/*
** Error handling module.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
/*
** This function prints out the history of errors
** that prevent the proper update of the given node.
*/
trace_errs(node)
reg Node *node;
{
reg List *ptr;
reg Node *bnode;
if (on_node(node, nf_TRACED))
return;
set_node(node, nf_TRACED);
for_list (ptr, node->n_badguys)
{
bnode = (Node *) ldata(ptr);
trace_errs(bnode);
}
if (strdiff(node->n_name, CHASEROOT))
printf("%s", node->n_msg);
}
/*
** This function adds msg to the list of error messages
** to be printed by trace_errs for the given node.
*/
add_error(node, msg, badguys, iserror)
reg Node *node;
reg char *msg;
reg List *badguys;
reg int iserror;
{
char buf[MAXSIZE];
if (node->n_msg == NULL)
node->n_msg = "";
if (iserror)
set_node(node, nf_ERR);
sprintf(buf, "%scake: %s\n", node->n_msg, msg);
if (strlen(buf) >= MAXSIZE)
{
fprintf(stderr, "cake internal error: buffer overflow in add_error\n");
exit_cake(FALSE);
}
node->n_msg = new_name(buf);
node->n_badguys = addlist(node->n_badguys, badguys);
}
char *
find_circle(name)
reg char *name;
{
extern int goal_stackp;
extern char *goal_stack[];
char buf[MAXSIZE];
reg int i;
cdebug("stackp = %d\n", goal_stackp);
cdebug("looking for %s\n", goal_stack[goal_stackp-1]);
if (goal_stack[goal_stackp-1] == name)
return "directly";
for (i = 0; i < goal_stackp; i++)
{
cdebug("checking %d: %s\n", i, goal_stack[i]);
if (goal_stack[i] == name)
{
cdebug("hit\n");
strcpy(buf, "through");
for (; i < goal_stackp; i++)
{
strcat(buf, " ");
strcat(buf, goal_stack[i]);
}
if (strlen(buf) >= MAXSIZE)
{
fprintf(stderr, "cake internal error: buffer overflow in find_circle\n");
exit_cake(FALSE);
}
return new_name(buf);
}
}
fprintf(stderr, "cake internal error: no circularity in find_circle\n");
exit_cake(TRUE);
return ""; /* to satisfy lint */
}
char *
list_names(list)
reg List *list; /* of Node */
{
reg List *ptr;
reg Node *node;
reg char *sep;
char buf[MAXSIZE];
buf[0] = '\0';
sep = "";
for_list (ptr, list)
{
node = (Node *) ldata(ptr);
strcat(buf, sep);
strcat(buf, node->n_name);
sep = " ";
}
if (strlen(buf) >= MAXSIZE)
{
fprintf(stderr, "cake internal error: buffer overflow in list_names\n");
exit_cake(FALSE);
}
return new_name(buf);
}
-276
View File
@@ -1,276 +0,0 @@
/*
** Module to expand out commands in patterns and actions.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
#include <ctype.h>
/*
** Expand any commands in actions. Doing this here instead of
** in the shell saves time because of cake's command cache.
*/
char *
expand_cmds(str)
reg char *str;
{
extern char *get_output();
reg char *s;
reg int n, cmds, offset;
reg int stackp;
reg char *rightbr;
char *leftbr_stack[MAXNEST];
char *nextbr_stack[MAXNEST];
char copybuf[MAXSIZE], buf[MAXSIZE];
reg char *result;
if (index(str, '[') == NULL)
return str;
put_trail("expand_cmds", "start");
cmds = 0;
stackp = 0;
if (strlen(str) >= MAXSIZE)
{
fprintf(stderr, "cake internal error: command too long %s\n", str);
exit_cake(FALSE);
}
strcpy(copybuf, str);
leftbr_stack[stackp] = copybuf;
nextbr_stack[stackp] = NULL;
/* Leftbr_stack[stackp] and rightbr enclose commands */
/* for stackp > 0; for stackp == 0 they enclose the string */
/* Nextbr_stack gives the beginning of the next segment */
/* after the corresponding leftbr; == 0 if not known (yet) */
/* The top entry on the stack always has nextbr == NULL */
for (s = copybuf; s[0] != '\0'; s++)
{
if (s[0] == '[' && s[1] == '[')
{
nextbr_stack[stackp] = s;
if (++stackp >= MAXNEST)
{
fprintf(stderr, "cake internal error: command nesting level too deep\n");
exit_cake(FALSE);
}
leftbr_stack[stackp] = s;
nextbr_stack[stackp] = NULL;
s++; /* avoid problems with [[[cmd]] ... */
}
or (s[0] == ']' && s[1] == ']')
{
if (stackp <= 0)
continue;
cmds++;
rightbr = s;
leftbr_stack[stackp][0] = '\0';
leftbr_stack[stackp][1] = '\0';
rightbr[0] = '\0';
rightbr[1] = '\0';
result = get_output(new_name(leftbr_stack[stackp]+2));
cdebug("expansion [[%s]] => [[%s]]\n", leftbr_stack[stackp]+2, result);
segcpy(buf, leftbr_stack[stackp-1], nextbr_stack[stackp-1]);
strcat(buf, result);
offset = strlen(buf) - 1;
strcat(buf, rightbr+2);
if (strlen(buf) >= MAXSIZE)
{
fprintf(stderr, "cake: expansion result '%s' is too long\n", buf);
exit_cake(FALSE);
}
stackp--;
leftbr_stack[stackp] = new_name(buf);
nextbr_stack[stackp] = NULL;
/* start next iteration with the */
/* first character after the ]] */
s = leftbr_stack[stackp] + offset;
}
or (s[0] == '\\')
{
/* don't check next char */
if (s[1] != '\0')
s++;
}
}
#ifdef CAKEDEBUG
if (entrydebug)
printf("after expand_cmds: [[%s]]\n", str);
#endif
if (cmds <= 0)
{
put_trail("expand_cmds", "finish");
return str;
}
or (stackp == 0)
{
put_trail("expand_cmds", "finish");
return leftbr_stack[0];
}
segcpy(buf, leftbr_stack[0], nextbr_stack[0]);
for (n = 1; n <= stackp; n++)
segcat(buf, leftbr_stack[n], nextbr_stack[n]);
if (strlen(buf) >= MAXSIZE)
{
fprintf(stderr, "cake: expansion result '%s' is too long\n", buf);
exit_cake(FALSE);
}
put_trail("expand_cmds", "finish");
return new_name(buf);
}
segcpy(target, left, right)
reg char *target, *left, *right;
{
reg int i;
reg char *s;
if (right == NULL)
strcpy(target, left);
else
{
for (s = left, i = 0; s != right; s++, i++)
target[i] = *s;
target[i] = '\0';
}
}
segcat(target, left, right)
reg char *target, *left, *right;
{
reg int i;
reg char *s;
if (right == NULL)
strcat(target, left);
else
{
for (s = left, i = strlen(target); s != right; s++, i++)
target[i] = *s;
target[i] = '\0';
}
}
/*
** Execute the given command and return its output.
** It is a fatal error for the command to terminate abnormally.
*/
char *
get_output(cmd)
reg char *cmd;
{
extern char *mktemp();
extern char *get_out();
extern char *flatten();
extern int cake_proc();
extern Wait cake_wait();
char buf[MAXSIZE];
Wait code;
reg char *out_filename;
reg FILE *fp;
reg int i, c;
reg int pid;
reg char *s, *result;
put_trail("get_output", "start");
cdebug("get_output of [%s]\n", cmd);
/* see if we have tried this command before */
if ((result = get_out(cmd)) != NULL)
{
cdebug("cache yields [%s]\n", result);
put_trail("get_output", "early finish");
return result;
}
out_filename = get_newname();
pid = cake_proc(cmd, Exec, out_filename, (Node *) NULL, (int (*)()) NULL, (List *) NULL);
code = cake_wait(pid);
if (code.w_status != 0 && ! zflag)
{
printf("cake, %s: nonzero exit status\n", cmd);
exit_cake(FALSE);
}
if ((fp = fopen(out_filename, "r")) == NULL)
{
sprintf(scratchbuf, "cake system error, fopen %s", out_filename);
perror(scratchbuf);
exit_cake(FALSE);
}
/* convert the chars in file fp to a string */
i = 0;
while ((c = getc(fp)) != EOF)
buf[i++] = c;
buf[i] = '\0';
fclose(fp);
if (MAXSIZE <= i)
{
printf("cake, %s: output too long\n", cmd);
exit_cake(FALSE);
}
#ifndef LEAVE_DIR
cdebug("get_output unlink out_filename %s\n", out_filename);
if (unlink(out_filename) != 0)
{
sprintf(scratchbuf, "cake system error, unlink %s", out_filename);
perror(scratchbuf);
}
#endif
/* save the result for posterity */
s = new_name(flatten(buf));
new_out(cmd, s);
cdebug("put result [%s] into cache\n", s);
put_trail("get_output", "finish");
return s;
}
/*
** Flatten the output of commands by converting newlines to spaces
** and by removing blanks around the edges.
*/
char *
flatten(str)
reg char *str;
{
reg char *s;
/* convert newlines (and formfeeds) to spaces */
for (s = str; *s != '\0'; s++)
if (*s == '\n' || *s == '\f')
*s = ' ';
/* remove blanks around the edges */
for (s = str+strlen(str)-1; str <= s && isspace(*s); s--)
*s = '\0';
for (s = str; *s != '\0' && isspace(*s); s++)
;
return s;
}
-81
View File
@@ -1,81 +0,0 @@
/*
** External definitions for Cake.
**
** $Header$
*/
/* library functions */
extern char *malloc();
#ifdef ATT
extern char *strchr();
extern char *strrchr();
#else
extern char *index();
extern char *rindex();
#endif
/* memory management */
extern Cast newmem();
extern oldmem();
/* make routines */
extern Node *make_node();
extern Entry *make_dep();
extern Test *make_test_mm();
extern Test *make_test_m();
extern Test *make_test_c();
extern Test *make_test_s();
extern Test *make_test_l();
extern Test *make_test_b();
extern Test *make_test_u();
extern Pat *make_pat();
extern Act *make_act();
extern Act *prep_act();
extern Act *prep_script();
/* table handling routines */
extern init_sym();
extern char *new_name();
/* printout routines */
extern char scratchbuf[];
extern print_pat();
extern print_test();
extern print_entry();
extern print_node();
/* flags */
extern int Gflag;
extern int Lflag;
extern int Rflag;
extern int Xflag;
extern int bflag;
extern int cflag;
extern int dflag;
extern int gflag;
extern int iflag;
extern int kflag;
extern int nflag;
extern int qflag;
extern int rflag;
extern int sflag;
extern int tflag;
extern int vflag;
extern int wflag;
extern int xflag;
extern int zflag;
extern int cakedebug;
extern int entrydebug;
extern int patdebug;
extern int lexdebug;
/* misc global vars */
extern char *cakefile;
extern int maxprocs;
/* misc functions */
extern char *get_newname();
extern put_trail();
extern get_trail();
-642
View File
@@ -1,642 +0,0 @@
/*
** File system interface module.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
#include <errno.h>
#include <sys/stat.h>
#ifndef ATT
#include <sys/dir.h>
#include <sys/time.h>
#endif
typedef struct timeval Tval;
typedef struct timezone Tzone;
typedef struct stat Stat;
#if defined(__convex__)
/* This is a hack, because Convex no longer defines struct direct */
typedef struct dirent Dirent;
#else
typedef struct direct Dirent;
#endif
extern int errno;
static char dir_name[30] = "/tmp/CakeXXXXXX";
/*
** Create the directory to be used for all temporary storage.
*/
dir_start()
{
reg bool successful;
mktemp(dir_name);
#ifdef ATT
{
extern int cake_proc();
extern Wait cake_wait();
reg int pid;
Wait code;
sprintf(scratchbuf, "mkdir %s", dir_name);
pid = cake_proc(new_name(scratchbuf), Exec, (char *) NULL,
(Node *) NULL, (int (*)()) NULL, (List *) NULL);
code = cake_wait(pid);
successful = code.w_status == 0;
}
#else
successful = mkdir(dir_name, 0700) == 0;
#endif
if (! successful)
{
sprintf(scratchbuf, "cake system error, mkdir %s", dir_name);
perror(scratchbuf);
exit_cake(FALSE);
}
#ifdef ATT
if (chmod(dir_name, 0700) != 0)
{
sprintf(scratchbuf, "cake system error, chmod 700 %s", dir_name);
perror(scratchbuf);
exit_cake(FALSE);
}
#endif
}
/*
** Clean up /tmp when we are finished
*/
dir_finish()
{
#ifndef LEAVE_DIR
#ifdef ATT
extern int cake_proc();
extern Wait cake_wait();
reg int pid;
Wait code;
sprintf(scratchbuf, "/bin/rm -fr %s", dir_name);
pid = cake_proc(new_name(scratchbuf), Exec, (char *) NULL,
(Node *) NULL, (int (*)()) NULL, (List *) NULL);
code = cake_wait(pid);
if (code.w_status != 0)
{
fprintf(stderr, "cake system error: cannot remove %s\n", dir_name);
return;
}
#else
char buf[1024];
reg DIR *dirp;
reg Dirent *dp;
reg int nameoffset;
if ((dirp = opendir(dir_name)) == NULL)
{
sprintf(scratchbuf, "cake system error, opendir %s", dir_name);
perror(scratchbuf);
return;
}
strcpy(buf, dir_name);
strcat(buf, "/");
nameoffset = strlen(buf);
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
if (strdiff(dp->d_name, ".") && strdiff(dp->d_name, ".."))
{
buf[nameoffset] = '\0';
strcat(buf, dp->d_name);
cdebug("dir_finish unlink %s\n", buf);
if (unlink(buf) != 0)
{
sprintf(scratchbuf, "cake system error, unlink %s", buf);
perror(scratchbuf);
}
}
closedir(dirp);
cdebug("rmdir %s\n", dir_name);
if (rmdir(dir_name) != 0)
{
sprintf(scratchbuf, "cake system error, rmdir %s", dir_name);
perror(scratchbuf);
}
#endif
#endif
}
/*
** Get a new filename in our private directory.
** These files are used to store shell scripts
** and the output of actions.
**
** These names MUST be different from those generated
** by get_savename, so they have different prefixes.
*/
char *
get_newname()
{
char buf[100];
static int count = 0;
++count;
sprintf(buf, "%s/gen_%d", dir_name, count);
return new_name(buf);
}
/*
** Save a nonvolatile file for later comparison.
** Any slashes in the filename are replaced by colons
** to avoid reference to nonexistent directories.
*/
save_novol(node)
reg Node *node;
{
char buf[MAXSIZE];
reg FILE *ifp, *ofp;
reg int c;
if (nflag)
{
node->n_stime = node->n_rtime;
return;
}
put_trail("save_novol", "start");
cdebug("saving %s\n", node->n_name);
node->n_stime = node->n_rtime;
get_savename(node->n_name, buf);
if ((ifp = fopen(node->n_name, "r")) == NULL)
{
if (errno == ENOENT)
{
cdebug("%s does not exist, considered volatile\n", node->n_name);
reset_node(node, nf_NONVOL);
put_trail("save_novol", "finish");
return;
}
sprintf(scratchbuf, "cake system error, fopen (r) %s", node->n_name);
perror(scratchbuf);
printf("cake: considering %s volatile\n", node->n_name);
reset_node(node, nf_NONVOL);
put_trail("save_novol", "finish");
return;
}
if ((ofp = fopen(buf, "w")) == NULL)
{
sprintf(scratchbuf, "cake system error, fopen (w) %s", buf);
perror(scratchbuf);
printf("cake: considering %s volatile\n", node->n_name);
reset_node(node, nf_NONVOL);
put_trail("save_novol", "finish");
return;
}
while ((c = getc(ifp)) != EOF)
putc(c, ofp);
fclose(ifp);
fclose(ofp);
put_trail("save_novol", "finish");
}
/*
** See if the given file has been changed since saved.
*/
bool
diff_novol(node)
reg Node *node;
{
char buf[MAXSIZE];
reg FILE *i1fp, *i2fp;
reg int c;
reg bool diff;
if (nflag)
return FALSE;
put_trail("diff_novol", "start");
cdebug("comparing saved copy of %s: ", node->n_name);
get_savename(node->n_name, buf);
if ((i1fp = fopen(node->n_name, "r")) == NULL)
{
sprintf(scratchbuf, "cake system error, fopen (r) %s", node->n_name);
perror(scratchbuf);
printf("cake: considering %s different\n", node->n_name);
reset_node(node, nf_NONVOL);
put_trail("diff_novol", "finish");
return TRUE;;
}
if ((i2fp = fopen(buf, "r")) == NULL)
{
sprintf(scratchbuf, "cake system error, fopen (r) %s", buf);
perror(scratchbuf);
printf("cake: considering %s different\n", node->n_name);
reset_node(node, nf_NONVOL);
put_trail("diff_novol", "finish");
return TRUE;;
}
diff = FALSE;
while ((c = getc(i1fp)) != EOF)
if (getc(i2fp) != c)
{
diff = TRUE;
break;
}
if (getc(i2fp) != EOF)
diff = TRUE;
fclose(i1fp);
fclose(i2fp);
cdebug("diff_novol unlink %s\n", buf);
if (unlink(buf) != 0)
{
sprintf(scratchbuf, "cake system error, unlink %s", buf);
perror(scratchbuf);
put_trail("diff_novol", "finish");
return TRUE;
}
cdebug("%s\n", diff? "different": "same");
put_trail("diff_novol", "finish");
return diff;
}
/*
** Get the the name of the saved copy of the given file.
*/
get_savename(name, buf)
reg char *name;
reg char buf[];
{
extern char *noslash();
strcpy(buf, dir_name);
strcat(buf, "/save_");
strcat(buf, noslash(name));
}
/*
** Remove any slashes from a filename.
*/
char *
noslash(name)
reg char *name;
{
char buf[MAXSIZE];
reg int i;
reg char *s;
i = 0;
for (s = name; *s != '\0'; s++)
if (*s == '/')
buf[i++] = ':';
else
buf[i++] = *s;
buf[i] = '\0';
return new_name(buf);
}
/*
** Perform a stat on the given file. The only relevant info
** is the return code, indicating whether the file exists or not
** and its last modify (or status change) date. Note that if a
** file does not exist, it is by definition volatile. An aside
** considers all directories precious.
*/
node_stat(node)
reg Node *node;
{
extern int stat();
Stat statbuf;
if (node->n_name != (char *) NULL && stat(node->n_name, &statbuf) == 0)
{
set_node(node, nf_EXIST);
if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
set_node(node, nf_PRECIOUS);
node->n_rtime = cflag? statbuf.st_ctime: statbuf.st_mtime;
}
else
{
reset_node(node, nf_EXIST);
reset_node(node, nf_NONVOL);
node->n_rtime = GENESIS;
}
}
/*
** Restore the previous stat of a nonvol file,
** both in the filesystem and in cake's memory.
** However, make sure that it will not need to be
** remade again and again to discover this anew
** while its ancestors remain the same.
*/
node_resetstat(node)
reg Node *node;
{
node_stat(node);
if (off_node(node, nf_EXIST))
return;
cake_utimes(node, max(node->n_stime, node->n_utime));
node->n_utime = node->n_rtime;
}
/*
** Set up the stat of a file as the latest ancestor's,
** both in the filesystem and in cake's memory.
*/
node_setstat(node)
reg Node *node;
{
extern time_t get_youngest();
reg time_t youngest;
node_stat(node);
if (off_node(node, nf_EXIST))
return;
youngest = get_youngest(node, FALSE);
if (youngest != node->n_utime && youngest != GENESIS)
{
fprintf(stderr, "cake internal error: youngest is mismatched for %s\n",
node->n_name);
exit_cake(TRUE);
}
cake_utimes(node, node->n_utime);
}
/*
** Return the time, converting formats.
*/
time_t
cake_gettime()
{
#ifdef ATT
extern long time();
long val;
if (time(&val) == -1)
{
sprintf(scratchbuf, "cake system error, time");
perror(scratchbuf);
exit_cake(FALSE);
}
return (time_t) val;
#else
Tzone tzone;
Tval tval;
if (gettimeofday(&tval, &tzone) != 0)
{
sprintf(scratchbuf, "cake system error, gettimeofday");
perror(scratchbuf);
exit_cake(FALSE);
}
return (time_t) tval.tv_sec;
#endif
}
/*
** Issue the system call utimes after expanding its arguments
** from time_t to Tval. If the time given is GENESIS, use the
** current time instead.
*/
#ifdef ATT
typedef struct utimbuf
{
time_t actime;
time_t modtime;
} Utimbuf;
#endif
cake_utimes(node, newtime)
reg Node *node;
time_t newtime;
{
#ifdef ATT
extern int utime();
#else
extern int utimes();
#endif
extern int stat();
Stat statbuf;
#ifdef ATT
Utimbuf timbuf;
long vals[2];
#else
Tzone tzone;
Tval tvals[2];
#endif
cdebug("resetting time for %s to %d, %s",
node->n_name, newtime, ctime(&newtime));
#ifdef ATT
if (time(&vals[0]) == -1)
{
sprintf(scratchbuf, "cake system error, time");
perror(scratchbuf);
exit_cake(FALSE);
}
#else
if (gettimeofday(&tvals[0], &tzone) != 0)
{
sprintf(scratchbuf, "cake system error, gettimeofday");
perror(scratchbuf);
exit_cake(FALSE);
}
#endif
if (newtime == GENESIS)
{
cdebug("reinterpreting GENESIS\n");
#ifdef ATT
if (time(&vals[1]) == -1)
{
sprintf(scratchbuf, "cake system error, time");
perror(scratchbuf);
exit_cake(FALSE);
}
#else
if (gettimeofday(&tvals[1], &tzone) != 0)
{
sprintf(scratchbuf, "cake system error, gettimeofday");
perror(scratchbuf);
exit_cake(FALSE);
}
#endif
}
else
{
#ifdef ATT
vals[1] = (long) newtime;
#else
tvals[1].tv_sec = newtime;
tvals[1].tv_usec = 0;
#endif
}
#ifdef ATT
timbuf.actime = vals[0];
timbuf.modtime = vals[1];
node->n_rtime = vals[1];
#else
node->n_rtime = (time_t) tvals[1].tv_sec;
#endif
if (nflag)
return;
#ifdef ATT
if (utime(node->n_name, &timbuf) != 0)
#else
if (utimes(node->n_name, tvals) != 0)
#endif
{
sprintf(scratchbuf, "cake system error, utime(s) %s", node->n_name);
perror(scratchbuf);
fprintf(stderr, "cake: continuing\n");
}
#ifdef CAKEDEBUG
if (cakedebug)
{
if (stat(node->n_name, &statbuf) != 0)
printf("cannot verify utimes\n");
else
{
print_time("accessed", statbuf.st_atime);
print_time("modified", statbuf.st_mtime);
print_time("changed ", statbuf.st_ctime);
}
}
#endif
}
/*
** See if the given file exists.
*/
bool
exist(name)
reg char *name;
{
Stat statbuf;
if (stat(name, &statbuf) == 0)
return TRUE;
else
return FALSE;
}
/*
** Remove the given file.
*/
cake_remove(name)
reg char *name;
{
#ifdef CAREFUL
if (! Xflag)
{
extern int getpid();
extern int cake_proc();
extern Wait cake_wait();
extern char *noslash();
reg int pid, cakepid;
Stat statbuf;
Wait code;
char buf[80];
#ifndef ATT
if (lstat(name, &statbuf) != 0)
{
sprintf(scratchbuf, "cake system error, lstat %s", name);
perror(scratchbuf);
fprintf(stderr, "cake: continuing\n");
return;
}
if ((statbuf.st_mode & S_IFMT) == S_IFLNK)
{
printf("removing the symbolic link %s\n", name);
cdebug("cake_remove unlink %s\n", name);
if (unlink(name) != 0)
{
sprintf(scratchbuf, "cake system error, unlink %s", name);
perror(scratchbuf);
fprintf(stderr, "cake: continuing\n");
}
return;
}
#endif
cakepid = getpid();
printf("moving %s to /tmp\n", name);
sprintf(buf, "mv %s /tmp/%s.%d", name, noslash(name), cakepid);
pid = cake_proc(buf, Exec, (char *) NULL, (Node *) NULL,
(int (*)()) NULL, (List *) NULL);
code = cake_wait(pid);
if (code.w_status != 0)
{
fprintf(stderr, "cake system error: '%s' failed\n", buf);
fprintf(stderr, "cake: continuing\n");
return;
}
sprintf(buf, "/tmp/%s.%d", noslash(name), cakepid);
if (chmod(buf, 0600) != 0)
{
sprintf(scratchbuf, "cake system error, chmod %s", buf);
perror(scratchbuf);
fprintf(stderr, "cake: continuing\n");
return;
}
return;
}
#endif
cdebug("cake_remove unlink %s\n", name);
if (unlink(name) != 0)
{
sprintf(scratchbuf, "cake system error, unlink %s", name);
perror(scratchbuf);
fprintf(stderr, "cake: continuing\n");
}
}
-171
View File
@@ -1,171 +0,0 @@
/*
** Linked list module.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
/*
** Make an empty list.
*/
List *
makelist0()
{
reg List *list;
list = make(List);
ldata(list) = (Cast) 0;
next(list) = list;
prev(list) = list;
return list;
}
/*
** Make a list with the argument is its only element.
*/
List *
_makelist(data)
reg Cast data;
{
return addhead(makelist0(), data);
}
/*
** Add some data to the head of a list.
*/
List *
_addhead(list, data)
reg List *list;
reg Cast data;
{
reg List *item;
if (list == NULL)
list = makelist0();
item = make(List);
ldata(item) = data;
ldata(list) = (Cast) ((int) ldata(list) + 1);
/* item's pointers */
next(item) = next(list);
prev(item) = list;
/* neighbours' pointers */
next(prev(item)) = item;
prev(next(item)) = item;
return list;
}
/*
** Add some data to the tail of a list.
*/
List *
_addtail(list, data)
reg List *list;
reg Cast data;
{
reg List *item;
if (list == NULL)
list = makelist0();
item = make(List);
ldata(item) = data;
ldata(list) = (Cast) ((int) ldata(list) + 1);
/* item's pointers */
next(item) = list;
prev(item) = prev(list);
/* neighbours' pointers */
next(prev(item)) = item;
prev(next(item)) = item;
return list;
}
/*
** Destructively append list2 to list1. Since the header of
** list2 is not meaningful after the operation, it is freed.
*/
List *
addlist(list1, list2)
reg List *list1;
reg List *list2;
{
if (list1 == NULL)
list1 = makelist0();
if (list2 == NULL)
list2 = makelist0();
if (length(list2) > 0)
{
if (length(list1) == 0)
{
ldata(list1) = ldata(list2);
/* pointers from header */
next(list1) = next(list2);
prev(list1) = prev(list2);
/* pointers to header */
prev(next(list1)) = list1;
next(prev(list1)) = list1;
}
else
{
ldata(list1) = (Cast) ((int) ldata(list1) + (int) ldata(list2));
/* end of list 1 to start of list 2 */
next(prev(list1)) = next(list2);
prev(next(list2)) = prev(list1);
/* end of list 2 to start of list 1 */
next(prev(list2)) = list1;
prev(list1) = prev(list2);
}
}
oldmem((Cast) list2);
return list1;
}
/*
** Return the length of a given list.
*/
int
length(list)
reg List *list;
{
if (list == NULL)
return 0;
return (int) ldata(list);
}
/*
** Delete an item from its linked list, and free the node.
*/
delete(list, item)
reg List *list;
reg List *item;
{
if (list == NULL)
return;
if (item == NULL)
return;
ldata(list) = (Cast) ((int) ldata(list) - 1);
next(prev(item)) = next(item);
prev(next(item)) = prev(item);
oldmem((Cast) item);
}
-40
View File
@@ -1,40 +0,0 @@
/*
** Definitions for the list module.
**
** $Header$
*/
typedef struct s_list
{
Cast l_data;
struct s_list *l_prev;
struct s_list *l_next;
} List;
#define next(ptr) (ptr)->l_next
#define prev(ptr) (ptr)->l_prev
#define ldata(ptr) (ptr)->l_data
#define first_ptr(list) ((list)->l_next)
#define last_ptr(list) ((list)->l_prev)
#define first(list) ((list)->l_next->l_data)
#define last(list) ((list)->l_prev->l_data)
#define for_list(p, l) for (p = (l? next(l): NULL); p != l && p != NULL; p = next(p))
#define for_2list(p1, p2, l1, l2) for \
(p1 = (l1? next(l1): NULL), p2 = (l2? next(l2): NULL); \
p1 != l1 && p1 != NULL && p2 != l2 && p2 != NULL; \
p1 = next(p1), p2 = next(p2))
#define end_list(p, l) (p == l || p == NULL)
#define makelist(d) _makelist((Cast) d)
#define addhead(l, d) _addhead(l, (Cast) d)
#define addtail(l, d) _addtail(l, (Cast) d)
#define insert_before(l, w, d) _insert_before(l, w, (Cast) d)
#define insert_after(l, w, d) _insert_after(l, w, (Cast) d)
extern List *makelist0();
extern List *_makelist();
extern List *_addhead();
extern List *_addtail();
extern List *addlist();
extern delete();
-35
View File
@@ -1,35 +0,0 @@
/*
** Common macros for Cake
**
** $Header$
*/
#define checkpatlen(p) if (strlen(p) > MAXPATSIZE) \
printf("Pattern %s too long\n", p), exit_cake(FALSE)
#define cdebug if (cakedebug) printf
#ifndef CAKEDEBUG
#define put_trail(func, event)
#define get_trail(fp)
#endif
/* Flag handling */
#define on_node(n, f) ((n)->n_flag & (f))
#define off_node(n, f) (!((n)->n_flag & (f)))
#define set_node(n, f) (n)->n_flag |= (f)
#define reset_node(n, f) (n)->n_flag &= ~(f)
#define on_pat(p, f) ((p)->p_flag & (f))
#define off_pat(p, f) (!((p)->p_flag & (f)))
#define set_pat(p, f) (p)->p_flag |= (f)
#define reset_pat(p, f) (p)->p_flag &= ~(f)
#define on_act(a, f) ((a)->a_flag & (f))
#define off_act(a, f) (!((a)->a_flag & (f)))
#define set_act(a, f) (a)->a_flag |= (f)
#define reset_act(a, f) (a)->a_flag &= ~(f)
#define is_ok(n) ((n)->n_kind == n_OK)
#define is_cando(n) ((n)->n_kind == n_CANDO)
#define is_noway(n) ((n)->n_kind == n_NOWAY)
-550
View File
@@ -1,550 +0,0 @@
/*
** Cake main file.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
#include <pwd.h>
#include <signal.h>
#include <sys/stat.h>
typedef struct passwd Pwent;
typedef struct stat Stat;
int Gflag = FALSE;
int Lflag = FALSE;
int Rflag = FALSE;
int Xflag = FALSE;
int Zflag = FALSE;
int bflag = FALSE;
int cflag = FALSE;
int dflag = FALSE;
int gflag = FALSE;
int iflag = FALSE;
int kflag = TRUE;
int nflag = FALSE;
int qflag = FALSE;
int rflag = FALSE;
int sflag = FALSE;
int tflag = FALSE;
int vflag = FALSE;
int wflag = FALSE;
int xflag = FALSE;
int zflag = FALSE;
char *cakefile = NULL;
char *shellfile[2] = { SYSTEM_CMD, SCRIPT_CMD };
char *metachars = METACHARS;
int maxprocs = 1;
List *active_procs;
char scratchbuf[128];
int cakedebug = FALSE;
int entrydebug = FALSE;
int patdebug = FALSE;
int lexdebug = FALSE;
char cakeflagbuf[MAXSIZE];
char *cppargv[MAXARGS];
int cppargc = 0;
extern int yydebug;
main(argc, argv)
int argc;
char **argv;
{
extern cake_abort(), cake_finish();
extern int parse_args(), process_args();
extern Node *chase();
extern char *getenv();
extern char *dir_setup();
#if !defined(__convex__)
extern Pwent *getpwuid();
#endif
extern int geteuid();
extern FILE *cake_popen();
extern FILE *yyin;
Stat statbuf;
int envc;
char *envv[MAXARGS];
reg Pwent *pwent;
reg char *envstr;
reg int status;
reg Node *rootnode;
signal(SIGINT, cake_finish);
signal(SIGQUIT, cake_finish);
if(cakedebug) {
/* If debugging enabled, catch signals to do get_trail() */
signal(SIGILL, cake_abort);
signal(SIGTRAP, cake_abort);
signal(SIGIOT, cake_abort);
signal(SIGEMT, cake_abort);
signal(SIGFPE, cake_abort);
signal(SIGBUS, cake_abort);
signal(SIGSEGV, cake_abort);
signal(SIGSYS, cake_abort);
}
signal(SIGPIPE, cake_abort);
signal(SIGALRM, cake_abort);
yydebug = FALSE;
active_procs = makelist0();
if (rindex(argv[0], 'f') != NULL
&& streq(rindex(argv[0], 'f'), "fake"))
cakedebug = TRUE;
init_sym();
cppargv[cppargc++] = new_name(CPP);
#if defined(CPP_OPTIONS)
cppargv[cppargc++] = new_name(CPP_OPTIONS);
#endif
strcpy(cakeflagbuf, "-DCAKEFLAGS=");
if ((envstr = getenv("CAKE")) != NULL)
{
envc = parse_args(envstr, envv);
process_args(envv, &envc, 0);
if (envc > 0)
fprintf(stderr, "cake: non-options in environment ignored\n");
}
argv += process_args(argv, &argc, 1);
#if defined(CAKEDEBUG) && !defined(ATT)
if (cakedebug || entrydebug || patdebug || lexdebug)
setlinebuf(stdout);
#endif
if (cakefile == NULL)
{
if (stat("cakefile", &statbuf) == 0)
cakefile = "cakefile";
or (stat("Cakefile", &statbuf) == 0)
cakefile = "Cakefile";
or (stat("recipe", &statbuf) == 0)
cakefile = "recipe";
or (stat("Recipe", &statbuf) == 0)
cakefile = "Recipe";
else
{
fprintf(stderr, "cake: cannot locate a cakefile\n");
exit(1);
}
}
if (gflag)
cakefile = dir_setup(cakefile);
if( (pwent = getpwuid(geteuid())) == (Pwent *)0 ) {
printf("cake: Warning: unable to get home directory for uid %d\n",
geteuid() );
} else {
strcpy(scratchbuf, "-I");
strcat(scratchbuf, pwent->pw_dir);
strcat(scratchbuf, ULIB);
cppargv[cppargc++] = new_name(scratchbuf);
}
strcpy(scratchbuf, "-I");
strcat(scratchbuf, SLIB);
cppargv[cppargc++] = new_name(scratchbuf);
cppargv[cppargc++] = cakeflagbuf;
cppargv[cppargc++] = cakefile;
cppargv[cppargc] = NULL;
if (cakedebug)
{
reg int i;
for (i = 0; i < cppargc; i++)
printf("%s\n", cppargv[i]);
}
if ((yyin = cake_popen(cppargv, "r")) == NULL)
{
fprintf(stderr, "cake: cannot open cpp filter\n");
exit(1);
}
if (Zflag)
{
reg int c;
while ((c = getc(yyin)) != EOF)
putchar(c);
cake_pclose(yyin);
exit(0);
}
yyinit();
init_entry();
if (yyparse())
{
fprintf(stderr, "cake: cannot parse %s\n", cakefile);
exit(1);
}
shell_setup(shellfile[0], 0);
shell_setup(shellfile[1], 1);
meta_setup(metachars);
cake_pclose(yyin);
dir_start();
prep_entries();
final_entry(argc, argv);
rootnode = chase(CHASEROOT, 0, (Entry *) NULL);
if (! qflag)
execute(rootnode);
dir_finish();
cleanup();
#ifdef STATS_FILE
statistics();
#endif
status = (off_node(rootnode, nf_ERR) && is_ok(rootnode))? 0: 1;
cdebug("exit status %d\n", status);
exit(status);
}
int
process_args(vector, count, base)
reg char **vector;
reg int *count;
reg int base;
{
reg int i, j;
j = 0;
cdebug("process args:");
while (*count > base && vector[base][0] == '-')
{
putflag(base, vector[base]);
for (i = 1; vector[base][i] != '\0'; i++)
{
switch (vector[base][i])
{
#ifdef CAKEDEBUG
when 'C': cdebug(" -C");
cakedebug = ! cakedebug;
when 'E': cdebug(" -E");
entrydebug = ! entrydebug;
when 'P': cdebug(" -P");
patdebug = ! patdebug;
when 'W': cdebug(" -W");
lexdebug = TRUE;
when 'Y': cdebug(" -Y");
yydebug = TRUE;
#endif
when 'G': cdebug(" -G");
Gflag = TRUE;
when 'L': cdebug(" -L");
Lflag = TRUE;
when 'R': cdebug(" -R");
Rflag = TRUE;
when 'X': cdebug(" -X");
Xflag = TRUE;
when 'Z': cdebug(" -Z");
Zflag = TRUE;
when 'a': cdebug(" -a");
kflag = FALSE;
when 'b': cdebug(" -b");
bflag = TRUE;
when 'c': cdebug(" -c");
cflag = TRUE;
when 'd': cdebug(" -d");
dflag = TRUE;
when 'g': cdebug(" -g");
gflag = TRUE;
when 'i': cdebug(" -i");
iflag = TRUE;
when 'k': cdebug(" -k");
kflag = TRUE;
when 'n': cdebug(" -n");
nflag = TRUE;
tflag = FALSE;
qflag = FALSE;
when 'q': cdebug(" -q");
qflag = TRUE;
nflag = FALSE;
tflag = FALSE;
when 'r': cdebug(" -r");
rflag = TRUE;
when 's': cdebug(" -s");
sflag = TRUE;
when 't': cdebug(" -t");
tflag = TRUE;
nflag = FALSE;
qflag = FALSE;
when 'v': cdebug(" -v");
vflag = TRUE;
when 'w': cdebug(" -w");
wflag = TRUE;
when 'x': cdebug(" -x");
xflag = TRUE;
when 'z': cdebug(" -z");
zflag = TRUE;
when 'D':
case 'I':
case 'U': if (i != 1)
usage();
cdebug(" %s", vector[base]);
cppargv[cppargc++] = new_name(vector[base]);
goto nextword;
when 'N': putflag(base, vector[base+1]);
sscanf(vector[base+1], "%d", &maxprocs);
if (vector[base][i+1] != '\0')
usage();
cdebug(" -N %d", maxprocs);
(*count)--;
vector++, j++;
goto nextword;
when 'S': putflag(base, vector[base+1]);
if (vector[base][i+1] == '1')
shellfile[0] = new_name(vector[base+1]);
or (vector[base][i+1] == '2')
shellfile[1] = new_name(vector[base+1]);
else
usage();
if (vector[base][i+2] != '\0')
usage();
cdebug(" -S%c %s", vector[base][i+1], vector[base+1]);
(*count)--;
vector++, j++;
goto nextword;
when 'T': putflag(base, vector[base+1]);
metachars = new_name(vector[base+1]);
if (vector[base][i+1] != '\0')
usage();
cdebug(" -T %s", metachars);
(*count)--;
vector++, j++;
goto nextword;
when 'f': putflag(base, vector[base+1]);
cakefile = new_name(vector[base+1]);
if (vector[base][i+1] != '\0')
usage();
cdebug(" -f %s", cakefile);
(*count)--;
vector++, j++;
goto nextword;
otherwise: usage();
}
}
nextword:
(*count)--;
vector++, j++;
}
cdebug(" \nreturn %d\n", j); /* BRL MOD */
return j;
}
/*
** Put a flag into the CAKEFLAGS definition.
*/
putflag(base, flag)
reg int base;
reg char *flag;
{
if (base == 1)
{
strcat(cakeflagbuf, " ");
strcat(cakeflagbuf, flag);
if (strlen(cakeflagbuf) >= MAXSIZE)
{
fprintf(stderr, "cake: CAKEFLAGS too long\n");
exit(1);
}
}
}
/*
** Tell the unfortunate user how to use cake.
*/
usage()
{
fprintf(stderr, "Usage: cake [-abcdgiknqrstvwxzGLRXZ] [-ffile]\n");
fprintf(stderr, " [-Ddefn] [-Idir] [-Uname] [-S shell] [-T metachars] [file ...]\n");
exit(1);
}
exit_cake(needtrail)
reg int needtrail;
{
if (cakedebug && needtrail)
get_trail(stdout);
else
dir_finish();
exit(1);
}
/*
** Handle bus errors and segmentation violations.
*/
cake_abort(signo)
int signo;
{
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
printf("cake: aborting on signal %d\n", signo);
if (cakedebug)
get_trail(stdout);
signal(SIGQUIT, SIG_DFL);
kill(getpid(), SIGQUIT);
}
/*
** Handle user interrupts.
*/
cake_finish()
{
reg List *ptr;
reg Proc *proc;
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
printf("*** Interrupt\n");
fflush(stdout);
for_list (ptr, active_procs)
{
proc = (Proc *) ldata(ptr);
if (proc->pr_node != NULL)
cake_error(proc->pr_node);
}
exit_cake(FALSE);
}
#ifdef STATS_FILE
#ifdef ATT
#include <sys/times.h>
typedef struct tms Tms;
#else
#include <sys/time.h>
#include <sys/resource.h>
typedef struct rusage Rusage;
#endif
statistics()
{
extern char *getlogin();
extern getpw();
extern int out_tried, out_found;
extern int stat_tried, stat_found;
FILE *sfp;
if ((sfp = fopen(STATS_FILE, "a")) != NULL)
{
#ifdef ATT
Tms tbuf;
#else
Rusage s, c;
#endif
long su, ss, cu, cs;
char *usr;
if ((usr = getlogin()) == NULL)
{
char buf[256];
char *usr_end;
if (getpw(getuid(), buf) != 0)
usr = "NULL";
else
{
usr = buf;
if ((usr_end = index(usr, ':')) != NULL)
*usr_end = '\0';
else
usr = "NULL";
}
usr = new_name(usr);
}
#ifdef ATT
if (times(&tbuf) == -1)
{
fclose(sfp);
return;
}
su = tbuf.tms_utime*100/TIMERES;
ss = tbuf.tms_stime*100/TIMERES;
cu = tbuf.tms_cutime*100/TIMERES;
cs = tbuf.tms_cstime*100/TIMERES;
#else
getrusage(RUSAGE_SELF, &s);
getrusage(RUSAGE_CHILDREN, &c);
su = s.ru_utime.tv_sec*100 + s.ru_utime.tv_usec/10000;
ss = s.ru_stime.tv_sec*100 + s.ru_stime.tv_usec/10000;
cu = c.ru_utime.tv_sec*100 + c.ru_utime.tv_usec/10000;
cs = c.ru_stime.tv_sec*100 + c.ru_stime.tv_usec/10000;
#endif
fprintf(sfp, "%s %ld %ld %ld %ld ", usr, su, ss, cu, cs);
fprintf(sfp, "%d %d %d %d %d\n", sbrk(0),
out_tried, out_found, stat_tried, stat_found);
fclose(sfp);
}
}
#endif
-200
View File
@@ -1,200 +0,0 @@
/*
** Module to make Cake data structures.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
Node *
make_node(name)
reg char *name;
{
reg Node *node;
node = make(Node);
node->n_name = name;
if (name == NULL)
return node;
node->n_kind = n_NOWAY; /* not yet */
node->n_flag = 0;
node->n_old = makelist0();
node->n_when = NULL;
node->n_act = NULL;
node->n_new = makelist(node);
#if 0 /* N must be 1 for the time being */
node->n_pid = 0;
node->n_file = NULL;
#endif
node_stat(node);
node->n_utime = 0;
node->n_stime = node->n_rtime;
node->n_badguys = NULL;
node->n_msg = NULL;
return node;
}
Entry *
make_dep(new, old, cond, file, colon)
reg List *new; /* of Pat */
reg List *old; /* of Pat */
reg Test *cond;
reg char *file;
reg char *colon;
{
reg Entry *entry;
entry = make(Entry);
entry->e_new = new;
entry->e_old = old;
entry->e_cond = cond;
entry->e_file = file;
entry->e_dblc = streq(colon, "::");
entry->e_when = makelist0();
return entry;
}
Test *
make_test_mm(name)
reg Pat *name;
{
reg Test *test;
test = make(Test);
test->t_kind = t_MATCH;
test->t_pat = name;
test->t_list = makelist0();
return test;
}
Test *
make_test_m(name, varpat, pattern)
reg Pat *name;
reg Pat *varpat;
reg Pat *pattern;
{
reg Test *test;
test = make(Test);
test->t_kind = t_MATCH;
test->t_pat = name;
test->t_list = makelist0();
if (varpat == NULL)
addtail(test->t_list, make_pat("-vX", FALSE, 0));
else
addtail(test->t_list, varpat); /* no assignment */
addtail(test->t_list, pattern); /* no assignment */
return test;
}
Test *
make_test_c(cmd)
reg char *cmd;
{
reg Test *test;
test = make(Test);
test->t_kind = t_CMD;
test->t_cmd = cmd;
return test;
}
Test *
make_test_s(tkind, pat)
reg T_kind tkind;
reg Pat *pat;
{
reg Test *test;
test = make(Test);
test->t_kind = tkind;
test->t_pat = pat;
return test;
}
Test *
make_test_l(pat, list)
reg Pat *pat;
reg List *list; /* of Pat */
{
reg Test *test;
test = make(Test);
test->t_kind = t_LIST;
test->t_pat = pat;
test->t_list = list;
return test;
}
Test *
make_test_b(tkind, left, right)
reg T_kind tkind;
reg Test *left;
reg Test *right;
{
reg Test *test;
test = make(Test);
test->t_kind = tkind;
test->t_left = left;
test->t_right = right;
return test;
}
Test *
make_test_u(tkind, left)
reg T_kind tkind;
reg Test *left;
{
reg Test *test;
test = make(Test);
test->t_kind = tkind;
test->t_left = left;
test->t_right = (Test *) NULL;
return test;
}
Pat *
make_pat(text, iscmd, flags)
reg char *text;
reg bool iscmd;
reg int flags;
{
reg Pat *pat;
pat = make(Pat);
pat->p_str = text;
pat->p_cmd = iscmd;
pat->p_flag = flags;
checkpatlen(text);
return pat;
}
Act *
make_act(str, flag)
reg char *str;
reg int flag;
{
reg Act *act;
act = make(Act);
act->a_str = str;
act->a_flag = flag;
return act;
}
-50
View File
@@ -1,50 +0,0 @@
/*
** Memory management module.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
/*
** Allocate space if possible. In the future it may record
** all pointers returned, so that old can do some checks.
*/
Cast
newmem(size)
int size;
{
reg char *space;
if ((space = malloc((unsigned) size)) == NULL)
{
fprintf(stderr, "cake system error: no more malloc\n");
exit_cake(FALSE);
}
#ifdef EXTRACHECK
if (((int) space & 03) != 0)
{
fprintf(stderr, "cake system error: malloc not aligned\n");
exit_cake(FALSE);
}
#endif
return (Cast) space;
}
/*
** Return some storage to the free list. This storage must
** have been obtained from new and malloc.
*/
/*ARGSUSED*/
oldmem(ptr)
Cast ptr;
{
#ifdef MEMUSED
free((char *) ptr);
#endif
}
-352
View File
@@ -1,352 +0,0 @@
/*
** Module to manipulate Cake patterns.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
#include <ctype.h>
/*
** This function serves as an interface to the rest of the system
** for domatch, looking after its environment.
*/
bool
match(env, str, pat)
Env env;
reg char *str;
reg Pat *pat;
{
extern bool domatch();
reg bool result;
reg int i;
reg char *s, *p;
if (patdebug)
printf("Match %s vs %s\n", str, pat->p_str);
if (pat->p_cmd)
{
fprintf(stderr, "cake internal error: undereferenced pattern %s in match\n",
pat->p_str);
exit_cake(TRUE);
}
if (streq(str, CHASEROOT))
result = streq(pat->p_str, CHASEROOT);
else
{
result = TRUE; /* assume so for the moment */
p = pat->p_str+strlen(pat->p_str)-1;
if (*p != '%' && !isdigit(*p)) /* not part of a var */
{
s = str+strlen(str)-1;
if (*s != *p) /* last chars differ */
result = FALSE;
}
if (result) /* if last-char test inconclusive */
{
for (i = 0; i < MAXVAR; i++)
env[i].v_bound = FALSE;
result = domatch(env, str, pat->p_str);
}
}
if (patdebug)
{
if (result == FALSE)
printf("Match failed\n");
else
{
printf("Match succeeded\n");
for (i = 0; i < MAXVAR; i++)
if (env[i].v_bound)
printf("X%d: %s\n", i, env[i].v_val);
}
}
return result;
}
/*
** Match a string against a pattern.
** The pattern is expected to have been dereferenced.
** To handle nondeterminism, a brute force recursion approach
** is taken.
*/
bool
domatch(env, str, patstr)
Env env;
reg char *str;
reg char *patstr;
{
char buf[MAXPATSIZE];
reg char *follow;
reg char *s, *t;
reg int varno;
reg int i;
reg bool more;
put_trail("domatch", "start");
if (patstr[0] == '%')
{
if (isdigit(patstr[1]))
{
varno = patstr[1] - '0';
follow = patstr + 2;
}
else
{
varno = NOVAR;
follow = patstr + 1;
}
if (env[varno].v_bound)
{
/* lifetime of buf is local */
strcpy(buf, env[varno].v_val);
strcat(buf, follow);
checkpatlen(buf);
put_trail("domatch", "recurse");
return domatch(env, str, buf);
}
i = 0;
buf[0] = '\0';
env[varno].v_bound = TRUE;
env[varno].v_val = buf;
/* keep invariant: buf = tentative value of var */
/* the value of a variable may never contain a % */
/* must consider *s == \0, but do not overshoot */
for (s = str, more = TRUE; more && *s != '%'; s++)
{
if (patdebug)
printf("trying X%d = '%s'\n", varno, buf);
if (domatch(env, s, follow))
{
checkpatlen(buf);
env[varno].v_val = new_name(buf);
/* lifetime of buf is now global */
put_trail("domatch", "finish");
return TRUE;
}
/* maintain invariant */
buf[i++] = *s;
buf[i] = '\0';
more = (*s != '\0');
}
/* no luck, match failed */
env[varno].v_bound = FALSE;
put_trail("domatch", "finish");
return FALSE;
}
/* here we have something other than a variable first off */
for (s = str, t = patstr; *t != '\0' && *t != '%'; s++, t++)
{
if (*t == '\\')
t++; /* the new *t is not checked for % */
if (*s != *t)
{
put_trail("domatch", "finish");
return FALSE;
}
}
/* see if we have come to the end of the pattern */
if (*t == '\0')
{
put_trail("domatch", "finish");
return *s == '\0';
}
/* if not, recurse on the next variable */
put_trail("domatch", "recurse");
return domatch(env, s, t);
}
/*
** Ground the argument string, i.e. replace all occurrences
** of variables in it. It is fatal error for the string to
** contain a variable which has no value.
*/
char *
ground(env, str)
Env env;
reg char *str;
{
reg char *s, *t;
reg int i, var;
char buf[MAXSIZE];
put_trail("ground", "start");
i = 0;
for (s = str; *s != '\0'; s++)
{
if (*s == '%')
{
if (isdigit(s[1]))
var = *++s - '0';
else
var = NOVAR;
if (! env[var].v_bound)
{
if (var == NOVAR)
fprintf(stderr, "cake: %s is undefined in %s\n", "%", str);
else
fprintf(stderr, "cake: %s%1d is undefined in %s\n", "%", var, str);
exit_cake(FALSE);
}
for (t = env[var].v_val; *t != '\0'; t++)
buf[i++] = *t;
}
or (*s == '\\')
{
if (s[1] != '\0')
buf[i++] = *++s;
}
else
buf[i++] = *s;
}
buf[i] = '\0';
if (i >= MAXSIZE)
{
fprintf(stderr, "cake internal error: pattern buffer overflow for %s\n", buf);
exit_cake(FALSE);
}
put_trail("ground", "new_name finish");
return new_name(buf);
}
/*
** See if the argument contains any variebles.
*/
bool
hasvars(str)
reg char *str;
{
reg char *s;
for (s = str; *s != '\0'; s++)
{
if (*s == '%')
return TRUE;
or (*s == '\\')
{
if (s[1] != '\0')
s++;
}
}
return FALSE;
}
/*
** Dereference the pattern; i.e. if it a command pattern
** replace it with the output of the command. It is the task
** of the caller to break this up if necessary.
** Note that the pattern will never have to be dereferenced again.
**
** The second arg says whether the pattern is to be broken after
** dereferencing: this is needed purely for debugging purposes.
*/
deref(pat, broken)
reg Pat *pat;
reg bool broken;
{
extern char *expand_cmds();
if (! pat->p_cmd)
return;
pat->p_cmd = FALSE;
pat->p_str = expand_cmds(pat->p_str);
if (! broken)
checkpatlen(pat->p_str);
}
/*
** Break the given pattern up into a (possibly empty) list
** of smaller patterns at white space positions.
*/
List *
break_pat(pat)
reg Pat *pat;
{
reg Pat *newpat;
reg List *list;
reg char *s;
put_trail("break_pat", "start");
if (pat->p_cmd)
{
fprintf(stderr, "cake internal error: trying to break command pattern %s\n", pat->p_str);
exit_cake(TRUE);
}
list = makelist0();
s = pat->p_str;
while (*s != '\0')
{
char buf[MAXSIZE];
reg int i;
for (; *s != '\0' && isspace(*s); s++)
;
i = 0;
for (; *s != '\0' && !isspace(*s); s++)
buf[i++] = *s;
buf[i] = '\0';
if (i > 0)
{
newpat = make_pat(new_name(buf), FALSE, pat->p_flag);
addtail(list, newpat); /* no assignment */
}
}
put_trail("break_pat", "finish");
return list;
}
/*
** Add flags to a list of patterns.
*/
List *
set_flag(patlist, flags)
reg List *patlist;
reg int flags;
{
reg List *ptr;
reg Pat *pat;
for_list (ptr, patlist)
{
pat = (Pat *) ldata(ptr);
pat->p_flag |= flags;
}
return patlist;
}
-106
View File
@@ -1,106 +0,0 @@
/*
** Cake portability aids.
**
** $Header$
*/
/* too long names */
#define cake_abort c_abort
#define cake_error c_error
#define cake_exec c_exec
#define cake_finish c_finish
#define cake_gettime c_gettime
#define cake_pclose c_pclose
#define cake_popen c_popen
#define cake_remove c_remove
#define cake_script c_script
#define cake_system c_system
#define cake_utimes c_utimes
#define cake_wait c_wait
#define chase chs
#define chase_node chs_node
#define cppargc cppcarg
#define cppargv cppvarg
#define deref drf
#define deref_entry drf_entry
#define dir_finish dr_finish
#define dir_setup dr_setup
#define dir_start dr_start
#define entry_anay en_nay
#define entry_ayea en_yea
#define expand_cmds ex_cmds
#define find_path fd_path
#define find_process fd_proc
#define found_incl fnd_incl
#define found_main fnd_main
#define get_allnodes g_allnodes
#define get_cmd_result gc_result
#define get_cmd_status gc_status
#define get_newname g_newname
#define get_output g_output
#define get_savename g_savename
#define get_utime g_utime
#define get_youngest g_youngest
#define goal_stackp gs_p
#define ground gr
#define ground_entry gr_entry
#define ground_test gr_test
#define init_chase i_chase
#define init_entry i_entry
#define init_sym i_sym
#define make_act m_act
#define make_cmd m_cmd
#define make_dep m_dep
#define make_node m_node
#define make_pat m_pat
#define make_test_b m_btest
#define make_test_c m_ctest
#define make_test_l m_ltest
#define make_test_m m_mtest
#define make_test_mm m_mmtest
#define make_test_s m_stest
#define make_test_u m_utest
#define makelist0 m_0list
#define miss_anay ms_nay
#define miss_ayea ms_yea
#define mutex_lock mx_lock
#define mutex_unlock mx_unlock
#define name_equal nm_equal
#define name_key nm_key
#define new_cmd nw_cmd
#define new_name nw_name
#define node_resetstat nd_resetstat
#define node_setstat nd_setstat
#define node_stat nd_stats
#define picked_time pck_time
#define prep_act pp_act
#define prep_entries pp_entries
#define prep_script pp_script
#define print_act pr_act
#define print_entry pr_entry
#define print_node pr_node
#define print_pat pr_pat
#define print_test pr_test
#define print_time pr_time
#define script_filename scr_fn
#define set_buddies st_buddies
#define set_flag st_flag
#define shell_cmd sh_cmd
#define shell_opt sh_opt
#define shell_path sh_path
#define signalint sg_int
#define signalquit sg_quit
#define spawn_finish sp_finish
#define spawn_start sp_start
#define stat_tried st_tried
#define str_aflag s_aflag
#define str_nkind s_nkind
#define str_pflag s_pflag
#define warn_equal w_equal
#define warn_key w_key
/* case sensitive variable names */
#define Gflag ggflag
#define Lflag llflag
#define Rflag rrflag
#define Xflag xxflag
-303
View File
@@ -1,303 +0,0 @@
/*
** Printout routines for Cake data structures.
*/
#ifdef CAKEDEBUG
static char
rcs_id[] = "$Header$";
#include "cake.h"
char *
str_pflag(flag)
reg int flag;
{
char buf[256];
strcpy(buf, "[");
if (flag & nf_NONVOL)
strcat(buf, "nonvol ");
if (flag & nf_PRECIOUS)
strcat(buf, "precious ");
if (flag & nf_PSEUDO)
strcat(buf, "pseudo ");
if (flag & nf_REDUNDANT)
strcat(buf, "redundant ");
if (flag & nf_WHEN)
strcat(buf, "when ");
if (flag & nf_DEPNONVOL)
strcat(buf, "depnonvol ");
if (flag & nf_NODELETE)
strcat(buf, "nodelete ");
if (flag & nf_NEWFILE)
strcat(buf, "newfile ");
if (flag & nf_EXIST)
strcat(buf, "exist ");
if (flag & nf_BUSY)
strcat(buf, "busy ");
if (flag & nf_ERR)
strcat(buf, "err ");
if (flag & nf_TRACED)
strcat(buf, "traced ");
if (flag & nf_WARNED)
strcat(buf, "warned ");
if (flag & nf_ORIG)
strcat(buf, "orig ");
if (strlen(buf) > 1)
buf[strlen(buf)-1] = '\0';
strcat(buf, "]");
return new_name(buf);
}
char *
str_aflag(flag)
reg int flag;
{
char buf[128];
strcpy(buf, "[");
if (flag & af_SILENT)
strcat(buf, "silent ");
if (flag & af_IGNORE)
strcat(buf, "ignore ");
if (flag & af_MINUSN)
strcat(buf, "minusn ");
if (flag & af_SYSTEM)
strcat(buf, "system ");
if (flag & af_SCRIPT)
strcat(buf, "script ");
if (strlen(buf) > 1)
buf[strlen(buf)-1] = '\0';
strcat(buf, "]");
return new_name(buf);
}
print_pat(pat)
reg Pat *pat;
{
if (pat->p_cmd)
printf("`%s`", pat->p_str);
else
printf("%s", pat->p_str);
printf(str_pflag(pat->p_flag));
}
print_act(act)
reg Act *act;
{
printf(str_aflag(act->a_flag));
printf("%s", act->a_str);
}
print_test(test)
reg Test *test;
{
reg List *ptr;
reg char *pre;
reg Pat *pat;
if (test == NULL)
{
printf("null");
return;
}
switch (test->t_kind)
{
when t_TRUE: printf("true");
when t_FALSE: printf("false");
when t_AND: print_test(test->t_left);
printf(" and ");
print_test(test->t_right);
when t_OR: print_test(test->t_left);
printf(" or ");
print_test(test->t_right);
when t_NOT: printf("not ");
print_test(test->t_left);
when t_CMD: printf("cmd `%s`", test->t_cmd);
when t_MATCH: printf("match ");
print_pat(test->t_pat);
printf(" against");
printf(" (");
print_pat((Pat *) first(test->t_list));
printf(") ");
print_pat((Pat *) last(test->t_list));
when t_LIST: printf("list ");
print_pat(test->t_pat);
printf(" in (");
pre = "";
for_list (ptr, test->t_list)
{
pat = (Pat *) ldata(ptr);
printf(pre);
print_pat(pat);
pre = ", ";
}
printf(")");
when t_EXIST: printf("exist ");
print_pat(test->t_pat);
when t_CANDO: printf("cando ");
print_pat(test->t_pat);
when t_OK: printf("ok ");
print_pat(test->t_pat);
otherwise: printf("Bad type kind %d in print_test\n", test->t_kind);
}
}
print_entry(entry)
reg Entry *entry;
{
reg List *ptr;
reg Pat *pat;
reg Act *act;
reg char *pre;
printf("ENTRY\nnew: ");
pre = "";
for_list (ptr, entry->e_new)
{
pat = (Pat *) ldata(ptr);
printf(pre);
print_pat(pat);
pre = ", ";
}
printf("\nold: ");
pre = "";
for_list (ptr, entry->e_old)
{
pat = (Pat *) ldata(ptr);
printf(pre);
print_pat(pat);
pre = ", ";
}
printf("\nwhen: ");
pre = "";
for_list (ptr, entry->e_when)
{
pat = (Pat *) ldata(ptr);
printf(pre);
print_pat(pat);
pre = ", ";
}
printf("\ntest: ");
print_test(entry->e_cond);
printf("\nactions:\n");
for_list (ptr, entry->e_act)
{
act = (Act *) ldata(ptr);
print_act(act);
}
printf("\n");
}
char *
str_nkind(nkind)
reg N_kind nkind;
{
switch (nkind)
{
when n_OK: return "ok";
when n_NOWAY: return "noway";
when n_CANDO: return "cando";
}
return "bizarre";
}
print_time(str, ntime)
reg char *str;
time_t ntime;
{
extern char *ctime();
printf("%s time: %d, %s", str, ntime, ctime(&ntime));
}
print_node(node)
reg Node *node;
{
reg List *ptr;
reg char *pre;
reg Node *bnode;
reg Act *act;
printf("\nNODE\n%s: kind %s flag %s\n", node->n_name,
str_nkind(node->n_kind), str_pflag(node->n_flag));
print_time("real", node->n_rtime);
print_time("used", node->n_utime);
print_time("saved", node->n_stime);
printf("new: ");
pre = "";
for_list (ptr, node->n_new)
{
bnode = (Node *) ldata(ptr);
printf(pre);
printf(bnode->n_name);
pre = ", ";
}
printf("\nold: ");
pre = "";
for_list (ptr, node->n_old)
{
bnode = (Node *) ldata(ptr);
printf(pre);
printf(bnode->n_name);
pre = ", ";
}
printf("\naction:\n");
for_list (ptr, node->n_act)
{
act = (Act *) ldata(ptr);
print_act(act);
}
if (node->n_badguys != (List *) NULL)
{
printf("bad guys: ");
pre = "";
for_list (ptr, node->n_badguys)
{
bnode = (Node *) ldata(ptr);
printf(pre);
printf(bnode->n_name);
pre = ", ";
}
printf("\n");
}
if (node->n_msg != NULL)
printf("msg: %s", node->n_msg);
printf("\n");
}
#endif
-493
View File
@@ -1,493 +0,0 @@
/*
** Cake interface to the other processes.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/param.h>
extern List *active_procs; /* of Proc */
/*
** Process the given command in the manner described by the args.
*/
int
cake_proc(cmd, type, file, node, func, args)
reg char *cmd;
reg A_kind type;
reg char *file;
reg Node *node;
reg int (*func)();
reg List *args;
{
extern bool has_meta();
extern char *strip_backslash();
extern char *shell_path[2];
extern char *shell_cmd[2];
extern char *shell_opt[2];
char *argv[MAXARGS];
reg Proc *proc;
reg int pid;
reg char *script_filename;
cmd = strip_backslash(cmd);
#ifdef CAKEDEBUG
if (file != NULL)
cdebug("file is %s\n", file);
else
cdebug("file is NULL\n");
#endif
if (type == Exec && has_meta(cmd, TRUE))
type = System;
cdebug("cake_proc, type %d: %s\n", type, cmd);
fflush(stdout);
if (type == Exec)
{
if( parse_args(cmd, argv) < 1) { /* BRL */
printf("cake_proc: Null exec command!\n");
exit_cake(FALSE);
}
}
or (type == Script)
{
reg FILE *script_fp;
script_filename = get_newname();
if ((script_fp = fopen(script_filename, "w")) == NULL)
{
sprintf(scratchbuf, "cake system error, fopen %s", script_filename);
perror(scratchbuf);
exit_cake(FALSE);
}
fprintf(script_fp, "%s", cmd);
fclose(script_fp);
}
mutex_lock();
if ((pid = vfork()) == 0)
{
reg int fd;
#ifdef CLOSE_ALL
for (fd = 3; fd < NOFILE; fd++)
close(fd);
#endif
if (file != NULL)
{
if (close(1) != 0)
{
perror("cake system error, close stdout");
_exit(127);
}
#ifdef ATT
if ((fd = open(file, O_WRONLY|O_CREAT, 0600)) < 0)
#else
if ((fd = creat(file, 0600)) < 0) /* BRL */
#endif
{
perror("cake system error, reopen stdout");
_exit(127);
}
if (fd != 1)
{
fprintf(stderr, "cake system error: reopen stdout gives fd %d\n", fd);
_exit(127);
}
}
switch (type)
{
when Script: if (shell_opt[1] != NULL)
execl(shell_path[1], shell_cmd[1], shell_opt[1], script_filename, 0);
else
execl(shell_path[1], shell_cmd[1], script_filename, 0);
perror("cake system error, shell script exec");
_exit(127);
when System: if (shell_opt[0] != NULL)
execl(shell_path[0], shell_cmd[0], shell_opt[0], cmd, 0);
else
execl(shell_path[0], shell_cmd[0], cmd, 0);
perror("cake system error, shell exec");
_exit(127);
when Exec: execvp(argv[0], argv);
sprintf(scratchbuf, "cake system error, %s exec", argv[0]);
perror(scratchbuf);
_exit(127);
otherwise: fprintf(stderr, "cake internal error: type = %x in cake_proc\n", type);
_exit(127);
}
}
or (pid == -1)
{
perror("cake system error, fork");
exit_cake(FALSE);
}
proc = make(Proc);
proc->pr_pid = pid;
proc->pr_node = node;
proc->pr_func = func;
proc->pr_args = args;
proc->pr_run = TRUE;
addtail(active_procs, proc);
cdebug("cake_proc pid = %d\n", pid);
mutex_unlock();
if (type == Script && ! cakedebug)
{
cdebug("cake_proc unlink script_filename %s\n", script_filename);
if (unlink(script_filename) != 0)
{
sprintf(scratchbuf, "cake system error, unlink %s", script_filename);
perror(scratchbuf);
exit_cake(FALSE);
}
}
return pid;
}
/*
** The cake code allows many child processes to be running
** at any given time. Cake waits for these processes
** when their results are required. However, there is no
** necessary relationship between between when a process exits
** and when its product is needed.
**
** The list of active processes contains all running processes
** and all exited processes that haven't been waited for yet.
** Cake_wait maintains this list. Whenever cake_wait gets
** an exit report from wait, it invokes the function (if any)
** associated with the exited process. If the exited process
** is the one cake_wait is looking for, it returns; otherwise
** it calls wait again and again until it finds that process.
*/
Wait
cake_wait(pid)
reg int pid;
{
extern List *find_process();
reg int exitpid;
reg List *ptr;
reg Proc *proc;
Wait status;
mutex_lock();
ptr = find_process(pid);
proc = (Proc *) ldata(ptr);
if (! proc->pr_run)
{
status = proc->pr_stat;
delete(active_procs, ptr);
mutex_unlock();
return status;
}
while ((exitpid = wait(&status)) != -1)
{
mutex_lock();
ptr = find_process(exitpid);
proc = (Proc *) ldata(ptr);
proc->pr_run = FALSE;
proc->pr_stat = status;
cdebug("cake_wait pid = %d, status = %d\n", exitpid, status.w_status);
fflush(stdout);
if (proc->pr_func != NULL)
{
cdebug("cake_wait calling function at %x\n", proc->pr_func);
fflush(stdout);
(*proc->pr_func)(status, proc->pr_args);
}
if (exitpid == pid)
{
delete(active_procs, ptr);
mutex_unlock();
return status; /* normal return */
}
mutex_unlock();
}
fprintf(stderr, "cake internal error: waiting for nonactive process %s\n", pid);
exit_cake(TRUE);
return status; /* to shut up lint */
}
/*
** Find an active process in the active process list.
*/
List *
find_process(pid)
reg int pid;
{
reg List *ptr;
reg Proc *proc;
reg bool found;
found = FALSE;
for_list (ptr, active_procs)
{
proc = (Proc *) ldata(ptr);
if (proc->pr_pid == pid)
{
found = TRUE;
break;
}
}
if (! found)
{
fprintf(stderr, "cake internal error: cannot find active process %d\n", pid);
exit_cake(TRUE);
}
return ptr;
}
/*
** Open a filter the cake way, with an execv instead of an execl.
*/
#define READSIDE 0
#define WRITESIDE 1
static int popen_pid[NOFILE];
FILE *
cake_popen(argv, mode)
reg char *argv[MAXARGS];
reg char *mode;
{
int pdesc[2];
reg int parent_end, child_end;
reg int replaced, pid;
reg Proc *proc;
if (pipe(pdesc) < 0)
return NULL;
if (mode[0] == 'r')
{
parent_end = pdesc[READSIDE];
child_end = pdesc[WRITESIDE];
replaced = 1;
}
else
{
parent_end = pdesc[WRITESIDE];
child_end = pdesc[READSIDE];
replaced = 0;
}
fflush(stdout);
mutex_lock();
if ((pid = vfork()) == 0)
{
close(parent_end);
close(replaced);
if (dup(child_end) != replaced)
_exit(127);
close(child_end);
execv(argv[0], argv);
sprintf(scratchbuf, "cake system error, %s exec", argv[0]);
perror(scratchbuf);
_exit(127);
}
or (pid == -1)
{
close(parent_end);
close(child_end);
perror("cake system error, fork");
exit_cake(FALSE);
}
proc = make(Proc);
proc->pr_pid = pid;
proc->pr_func = NULL;
proc->pr_args = NULL;
proc->pr_run = TRUE;
addtail(active_procs, proc);
close(child_end);
popen_pid[parent_end] = pid;
mutex_unlock();
return fdopen(parent_end, mode);
}
int
cake_pclose(fp)
reg FILE *fp;
{
Wait code;
reg int f;
f = fileno(fp);
fclose(fp);
code = cake_wait(popen_pid[f]);
return code.w_status;
}
/*
** Parse the given command into argv, argc.
*/
int
parse_args(cmd, vector)
reg char *cmd;
reg char **vector;
{
char buf[MAXARGSIZE];
reg int i, count;
reg char *s;
reg bool instring;
cdebug("parse_args: ");
s = cmd;
for (count = 0; *s != '\0'; count++)
{
while (*s != '\0' && isspace(*s))
s++;
instring = FALSE;
for (i = 0; *s != '\0' && (! isspace(*s) || instring); s++)
{
if (*s == '\\')
{
if (s[1] != '\0')
buf[i++] = *++s;
}
or (*s == '"')
instring = ! instring;
else
buf[i++] = *s;
}
buf[i] = '\0';
if (i >= MAXARGSIZE)
{
fprintf(stderr, "cake: argument '%s' too long\n", buf);
exit_cake(FALSE);
}
if (count >= MAXARGS)
{
fprintf(stderr, "cake: '%s' has too many arguments\n", cmd);
exit_cake(FALSE);
}
if (i == 0)
count--;
else
{
cdebug("<%s>", buf);
vector[count] = new_name(buf);
}
}
vector[count] = NULL;
cdebug("/%d\n", count);
return count;
}
/*
** Strip one level of backslashes from the given string.
*/
char *
strip_backslash(str)
reg char *str;
{
char buf[MAXSIZE];
reg char *s;
reg int i;
if (index(str, '\\') == NULL)
return str;
for (i = 0, s = str; *s != '\0'; s++)
{
if (*s != '\\')
buf[i++] = *s;
or (s[1] != '\0')
buf[i++] = *++s;
}
buf[i] = '\0';
if (i >= MAXSIZE)
{
fprintf(stderr, "cake: command '%s' too long.\n", str);
exit_cake(FALSE);
}
return new_name(buf);
}
/*
** These functions implement mutual exclusion.
** They prevent cake from being interrupted
** between calls to lock and unlock.
** This is used to preserve the consistency
** of the active_procs data structure in the presence
** of multiple executing children.
*/
#if 0 /* mutual exclusion is not necessary & has bug */
#ifdef ATT
int (*signalint)();
int (*signalquit)();
#else
int signalmask;
#endif
#endif
mutex_lock()
{
#if 0
#ifdef ATT
signalint = signal(SIGINT, SIG_IGN);
signalquit = signal(SIGQUIT, SIG_IGN);
#else
signalmask = sigblock(mask(SIGINT)|mask(SIGQUIT));
#endif
#endif
}
mutex_unlock()
{
#if 0
#ifdef ATT
signal(SIGINT, signalint);
signal(SIGQUIT, signalquit);
#else
sigsetmask(signalmask);
#endif
#endif
}
-42
View File
@@ -1,42 +0,0 @@
/*
** Standard definitions for C
**
** $Header$
*/
#define or else if
#define when break;case
#define otherwise break;default
#define loop for(;;)
#define until(expr) while(!(expr))
#ifndef reg
#define reg register
#endif
#ifndef bool
#define bool char
#endif
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define streq(s1, s2) (strcmp(s1, s2) == 0)
#define strdiff(s1, s2) (strcmp(s1, s2) != 0)
#define strneq(s1, s2, n) (strncmp(s1, s2, n) == 0)
#define strndiff(s1, s2, n) (strncmp(s1, s2, n) != 0)
#define ungetchar(c) ungetc(c, stdin)
#define make(type) ((type *) newmem(sizeof(type)))
#define make_many(type, count) ((type *) newmem(count * sizeof(type)))
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
#define CNULL (char *) 0
#define LNULL (List *) 0
-277
View File
@@ -1,277 +0,0 @@
/*
** Symbol table module
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
typedef struct s_out
{
char *o_cmd;
char *o_out;
} Out;
typedef struct s_stat
{
char *s_cmd;
int s_stat;
} Stat;
extern int hash();
extern Cast name_key(); extern bool name_equal();
extern Cast node_key(); extern bool node_equal();
extern Cast out_key(); extern bool out_equal();
extern Cast stat_key(); extern bool stat_equal();
Table name_tab = { SIZE, NULL, name_key, hash, name_equal };
Table node_tab = { SIZE, NULL, node_key, hash, node_equal };
Table out_tab = { SIZE, NULL, out_key, hash, out_equal };
Table stat_tab = { SIZE, NULL, stat_key, hash, stat_equal };
/*
** Initialize the name and the command tables.
*/
init_sym()
{
init_table(name_tab);
init_table(node_tab);
init_table(out_tab);
init_table(stat_tab);
}
/**********************************************************************/
/* Name table */
/*
** Save the given string in the name table if not already there;
** return its new address. This address is unique, so comparing
** two identifiers for equality can be done by comparing their
** addresses.
*/
char *
new_name(str)
reg char *str;
{
reg Cast old;
reg char *copy;
if ((old = lookup_table(name_tab, str)) != NULL)
return (char *) old;
copy = (char *) newmem(strlen(str) + 1);
strcpy(copy, str);
insert_table(name_tab, copy);
return copy;
}
Cast
name_key(entry)
reg Cast entry;
{
return entry;
}
bool
name_equal(key1, key2)
reg Cast key1, key2;
{
return streq((char *) key1, (char *) key2);
}
/**********************************************************************/
/* Node table */
/*
** Th insertion function for the node table is chase(),
** which is in chase.c with the rest of the chase stuff.
*/
/*
** This function merely reports on the results
** of past calls to chase.
*/
Node *
chase_node(name)
reg char *name;
{
return (Node *) lookup_table(node_tab, name);
}
/*
** Return a list of all the nodes of this run.
*/
List *
get_allnodes()
{
return contents_table(node_tab);
}
Cast
node_key(entry)
reg Cast entry;
{
return (Cast) ((Node *) entry)->n_name;
}
bool
node_equal(key1, key2)
reg Cast key1, key2;
{
#ifdef EXTRACHECK
if (key1 != key2 && streq((char *) key1, (char *) key2))
{
fprintf(stderr, "cake internal error: inconsistency in node_equal\n");
exit_cake(TRUE);
}
#endif
return key1 == key2;
}
/**********************************************************************/
/* Command output table */
#ifdef STATS_FILE
int out_tried = 0;
int out_found = 0;
#endif
/*
** Save a command and its output.
*/
new_out(cmd, output)
reg char *cmd;
reg char *output;
{
reg Out *out;
out = make(Out);
out->o_cmd = cmd;
out->o_out = output;
insert_table(out_tab, out);
}
/*
** Return the output if any associated with a given command.
*/
char *
get_out(cmd)
reg char *cmd;
{
reg Out *out;
#ifdef STATS_FILE
out_tried++;
#endif
if ((out = (Out *) lookup_table(out_tab, cmd)) == NULL)
return NULL;
#ifdef STATS_FILE
out_found++;
#endif
return out->o_out;
}
Cast
out_key(entry)
reg Cast entry;
{
return (Cast) ((Out *) entry)->o_cmd;
}
bool
out_equal(key1, key2)
reg Cast key1, key2;
{
#ifdef EXTRACHECK
if (key1 != key2 && streq((char *) key1, (char *) key2))
{
fprintf(stderr, "cake internal error: inconsistency in out_equal\n");
exit_cake(TRUE);
}
#endif
return key1 == key2;
}
/**********************************************************************/
/* Command status table */
#ifdef STATS_FILE
int stat_tried = 0;
int stat_found = 0;
#endif
/*
** Save a command and its status.
*/
new_stat(cmd, status)
reg char *cmd;
reg int status;
{
reg Stat *stat;
stat = make(Stat);
stat->s_cmd = cmd;
stat->s_stat = status;
insert_table(stat_tab, stat);
}
/*
** Return the status if any associated with a given command.
*/
bool
get_stat(cmd, code)
reg char *cmd;
reg int *code;
{
reg Stat *stat;
#ifdef STATS_FILE
stat_tried++;
#endif
if ((stat = (Stat *) lookup_table(stat_tab, cmd)) == NULL)
return FALSE;
#ifdef STATS_FILE
stat_found++;
#endif
*code = stat->s_stat;
return TRUE;
}
Cast
stat_key(entry)
reg Cast entry;
{
return (Cast) ((Stat *) entry)->s_cmd;
}
bool
stat_equal(key1, key2)
reg Cast key1, key2;
{
#ifdef EXTRACHECK
if (key1 != key2 && streq((char *) key1, (char *) key2))
{
fprintf(stderr, "cake internal error: inconsistency in stat_equal\n");
exit_cake(TRUE);
}
#endif
return key1 == key2;
}
-156
View File
@@ -1,156 +0,0 @@
/*
** Cake system interface.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
/*
** Change to the directory of the cakefile.
** Return the shortened name of the cakefile.
*/
char *
dir_setup(name)
reg char *name;
{
char buf[MAXSIZE];
reg int i, l; /* l is the subscript of the last / */
l = -1;
for (i = 0; name[i] != '\0'; i++)
if (name[i] == '/')
l = i;
if (l < 0)
return name;
else
{
for (i = 0; i < l; i++)
buf[i] = name[i];
if (i == 0)
buf[i++] = '/';
buf[i] = '\0';
if (chdir(buf) != 0)
{
sprintf(scratchbuf, "cake system error, chdir %s", buf);
perror(scratchbuf);
exit(1);
}
return name+l+1;
}
}
/*
** Set up the arguments to shell exec's.
** pattern: execl("/bin/sh", "sh", "-c", s, 0);
** pattern: execl("/bin/csh", "csh", "-cf", s, 0);
*/
char *shell_path[2];
char *shell_cmd[2];
char *shell_opt[2];
shell_setup(shell, which)
reg char *shell;
reg int which;
{
char buf[MAXSIZE];
reg char *s;
reg int i, l;
/* find the shell path */
i = 0;
for (s = shell; *s != '\0' && *s != ' ' && *s != '\t'; s++)
buf[i++] = *s;
buf[i] = '\0';
shell_path[which] = new_name(buf);
for (; *s != '\0' && *s != '-'; s++)
;
/* find the options */
i = 0;
for (; *s != '\0' && *s != ' ' && *s != '\t'; s++)
buf[i++] = *s;
buf[i] = '\0';
if (i != 0)
shell_opt[which] = new_name(buf);
else
shell_opt[which] = NULL;
if (*s != NULL)
{
fprintf(stderr, "cake: cannot parse shell command '%s'\n", shell);
exit_cake(FALSE);
}
/* find the shell command itself */
s = shell_path[which];
l = -1;
for (i = 0; s[i] != '\0'; i++)
if (s[i] == '/')
l = i;
shell_cmd[which] = new_name(s+l+1);
if (cakedebug)
{
printf("shell path%d: %s\n", which, shell_path[which]);
printf("shell cmd%d: %s\n", which, shell_cmd[which]);
if (shell_opt[which] != NULL)
printf("shell opt%d: %s\n", which, shell_opt[which]);
else
printf("shell opt%d: NULL\n", which);
}
}
bool metatab[CHARSETSIZE];
/*
** Set up the metacharacter table.
*/
meta_setup(metachars)
reg char *metachars;
{
reg int i;
reg char *s;
for (i = 0; i < CHARSETSIZE; i++)
metatab[i] = FALSE;
for (s = metachars; *s != '\0'; s++)
metatab[*s] = TRUE;
}
/*
** Decide whether the given string has metacharacters or not.
** The second arg tells whether to honour backslash escapes.
*/
bool
has_meta(str, allow_esc)
reg char *str;
reg bool allow_esc;
{
reg char *s;
for (s = str; *s != '\0'; s++)
if (metatab[(unsigned) *s])
return TRUE;
or (allow_esc && (*s == '\\'))
{
if (s[1] != '\0')
s++;
}
return FALSE;
}
-135
View File
@@ -1,135 +0,0 @@
/*
** Table handling module.
**
** This file supplies data manipulation routines to other modules;
** it does not store any data itself. Its routines are generic,
** applicable to the storage of any kind of data structure with
** primary key and a hash function on it.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
/*
** Initialize a table.
*/
_init_table(table)
reg Table *table;
{
reg int i;
table->ta_store = make_many(List *, table->ta_size);
for (i = 0; i < table->ta_size; i++)
table->ta_store[i] = NULL;
}
/*
** Look up and return the entry corresponding to the key
** in a table.
*/
Cast
_lookup_table(table, key)
reg Table *table;
reg Cast key;
{
reg List *ptr;
reg int h;
put_trail("lookup_table", "start");
h = tablehash(table)(key);
for_list (ptr, table->ta_store[h])
{
if (tableequal(table)(key, tablekey(table)(ldata(ptr))))
{
#ifdef EXTRACHECK
if (ldata(ptr) == NULL)
{
fprintf(stderr, "cake internal error: returning null in lookup_table\n");
exit_cake(TRUE);
}
#endif
put_trail("lookup_table", "finish");
return ldata(ptr);
}
}
put_trail("lookup_table", "finish");
return NULL;
}
/*
** Insert a new entry into the table.
** Return whether it was there before.
*/
bool
_insert_table(table, entry)
reg Table *table;
reg Cast entry;
{
reg List *ptr;
reg Cast key;
reg int h;
put_trail("insert_table", "start");
key = tablekey(table)(entry);
h = tablehash(table)(key);
for_list (ptr, table->ta_store[h])
if (tableequal(table)(key, tablekey(table)(ldata(ptr))))
{
put_trail("insert_table", "finish");
return TRUE;
}
table->ta_store[h] = addhead(table->ta_store[h], entry);
put_trail("insert_table", "finish");
return FALSE;
}
/*
** Hash str into the range 0 to SIZE-1.
*/
int
hash(s)
reg char *s;
{
#ifdef CRAY
reg long h;
#else
reg int h;
#endif
for (h = 0; *s != '\0'; s++)
h = (h << 1) + *s;
h = (h >= 0? h: -h) % SIZE;
if( h < 0 || h > SIZE ) {
fprintf(stderr, "cake: hash error, h=%d\n", h); /* BRL */
}
return h;
}
/*
** Return a list of all the entries in a table.
*/
List *
_contents_table(table)
reg Table *table;
{
reg List *all;
reg List *ptr;
reg int i;
all = makelist0();
for (i = 0; i < table->ta_size; i++)
for_list (ptr, table->ta_store[i])
addtail(all, ldata(ptr)); /* na */
return all;
}
-28
View File
@@ -1,28 +0,0 @@
/*
** Definitions for the table module.
**
** $Header$
*/
typedef struct s_table
{
int ta_size; /* the size of the store */
List **ta_store; /* the store, an array of lists */
Cast (*ta_key)(); /* applied to entries */
int (*ta_hash)(); /* applied to keys */
bool (*ta_equal)(); /* applied to two keys */
} Table;
#define init_table(t) _init_table(&t)
#define lookup_table(t, k) _lookup_table(&t, (Cast) k)
#define insert_table(t, e) _insert_table(&t, (Cast) e)
#define contents_table(t) _contents_table(&t)
#define tablekey(table) (*(table->ta_key))
#define tablehash(table) (*(table->ta_hash))
#define tableequal(table) (*(table->ta_equal))
extern _init_table();
extern Cast _lookup_table();
extern bool _insert_table();
extern List *_contents_table();
-144
View File
@@ -1,144 +0,0 @@
/*
** Module to handle Cake's tests.
*/
static char
rcs_id[] = "$Header$";
#include "cake.h"
bool
eval(node, test, env)
reg Node *node;
reg Test *test;
Env env;
{
extern char *expand_cmds();
extern int cake_proc();
extern Wait cake_wait();
extern Node *chase();
extern bool get_stat();
extern bool exist();
extern char *ground();
char buf[256];
Wait status;
reg List *ptr;
reg Pat *pat;
reg char *text1, *text2;
reg char *cmd;
reg Node *chasenode;
reg int result;
reg int pid;
if (test == (Test *) NULL)
return TRUE;
#ifdef CAKEDEBUG
if (cakedebug)
{
printf("testing ");
print_test(test);
printf("\n");
}
#endif
switch (test->t_kind)
{
when t_TRUE: return TRUE;
when t_FALSE: return FALSE;
when t_AND: return eval(node, test->t_left, env) && eval(node, test->t_right, env);
when t_OR: return eval(node, test->t_left, env) || eval(node, test->t_right, env);
when t_NOT: return ! eval(node, test->t_left, env);
when t_CMD: if (get_stat(test->t_cmd, &status.w_status))
{
test->t_kind = (status.w_status == 0)? t_TRUE: t_FALSE;
cdebug("test cmd cache %s: %s\n", test->t_cmd,
(status.w_status == 0)? "True": "False");
return (status.w_status == 0)? TRUE: FALSE;
}
cmd = expand_cmds(ground(env, test->t_cmd));
pid = cake_proc(cmd, Exec, "/dev/null", (Node *) NULL,
(int (*)()) NULL, (List *) NULL);
status = cake_wait(pid);
new_stat(test->t_cmd, status.w_status);
test->t_kind = (status.w_status == 0)? t_TRUE: t_FALSE;
cdebug("test cmd %s: %s\n", test->t_cmd,
(status.w_status == 0)? "True": "False");
return (status.w_status == 0)? TRUE: FALSE;
when t_MATCH: text1 = (char *) first(test->t_list); /* -vX */
text2 = (char *) last(test->t_list); /* file */
/* e.g. sub -vX X.c NULL file.c */
sprintf(buf, "sub %s %s NULL %s > /dev/null",
text1, text2, test->t_pat->p_str);
cmd = new_name(buf);
cdebug("matching command: %s\n", cmd);
if (get_stat(cmd, &status.w_status))
{
test->t_kind = (status.w_status == 0)? t_TRUE: t_FALSE;
cdebug("test cmd cache %s: %s\n", test->t_cmd,
(status.w_status == 0)? "True": "False");
return (status.w_status == 0)? TRUE: FALSE;
}
pid = cake_proc(cmd, Exec, "/dev/null", (Node *) NULL,
(int (*)()) NULL, (List *) NULL);
status = cake_wait(pid);
new_stat(test->t_cmd, status.w_status);
test->t_kind = (status.w_status == 0)? t_TRUE: t_FALSE;
cdebug("test cmd %s: %s\n", test->t_cmd,
(status.w_status == 0)? "True": "False");
return (status.w_status == 0)? TRUE: FALSE;
when t_LIST: for_list (ptr, test->t_list)
{
pat = (Pat *) ldata(ptr);
if (streq(test->t_pat->p_str, pat->p_str))
return TRUE;
}
return FALSE;
when t_EXIST: result = exist(test->t_pat->p_str);
cdebug("test exist %s: %s\n", test->t_pat->p_str,
result? "True": "False");
return result;
when t_CANDO: chasenode = chase(test->t_pat->p_str, 0, (Entry *) NULL);
if (on_node(chasenode, nf_ERR))
{
sprintf(scratchbuf, "cannot evaluate 'cando %s' test for %s",
chasenode->n_name, node->n_name);
add_error(node, new_name(scratchbuf), LNULL, TRUE);
}
result = is_ok(chasenode) || is_cando(chasenode);
cdebug("test cando %s: %s\n", test->t_pat->p_str,
result? "True": "False");
return result;
when t_OK: chasenode = chase(test->t_pat->p_str, 0, (Entry *) NULL);
if (on_node(chasenode, nf_ERR))
{
sprintf(scratchbuf, "cannot evaluate 'ok %s' test for %s",
chasenode->n_name, node->n_name);
add_error(node, new_name(scratchbuf), LNULL, TRUE);
}
result = is_ok(chasenode);
cdebug("test ok %s: %s\n", test->t_pat->p_str,
result? "True": "False");
return result;
otherwise: fprintf(stderr, "cake internal error: invalid test type %x in eval\n",
test->t_kind);
exit_cake(TRUE);
}
/*NOTREACHED*/
return FALSE;
}
-55
View File
@@ -1,55 +0,0 @@
/*
** Trail module.
*/
static char
rcs_id[] = "$Header$";
#ifdef CAKEDEBUG
#include "cake.h"
#define TRAILSIZE 100
static int trail_entries = 0; /* no. of calls to put_tr */
static int slot = 0; /* next slot */
static char *trailfunc[TRAILSIZE]; /* functions and events */
static char *trailevent[TRAILSIZE]; /* init to NULL by C */
/*
** Register this function on the trail.
*/
put_trail(func, event)
reg char *func;
reg char *event;
{
trailfunc[slot] = func;
trailevent[slot] = event;
trail_entries++;
if (++slot == TRAILSIZE)
slot = 0;
}
/*
** Print the trail on the given file.
*/
get_trail(fp)
reg FILE *fp;
{
reg int maxent;
fprintf(fp, "^^^^^^^^^^^^^^^^^^^ TRAIL ^^^^^^^^^^^^^^^^^^^\n");
fprintf(fp, "%d entries\n", trail_entries);
maxent = (trail_entries < TRAILSIZE)? trail_entries: TRAILSIZE;
while (maxent-- > 0)
{
if (--slot == -1)
slot = TRAILSIZE - 1;
fprintf(fp, "%s %s\n", trailfunc[slot], trailevent[slot]);
}
}
#endif
-81
View File
@@ -1,81 +0,0 @@
/*
** Compatibility for ATT versions of Unix
** with Berkeley's wait system calls.
**
** $Header$
*/
#ifdef ATT
/*
* Copyright (c) 1982 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
* @(#)wait.h 6.2 (Berkeley) 6/8/85
*/
/*
* This file holds definitions relevent to the wait system call.
* Some of the options here are available only through the ``wait3''
* entry point; the old entry point with one argument has more fixed
* semantics, never returning status of unstopped children, hanging until
* a process terminates if any are outstanding, and never returns
* detailed information about process resource utilization (<vtimes.h>).
*/
/*
* Structure of the information in the first word returned by both
* wait and wait3. If w_stopval==WSTOPPED, then the second structure
* describes the information returned, else the first. See WUNTRACED below.
*/
union wait {
int w_status; /* used in syscall */
/*
* Terminated process status.
*/
struct {
unsigned short w_Termsig:7; /* termination signal */
unsigned short w_Coredump:1; /* core dump indicator */
unsigned short w_Retcode:8; /* exit code if w_termsig==0 */
} w_T;
/*
* Stopped process status. Returned
* only for traced children unless requested
* with the WUNTRACED option bit.
*/
struct {
unsigned short w_Stopval:8; /* == W_STOPPED if stopped */
unsigned short w_Stopsig:8; /* signal that stopped us */
} w_S;
};
#define w_termsig w_T.w_Termsig
#define w_coredump w_T.w_Coredump
#define w_retcode w_T.w_Retcode
#define w_stopval w_S.w_Stopval
#define w_stopsig w_S.w_Stopsig
#define WSTOPPED 0177 /* value of s.stopval if process is stopped */
/*
* Option bits for the second argument of wait3. WNOHANG causes the
* wait to not hang if there are no stopped or terminated processes, rather
* returning an error indication in this case (pid==0). WUNTRACED
* indicates that the caller should receive status about untraced children
* which stop due to signals. If children are stopped and a wait without
* this option is done, it is as though they were still running... nothing
* about them is returned.
*/
#define WNOHANG 1 /* dont hang in wait */
#define WUNTRACED 2 /* tell about stopped, untraced children */
#define WIFSTOPPED(x) ((x).w_stopval == WSTOPPED)
#define WIFSIGNALED(x) ((x).w_stopval != WSTOPPED && (x).w_termsig != 0)
#define WIFEXITED(x) ((x).w_stopval != WSTOPPED && (x).w_termsig == 0)
#else
#include <sys/wait.h>
#define mask(s) (1 << ((s)-1))
#endif
typedef union wait Wait;
-65
View File
@@ -1,65 +0,0 @@
# cakeaux/Makefile
#
# Makefile for some of cake's auxiliary programs
#
# @(#)$Header$ (BRL)
SHELL=/bin/sh
PROGS = base ccincl later need needed cakesub subcmd usrc gsrc cakeinclude
BINDIR=/usr/brlcad/bin
all: $(PROGS)
install: $(PROGS)
cp $(PROGS) $(BINDIR)
base: base.o pattern_s.o
cc -o base base.o pattern_s.o
cakeinclude: cakeinclude.o
cc -o cakeinclude cakeinclude.o
ccincl: ccincl.o ccincl_s.o
cc -o ccincl ccincl.o ccincl_s.o
later: later.c
cc -o later later.c
need: need.c
cc -o need need.c
needed: needed.c
cc -o needed needed.c
refs: refs.o pattern_s.o
cc -o refs refs.o pattern_s.o
cakesub: cakesub.c
cc -o cakesub cakesub.c
subcmd: subcmd.c
cc -o subcmd subcmd.c
usrc: usrc.c
cc -o usrc usrc.c
gsrc: gsrc.c
cc -o gsrc gsrc.c
ccincl_s.c: ccincl_s.l
lex ccincl_s.l
@mv lex.yy.c ccincl_s.c
pattern_s.c: pattern_s.l
lex pattern_s.l
@mv lex.yy.c pattern_s.c
clean:
-/bin/rm -f Make_errs *.o *_s.c
gclean:
-/bin/rm -f *_s.c
clobber: clean
-/bin/rm -f ${PROGS}
-224
View File
@@ -1,224 +0,0 @@
/*
* C A K E I N C L U D E . C
*
* This program is intended to be a faster replacement for the
* cakeinclude.sh script used for BRL-CAD distributions.
* It therefore embodies the same conventions and restrictions.
*
* This program prints the names of all header files that a given
* C source module includes. No attempt is made to deal with
* conditional inclusion of header files.
*
* The BRL-CAD convention for writing #include directives is:
* #include "./file" gives file in "current" directory (SRCDIR)
* #include "/file" gives file at absolute path
* #include "file" gives file in ${INCDIR}
* #include <file> leaves to CPP
*
* Note that there must be whitespace between the "#" and the word "include"
* to defeat the detection of the include.
* This allows conditional includes (if needed) to be indicated
* by a # SP include, so as to not cause trouble.
*
* This routine does not handle nested #includes, which is bad style anyway.
*
* Options -
* i dir Specify Include dir
* s dir Specify Source dir
* b # Buffer size
* h help
*
* Author -
* Lee A. Butler
*
* Source -
* SECAD/VLD Computing Consortium, Bldg 394
* The U. S. Army Ballistic Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5066
*
* Distribution Status -
* Public Domain, Distribution Unlimitied.
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
/* declarations to support use of getopt() system call */
char *options = "hb:i:s:";
char optflags[sizeof(options)];
extern char *optarg;
extern int optind, opterr, getopt();
char *progname = "(noname)";
char *buffer, *malloc(), *realloc();
unsigned bufsiz=16384;
char *srcdir = ".";
char *incdir = ".";
int status;
FILE *fd, *fopen();
/*
* U S A G E --- tell user how to invoke this program, then exit
*/
void usage()
{
(void) fprintf(stderr, "Usage: %s [ -%s ] file [ file ... ]\n",
progname, options);
exit(1);
}
/*
* P A R S E _ A R G S --- Parse through command line flags
*/
int parse_args(ac, av)
int ac;
char *av[];
{
int c;
progname = *av;
/* turn all the option flags off */
for (c=strlen(options) ; c-- ; optflags[c] = '\0');
/* Turn off getopt's error messages */
opterr = 0;
/* get all the option flags from the command line */
while ((c=getopt(ac,av,options)) != EOF)
switch (c) {
case 'b' : if ((bufsiz = atoi(optarg)) < 11)
usage();
break;
case 'i':
incdir = optarg;
break;
case 's':
srcdir = optarg;
break;
default : usage(); break;
}
return(optind);
}
/* C H K I N C L
*
* check an include statement for suitability
*/
int chkincl(j, i)
register int j, *i;
{
int k;
/* skip over any white space */
while (j < *i && buffer[j] == ' ' || buffer[j] == '\t') j++;
if (j >= *i) return(j);
/* ignore the #include <> format and # include " " format.
* we are only interested in lines of the form:
* #include "filespec"
*/
if (buffer[j++] != '"') return(j);
/* find end of filename */
label: for (k = j ; k < *i && buffer[k] != '"' && buffer[k] != '\n' ; k++)
;
if (buffer[k] == '\n')
return(k);
else if (k >= *i) {
/* we hit the end of the buffer in the middle of an include
* statement. If the buffer wasn't full, we hit EOF and can
* just give up. On the other hand, if the buffer was full,
* we should try to extend the buffer and read in the rest
* of the include statment
*/
if (*i < bufsiz-1) return(k);
if ((buffer=realloc(buffer, bufsiz+1024)) == (char *)NULL) {
fprintf(stderr, "%s: Error extending buffer\n",
progname);
exit(-1);
}
/* read a little more data */
bufsiz += 1024;
while ( *i < bufsiz-1 &&
(status=fread(&buffer[*i], 1, bufsiz-1-(*i), fd)) )
*i += status;
goto label;
}
else
buffer[k] = '\0';
/* ignore the "...debug.h" files */
if (k-7 >= j && !strncmp("debug.h", &buffer[k-7], 7))
return(k);
if (buffer[j] == '.' && buffer[j+1] == '/')
(void)printf("%s%s\n", srcdir, &buffer[j+1]);
else if (buffer[j] == '/')
(void)printf("%s\n", &buffer[j]);
else
(void)printf("%s/%s\n", incdir, &buffer[j]);
return(k);
}
/*
* M A I N
*
* Call parse_args to handle command line arguments first, then
* process input.
*/
int main(ac,av)
int ac;
char *av[];
{
int arg_index;
int j, eob, newline;
/* parse command flags, and make sure there are arguments
* left over for processing.
*/
if ((arg_index = parse_args(ac, av)) >= ac) usage();
if ((buffer=malloc(bufsiz)) == (char *)0) {
fprintf(stderr, "%s: Unable to allocate %d bytes for buffer\n",
progname, bufsiz);
exit(-1);
}
/* This part might be done in a loop, to match usage message? */
if ((fd = fopen(av[arg_index], "r")) == (FILE *)NULL) {
perror(av[arg_index]);
exit(-1);
}
/* fill buffer */
for (eob=0 ; eob < bufsiz-1 &&
(status=fread(&buffer[eob], 1, bufsiz-1-eob, fd)) ; eob += status)
;
if (eob == 0) {
fprintf(stderr, "%s: Error reading file \"%s\"\n",
progname, av[arg_index]);
exit(-1);
}
newline = 1;
for (j = 0 ; j < eob ; j++) {
if (newline && !strncmp("#include", &buffer[j], 8))
j = chkincl(j+8, &eob);
newline = (buffer[j] == '\n');
}
(void)fclose(fd);
}
-198
View File
@@ -1,198 +0,0 @@
/*
* 3 D . H
*
* This header file describes the object file structure,
* and some commonly used 3D vector math macros.
*
* Authors -
* Michael John Muuss
* Earl P Weaver
*
* Ballistic Research Laboratory
* U. S. Army
* March, 1980
*
*
* R E V I S I O N H I S T O R Y
*
* March 81 CAS Added ARS 'A' and 'B' record information
*
* 09/22/81 MJM Changed m_ record to use matrix transformation
*/
#define NAMESIZE 16
#define NAMEMOVE(from,to) strncpy(to,from,NAMESIZE)
extern char *strncpy();
/*
* OBJECT FILE FORMAT
*
* All records are 128 bytes long, and are composed of one of 5 formats:
* A SOLID description
* A COMBINATION description (1 header, 1 member)
* A COMBINATION extention (2 members)
* An ARS 'A' (header) record
* An ARS 'B' (data) record
*/
union record {
char u_id; /* To differentiate SOLID vs COMB */
char u_size[128]; /* Total record size */
struct solids {
char s_id;
char s_type;
char s_name[16];
short s_num; /* COMGEOM solid # temporary */
float s_values[24];
} s;
struct combination {
char c_id;
char c_flags;
char c_name[16];
short c_regionid;
short c_aircode;
short c_length; /* in 128 byte granules */
short c_num; /* region #, from COMGEOM */
short c_material; /* material code */
short c_los; /* line of sight percentage */
char c_pad[128-30];
} c;
struct members {
char m_id;
char m_relation; /* OR, UNION, DIFF */
char m_brname[16]; /* Name of this branch */
char m_instname[16]; /* Name of refered-to obj */
short m_pad1;
mat_t m_mat; /* Homogeneous Xform Matrix */
short m_num; /* solid # ref, from COMGEOM */
short m_pad2;
} M;
struct ars_rec {
char a_id; /* A */
char a_type;
char a_name[16];
short a_m; /* # curves */
short a_n; /* # points per curve */
short a_curlen; /* # granules per curve */
short a_totlen; /* # granules per solid */
short a_pad;
float a_xmax; /* max x coordinate */
float a_xmin; /* min x coordinate */
float a_ymax; /* max y coordinate */
float a_ymin; /* min y coordinate */
float a_zmax; /* max z coordinate */
float a_zmin; /* min z coordinate */
} a;
struct ars_ext {
char b_id; /* B */
char b_type;
short b_n; /* 1.1 1.2 1.3 2.1 2.2 2.3 */
short b_ngranule;
short b_pad;
float b_values[8*3];
} b;
};
/*
* Record id types
*/
#define SOLID 'S'
#define COMB 'C'
#define MEMB 'M'
#define ARS_A 'A'
#define ARS_B 'B'
/*
* for the m_relation fields
*/
#define UNION 'u'
#define SUBTRACT '-'
#define INTERSECT '+'
/*
* SOLID TYPES
*/
#define RPP 1
#define BOX 2
#define RAW 3
#define ARB4 4
#define ARB5 5
#define ARB6 6
#define ARB7 7
#define ARB8 8
#define ELL 9
#define ELL1 10
#define SPH 11
#define RCC 12
#define REC 13
#define TRC 14
#define TEC 15
#define TOR 16
#define TGC 17
#define GENTGC 18 /* Supergeneralized TGC; internal form */
#define GENELL 19 /* Ready for drawing ELL: V,A,B,C */
#define GENARB8 20 /* Generalized ARB8: V, and 7 other vectors */
#define ARS 21 /* arbitrary triangular surfaced polyhedron */
#define ARSCONT 22 /* extention record type for ARS solid */
/*
* V E C T O R M A T H
*/
/* Set a vector pointer 'a' to have x,y,z elements b,c,d */
#define VSET(a,b,c,d) *(a) = (b);\
*((a)+1) = (c);\
*((a)+2) = (d)
/* Transfer x,y,z from vector pointed at by 'b' to that pointed by 'a' */
#define VMOVE(a,b) *(a) = *(b);\
*((a)+1) = *((b)+1);\
*((a)+2) = *((b)+2)
/* Add x,y,z in vectors 'b' and 'c', store in 'a' */
#define VADD2(a,b,c) *(a) = *(b) + *(c);\
*((a)+1) = *((b)+1) + *((c)+1);\
*((a)+2) = *((b)+2) + *((c)+2)
/* Subtract x,y,z in vector 'c' from 'b', store in 'a' */
#define VSUB2(a,b,c) *(a) = *(b) - *(c);\
*((a)+1) = *((b)+1) - *((c)+1);\
*((a)+2) = *((b)+2) - *((c)+2)
#define VADD3(a,b,c,d) *(a) = *(b) + *(c) + *(d);\
*((a)+1) = *((b)+1) + *((c)+1) + *((d)+1);\
*((a)+2) = *((b)+2) + *((c)+2) + *((d)+2)
#define VADD4(a,b,c,d,e) *(a) = *(b) + *(c) + *(d) + *(e);\
*((a)+1) = *((b)+1) + *((c)+1) + *((d)+1) + *((e)+1);\
*((a)+2) = *((b)+2) + *((c)+2) + *((d)+2) + *((e)+2)
/* Scale all elements in 'b' by multiplication by scalar 'c', store in 'a' */
#define VSCALE(a,b,c) *(a) = *(b) * (c);\
*((a)+1) = *((b)+1) * (c);\
*((a)+2) = *((b)+2) * (c)
/* Compose vector 'a' of:
* Vector 'b' plus
* scalar 'c' times vector 'd' plus
* scalar 'e' times vector 'f'
*/
#define VCOMPOSE(a,b,c,d,e,f) \
*(a+0) = *(b+0) + c * (*(d+0)) + e * (*(f+0));\
*(a+1) = *(b+1) + c * (*(d+1)) + e * (*(f+1));\
*(a+2) = *(b+2) + c * (*(d+2)) + e * (*(f+2))
/* Return scalar magnitude of vector pointed at by 'a' */
#define MAGNITUDE(a) sqrt( MAGSQ( (a) ))
#define MAGSQ(a) ( *(a)*(*(a)) + *((a)+1)*(*((a)+1)) + *((a)+2)*(*((a)+2)) )
/*
* Cross product:
* 12-21, 20-02, 01-10
* b1*c2-b2*c1, b2c0-b0c2, b0c1-b1c0
*/
#define VCROSS( a, b, c) \
*(a+0) = *(b+1) * *(c+2) - *(b+2) * *(c+1);\
*(a+1) = *(b+2) * *(c+0) - *(b+0) * *(c+2);\
*(a+2) = *(b+0) * *(c+1) - *(b+1) * *(c+0)
#define VPRINT( a, b ) printf("%s (%f, %f, %f)\n", a, (b)[0], (b)[1], (b)[2] )
-20
View File
@@ -1,20 +0,0 @@
/*
* comgeom-g/Cakefile
*/
#define SRCDIR comgeom-g
#define PRODUCTS comgeom-g
#define SRCSUFF .c
#define MANSECTION 1
#define FILES cvt solid read region
#include "../Cakefile.defs"
#include "../Cakefile.prog"
/* Explicit composition of each product */
comgeom-g: OBJ LIBRT LIBWDB
CC LDFLAGS -o comgeom-g OBJ LIB_PRE''LIBWDB LIB_PRE''LIBRT LIBRT_LIBES LIBES
#include "../Cakefile.rules"
-70
View File
@@ -1,70 +0,0 @@
.TH COMGEOM-G 1 BRL-CAD
.SH NAME
comgeom-g \- convert GIFT COMGEOM model into MGED database
.SH SYNOPSIS
.B comgeom-g
.RB [ \-d\ debug_lvl]
.RB [ \-v\ version_num]
.RB [ \-s\ name_suffix]
file.cg file.g
.br
.SH DESCRIPTION
Read a COMGEOM version 4 or version 5 format model from
a GIFT-style input file, convert the geometry into
the internal form used by the BRL-CAD package,
and write an MGED-style binary database.
.PP
Each solid is given the name ``s###'', retaining the COMGEOM solid number.
Each region is given the name ``r###'', retaining the COMGEOM region number.
Regions are grouped together into various groups ``g###'' based
on the region-id numbers. Group ``g00'' gets all regions with region-id
of zero, ``g0'' gets ids one through 99, ``g1'' gets ids 100 through 199, etc.
.PP
The default input is COMGEOM version 5.
Version 4 can be converted by specifying the
.B \-v4
flag.
For the time being, the DoE MORSE/RAFFLE format (believed to be the
original MAGIC format) can be converted by specifying the
.B \-v1
flag.
.PP
By default, the program
.I comgeom-g
operates silently.
Because the program may require a minute or two to convert a large
database, some users prefer to have various status reports that
indicate the progress of the conversion.
This can be selected by specifying the
.B \-d1
flag (debug level 1).
.PP
The units used in a COMGEOM file are specified on a header record.
The units of an MGED database are always milimeters.
.I comgeom-g
performs automatic units conversion using the built-in units conversion
feature of
\fIlibwdb\fR(3).
.SH EXAMPLE
.I
comgeom-g < file.cg > file.g
.SH DIAGNOSTICS
The diagnostics are intended to be self-explanatory.
Familiarity with GIFT COMGEOM terminology will be helpful.
.SH BUGS
It is expected that the input file should be a valid COMGEOM model.
While quite a bit of input checking is performed, wildly incorrect
input may produce amusing results.
.SH SEE ALSO
brlcad(1), mged(1), libwdb(3)
.SH AUTHOR
Michael John Muuss
.SH SOURCE
SECAD/VLD Computing Consortium, Bldg 394
.br
The U. S. Army Ballistic Research Laboratory
.br
Aberdeen Proving Ground, Maryland 21005
.SH BUG REPORTS
Reports of bugs or problems should be submitted via electronic
mail to <CAD@BRL.MIL>.
-335
View File
@@ -1,335 +0,0 @@
/*
* C V T . C
*
* This is the mainline for converting COM-GEOM
* cards to a GED style database.
*
* Author -
* Michael John Muuss
*
* Original Version -
* February, 1980
*
* Source -
* SECAD/VLD Computing Consortium, Bldg 394
* The U. S. Army Ballistic Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5066
*
* Copyright Notice -
* This software is Copyright (C) 1989 by the United States Army.
* All rights reserved.
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include "externs.h"
#include "machine.h"
#include "vmath.h"
#include "rtlist.h"
#include "wdb.h"
extern int getopt();
extern char *optarg;
extern int optind;
struct wmember *wmp; /* array indexed by region number */
int version = 5; /* v4 or v5 ? */
int verbose = 0; /* verbose = print a message on every item read */
char name_it[16]; /* stores argv if it exists and appends it
to each name generated.*/
int cur_col = 0;
FILE *infp;
FILE *outfp; /* Output file descriptor */
int sol_total, sol_work; /* total num solids, num solids processed */
int reg_total;
extern void getid();
static char usage[] = "\
Usage: comgeom-g [options] input_file output_file\n\
Options:\n\
-v input_vers# default is 5 (cg5)\n\
-d debug_lvl\n\
-s name_suffix\n\
";
int
get_args( argc, argv )
register char **argv;
{
register int c;
char *file_name;
while ( (c = getopt( argc, argv, "d:v:s:" )) != EOF ) {
switch( c ) {
case 'd':
verbose = atoi(optarg);
break;
case 's':
strncpy( name_it, optarg, sizeof(name_it) );
break;
case 'v':
version = atoi(optarg);
break;
default: /* '?' */
return(0);
}
}
if( optind+2 > argc )
return(0); /* FAIL */
/* Input File */
if( optind >= argc ) {
if( isatty(fileno(stdin)) )
return(0);
infp = stdin;
optind++;
} else {
file_name = argv[optind++];
if( (infp = fopen(file_name, "r")) == NULL ) {
perror(file_name);
return(0);
}
}
/* Output File */
if( optind >= argc ) {
if( isatty(fileno(stdout)) )
return(0);
outfp = stdout;
optind++;
} else {
file_name = argv[optind++];
if( (outfp = fopen(file_name, "w")) == NULL ) {
perror(file_name);
return(0);
}
}
if ( argc > ++optind )
(void)fprintf( stderr, "comgeom-g: excess argument(s) ignored\n" );
return(1); /* OK */
}
/*
* M A I N
*/
int
main( argc, argv )
char **argv;
{
register int i;
char ctitle[132];
char *title;
char units[16];
if ( !get_args( argc, argv ) ) {
(void)fputs(usage, stderr);
exit( 1 );
}
if( version != 1 && version != 4 && version != 5 ) {
fprintf(stderr,"version %d not supported\n", version );
(void)fputs(usage, stderr);
exit( 1 );
}
printf("Reading version %d COMGEOM file\n", version );
if( verbose ) {
printf("COMGEOM input file must have this format:\n");
switch(version) {
case 1:
printf(" 1. title card\n");
printf(" 2. solid table\n");
printf(" 3. END\n");
printf(" 4. region table\n");
printf(" 5. END\n");
break;
case 4:
printf(" 1. units & title card\n");
printf(" 2. solid & region count card\n");
printf(" 3. solid table\n");
printf(" 4. region table\n");
printf(" 5. -1\n");
printf(" 6. blank\n");
printf(" 7. region ident table\n\n");
break;
case 5:
printf(" 1. units & title card\n");
printf(" 2. solid & region count card\n");
printf(" 3. solid table\n");
printf(" 4. region table\n");
printf(" 5. -1\n");
printf(" 6. region ident table\n\n");
break;
}
}
group_init();
/*
* Read title card
*/
if( getline( ctitle, sizeof(ctitle), "title card" ) == EOF ) {
printf("Empty input file: no title record\n");
exit(10);
}
switch( version ) {
case 1:
title = ctitle;
strcpy( units, "in" ); /* XXX is this right? */
break;
case 4:
case 5:
/* First 2 chars are units */
units[0] = ctitle[0];
units[1] = ctitle[1];
units[2] = '\0';
title = ctitle+3;
break;
}
/* Drop leading blanks in title */
while( isspace( *title ) ) title++;
trim_trail_spaces( title );
trim_trail_spaces( units );
printf("Title: %s\n", title);
printf("Units: %s\n", units);
/* Before converting any geometry, establish the units conversion
* factor which all mk_* routines will apply.
*/
if( mk_conversion( units ) < 0 ) {
printf("WARNING: unknown units '%s', using inches\n", units);
(void)mk_conversion( "inches" );
}
/* Output the MGED database header */
mk_id( outfp, title );
/*
* Read control card, if present
*/
sol_total = reg_total = 0;
switch( version ) {
case 1:
sol_total = reg_total = 9999; /* Reads until 'END' rec */
break;
case 4:
if( getline( ctitle, sizeof(ctitle), "control card" ) == EOF ) {
printf("No control card .... STOP\n");
exit(10);
}
sscanf( ctitle, "%20d%10d", &sol_total, &reg_total );
break;
case 5:
if( getline( ctitle, sizeof(ctitle), "control card" ) == EOF ) {
printf("No control card .... STOP\n");
exit(10);
}
sscanf( ctitle, "%5d%5d", &sol_total, &reg_total );
break;
}
if(verbose) printf("Expecting %d solids, %d regions\n", sol_total, reg_total);
/*
* SOLID TABLE
*/
if(verbose) printf("Solid table\n");
sol_work = 0;
while( sol_work < sol_total ) {
i = getsolid();
if( i < 0 ) {
printf("error converting solid %d\n", sol_work);
/* Should we abort here? */
continue;
}
if( i > 0 ) {
printf("\nprocessed %d of %d solids\n\n",sol_work,sol_total);
if( sol_work < sol_total && version > 1 ) {
printf("some solids are missing, aborting\n");
exit(1);
}
break; /* done */
}
}
/* REGION TABLE */
if(verbose)printf("\nRegion table\n");
i = sizeof(struct wmember) * (reg_total+2);
if( (wmp = (struct wmember *)malloc(i)) == (struct wmember *)0 ) {
printf("malloc(%d) failed\n", i );
exit(42);
}
for( i=reg_total+1; i>=0; i-- ) {
RT_LIST_INIT( &wmp[i].l );
}
cur_col = 0;
if( getregion() < 0 ) exit(10);
if( version == 1 ) {
for( i=1; i < reg_total; i++ ) {
region_register( i, 0, 0, 0, 0 );
}
} else {
if( version == 4 ) {
char dummy[88];
/* read the blank card (line) */
(void)getline( dummy, sizeof(dummy), "blank card" );
}
if(verbose) printf("\nRegion ident table\n");
getid();
}
if(verbose) printf("\nGroups\n");
cur_col = 0;
group_write();
if(verbose) printf("\n");
return(0); /* exit(0) */
}
/*
* C O L _ P R
*/
col_pr( str )
char *str;
{
printf("%s", str);
cur_col += strlen(str);
while( cur_col < 78 && ((cur_col%10) > 0) ) {
putchar(' ');
cur_col++;
}
if( cur_col >= 78 ) {
printf("\n");
cur_col = 0;
}
}
-38
View File
@@ -1,38 +0,0 @@
/* F 2 A () ==== convert float to ascii w.df format. No leading blanks */
f2a( f, s, w, d )
float f; /* INPUT ===*/
char s[]; /* OUTPUT ===*/
int w, d; /* length ===*/
{ int c, i, j;
long n, sign;
if( w <= d + 2 )
{ printf( "ftoascii: incorrect format need w.df\n");
printf( "w must be at least 2 bigger then d.\n" );
printf( "w= %f\t d= %f\n", w, d );
printf( "STOP\n");
exit( 10 );
}
for( i = 1; i <= d; i++ ) f = f * 10.0; /* shift left.*/
if( f < 0.0 ) f -= 0.5; /* round up */
else f += 0.5;
n = f; /* truncate.*/
if( (sign = n) < 0 ) n = -n; /* get sign.*/
i = 0; /* CONVERT to ASCII.*/
do { s[i++] = n % 10 + '0';
if( i == d ) s[i++] = '.';
} while( (n /= 10) > 0 );
if( i < d ) /* zero fill the d field if (f < 1).*/
{ for( j = i; j < d; j++ ) s[j] = '0';
s[j++] = '.';
i = j;
}
if( sign < 0 ) s[i++] = '-'; /* apply sign.*/
if( i > w ) printf("ftoascii: field length too small\n");
w = i; /* do not blank fill.*/
for ( j = i; j < w; j++ ) s[j] = ' '; /* blank fill.*/
s[w] = '\0';
for( i = 0, j = w - 1; /* reverse the array.*/
i < j;
i++, j-- )
{ c = s[i]; s[i] = s[j]; s[j] = c; }
}
-18
View File
@@ -1,18 +0,0 @@
/*
* type definition for new "C" declaration: "homog_t".
*
* This is to make declairing Homogeneous Transform matricies easier.
*/
typedef float mat_t[4*4];
typedef float *matp_t;
typedef float vect_t[4];
typedef float *vectp_t;
#define X 0
#define Y 1
#define Z 2
#define H 3
#define ALPHA 0
#define BETA 1
#define GAMMA 2
-347
View File
@@ -1,347 +0,0 @@
/*
* M A T . C
*
* 4 x 4 Matrix manipulation functions..............
*
* mat_zero( &m ) Fill matrix m with zeros
* mat_idn( &m ) Fill matrix m with identity matrix
* mat_copy( &o, &i ) Copy matrix i to matrix o
* mat_mul( &o, &i1, &i2 ) Multiply i1 by i2 and store in o
* vecXmat( &ov, &iv, &m ) Multiply vector iv by m and store in ov
* matXvec( &ov, &m, &iv ) Multiply m by vector iv and store in ov
* mat_print( &m ) Print out the 4x4 matrix - calls printf
* mat_hscale( &m, hscale ) Homogenious scale of input matrix
* mat_inv( &om, &im ) Invert matrix im and store result in om
*
*
* Matrix array elements have the following positions in the matrix:
*
* | 0 1 2 3 | | 0 |
* [ 0 1 2 3 ] | 4 5 6 7 | | 1 |
* | 8 9 10 11 | | 2 |
* | 12 13 14 15 | | 3 |
*
* preVector (vect_t) Matrix (mat_t) postVector (vect_t)
*
*/
#include "./ged_types.h"
/*
* M A T _ Z E R O
*
* Fill in the matrix "m" with zeros.
*/
mat_zero( m )
register matp_t m;
{
register int i = 0;
/* Clear everything */
for(; i<16; i++)
*m++ = 0;
}
/*
* M A T _ I D N
*
* Fill in the matrix "m" with an identity matrix.
*/
mat_idn( m )
register matp_t m;
{
/* Clear everything first */
mat_zero( m );
/* Set ones in the diagonal */
m[0] = m[5] = m[10] = m[15] = 1;
}
/*
* M A T _ C O P Y
*
* Copy the matrix "im" into the matrix "om".
*/
mat_copy( om, im )
register matp_t om;
register matp_t im;
{
register int i = 0;
/* Copy all elements */
for(; i<16; i++)
*om++ = *im++;
}
/*
* M A T _ M U L
*
* Multiply matrix "im1" by "im2" and store the result in "om".
* NOTE: This is different from multiplying "im2" by "im1" (most
* of the time!)
*/
mat_mul( om, im1, im2 )
register matp_t om;
register matp_t im1;
register matp_t im2;
{
register int em1; /* Element subscript for im1 */
register int em2; /* Element subscript for im2 */
register int el = 0; /* Element subscript for om */
register int i; /* For counting */
/* For each element in the output matrix... */
for(; el<16; el++) {
om[el] = 0; /* Start with zero in output */
em1 = (el/4)*4; /* Element at right of row in im1 */
em2 = el%4; /* Element at top of column in im2 */
for(i=0; i<4; i++) {
om[el] += im1[em1] * im2[em2];
em1++; /* Next row element in m1 */
em2 += 4; /* Next column element in m2 */
}
}
}
/*
* V E C X M A T
*
* Multiply the vector "iv" by the matrix "im" and store the result
* in the vector "ov". Note this is pre-multiply.
*/
vecXmat(ov, iv, im)
register vectp_t ov;
register vectp_t iv;
register matp_t im;
{
register int el = 0; /* Position in output vector */
register int ev; /* Position in input vector */
register int em; /* Position in input matrix */
/* For each element in the output array... */
for(; el<4; el++) {
ov[el] = 0; /* Start with zero in output */
em = el; /* Top of column in input matrix */
for(ev=0; ev<4; ev++) {
ov[el] += iv[ev] * im[em];
em += 4; /* Next element in column from im */
}
}
}
/*
* M A T X V E C
*
* Multiply the matrix "im" by the vector "iv" and store the result
* in the vector "ov". Note this is post-multiply.
*/
matXvec(ov, im, iv)
register vectp_t ov;
register matp_t im;
register vectp_t iv;
{
register int eo = 0; /* Position in output vector */
register int em = 0; /* Position in input matrix */
register int ei; /* Position in input vector */
/* For each element in the output array... */
for(; eo<4; eo++) {
ov[eo] = 0; /* Start with zero in output */
for(ei=0; ei<4; ei++)
ov[eo] += im[em++] * iv[ei];
}
}
/*
* M A T _ P R I N T
*
* Print out the 4x4 matrix addressed by "m".
*/
mat_print( m )
register matp_t m;
{
register int i;
for(i=0; i<16; i++) {
printf("%f%c", m[i], ((i+1)%4) ? '\t' : '\n');
}
}
/*
* M A T _ H S C A L E
*
* The matrix pointed at by "m" is homogeniously scaled by the
* variable "hscale". NOTE that the input matrix is ALSO the output
* matrix.
*/
mat_hscale( m, hscale )
register matp_t m;
float hscale;
{
m[0] *= hscale;
m[5] *= hscale;
m[10] *= hscale;
}
/*
* M A T _ I N V
*
* The matrix pointed at by "im" is inverted and stored in the area
* pointed at by "om".
*/
double abs();
#define EPSILON 0.000001
/*
* Invert a 4-by-4 matrix using Algorithm 120 from ACM.
* This is a modified Gauss-Jordan alogorithm
* Note: Inversion is done in place, with 3 work vectors
*/
void
mat_inv( output, input )
matp_t input;
register matp_t output;
{
register int i, j; /* Indices */
static int k; /* Indices */
static int z[4]; /* Temporary */
static float b[4]; /* Temporary */
static float c[4]; /* Temporary */
mat_copy( output, input ); /* Duplicate */
/* Initialization */
for( j = 0; j < 4; j++ )
z[j] = j;
/* Main Loop */
for( i = 0; i < 4; i++ ) {
static float y; /* local temporary */
k = i;
y = output[i*4+i];
for( j = i+1; j < 4; j++ ) {
static float w; /* local temporary */
w = output[i*4+j];
if( abs(w) > abs(y) ) {
k = j;
y = w;
}
}
if( abs(y) < EPSILON ) {
printf("mat_inv: error!\n");
return;
}
y = 1.0 / y;
for( j = 0; j < 4; j++ ) {
static float temp; /* Local */
c[j] = output[j*4+k];
output[j*4+k] = output[j*4+i];
output[j*4+i] = - c[j] * y;
temp = output[i*4+j] * y;
b[j] = temp;
output[i*4+j] = temp;
}
output[i*4+i] = y;
j = z[i];
z[i] = z[k];
z[k] = j;
for( k = 0; k < 4; k++ ) {
if( k == i ) continue;
for( j = 0; j < 4; j++ ) {
if( j == i ) continue;
output[k*4+j] = output[k*4+j] - b[j] * c[k];
}
}
}
/* Second Loop */
for( i = 0; i < 4; i++ ) {
while( (k = z[i]) != i ) {
static int p; /* Local temp */
for( j = 0; j < 4; j++ ) {
static float w; /* Local temp */
w = output[i*4+j];
output[i*4+j] = output[k*4+j];
output[k*4+j] = w;
}
p = z[i];
z[i] = z[k];
z[k] = p;
}
}
return;
}
double abs( foo )
double foo;
{
if( foo < 0 )
return( -foo );
else
return( foo );
}
/*
* V T O H _ M O V E
*
* Takes a pointer to a [x,y,z] vector, and a pointer
* to space for a homogeneous vector [x,y,z,w],
* and builds [x,y,z,1].
*/
vtoh_move( h, v )
register float *h, *v;
{
*h++ = *v++;
*h++ = *v++;
*h++ = *v;
*h++ = 1;
}
/*
* H T O V _ M O V E
*
* Takes a pointer to [x,y,z,w], and converts it to
* an ordinary vector [x/w, y/w, z/w].
* Optimization for the case of w==1 is performed.
*/
htov_move( v, h )
register float *v, *h;
{
static float inv;
if( h[3] == 1 ) {
*v++ = *h++;
*v++ = *h++;
*v = *h;
} else {
inv = 1 / h[3];
*v++ = *h++ * inv;
*v++ = *h++ * inv;
*v = *h * inv;
}
}
-110
View File
@@ -1,110 +0,0 @@
/*
* R E A D . C
*
* This module contains all of the routines necessary to read in
* a COMGEOM input file, and put the information into internal form.
*
* Author -
* Michael John Muuss
*
* Original Version -
* March 17, 1980
*
* Source -
* SECAD/VLD Computing Consortium, Bldg 394
* The U. S. Army Ballistic Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5066
*
* Copyright Notice -
* This software is Copyright (C) 1989 by the United States Army.
* All rights reserved.
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#include <math.h>
#include "externs.h"
extern FILE *infp;
extern char name_it[16]; /* argv[3] */
/*
* G E T L I N E
*/
int
getline( cp, buflen, title )
register char *cp;
int buflen;
char *title;
{
register int c;
register int count = buflen;
while( (c = fgetc(infp)) == '\n' ) /* Skip blank lines. */
;
while( c != EOF && c != '\n' ) {
*cp++ = c;
count--;
if( count <= 0 ) {
printf("getline(x%x, %d) input record overflows buffer for %s\n", cp, buflen, title);
break;
}
c = fgetc(infp);
}
if( c == EOF )
return EOF;
while( count-- > 0 )
*cp++ = 0;
return c;
}
/*
* G E T I N T
*/
int
getint( cp, start, len )
char *cp;
int start;
int len;
{
char buf[128];
if( len >= sizeof(buf) ) len = sizeof(buf)-1;
strncpy( buf, cp+start, len );
buf[len] = '\0';
return atoi(buf);
}
/*
* G E T D O U B L E
*/
double
getdouble( cp, start, len )
char *cp;
int start;
int len;
{
char buf[128];
if( len >= sizeof(buf) ) len = sizeof(buf)-1;
strncpy( buf, cp+start, len );
buf[len] = '\0';
return atof(buf);
}
/* N A M E C V T */
namecvt( n, cp, c )
register char *cp;
register int n;
{
static char str[32];
sprintf( str, "%c%d%s", c, n, name_it );
strncpy( cp, str, 16 ); /* truncate str to 16 chars.*/
}
-368
View File
@@ -1,368 +0,0 @@
/*
* R E G I O N . C
* Author -
* Michael John Muuss
*
* Source -
* SECAD/VLD Computing Consortium, Bldg 394
* The U. S. Army Ballistic Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5066
*
* Copyright Notice -
* This software is Copyright (C) 1989 by the United States Army.
* All rights reserved.
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#include <ctype.h>
#include "externs.h"
#include "machine.h"
#include "vmath.h"
#include "rtlist.h"
#include "wdb.h"
extern char name_it[];
extern struct wmember *wmp; /* array indexed by region number */
extern FILE *infp;
extern FILE *outfp;
extern int reg_total;
extern int version;
extern int verbose;
char rcard[128];
void region_register();
void group_init();
void group_register();
void group_add();
void group_write();
/*
* G E T R E G I O N
*
* Use wmp[region_number] as head for each region.
*
* Returns -
* -1 error
* 0 done
*/
getregion()
{
int i, j;
int card;
int op;
int reg_reg_flag;
int reg_num;
char inst_name[32];
int inst_num;
char *cp;
reg_num = 0; /* safety */
/* Pre-load very first region card */
if( getline( rcard, sizeof(rcard), "region card" ) == EOF ) {
printf("getregion: premature EOF\n");
return( -1 );
}
if( getint( rcard, 0, 5 ) != 1 ) {
printf("First region card not #1\ncard='%s'\n", rcard);
return(-1);
}
top:
reg_reg_flag = 0;
for( card=0; ; card++ ) {
if( card == 0 ) {
/* First card is already in input buffer */
reg_num = getint( rcard, 0, 5 );
/* -1 region number terminates table */
if( reg_num < 0 )
return( 0 ); /* Done */
if( reg_num > reg_total ) {
printf("%d regions is more than claimed %d\n",
reg_num, reg_total );
return(-1);
}
namecvt( reg_num, wmp[reg_num].wm_name, 'r' );
} else {
if( getline( rcard, sizeof(rcard), "region card" ) == EOF ) {
printf("getregion: premature EOF\n");
return( -1 );
}
if( strcmp( rcard, " end" ) == 0 ||
strcmp( rcard, " END" ) == 0 ) {
/* Version 1, DoE/MORSE */
reg_total = reg_num;
return(0); /* done */
}
if( getint( rcard, 0, 5 ) != 0 ) {
/* finished with this region */
break;
}
}
if( version == 1 ) {
cp = rcard + 10;
} else {
cp = rcard + 6;
}
/* Scan each of the 9 fields on the card */
for( i=0; i<9; i++, cp += 7 ) {
char nbuf[32];
char *np;
/* Remove all spaces from the number */
np = nbuf;
for( j=2; j<7; j++ ) {
if( !isascii( cp[j] ) ) *np++ = '?';
else if( isspace( cp[j] ) ) continue;
*np++ = cp[j];
}
*np = '\0';
/* Check for null field -- they are to be skipped */
if( (inst_num = atoi(nbuf)) == 0 ) {
/* zeros are allowed as placeholders */
continue;
}
if( version == 5 ) {
/* Region references region in Gift5 */
if( cp[1] == 'g' || cp[1] == 'G' ) {
reg_reg_flag = 1;
} else if( cp[1] == 'R' || cp[1] == 'r' ) {
/* 'OR' */
op = WMOP_UNION;
} else {
if( inst_num < 0 ) {
op = WMOP_SUBTRACT;
inst_num = -inst_num;
} else {
op = WMOP_INTERSECT;
}
}
} else {
/* XXX this may actually be an old piece of code,
* rather than the V4 way of doing it. */
if( cp[1] != ' ' ) {
op = WMOP_UNION;
} else {
if( inst_num < 0 ) {
op = WMOP_SUBTRACT;
inst_num = -inst_num;
} else {
op = WMOP_INTERSECT;
}
}
}
/* In Gift5, regions can reference regions */
if( reg_reg_flag )
namecvt(inst_num, inst_name, 'r');
else
namecvt( inst_num, inst_name, 's' );
reg_reg_flag = 0;
(void)mk_addmember( inst_name, &wmp[reg_num], op );
}
}
if(verbose) col_pr( wmp[reg_num].wm_name );
/* The region will be output later in getid(), below */
goto top;
}
/*
* G E T I D
*
* Load the region ID information into the structures
*/
void
getid()
{
int reg_num;
int id;
int air;
int mat= -1;
int los= -2;
char idcard[132];
while(1) {
if( getline( idcard, sizeof(idcard), "region ident card" ) == EOF ) {
printf("\ngetid: EOF\n");
return;
}
if( idcard[0] == '\n' )
return;
if( version == 5 ) {
reg_num = getint( idcard, 0, 5 );
id = getint( idcard, 5, 5 );
air = getint( idcard, 10, 5 );
mat = getint( idcard, 15, 5 );
los = getint( idcard, 20, 5 );
} else {
reg_num = getint( idcard, 0, 10 );
id = getint( idcard, 10, 10 );
air = getint( idcard, 20, 10 );
mat = getint( idcard, 74, 3 );
los = getint( idcard, 77, 3 );
}
if( reg_num <= 0 ) {
printf("\ngetid: region_id %d encountered, stoping\n", reg_num);
return;
}
region_register( reg_num, id, air, mat, los );
}
}
/*
* R E G I O N _ R E G I S T E R
*/
void
region_register( reg_num, id, air, mat, los )
{
register struct wmember *wp;
#if 0
printf("reg_num=%d,id=%d,air=%d,mat=%d,los=%d\n", reg_num,id,air,mat,los);
#endif
wp = &wmp[reg_num];
if( RT_LIST_IS_EMPTY( &wp->l ) ) {
if( verbose ) {
char paren[32];
/* Denote an empty region */
sprintf( paren, "(%s)", wp->wm_name );
col_pr( paren );
}
return;
}
mk_lrcomb( outfp, wp->wm_name, wp, reg_num,
"", "", (char *)0, id, air, mat, los, 0 );
/* Add region to the one group that it belongs to. */
group_add( id, wp->wm_name );
if(verbose) col_pr( wp->wm_name );
}
#define NGROUPS 21
struct groups {
struct wmember grp_wm;
int grp_lo;
int grp_hi;
} groups[NGROUPS];
int ngroups;
void
group_init()
{
group_register( "g00", 0, 0 );
group_register( "g0", 1, 99 );
group_register( "g1", 100, 199);
group_register( "g2", 200, 299 );
group_register( "g3", 300, 399 );
group_register( "g4", 400, 499 );
group_register( "g5", 500, 599 );
group_register( "g6", 600, 699 );
group_register( "g7", 700, 799 );
group_register( "g8", 800, 899 );
group_register( "g9", 900, 999 );
group_register( "g10", 1000, 1999 );
group_register( "g11", 2000, 2999 );
group_register( "g12", 3000, 3999 );
group_register( "g13", 4000, 4999 );
group_register( "g14", 5000, 5999 );
group_register( "g15", 6000, 6999 );
group_register( "g16", 7000, 7999 );
group_register( "g17", 8000, 8999 );
group_register( "g18", 9000, 9999 );
group_register( "g19", 10000, 32767 );
}
void
group_register( name, lo, hi )
char *name;
{
char nbuf[32];
register struct wmember *wp;
if( ngroups >= NGROUPS ) {
printf("Too many groups, ABORTING\n");
exit(13);
}
wp = &groups[ngroups].grp_wm;
sprintf( nbuf, "%s%s", name, name_it );
strncpy( wp->wm_name, nbuf, sizeof(wp->wm_name) );
RT_LIST_INIT( &wp->l );
groups[ngroups].grp_lo = lo;
groups[ngroups].grp_hi = hi;
ngroups++;
}
void
group_add( val, name )
register int val;
char *name;
{
register int i;
for( i=ngroups-1; i>=0; i-- ) {
if( val < groups[i].grp_lo ) continue;
if( val > groups[i].grp_hi ) continue;
goto add;
}
printf("Unable to find group for value %d\n", val);
i = 0;
add:
(void)mk_addmember( name, &groups[i].grp_wm, WMOP_UNION );
}
void
group_write()
{
register struct wmember *wp;
struct wmember allhead;
register int i;
RT_LIST_INIT( &allhead.l );
for( i=0; i < ngroups; i++ ) {
wp = &groups[i].grp_wm;
/* Skip empty groups */
if( RT_LIST_IS_EMPTY( &wp->l ) ) continue;
/* Make a non-region combination */
mk_lfcomb( outfp, wp->wm_name, wp, 0 );
/* Add it to "all.g" */
(void)mk_addmember( wp->wm_name, &allhead, WMOP_UNION );
if(verbose) col_pr( wp->wm_name );
}
/* Make all-encompasing "all.g" group here */
mk_lfcomb( outfp, "all.g", &allhead, 0 );
}
-947
View File
@@ -1,947 +0,0 @@
/*
* S O L I D . C
*
* Subroutine to convert solids from
* COMGEOM card decks into GED object files. This conversion routine
* is used to translate between COMGEOM solids, and the
* more general GED solids.
*
* Authors -
* Michael John Muuss
* Susanne L. Muuss, J.D.
*
* Original Version -
* March, 1980
*
* Source -
* SECAD/VLD Computing Consortium, Bldg 394
* The U. S. Army Ballistic Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5066
*
* Copyright Notice -
* This software is Copyright (C) 1989 by the United States Army.
* All rights reserved.
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include "externs.h"
#include "machine.h"
#include "vmath.h"
#include "rtlist.h"
#include "wdb.h"
extern FILE *outfp;
extern int version;
extern int verbose;
extern double getdouble();
extern int sol_total, sol_work;
#define PI 3.14159265358979323846264 /* Approx */
#define DEG2RAD 0.0174532925199433
char scard[132]; /* Solid card buffer area */
/*
* G E T S O L D A T A
*
* Obtain 'num' data items from input card(s).
* The first input card is already in global 'scard'.
*
* Returns -
* 0 OK
* -1 failure
*/
int
getsoldata( dp, num, solid_num )
double *dp;
int num;
int solid_num;
{
int cd;
double *fp;
int i;
int j;
fp = dp;
for( cd=1; num > 0; cd++ ) {
if( cd != 1 ) {
if( getline( scard, sizeof(scard), "solid continuation card" ) == EOF ) {
printf("too few cards for solid %d\n",
solid_num);
return(-1);
}
/* continuation card
* solid type should be blank
*/
if( (version==5 && scard[5] != ' ' ) ||
(version==4 && scard[3] != ' ' ) ) {
printf("solid %d (continuation) card %d non-blank\n",
solid_num, cd);
return(-1);
}
}
if( num < 6 )
j = num;
else
j = 6;
for( i=0; i<j; i++ ) {
*fp++ = getdouble( scard, 10+i*10, 10 );
}
num -= j;
}
return(0);
}
/*
* G E T X S O L D A T A
*
* Obtain 'num' data items from input card(s).
* All input cards must be freshly read.
*
* Returns -
* 0 OK
* -1 failure
*/
int
getxsoldata( dp, num, solid_num )
double *dp;
int num;
int solid_num;
{
int cd;
double *fp;
int i;
int j;
fp = dp;
for( cd=1; num > 0; cd++ ) {
if( getline( scard, sizeof(scard), "x solid card" ) == EOF ) {
printf("too few cards for solid %d\n",
solid_num);
return(-1);
}
if( cd != 1 ) {
/* continuation card
* solid type should be blank
*/
if( (version==5 && scard[5] != ' ' ) ||
(version==4 && scard[3] != ' ' ) ) {
printf("solid %d (continuation) card %d non-blank\n",
solid_num, cd);
return(-1);
}
}
if( num < 6 )
j = num;
else
j = 6;
for( i=0; i<j; i++ ) {
*fp++ = getdouble( scard, 10+i*10, 10 );
}
num -= j;
}
return(0);
}
/*
* T R I M _ T R A I L _ S P A C E S
*/
trim_trail_spaces( cp )
register char *cp;
{
register char *ep;
ep = cp + strlen(cp) - 1;
while( ep >= cp ) {
if( *ep != ' ' ) break;
*ep-- = '\0';
}
}
/*
* G E T S O L I D
*
* Returns -
* -1 error
* 0 conversion OK
* 1 EOF
*/
getsolid()
{
char given_solid_num[16];
char solid_type[16];
int i;
double r1, r2;
vect_t work;
double m1, m2; /* Magnitude temporaries */
char name[16+2];
double dd[4*6]; /* 4 cards of 6 nums each */
point_t tmp[8]; /* 8 vectors of 3 nums each */
#define D(_i) (&(dd[_i*3]))
#define T(_i) (&(tmp[_i][0]))
if( (i = getline( scard, sizeof(scard), "solid card" )) == EOF ) {
printf("getsolid: unexpected EOF\n");
return( 1 );
}
switch( version ) {
case 5:
strncpy( given_solid_num, scard+0, 5 );
given_solid_num[5] = '\0';
strncpy( solid_type, scard+5, 5 );
solid_type[5] = '\0';
break;
case 4:
strncpy( given_solid_num, scard+0, 3 );
given_solid_num[3] = '\0';
strncpy( solid_type, scard+3, 7 );
solid_type[7] = '\0';
break;
case 1:
/* DoE/MORSE version, believed to be original MAGIC format */
strncpy( given_solid_num, scard+5, 4 );
given_solid_num[4] = '\0';
strncpy( solid_type, scard+2, 3 );
break;
default:
fprintf(stderr,"getsolid() version %d unimplemented\n", version);
exit(1);
break;
}
/* Trim trailing spaces */
trim_trail_spaces( given_solid_num );
trim_trail_spaces( solid_type );
/* another solid - increment solid counter
* rather than using number from the card, which may go into
* pseudo-hex format in version 4 models (due to 3 column limit).
*/
sol_work++;
if( version == 5 ) {
if( (i = getint( scard, 0, 5 )) != sol_work ) {
printf("expected solid card %d, got %d, abort\n",
sol_work, i );
return(1);
}
}
/* Reduce solid type to lower case */
{
register char *cp;
register char c;
cp = solid_type;
while( (c = *cp) != '\0' ) {
if( !isascii(c) ) {
*cp++ = '?';
} else if( isupper(c) ) {
*cp++ = tolower(c);
} else {
cp++;
}
}
}
namecvt( sol_work, name, 's' );
if(verbose) col_pr( name );
if( strcmp( solid_type, "end" ) == 0 ) {
/* DoE/MORSE version 1 format */
return(1); /* END */
}
if( strcmp( solid_type, "ars" ) == 0 ) {
int ncurves;
int pts_per_curve;
double **curve;
int ret;
ncurves = getint( scard, 10, 10 );
pts_per_curve = getint( scard, 20, 10 );
/* Allocate curves pointer array */
if( (curve = (double **)malloc((ncurves+1)*sizeof(double *))) == ((double **)0) ) {
printf("malloc failure for ARS %d\n", sol_work);
return(-1);
}
/* Allocate space for a curve, and read it in */
for( i=0; i<ncurves; i++ ) {
if( (curve[i] = (double *)malloc(
(pts_per_curve+1)*3*sizeof(double) )) ==
((double *)0) ) {
printf("malloc failure for ARS %d curve %d\n",
sol_work, i);
return(-1);
}
/* Get data for this curve */
if( getxsoldata( curve[i], pts_per_curve*3, sol_work ) < 0 ) {
printf("ARS %d: getxsoldata failed, curve %d\n",
sol_work, i);
return(-1);
}
}
if( (ret = mk_ars( outfp, name, ncurves, pts_per_curve, curve )) < 0 ) {
printf("mk_ars(%s) failed\n", name );
/* Need to free memory; 'ret' is returned below */
}
for( i=0; i<ncurves; i++ ) {
free( (char *)curve[i] );
}
free( (char *)curve);
return(ret);
}
if( strcmp( solid_type, "rpp" ) == 0 ) {
double min[3], max[3];
if( getsoldata( dd, 2*3, sol_work ) < 0 )
return(-1);
VSET( min, dd[0], dd[2], dd[4] );
VSET( max, dd[1], dd[3], dd[5] );
return( mk_rpp( outfp, name, min, max ) );
}
if( strcmp( solid_type, "box" ) == 0 ) {
if( getsoldata( dd, 4*3, sol_work ) < 0 )
return(-1);
VMOVE( T(0), D(0) );
VADD2( T(1), D(0), D(2) );
VADD3( T(2), D(0), D(2), D(1) );
VADD2( T(3), D(0), D(1) );
VADD2( T(4), D(0), D(3) );
VADD3( T(5), D(0), D(3), D(2) );
VADD4( T(6), D(0), D(3), D(2), D(1) );
VADD3( T(7), D(0), D(3), D(1) );
return( mk_arb8( outfp, name, tmp ) );
}
if( strcmp( solid_type, "raw" ) == 0 ||
strcmp( solid_type, "wed" ) == 0 /* DoE name */
) {
if( getsoldata( dd, 4*3, sol_work ) < 0 )
return(-1);
VMOVE( T(0), D(0) );
VADD2( T(1), D(0), D(2) );
VMOVE( T(2), T(1) );
VADD2( T(3), D(0), D(1) );
VADD2( T(4), D(0), D(3) );
VADD3( T(5), D(0), D(3), D(2) );
VMOVE( T(6), T(5) );
VADD3( T(7), D(0), D(3), D(1) );
return( mk_arb8( outfp, name, tmp ) );
}
if( strcmp( solid_type, "rvw" ) == 0 ) {
/* Right Vertical Wedge (Origin: DoE/MORSE) */
double a2, theta, phi, h2;
double a2theta;
double angle1, angle2;
vect_t a, b, c;
if( getsoldata( dd, 1*3+4, sol_work ) < 0 )
return(-1);
a2 = dd[3]; /* XY side length */
theta = dd[4];
phi = dd[5];
h2 = dd[6]; /* height in +Z */
angle1 = (phi+theta-90) * DEG2RAD;
angle2 = (phi+theta) * DEG2RAD;
a2theta = a2 * tan(theta * DEG2RAD);
VSET( a, a2theta*cos(angle1), a2theta*sin(angle1), 0 );
VSET( b, -a2*cos(angle2), -a2*sin(angle2), 0 );
VSET( c, 0, 0, h2 );
VSUB2( T(0), D(0), b );
VMOVE( T(1), D(0) );
VMOVE( T(2), D(0) );
VADD2( T(3), T(0), a );
VADD2( T(4), T(0), c );
VADD2( T(5), T(1), c );
VMOVE( T(6), T(5) );
VADD2( T(7), T(3), c );
return( mk_arb8( outfp, name, tmp ) );
}
if( strcmp( solid_type, "arw" ) == 0) {
/* ARbitrary Wedge --- ERIM */
if( getsoldata( dd, 4*3, sol_work ) < 0)
return(-1);
VMOVE( T(0), D(0) );
VADD2( T(1), D(0), D(2) );
VADD3( T(2), D(0), D(2), D(3) );
VADD2( T(3), D(0), D(3) );
VADD2( T(4), D(0), D(1) );
VMOVE( T(5), T(4) );
VADD3( T(6), D(0), D(1), D(3) );
VMOVE( T(7), T(6) );
return( mk_arb8( outfp, name, (point_t *)tmp) );
}
if( strcmp( solid_type, "arb8" ) == 0 ) {
if( getsoldata( dd, 8*3, sol_work ) < 0 )
return(-1);
return( mk_arb8( outfp, name, (point_t *)dd ) );
}
if( strcmp( solid_type, "arb7" ) == 0 ) {
if( getsoldata( dd, 7*3, sol_work ) < 0 )
return(-1);
VMOVE( D(7), D(4) );
return( mk_arb8( outfp, name, (point_t *)dd ) );
}
if( strcmp( solid_type, "arb6" ) == 0 ) {
if( getsoldata( dd, 6*3, sol_work ) < 0 )
return(-1);
/* Note that the ordering is important, as data is in D(4), D(5) */
VMOVE( D(7), D(5) );
VMOVE( D(6), D(5) );
VMOVE( D(5), D(4) );
return( mk_arb8( outfp, name, (point_t *)dd ) );
}
if( strcmp( solid_type, "arb5" ) == 0 ) {
if( getsoldata( dd, 5*3, sol_work ) < 0 )
return(-1);
VMOVE( D(5), D(4) );
VMOVE( D(6), D(4) );
VMOVE( D(7), D(4) );
return( mk_arb8( outfp, name, (point_t *)dd ) );
}
if( strcmp( solid_type, "arb4" ) == 0 ) {
if( getsoldata( dd, 4*3, sol_work ) < 0 )
return(-1);
return( mk_arb4( outfp, name, (point_t *)dd ) );
}
if( strcmp( solid_type, "rcc" ) == 0 ) {
/* V, H, r */
if( getsoldata( dd, 2*3+1, sol_work ) < 0 )
return(-1);
return( mk_rcc( outfp, name, D(0), D(1), dd[6] ) );
}
if( strcmp( solid_type, "rec" ) == 0 ) {
/* V, H, A, B */
if( getsoldata( dd, 4*3, sol_work ) < 0 )
return(-1);
return( mk_tgc( outfp, name, D(0), D(1),
D(2), D(3), D(2), D(3) ) );
}
if( strcmp( solid_type, "trc" ) == 0 ) {
/* V, H, r1, r2 */
if( getsoldata( dd, 2*3+2, sol_work ) < 0 )
return(-1);
return( mk_trc( outfp, name, D(0), D(1), dd[6], dd[7] ) );
}
if( strcmp( solid_type, "tec" ) == 0 ) {
/* V, H, A, B, p */
if( getsoldata( dd, 4*3+1, sol_work ) < 0 )
return(-1);
r1 = 1.0/dd[12]; /* P */
VSCALE( D(4), D(2), r1 );
VSCALE( D(5), D(3), r1 );
return( mk_tgc( outfp, name, D(0), D(1),
D(2), D(3), D(4), D(5) ) );
}
if( strcmp( solid_type, "tgc" ) == 0 ) {
/* V, H, A, B, r1, r2 */
if( getsoldata( dd, 4*3+2, sol_work ) < 0 )
return(-1);
r1 = dd[12] / MAGNITUDE( D(2) ); /* A/|A| * C */
r2 = dd[13] / MAGNITUDE( D(3) ); /* B/|B| * D */
VSCALE( D(4), D(2), r1 );
VSCALE( D(5), D(3), r2 );
return( mk_tgc( outfp, name, D(0), D(1),
D(2), D(3), D(4), D(5) ) );
}
if( strcmp( solid_type, "sph" ) == 0 ) {
/* V, radius */
if( getsoldata( dd, 1*3+1, sol_work ) < 0 )
return(-1);
return( mk_sph( outfp, name, D(0), dd[3] ) );
}
if( strncmp( solid_type, "wir", 3 ) == 0 ) {
int numpts; /* points per wire */
int num;
int i;
double rad;
double *pts; /* 3 entries per pt */
struct wdb_pipeseg *ps;
struct wdb_pipeseg head; /* all ow a whole struct for head */
/* This might be getint( solid_type, 3, 2 ); for non-V5 */
numpts = getint( scard, 9, 2 );
num = numpts * 3 + 1; /* 3 entries per pt */
/* allocate space for the points array */
if( (pts = ( double *)malloc(num * sizeof( double)) ) == NULL ) {
printf("malloc failure for WIR %d\n", sol_work);
return(-1);
}
if( getsoldata( pts, num, sol_work ) < 0 ) {
return(-1);
}
rad = pts[num-1];
/* allocate nodes on a list and store all information in
* the appropriate location.
*/
RT_LIST_INIT( &head.l );
for( i = 0; i < numpts - 1; i++ ) {
/* malloc a new structure */
if( (ps = (struct wdb_pipeseg *)malloc(
sizeof( struct wdb_pipeseg)) ) == WDB_PIPESEG_NULL ) {
printf("malloc failure for WIR %d\n", sol_work);
return(-1);
}
VMOVE( ps->ps_start, &pts[i*3]); /* 3 pts at a time */
ps->ps_id = 0; /* solid */
ps->ps_od = rad;
ps->ps_type = WDB_PIPESEG_TYPE_LINEAR;
RT_LIST_INSERT( &head.l, &ps->l );
}
/* make the end plate */
if( (ps = ( struct wdb_pipeseg *)malloc( sizeof(
struct wdb_pipeseg)) ) == WDB_PIPESEG_NULL ) {
printf("malloc failure for WIR %d\n", sol_work);
return(-1);
}
VMOVE( ps->ps_start, &pts[3 * (numpts-1)] );
ps->ps_type = WDB_PIPESEG_TYPE_END;
ps->ps_id = 0;
ps->ps_od = rad;
RT_LIST_INSERT( &head.l, &ps->l );
if( mk_pipe( outfp, name, &head ) < 0 )
return(-1);
mk_pipe_free( &head );
return(0); /* OK */
}
if( version <= 4 && strcmp( solid_type, "ell" ) == 0 ) {
/* Foci F1, F2, major axis length L */
vect_t v;
/*
* For simplicity, we convert ELL to ELL1, then
* fall through to ELL1 code.
* Format of ELL is F1, F2, len
* ELL1 format is V, A, r
*/
if( getsoldata( dd, 2*3+1, sol_work ) < 0 )
return(-1);
VADD2SCALE( v, D(0), D(1), 0.5 ); /* V is midpoint */
VSUB2( work, D(1), D(0) ); /* work holds F2 - F1 */
m1 = MAGNITUDE( work );
r2 = 0.5 * dd[6] / m1;
VSCALE( D(1), work, r2 ); /* A */
dd[6] = sqrt( MAGSQ( D(1) ) -
(m1 * 0.5)*(m1 * 0.5) ); /* r */
VMOVE( D(0), v );
goto ell1;
}
if( (version == 5 && strcmp( solid_type, "ell" ) == 0) ||
strcmp( solid_type, "ell1" ) == 0 ) {
/* V, A, r */
/* GIFT4 name is "ell1", GIFT5 name is "ell" */
if( getsoldata( dd, 2*3+1, sol_work ) < 0 )
return(-1);
ell1:
r1 = dd[6]; /* R */
VMOVE( work, D(0) );
work[0] += PI;
work[1] += PI;
work[2] += PI;
VCROSS( D(2), work, D(1) );
m1 = r1/MAGNITUDE( D(2) );
VSCALE( D(2), D(2), m1 );
VCROSS( D(3), D(1), D(2) );
m2 = r1/MAGNITUDE( D(3) );
VSCALE( D(3), D(3), m2 );
/* Now we have V, A, B, C */
return( mk_ell( outfp, name, D(0), D(1), D(2), D(3) ) );
}
if( strcmp( solid_type, "ellg" ) == 0 ) {
/* V, A, B, C */
if( getsoldata( dd, 4*3, sol_work ) < 0 )
return(-1);
return( mk_ell( outfp, name, D(0), D(1), D(2), D(3) ) );
}
if( strcmp( solid_type, "tor" ) == 0 ) {
/* V, N, r1, r2 */
if( getsoldata( dd, 2*3+2, sol_work ) < 0 )
return(-1);
return( mk_tor( outfp, name, D(0), D(1), dd[6], dd[7] ) );
}
if( strcmp( solid_type, "haf" ) == 0 ) {
/* N, d */
if( getsoldata( dd, 1*3+1, sol_work ) < 0 )
return(-1);
return( mk_half( outfp, name, D(0), dd[3] ) );
}
if( strcmp( solid_type, "arbn" ) == 0 ) {
return( read_arbn( name ) );
}
/*
* The solid type string is defective,
* or that solid is not currently supported.
*/
printf("getsolid: no support for solid type '%s'\n", solid_type );
return(-1);
}
read_arbn( name )
char *name;
{
int npt; /* # vertex pts to be read in */
int npe; /* # planes from 3 vertex points */
int neq; /* # planes from equation */
int nae; /* # planes from az,el & vertex index */
int nface; /* total number of faces */
double *input_points = (double *)0;
double *vertex = (double *)0; /* vertex list of final solid */
int last_vertex; /* index of first unused vertex */
int max_vertex; /* size of vertex array */
int *used = (int *)0; /* plane eqn use count */
plane_t *eqn = (plane_t *)0; /* plane equations */
int cur_eq = 0; /* current (free) equation number */
int symm = 0; /* symmetry about Y used */
register int i;
int j;
int k;
register int m;
point_t cent; /* centroid of arbn */
npt = getint( scard, 10+0*10, 10 );
npe = getint( scard, 10+1*10, 10 );
neq = getint( scard, 10+2*10, 10 );
nae = getint( scard, 10+3*10, 10 );
nface = npe + neq + nae;
if( npt < 1 ) {
/* Having one point is necessary to compute centroid */
printf("arbn defined without at least one point\n");
bad:
if(npt>0) eat( (npt+1)/2 ); /* vertex input_points */
if(npe>0) eat( (npe+5)/6 ); /* vertex pt index numbers */
if(neq>0) eat( neq ); /* plane eqns? */
if(nae>0) eat( (nae+1)/2 ); /* az el & vertex index? */
return(-1);
}
/* Allocate storage for plane equations */
if( (eqn = (plane_t *)malloc(nface*sizeof(plane_t))) == (plane_t *)0 ) {
printf("arbn plane equation malloc failure\n");
goto bad;
}
/* Allocate storage for per-plane use count */
if( (used = (int *)malloc(nface*sizeof(int))) == (int *)0 ) {
printf("arbn use count malloc failure\n");
goto bad;
}
if( npt >= 1 ) {
/* Obtain vertex input_points */
if( (input_points = (double *)malloc(npt*3*sizeof(double))) == (double *)0 ) {
printf("arbn point malloc failure\n");
goto bad;
}
if( getxsoldata( input_points, npt*3, sol_work ) < 0 )
goto bad;
}
/* Get planes defined by three points, 6 per card */
for( i=0; i<npe; i += 6 ) {
if( getline( scard, sizeof(scard), "arbn vertex point indices" ) == EOF ) {
printf("too few cards for arbn %d\n",
sol_work);
return(-1);
}
for( j=0; j<6; j++ ) {
int q,r,s;
point_t a,b,c;
q = getint( scard, 10+j*10+0, 4 );
r = getint( scard, 10+j*10+4, 3 );
s = getint( scard, 10+j*10+7, 3 );
if( q == 0 || r == 0 || s == 0 ) continue;
if( q < 0 ) {
VMOVE( a, &input_points[((-q)-1)*3] );
a[Y] = -a[Y];
symm = 1;
} else {
VMOVE( a, &input_points[((q)-1)*3] );
}
if( r < 0 ) {
VMOVE( b, &input_points[((-r)-1)*3] );
b[Y] = -b[Y];
symm = 1;
} else {
VMOVE( b, &input_points[((r)-1)*3] );
}
if( s < 0 ) {
VMOVE( c, &input_points[((-s)-1)*3] );
c[Y] = -c[Y];
symm = 1;
} else {
VMOVE( c, &input_points[((s)-1)*3] );
}
/* XXX The tol_sq here is sheer guesswork */
if( rt_mk_plane_3pts( eqn[cur_eq], a,b,c, 0.00001 ) < 0 ) {
printf("arbn degenerate plane\n");
VPRINT("a", a);
VPRINT("b", b);
VPRINT("c", c);
continue;
}
cur_eq++;
}
}
/* Get planes defined by their equation */
for( i=0; i < neq; i++ ) {
register double scale;
if( getline( scard, sizeof(scard), "arbn plane equation card" ) == EOF ) {
printf("too few cards for arbn %d\n",
sol_work);
return(-1);
}
eqn[cur_eq][0] = getdouble( scard, 10+0*10, 10 );
eqn[cur_eq][1] = getdouble( scard, 10+1*10, 10 );
eqn[cur_eq][2] = getdouble( scard, 10+2*10, 10 );
eqn[cur_eq][3] = getdouble( scard, 10+3*10, 10 );
scale = MAGNITUDE(eqn[cur_eq]);
if( scale < SMALL ) {
printf("arbn plane normal too small\n");
continue;
}
scale = 1/scale;
VSCALE( eqn[cur_eq], eqn[cur_eq], scale );
eqn[cur_eq][3] *= scale;
cur_eq++;
}
/* Get planes defined by azimuth, elevation, and pt, 2 per card */
for( i=0; i < nae; i += 2 ) {
if( getline( scard, sizeof(scard), "arbn az/el card" ) == EOF ) {
printf("too few cards for arbn %d\n",
sol_work);
return(-1);
}
for( j=0; j<2; j++ ) {
double az, el;
int vert_no;
double cos_el;
point_t pt;
az = getdouble( scard, 10+j*30+0*10, 10 ) * DEG2RAD;
el = getdouble( scard, 10+j*30+1*10, 10 ) * DEG2RAD;
vert_no = getint( scard, 10+j*30+2*10, 10 );
if( vert_no == 0 ) break;
cos_el = cos(el);
eqn[cur_eq][X] = cos(az)*cos_el;
eqn[cur_eq][Y] = sin(az)*cos_el;
eqn[cur_eq][Z] = sin(el);
if( vert_no < 0 ) {
VMOVE( pt, &input_points[((-vert_no)-1)*3] );
pt[Y] = -pt[Y];
} else {
VMOVE( pt, &input_points[((vert_no)-1)*3] );
}
eqn[cur_eq][3] = VDOT(pt, eqn[cur_eq]);
cur_eq++;
}
}
if( nface != cur_eq ) {
printf("arbn expected %d faces, got %d\n", nface, cur_eq);
return(-1);
}
/* Average all given points together to find centroid */
/* This is why there must be at least one (two?) point given */
VSETALL(cent, 0);
for( i=0; i<npt; i++ ) {
VADD2( cent, cent, &input_points[i*3] );
}
VSCALE( cent, cent, 1.0/npt );
if( symm ) cent[Y] = 0;
/* Point normals away from centroid */
for( i=0; i<nface; i++ ) {
double dist;
dist = VDOT( eqn[i], cent ) - eqn[i][3];
/* If dist is negative, 'cent' is inside halfspace */
#define DIST_TOL (1.0e-8)
#define DIST_TOL_SQ (1.0e-10)
if( dist < -DIST_TOL ) continue;
if( dist > DIST_TOL ) {
/* Flip halfspace over */
VREVERSE( eqn[i], eqn[i] );
eqn[i][3] = -eqn[i][3];
} else {
/* Centroid lies on this face */
printf("arbn centroid lies on face\n");
return(-1);
}
}
/* Release storage for input points */
free( (char *)input_points );
input_points = (double *)0;
/*
* ARBN must be convex. Test for concavity.
* Byproduct is an enumeration of all the verticies.
*/
last_vertex = max_vertex = 0;
/* Zero face use counts */
for( i=0; i<nface; i++ ) {
used[i] = 0;
}
for( i=0; i<nface-2; i++ ) {
for( j=i+1; j<nface-1; j++ ) {
double dot;
int point_count; /* # points on this line */
/* If normals are parallel, no intersection */
dot = VDOT( eqn[i], eqn[j] );
if( !NEAR_ZERO( dot, 0.999999 ) ) continue;
point_count = 0;
for( k=j+1; k<nface; k++ ) {
point_t pt;
if( rt_mkpoint_3planes( pt, eqn[i], eqn[j], eqn[k] ) < 0 ) continue;
/* See if point is outside arb */
for( m=0; m<nface; m++ ) {
if( i==m || j==m || k==m ) continue;
if( VDOT(pt, eqn[m])-eqn[m][3] > DIST_TOL )
goto next_k;
}
/* See if vertex already was found */
for( m=0; m<last_vertex; m++ ) {
vect_t dist;
VSUB2( dist, pt, &vertex[m*3] );
if( MAGSQ(dist) < DIST_TOL_SQ )
goto next_k;
}
/*
* Add point to vertex array.
* If more room needed, realloc.
*/
if( last_vertex >= max_vertex ) {
if( max_vertex == 0 ) {
max_vertex = 3;
vertex = (double *)malloc( max_vertex*3*sizeof(double) );
} else {
max_vertex *= 10;
vertex = (double *)realloc( (char *)vertex, max_vertex*3*sizeof(double) );
}
if( vertex == (double *)0 ) {
printf("arbn vertex realloc fail\n");
goto bad;
}
}
VMOVE( &vertex[last_vertex*3], pt );
last_vertex++;
point_count++;
/* Increment "face used" counts */
used[i]++;
used[j]++;
used[k]++;
next_k: ;
}
if( point_count > 2 ) {
printf("arbn: warning, point_count on line=%d\n", point_count);
}
}
}
/* If any planes were not used, then arbn is not convex */
for( i=0; i<nface; i++ ) {
if( used[i] != 0 ) continue; /* face was used */
printf("arbn face %d unused, solid is not convex\n", i);
return(-1);
}
/* Write out the solid ! */
i = mk_arbn( outfp, name, nface, eqn );
if( input_points ) free( (char *)input_points );
if( vertex ) free( (char *)vertex );
if( eqn ) free( (char *)eqn );
if( used ) free( (char *)used );
return(i);
}
/*
* E A T
*
* Eat the indicated number of input lines
*/
eat( count )
int count;
{
char lbuf[132];
int i;
for( i=0; i<count; i++ ) {
(void)getline( lbuf, sizeof(lbuf), "eaten card" );
}
}
-36
View File
@@ -1,36 +0,0 @@
#define PADCHR ~(1<<15) /* non data value.*/
char *
endstr( str )
char *str;
{ while( *str != 0 ) *str++;
return( str );
}
strcpy( s, t ) /* === */
char *s, *t;
{
while( (*s++ = *t++) != '\0' );
*s = '\0';
}
strappend( s, t ) /* === */
char *s, *t;
{ s = endstr( s );
while( (*s++ = *t++) != '\0' );
*s = '\0';
}
maxmin( l, n, max, min ) /* === */
int *l, n,*max,*min;
{
*max = -PADCHR;
*min = PADCHR;
/*BUGoff/printf( "max=%d min=%d\n", *max, *min );/* BUG */
while( --n>0 )
{
if( *l > *max ) *max = *l;
if( *l < *min ) *min = *l;
++l;
}
/*BUGoff/printf( "max=%d min=%d\n", *max, *min );/* BUG */
}
-32
View File
@@ -1,32 +0,0 @@
/*
* conv/Cakefile
*
* $Header$
*/
#define SRCDIR conv
#define PRODUCTS asc2g g2asc conv-vg2g pix2asc asc2pix
#define SRCSUFF .c
#define MANSECTION 1
#include "../Cakefile.defs"
#include "../Cakefile.prog"
/* Explicit composition of each product */
asc2g: asc2g.o
CC LDFLAGS asc2g.o LIBWDB LIBPLOT LIBRT LIBRT_LIBES LIBES -o asc2g
g2asc: g2asc.o
CC LDFLAGS g2asc.o LIBWDB LIBPLOT LIBRT LIBRT_LIBES LIBES -o g2asc
conv-vg2g: conv-vg2g.o
CC LDFLAGS conv-vg2g.o -o conv-vg2g
pix2asc: pix2asc.o
CC LDFLAGS pix2asc.o -o pix2asc
asc2pix: asc2pix.o
CC LDFLAGS asc2pix.o -o asc2pix
#include "../Cakefile.rules"
-949
View File
@@ -1,949 +0,0 @@
/*
* A S C 2 G . C
*
* This program generates a GED database from an
* ASCII GED data file.
*
* Usage: asc2g < file.asc > file.g
*
* Authors -
* Charles M Kennedy
* Michael J Muuss
* Susanne Muuss, J.D. Converted to libwdb, Oct. 1990
*
*
* Source -
* SECAD/VLD Computing Consortium, Bldg 394
* The U. S. Army Ballistic Research Laboratory
* Aberdeen Proving Ground, Maryland 21005
*
* Copyright Notice -
* This software is Copyright (C) 1985 by the United States Army.
* All rights reserved.
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#include "machine.h"
#include "vmath.h"
#include "rtlist.h"
#include "db.h"
#include "wdb.h"
#include "externs.h"
#define BUFSIZE (8*1024) /* input line buffer size */
#define TYPELEN 10
#define NAMELEN 20
void identbld(), polyhbld(), polydbld(), pipebld(), particlebld();
void solbld();
int combbld();
void membbld(), arsabld(), arsbbld();
void materbld(), bsplbld(), bsurfbld(), zap_nl();
char *nxt_spc();
static union record record; /* GED database record */
static char buf[BUFSIZE]; /* Record input buffer */
char name[NAMESIZE + 2];
int debug;
main(argc, argv)
char **argv;
{
if( argc > 1 )
debug = 1;
/* Read ASCII input file, each record on a line */
while( ( fgets( buf, BUFSIZE, stdin ) ) != (char *)0 ) {
after_read:
/* Clear the output record -- vital! */
(void)bzero( (char *)&record, sizeof(record) );
/* Check record type */
if( debug )
(void)fprintf(stderr,"rec %c\n", buf[0] );
switch( buf[0] ) {
case ID_SOLID:
solbld();
continue;
case ID_COMB:
if( combbld() > 0 ) goto after_read;
continue;
case ID_MEMB:
(void)fprintf(stderr,"Warning: unattached Member record, ignored\n");
continue;
case ID_ARS_A:
arsabld();
continue;
case ID_ARS_B:
arsbbld();
continue;
case ID_P_HEAD:
polyhbld();
continue;
case ID_P_DATA:
polydbld();
continue;
case ID_IDENT:
identbld();
continue;
case ID_MATERIAL:
materbld();
continue;
case ID_BSOLID:
bsplbld();
continue;
case ID_BSURF:
bsurfbld();
continue;
case DBID_PIPE:
pipebld();
continue;
case DBID_PARTICLE:
particlebld();
continue;
default:
(void)fprintf(stderr,"asc2g: bad record type '%c' (0%o), skipping\n", buf[0], buf[0]);
(void)fprintf(stderr,"%s\n", buf );
continue;
}
}
exit(0);
}
/* S O L B L D
*
* This routine parses a solid record and determines which libwdb routine
* to call to replicate this solid. Simple primitives are expected.
*/
void
solbld()
{
register char *cp;
register char *np;
register int i;
char s_id; /* id code for the record */
char s_type; /* id for the type of primitive */
short s_cgtype; /* comgeom solid type */
fastf_t val[24]; /* array of values/parameters for solid */
point_t center; /* center; used by many solids */
point_t pnts[9]; /* array of points for the arbs */
point_t norm;
point_t min, max;
vect_t a, b, c, d, n, r1, r2; /* various vectors required */
vect_t height; /* height vector for tgc */
double dd, rad1, rad2;
cp = buf;
s_id = *cp++;
cp = nxt_spc( cp ); /* skip the space */
s_type = (char)atoi( cp );
cp = nxt_spc( cp );
np = name;
while( *cp != ' ' ) {
*np++ = *cp++;
}
*np = '\0';
cp = nxt_spc( cp );
s_cgtype = (short)atoi( cp );
for( i = 0; i < 24; i++ ) {
cp = nxt_spc( cp );
val[i] = atof( cp );
}
/* Switch on the record type to make the solids. */
switch( s_type ) {
case TOR:
VSET(center, val[0], val[1], val[2]);
VSET(n, val[3], val[4], val[5]);
rad1 = MAGNITUDE(&val[6]);
rad2 = MAGNITUDE(n);
VUNITIZE(n);
/* Prevent illegal torii from floating point fuzz */
if( rad2 > rad1 ) rad2 = rad1;
mk_tor(stdout, name, center, n, rad1, rad2);
break;
case GENTGC:
VSET(center, val[0], val[1], val[2]);
VSET(height, val[3], val[4], val[5]);
VSET(a, val[6], val[7], val[8]);
VSET(b, val[9], val[10], val[11]);
VSET(c, val[12], val[13], val[14]);
VSET(d, val[15], val[16], val[17]);
mk_tgc(stdout, name, center, height, a, b, c, d);
break;
case GENELL:
VSET(center, val[0], val[1], val[2]);
VSET(a, val[3], val[4], val[5]);
VSET(b, val[6], val[7], val[8]);
VSET(c, val[9], val[10], val[11]);
mk_ell(stdout, name, center, a, b, c);
break;
case GENARB8:
VSET(pnts[0], val[0], val[1], val[2]);
VSET(pnts[1], val[3], val[4], val[5]);
VSET(pnts[2], val[6], val[7], val[8]);
VSET(pnts[3], val[9], val[10], val[11]);
VSET(pnts[4], val[12], val[13], val[14]);
VSET(pnts[5], val[15], val[16], val[17]);
VSET(pnts[6], val[18], val[19], val[20]);
VSET(pnts[7], val[21], val[22], val[23]);
/* Convert from vector notation to absolute points */
for( i=1; i<8; i++ ) {
VADD2( pnts[i], pnts[i], pnts[0] );
}
mk_arb8(stdout, name, pnts);
break;
case HALFSPACE:
VSET(norm, val[0], val[1], val[2]);
dd = val[3];
mk_half(stdout, name, norm, dd);
break;
default:
fprintf(stderr, "asc2g: bad solid %s s_type= %d, skipping\n",
name, s_type);
}
}
/* C O M B B L D
*
* This routine builds combinations.
* It does so by processing the "C" combination input line,
* (which may be followed by optional material properties lines),
* and it then slurps up any following "M" member lines,
* building up a linked list of all members.
* Reading continues until a non-"M" record is encountered.
*
* Returns -
* 0 OK
* 1 OK, another record exists in global input line buffer.
*/
int
combbld()
{
struct wmember head;
register char *cp;
register char *np;
int temp_nflag, temp_pflag;
char override;
char id; /* == ID_COMB */
char reg_flags; /* region flag */
int is_reg;
short regionid;
short aircode;
short length; /* DEPRECTED: number of members expected */
short num; /* DEPRECATED: Comgeom reference number */
short material; /* GIFT material code */
short los; /* LOS estimate */
unsigned char rgb[3]; /* Red, green, blue values */
char matname[32]; /* String of material name */
char matparm[60]; /* String of material parameters */
char inherit; /* Inheritance property */
/* Set all flags initially. */
RT_LIST_INIT( &head.l );
override = 0;
temp_nflag = temp_pflag = 0; /* indicators for optional fields */
cp = buf;
id = *cp++; /* ID_COMB */
cp = nxt_spc( cp ); /* skip the space */
reg_flags = *cp++;
cp = nxt_spc( cp );
np = name;
while( *cp != ' ' ) {
*np++ = *cp++;
}
*np = '\0';
cp = nxt_spc( cp );
regionid = (short)atoi( cp );
cp = nxt_spc( cp );
aircode = (short)atoi( cp );
cp = nxt_spc( cp );
length = (short)atoi( cp ); /* unused */
cp = nxt_spc( cp );
num = (short)atoi( cp ); /* unused */
cp = nxt_spc( cp );
material = (short)atoi( cp );
cp = nxt_spc( cp );
los = (short)atoi( cp );
cp = nxt_spc( cp );
override = (char)atoi( cp );
cp = nxt_spc( cp );
rgb[0] = (unsigned char)atoi( cp );
cp = nxt_spc( cp );
rgb[1] = (unsigned char)atoi( cp );
cp = nxt_spc( cp );
rgb[2] = (unsigned char)atoi( cp );
cp = nxt_spc( cp );
temp_nflag = atoi( cp );
cp = nxt_spc( cp );
temp_pflag = atoi( cp );
cp = nxt_spc( cp );
inherit = atoi( cp );
if( reg_flags == 'Y' )
is_reg = 1;
else
is_reg = 0;
if( temp_nflag ) {
fgets( buf, BUFSIZE, stdin );
zap_nl();
strncpy( matname, buf, sizeof(matname)-1 );
}
if( temp_pflag ) {
fgets( buf, BUFSIZE, stdin );
zap_nl();
strncpy( matparm, buf, sizeof(matparm)-1 );
}
for(;;) {
buf[0] = '\0';
if( fgets( buf, BUFSIZE, stdin ) == (char *)0 )
break;
if( buf[0] != ID_MEMB ) break;
/* Process (and accumulate) the members */
membbld( &head );
}
/* Spit them out, all at once */
if( mk_lrcomb(stdout, name, &head, is_reg,
temp_nflag ? matname : (char *)0,
temp_pflag ? matparm : (char *)0,
override ? rgb : (char *)0,
regionid, aircode, material, los, inherit) < 0 ) {
fprintf(stderr,"asc2g: mk_rcomb fail\n");
exit(1);
}
if( buf[0] == '\0' ) return(0);
return(1);
}
/* M E M B B L D
*
* This routine invokes libwdb to build a member of a combination.
* Called only from combbld()
*/
void
membbld( headp )
struct wmember *headp;
{
register char *cp;
register char *np;
register int i;
char id;
char relation; /* boolean operation */
char inst_name[NAMESIZE+2];
struct wmember *memb;
cp = buf;
id = *cp++;
cp = nxt_spc( cp ); /* skip the space */
relation = *cp++;
cp = nxt_spc( cp );
np = inst_name;
while( *cp != ' ' ) {
*np++ = *cp++;
}
*np = '\0';
cp = nxt_spc( cp );
memb = mk_addmember( inst_name, headp, relation );
for( i = 0; i < 16; i++ ) {
memb->wm_mat[i] = atof( cp );
cp = nxt_spc( cp );
}
}
/* A R S B L D
*
* This routine builds ARS's.
*/
void
arsabld()
{
register char *cp;
register char *np;
point_t max[3];
point_t min[3];
cp = buf;
record.a.a_id = *cp++;
cp = nxt_spc( cp ); /* skip the space */
record.a.a_type = (char)atoi( cp );
cp = nxt_spc( cp );
np = record.a.a_name;
while( *cp != ' ' ) {
*np++ = *cp++;
}
cp = nxt_spc( cp );
record.a.a_m = (short)atoi( cp );
cp = nxt_spc( cp );
record.a.a_n = (short)atoi( cp );
cp = nxt_spc( cp );
record.a.a_curlen = (short)atoi( cp );
cp = nxt_spc( cp );
record.a.a_totlen = (short)atoi( cp );
cp = nxt_spc( cp );
record.a.a_xmax = atof( cp );
cp = nxt_spc( cp );
record.a.a_xmin = atof( cp );
cp = nxt_spc( cp );
record.a.a_ymax = atof( cp );
cp = nxt_spc( cp );
record.a.a_ymin = atof( cp );
cp = nxt_spc( cp );
record.a.a_zmax = atof( cp );
cp = nxt_spc( cp );
record.a.a_zmin = atof( cp );
/* Write out the record */
(void)fwrite( (char *)&record, sizeof record, 1, stdout );
}
/* A R S B L D
*
* This is the second half of the ARS-building. It builds the ARS B record.
*/
void
arsbbld()
{
register char *cp;
register int i;
point_t pnt[8]; /* need 8 points */
cp = buf;
record.b.b_id = *cp++;
cp = nxt_spc( cp ); /* skip the space */
record.b.b_type = (char)atoi( cp );
cp = nxt_spc( cp );
record.b.b_n = (short)atoi( cp );
cp = nxt_spc( cp );
record.b.b_ngranule = (short)atoi( cp );
for( i = 0; i < 24; i++ ) {
cp = nxt_spc( cp );
record.b.b_values[i] = atof( cp );
}
/* Write out the record */
(void)fwrite( (char *)&record, sizeof record, 1, stdout );
}
/* Z A P _ N L
*
* This routine removes newline characters from the buffer and substitutes
* in NULL.
*/
void
zap_nl()
{
register char *bp;
bp = &buf[0];
while( *bp != '\0' ) {
if( *bp == '\n' )
*bp = '\0';
bp++;
}
}
/* I D E N T B L D
*
* This routine makes an ident record. It calls libwdb to do this.
*/
void
identbld()
{
register char *cp;
register char *np;
char id; /* a freebie */
char units; /* libwdb doesn't take this?! */
char version[6];
char title[72];
cp = buf;
id = *cp++;
cp = nxt_spc( cp ); /* skip the space */
/* Note that there is no provision for handing libwdb the units. Just
* ignore.
*/
units = (char)atoi( cp );
cp = nxt_spc( cp );
/* Note that there is no provision for handing libwdb the version either.
* However, this is automatically provided when needed.
*/
np = version;
while( *cp != '\n' && *cp != '\0' ) {
*np++ = *cp++;
}
*np = '\0';
if( strcmp( version, ID_VERSION ) != 0 ) {
fprintf(stderr, "WARNING: input file version (%s) is not %s\n",
version, ID_VERSION);
}
(void)fgets( buf, BUFSIZE, stdin);
zap_nl();
(void)strncpy( title, buf, sizeof(title)-1 );
mk_id(stdout, title);
}
/* P O L Y H B L D
*
* This routine builds the record headder for a polysolid.
*/
void
polyhbld()
{
/* Headder for polysolid */
register char *cp;
register char *np;
char id;
cp = buf;
id = *cp++;
cp = nxt_spc( cp ); /* skip the space */
np = name;
while( *cp != '\n' && *cp != '\0' ) {
*np++ = *cp++;
}
mk_polysolid(stdout, name);
}
/* P O L Y D B L D
*
* This routine builds a polydata record using libwdb.
*/
void
polydbld()
{
register char *cp;
register int i, j;
char id;
char count; /* number of vertices */
fastf_t verts[5][3]; /* vertices for the polygon */
fastf_t norms[5][3]; /* normals at each vertex */
cp = buf;
id = *cp++;
cp = nxt_spc( cp ); /* skip the space */
count = (char)atoi( cp );
for( i = 0; i < 5; i++ ) {
for( j = 0; j < 3; j++ ) {
cp = nxt_spc( cp );
verts[i][j] = atof( cp );
}
}
for( i = 0; i < 5; i++ ) {
for( j = 0; j < 3; j++ ) {
cp = nxt_spc( cp );
norms[i][j] = atof( cp );
}
}
mk_poly(stdout, count, verts, norms);
}
/* M A T E R B L D
*
* The need for this is being phased out. Leave alone.
*/
void
materbld()
{
register char *cp;
register char *np;
cp = buf;
record.md.md_id = *cp++;
cp = nxt_spc( cp ); /* skip the space */
record.md.md_flags = (char)atoi( cp );
cp = nxt_spc( cp );
record.md.md_low = (short)atoi( cp );
cp = nxt_spc( cp );
record.md.md_hi = (short)atoi( cp );
cp = nxt_spc( cp );
record.md.md_r = (unsigned char)atoi( cp);
cp = nxt_spc( cp );
record.md.md_g = (unsigned char)atoi( cp);
cp = nxt_spc( cp );
record.md.md_b = (unsigned char)atoi( cp);
/* Write out the record */
(void)fwrite( (char *)&record, sizeof record, 1, stdout );
}
/* B S P L B L D
*
* This routine builds B-splines using libwdb.
*/
void
bsplbld()
{
register char *cp;
register char *np;
char id;
short nsurf; /* number of surfaces */
fastf_t resolution; /* resolution of flatness */
cp = buf;
id = *cp++;
cp = nxt_spc( cp ); /* skip the space */
np = name;
while( *cp != ' ' ) {
*np++ = *cp++;
}
*np = '\0';
cp = nxt_spc( cp );
nsurf = (short)atoi( cp );
cp = nxt_spc( cp );
resolution = atof( cp );
mk_bsolid(stdout, name, nsurf, resolution);
}
/* B S U R F B L D
*
* This routine builds d-spline surface descriptions using libwdb.
*/
void
bsurfbld()
{
/* HELP! This involves mk_bsurf(filep, bp) where bp is a ptr to struct */
register char *cp;
register int i;
register float *vp;
int nbytes, count;
float *fp;
cp = buf;
record.d.d_id = *cp++;
cp = nxt_spc( cp ); /* skip the space */
record.d.d_order[0] = (short)atoi( cp );
cp = nxt_spc( cp );
record.d.d_order[1] = (short)atoi( cp );
cp = nxt_spc( cp );
record.d.d_kv_size[0] = (short)atoi( cp );
cp = nxt_spc( cp );
record.d.d_kv_size[1] = (short)atoi( cp );
cp = nxt_spc( cp );
record.d.d_ctl_size[0] = (short)atoi( cp );
cp = nxt_spc( cp );
record.d.d_ctl_size[1] = (short)atoi( cp );
cp = nxt_spc( cp );
record.d.d_geom_type = (short)atoi( cp );
cp = nxt_spc( cp );
record.d.d_nknots = (short)atoi( cp );
cp = nxt_spc( cp );
record.d.d_nctls = (short)atoi( cp );
record.d.d_nknots =
ngran( record.d.d_kv_size[0] + record.d.d_kv_size[1] );
record.d.d_nctls =
ngran( record.d.d_ctl_size[0] * record.d.d_ctl_size[1]
* record.d.d_geom_type);
/* Write out the record */
(void)fwrite( (char *)&record, sizeof record, 1, stdout );
/*
* The b_surf_head record is followed by
* d_nknots granules of knot vectors (first u, then v),
* and then by d_nctls granules of control mesh information.
* Note that neither of these have an ID field!
*
* B-spline surface record, followed by
* d_kv_size[0] floats,
* d_kv_size[1] floats,
* padded to d_nknots granules, followed by
* ctl_size[0]*ctl_size[1]*geom_type floats,
* padded to d_nctls granules.
*
* IMPORTANT NOTE: granule == sizeof(union record)
*/
/* Malloc and clear memory for the KNOT DATA and read it */
nbytes = record.d.d_nknots * sizeof(union record);
if( (vp = (float *)malloc(nbytes)) == (float *)0 ) {
(void)fprintf(stderr, "asc2g: spline knot malloc error\n");
exit(1);
}
fp = vp;
(void)bzero( (char *)vp, nbytes );
/* Read the knot vector information */
count = record.d.d_kv_size[0] + record.d.d_kv_size[1];
for( i = 0; i < count; i++ ) {
fgets( buf, BUFSIZE, stdin );
(void)sscanf( buf, "%f", vp++);
}
/* Write out the information */
(void)fwrite( (char *)fp, nbytes, 1, stdout );
/* Free the knot data memory */
(void)free( (char *)fp );
/* Malloc and clear memory for the CONTROL MESH data and read it */
nbytes = record.d.d_nctls * sizeof(union record);
if( (vp = (float *)malloc(nbytes)) == (float *)0 ) {
(void)fprintf(stderr, "asc2g: control mesh malloc error\n");
exit(1);
}
fp = vp;
(void)bzero( (char *)vp, nbytes );
/* Read the control mesh information */
count = record.d.d_ctl_size[0] * record.d.d_ctl_size[1] *
record.d.d_geom_type;
for( i = 0; i < count; i++ ) {
fgets( buf, BUFSIZE, stdin );
(void)sscanf( buf, "%f", vp++);
}
/* Write out the information */
(void)fwrite( (char *)fp, nbytes, 1, stdout );
/* Free the control mesh memory */
(void)free( (char *)fp );
}
/* P I P E B L D
*
* This routine reads pipe data from standard in, constructs a doublely
* linked list of pipe segments, and sends this list to mk_pipe().
*/
void
pipebld()
{
char name[NAMELEN];
char ident;
char type[TYPELEN];
int ret;
fastf_t id;
fastf_t od;
point_t start;
point_t bendcenter;
register char *cp;
register char *np;
struct wdb_pipeseg *sp;
struct wdb_pipeseg head;
/* Process the first buffer */
cp = buf;
ident = *cp++; /* not used later */
cp = nxt_spc( cp ); /* skip spaces */
np = name;
while( *cp != '\n' ) {
*np++ = *cp++;
}
*np = '\0'; /* null terminate the string */
/* Read data lines and process */
RT_LIST_INIT( &head.l );
do{
fgets( buf, BUFSIZE, stdin);
(void)sscanf( buf, "%s %le %le %le %le %le %le %le %le", type,
&id, &od,
&start[0],
&start[1],
&start[2],
&bendcenter[0],
&bendcenter[1],
&bendcenter[2]);
if( (sp = (struct wdb_pipeseg *)malloc(sizeof(struct wdb_pipeseg) ) )
== WDB_PIPESEG_NULL) {
printf("asc2g: malloc failure for pipe\n");
exit(-1);
}
sp->ps_id = id;
sp->ps_od = od;
VMOVE(sp->ps_start, start);
/* Identify type */
if( (ret = (strcmp( type, "end" ))) == 0) {
sp->ps_type = WDB_PIPESEG_TYPE_END;
} else if( (ret = (strcmp( type, "linear" ))) == 0) {
sp->ps_type = WDB_PIPESEG_TYPE_LINEAR;
} else if( (ret = (strcmp( type, "bend"))) == 0) {
sp->ps_type = WDB_PIPESEG_TYPE_BEND;
VMOVE(sp->ps_bendcenter, bendcenter);
} else {
fprintf(stderr, "asc2g: no pipe type %s\n", type);
}
RT_LIST_INSERT( &head.l, &sp->l);
} while( (ret = (strcmp (type , "end"))) != 0);
mk_pipe(stdout, name, &head);
mk_pipe_free( &head );
free( (char *)sp );
}
/* P A R T I C L E B L D
*
* This routine reads particle data from standard in, and constructs the
* parameters required by mk_particle.
*/
void
particlebld()
{
char name[NAMELEN];
char ident;
char type[TYPELEN];
point_t vertex;
vect_t height;
double vrad;
double hrad;
register char *cp;
register char *np;
/* Read all the information out of the existing buffer. Note that
* particles fit into one granule.
*/
(void)sscanf(buf, "%c %s %le %le %le %le %le %le %le %le",
&ident, name,
&vertex[0],
&vertex[1],
&vertex[2],
&height[0],
&height[1],
&height[2],
&vrad, &hrad);
mk_particle( stdout, name, vertex, height, vrad, hrad);
}
char *
nxt_spc( cp)
register char *cp;
{
while( *cp != ' ' && *cp != '\t' && *cp !='\0' ) {
cp++;
}
if( *cp != '\0' ) {
cp++;
}
return( cp );
}
ngran( nfloat )
{
register int gran;
/* Round up */
gran = nfloat + ((sizeof(union record)-1) / sizeof(float) );
gran = (gran * sizeof(float)) / sizeof(union record);
return(gran);
}
-65
View File
@@ -1,65 +0,0 @@
/*
* A S C 2 P I X . C
*
* Convert ASCII (hex) pixel files to the binary form.
* For portable images.
*
* Author -
* Michael John Muuss
*
* Source -
* SECAD/VLD Computing Consortium, Bldg 394
* The U. S. Army Ballistic Research Laboratory
* Aberdeen Proving Ground, Maryland 21005
*
* Copyright Notice -
* This software is Copyright (C) 1985 by the United States Army.
* All rights reserved.
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
int lmap[256]; /* Map HEX ASCII to binary in left nybble */
int rmap[256]; /* Map HEX ASCII to binary in right nybble */
unsigned char line[256];
main()
{
register unsigned char *cp;
register int i;
/* Init map */
for(i=0; i<10; i++) rmap['0'+i] = i;
for(i=10; i<16; i++) rmap['A'-10+i] = i;
for(i=10; i<16; i++) rmap['a'-10+i] = i;
for(i=0;i<256;i++) lmap[i] = rmap[i]<<4;
for(;;) {
(void)fgets((char *)line, sizeof(line), stdin);
if( feof(stdin) ) break;
cp = line;
/* R */
i = lmap[*cp++];
i |= rmap[*cp++];
putc( i, stdout );
/* G */
i = lmap[*cp++];
i |= rmap[*cp++];
putc( i, stdout );
/* B */
i = lmap[*cp++];
i |= rmap[*cp++];
putc( i, stdout );
/* Ignore rest of line, for now */
}
fflush(stdout);
exit(0);
}
-37
View File
@@ -1,37 +0,0 @@
.TH CONV-VG2G 1 BRL/CAD
.SH NAME
conv-vg2g \- upgrade old to new format binary MGED database
.SH SYNOPSIS
.B conv-vg2g
file.vg file.g
.SH DESCRIPTION
.I Conv-vg2g
converts several older forms of binary
.IR mged (1)
databases to the current form.
.PP
The conversion from version 3 to version 4 (the current version)
is fairly straightforward.
Conversion from older versions requires additional information,
for which the user is prompted. The units of the database must
be specified as:
1=mm, 2=cm, 3=meters, 4=inches, 5=feet.
A title for the database is also requested.
.SH SEE ALSO
brlcad(1), mged(1), libged(3)
.SH DIAGNOSTICS
Error messages are intended to be self-explanatory,
and usually indicate errors in the input database.
It may be possible to rescue a damaged old database
by suitably modifying the source code to the converter.
.SH AUTHOR
Keith A. Applin
.SH SOURCE
SECAD/VLD Computing Consortium, Bldg 394
.br
The U. S. Army Ballistic Research Laboratory
.br
Aberdeen Proving Ground, Maryland 21005
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@BRL.MIL>.
-214
View File
@@ -1,214 +0,0 @@
/*
* C V . C
*
* Converts .vg files to .g (latest style, with idents).
*
* Authors -
* Mike Muuss, BRL, 5/25/84.
* Keith A. Applin
*
* Source -
* SECAD/VLD Computing Consortium, Bldg 394
* The U. S. Army Ballistic Research Laboratory
* Aberdeen Proving Ground, Maryland 21005
*
* Copyright Notice -
* This software is Copyright (C) 1985 by the United States Army.
* All rights reserved.
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#include "machine.h"
#include "db.h"
void mat_pr();
union record rec;
char line[256];
main(argc, argv)
int argc;
char *argv[];
{
static int ifd, ofd;
static int units;
static int count;
static int i;
double factor = 1.0;
if( argc != 3 ) {
printf("Usage: conv-vg2g file.vg file.g\n");
exit(11);
}
if( (ifd = open( argv[1], 0 )) < 0 ) {
perror(argv[1]);
exit(12);
}
if( (ofd = creat(argv[2], 0664)) < 0 ) {
perror(argv[2]);
exit(13);
}
/* check for conversion from version 3 to version 4 */
read(ifd, &rec, sizeof rec);
if(rec.u_id == ID_IDENT) {
/* have an mged type file - check its version */
if( strcmp(rec.i.i_version, ID_VERSION) == 0 ) {
(void)printf("%s: NO conversion necessary\n", argv[1]);
(void)putchar(7);
exit(0);
}
else {
/* convert from version 3 to version 4 */
(void)printf("convert from ver 3 to ver 4\n");
units = ID_IN_UNIT;
rec.i.i_version[0] = '\0';
strcpy(rec.i.i_version, ID_VERSION);
}
}
else {
lseek(ifd, 0L, 0);
/* have an old vged file to convert */
/* units are inportant now because:
* The ged data records will be stored in a constant BASE unit
* of MiliMeters (MM).
* At any time the ged user can change his local units.
* Hence cv must know the original units of the ".vg" file so
* that they can be converted to BASE units.
*/
(void)printf("* * V E R Y I M P O R T A N T N O T I C E * *\n");
(void)printf(" You must KNOW the units of the %s file\n",argv[1]);
(void)printf(" If you don't know, DON'T guess....find out\n");
(void)putchar( 7 );
rec.i.i_id = ID_IDENT;
strcpy( rec.i.i_version, ID_VERSION );
rec.i.i_units = 100;
while( rec.i.i_units < ID_MM_UNIT || rec.i.i_units > ID_FT_UNIT ) {
printf("Units: 1=mm, 2=cm, 3=meters, 4=inches, 5=feet\nUnits? ");
gets( line );
sscanf( line, "%d", &units );
rec.i.i_units = units;
printf("units=%d\n", rec.i.i_units);
}
printf("Title? "); fflush(stdout);
gets( line );
strncpy( rec.i.i_title, line, 71 );
rec.i.i_title[71] = '\0';
printf("Title=%s\n", rec.i.i_title );
}
write( ofd, &rec, sizeof rec );
count = 1;
/* find the units scale factor */
switch( units ) {
case ID_MM_UNIT:
factor = 1.0; /* from MM to MM */
break;
case ID_CM_UNIT:
factor = 10.0; /* from CM to MM */
break;
case ID_M_UNIT:
factor = 1000.0; /* from M to MM */
break;
case ID_IN_UNIT:
factor = 25.4; /* from IN to MM */
break;
case ID_FT_UNIT:
factor = 304.8; /* from FT to MM */
break;
default:
printf("eh?\n");
}
top:
while( read( ifd, &rec, sizeof rec ) == sizeof rec ) {
after_read:
switch( rec.u_id ) {
case ID_IDENT:
printf("Unexpected ID record encountered in input\n");
printf("Title=%s\n", rec.i.i_title );
break;
case ID_FREE:
goto top;
case ID_SOLID:
if( rec.s.s_name[0] == '\0' )
goto top;
for(i=0; i<24; i++)
rec.s.s_values[i] *= factor;
break;
case ID_COMB:
if( rec.c.c_name[0] == '\0' ) {
/* This is an old-style flag for a deleted combination */
/* Skip any folowing member records */
do {
(void)read( ifd, &rec, sizeof(rec) );
} while( rec.u_id == ID_MEMB );
goto after_read;
}
break;
case ID_ARS_B:
for(i=0; i<24; i++)
rec.b.b_values[i] *= factor;
break;
case ID_ARS_A:
if( rec.a.a_name[0] == '\0' ) {
/* Skip deleted junk */
lseek( ifd, (long)(rec.a.a_totlen) *
(long)(sizeof rec), 1 );
goto top;
}
rec.a.a_xmin *= factor;
rec.a.a_xmax *= factor;
rec.a.a_ymin *= factor;
rec.a.a_ymax *= factor;
rec.a.a_zmin *= factor;
rec.a.a_zmax *= factor;
break;
case ID_P_HEAD:
case ID_P_DATA:
break;
default:
printf("Garbage record in database\n");
exit(42);
case ID_MEMB:
/* flip translation to other side */
#define m rec.M.m_mat
m[3] *= factor;
m[7] *= factor;
m[11] *= factor;
break;
}
write( ofd, &rec, sizeof(rec) );
count++;
}
printf("%d database granules written\n", count);
}
void
mat_pr( title, mp )
char *title;
float *mp;
{
register int i;
printf("MATRIX %s:\n ", title);
for(i=0; i<16; i++) {
printf(" %8.3f", mp[i]);
if( (i&3) == 3 ) printf("\n ");
}
}
-57
View File
@@ -1,57 +0,0 @@
.TH G2ASC 1 BRL/CAD
.SH NAME
g2asc,
asc2g \- convert between binary and ASCII MGED databases.
.SH SYNOPSIS
.B g2asc
< file.g > file.asc
.br
.B asc2g
< file.asc > file.g
.SH DESCRIPTION
The local machine binary representation
of an
.IR mged (1)
database is inherently non-portable.
.I G2asc
and
.I asc2g
are simple filters which convert between
the binary form and a portable ASCII representation.
Any warning messages are written to standard error.
.PP
.I G2asc
and
.I asc2g
are typically used to convert binary
.IR mged (1)
files to a portable ASCII format so the files can be transferred
to another machine. On the local machine, files are converted to ASCII using
.IR g2asc (1),
then transferred to the remote machine. On the remote machine, the files
are then converted back to the binary representation for that machine using
.IR asc2g (1).
.SH EXAMPLE
.I
g2asc < file.g > file.asc
.br
rcp file.asc remote:file.asc
.br
rsh remote "asc2g < file.asc > file.g"
.SH DIAGNOSTICS
The diagnostics are intended to be self-explanatory.
.SH SEE ALSO
brlcad(1), mged(1)
.SH AUTHOR
Charles Michael Kennedy
.br
Michael John Muuss
.SH SOURCE
SECAD/VLD Computing Consortium, Bldg 394
.br
The U. S. Army Ballistic Research Laboratory
.br
Aberdeen Proving Ground, Maryland 21005
.SH BUG REPORTS
Reports of bugs or problems should be submitted via electronic
mail to <CAD@BRL.MIL>.
-770
View File
@@ -1,770 +0,0 @@
/*
* G 2 A S C . C
*
* This program generates an ASCII data file which contains
* a GED database.
*
* Usage: g2asc < file.g > file.asc
*
* Author -
* Charles M Kennedy
* Michael J Muuss
* Susanne Muuss, J.D.
*
* Source -
* SECAD/VLD Computing Consortium, Bldg 394
* The U. S. Army Ballistic Research Laboratory
* Aberdeen Proving Ground, Maryland 21005
*
* Copyright Notice -
* This software is Copyright (C) 1985 by the United States Army.
* All rights reserved.
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
#include <ctype.h>
#include "machine.h"
#include "vmath.h"
#include "db.h"
#include "wdb.h"
#include "rtlist.h"
#include "raytrace.h"
#include "externs.h"
#define RT_PARTICLE_TYPE_SPHERE 1
#define RT_PARTICLE_TYPE_CYLINDER 2
#define RT_PARTICLE_TYPE_CONE 3
struct pipe_internal {
int pipe_count;
struct wdb_pipeseg pipe_segs;
};
struct part_internal {
point_t part_V;
vect_t part_H;
fastf_t part_vrad;
fastf_t part_hrad;
int part_type;
};
mat_t id_mat = {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0}; /* identity matrix for pipes */
char *name();
char *strchop();
#define CH(x) strchop(x,sizeof(x))
void combdump();
void idendump(), polyhead(), polydata();
void soldump();
void membdump(), arsadump(), arsbdump();
void materdump(), bspldump(), bsurfdump();
void pipe_dump(), particle_dump(), dump_pipe_segs();
union record record; /* GED database record */
main(argc, argv)
char **argv;
{
/* Read database file */
while( fread( (char *)&record, sizeof record, 1, stdin ) == 1 &&
!feof(stdin) ) {
if( argc > 1 )
(void)fprintf(stderr,"0%o (%c)\n", record.u_id, record.u_id);
/* Check record type and skip deleted records */
switch( record.u_id ) {
case ID_FREE:
continue;
case ID_SOLID:
soldump();
continue;
case ID_COMB:
combdump();
continue;
case ID_MEMB:
/* Just convert them as they are found. Assume DB is good */
membdump();
continue;
case ID_ARS_A:
arsadump();
continue;
case ID_P_HEAD:
polyhead();
continue;
case ID_P_DATA:
polydata();
continue;
case ID_IDENT:
idendump();
continue;
case ID_MATERIAL:
materdump();
continue;
case DBID_PIPE:
pipe_dump();
continue;
case DBID_PARTICLE:
particle_dump();
continue;
case ID_BSOLID:
bspldump();
continue;
case ID_BSURF:
bsurfdump();
continue;
default:
(void)fprintf(stderr,
"g2asc: unable to convert record type '%c' (0%o), skipping\n",
record.u_id, record.u_id);
continue;
}
}
exit(0);
}
void
idendump() /* Print out Ident record information */
{
(void)printf( "%c %d %.6s\n",
record.i.i_id, /* I */
record.i.i_units, /* units */
CH(record.i.i_version) /* version */
);
(void)printf( "%.72s\n",
CH(record.i.i_title) /* title or description */
);
/* Print a warning message on stderr if versions differ */
if( strcmp( record.i.i_version, ID_VERSION ) != 0 ) {
(void)fprintf(stderr,
"g2asc: File is version (%s), Program is version (%s)\n",
record.i.i_version, ID_VERSION );
}
}
void
polyhead() /* Print out Polyhead record information */
{
(void)printf("%c ", record.p.p_id ); /* P */
(void)printf("%.16s", name(record.p.p_name) ); /* unique name */
(void)printf("\n"); /* Terminate w/ a newline */
}
void
polydata() /* Print out Polydata record information */
{
register int i, j;
(void)printf("%c ", record.q.q_id ); /* Q */
(void)printf("%d ", record.q.q_count ); /* # of vertices <= 5 */
for( i = 0; i < 5; i++ ) { /* [5][3] vertices */
for( j = 0; j < 3; j++ ) {
(void)printf("%.12e ", record.q.q_verts[i][j] );
}
}
for( i = 0; i < 5; i++ ) { /* [5][3] normals */
for( j = 0; j < 3; j++ ) {
(void)printf("%.12e ", record.q.q_norms[i][j] );
}
}
(void)printf("\n"); /* Terminate w/ a newline */
}
void
soldump() /* Print out Solid record information */
{
register int i;
(void)printf("%c ", record.s.s_id ); /* S */
(void)printf("%d ", record.s.s_type ); /* GED primitive type */
(void)printf("%.16s ", name(record.s.s_name) ); /* unique name */
(void)printf("%d ", record.s.s_cgtype );/* COMGEOM solid type */
for( i = 0; i < 24; i++ )
(void)printf("%.12e ", record.s.s_values[i] ); /* parameters */
(void)printf("\n"); /* Terminate w/ a newline */
}
void
pipe_dump() /* Print out Pipe record information */
{
int ngranules; /* number of granules, total */
int count;
int ret;
char *name;
char id;
union record *rp; /* pointer to an array of granules */
struct pipe_internal pipe; /* want a struct for the head, not a ptr. */
struct wdb_pipeseg head; /* actual head, not a ptr. */
ngranules = record.pw.pw_count;
name = record.pw.pw_name;
id = record.pw.pw_id;
/* malloc enough space for ngranules */
if( (rp = (union record *)malloc(ngranules * sizeof(union record)) ) == 0) {
fprintf(stderr, "g2asc: malloc failure\n");
exit(-1);
}
/* copy the freebee record into the array */
bcopy( (char *)&record, (char *)rp, sizeof(union record) );
/* copy ngranules-1 more records into the array */
if( (count = fread( (char *)&rp[1], sizeof(union record), ngranules - 1, stdin) ) != ngranules - 1) {
fprintf(stderr, "g2asc: pipe read failure\n");
exit(-1);
}
/* Send this off to rt_pipe_import() for conversion into machine
* dependent format and making of a doubly linked list. rt_pipe_internal()
* fills in the "pipe_internal" structure.
*/
if( (ret = (rt_pipe_import(&pipe, rp, id_mat) ) !=0 ) ) {
fprintf(stderr, "g2asc: pipe_import failure\n" );
exit(-1);
}
/* send the doubly linked list off to dump_pipe_segs(), which
* will print all the information.
*/
dump_pipe_segs(id, name, &pipe.pipe_segs);
mk_pipe_free( &pipe.pipe_segs ); /* give back memory */
free( (char *)rp );
}
void
dump_pipe_segs(id, name, headp)
char id;
char *name;
struct wdb_pipeseg *headp;
{
struct wdb_pipeseg *sp;
printf("%c %.16s\n", id, name);
/* print parameters for each segment: one segment per line */
for( RT_LIST( sp, wdb_pipeseg, &(headp->l) ) ) {
switch(sp->ps_type) {
case WDB_PIPESEG_TYPE_END:
printf("end %e %e %e %e %e\n",
sp->ps_id, sp->ps_od,
sp->ps_start[X],
sp->ps_start[Y],
sp->ps_start[Z] );
break;
case WDB_PIPESEG_TYPE_LINEAR:
printf("linear %e %e %e %e %e\n",
sp->ps_id, sp->ps_od,
sp->ps_start[X],
sp->ps_start[Y],
sp->ps_start[Z] );
break;
case WDB_PIPESEG_TYPE_BEND:
printf("bend %e %e %e %e %e %e %e %e\n",
sp->ps_id, sp->ps_od,
sp->ps_start[X],
sp->ps_start[Y],
sp->ps_start[Z],
sp->ps_bendcenter[X],
sp->ps_bendcenter[Y],
sp->ps_bendcenter[Z]);
break;
default:
fprintf(stderr, "g2asc: unknown pipe type %d\n",
sp->ps_type);
break;
}
}
}
void
particle_dump() /* Print out Particle record information */
{
/* Note that particles fit into one granule only. */
int ret;
char *type;
struct part_internal part; /* head for the structure */
if( (ret = (rt_part_import(&part, &record, id_mat)) ) != 0) {
fprintf(stderr, "g2asc: particle import failure\n");
exit(-1);
}
/* Particle type is picked up on here merely to ensure receiving
* valid data. The type is not used any further.
*/
switch( part.part_type ) {
case RT_PARTICLE_TYPE_SPHERE:
type = "sphere";
break;
case RT_PARTICLE_TYPE_CYLINDER:
type = "cylinder";
break;
case RT_PARTICLE_TYPE_CONE:
type = "cone";
break;
default:
fprintf(stderr, "g2asc: no particle type %s\n", type);
exit(-1);
}
printf("%c %.16s %e %e %e %e %e %e %e %e\n",
record.part.p_id, record.part.p_name,
part.part_V[X],
part.part_V[Y],
part.part_V[Z],
part.part_H[X],
part.part_H[Y],
part.part_H[Z],
part.part_vrad, part.part_hrad);
}
/*
* C O M B D U M P
*
*/
void
combdump() /* Print out Combination record information */
{
register int i;
register int length; /* Keep track of number of members */
int m1, m2; /* material property flags */
(void)printf("%c ", record.c.c_id ); /* C */
if( record.c.c_flags == 'R' ) /* set region flag */
(void)printf("Y "); /* Y if `R' */
else
(void)printf("N "); /* N if ` ' */
(void)printf("%.16s ", name(record.c.c_name) ); /* unique name */
(void)printf("%d ", record.c.c_regionid ); /* region ID code */
(void)printf("%d ", record.c.c_aircode ); /* air space code */
#if 1
(void)printf("%d ", 0 ); /* DEPRECATED: # of members */
(void)printf("%d ", 0 ); /* DEPRECATED: COMGEOM region # */
#else
(void)printf("%d ", record.c.c_length ); /* DEPRECATED: # of members */
(void)printf("%d ", record.c.c_num ); /* DEPRECATED: COMGEOM region # */
#endif
(void)printf("%d ", record.c.c_material ); /* material code */
(void)printf("%d ", record.c.c_los ); /* equiv. LOS est. */
(void)printf("%d %d %d %d ",
record.c.c_override ? 1 : 0,
record.c.c_rgb[0],
record.c.c_rgb[1],
record.c.c_rgb[2] );
m1 = m2 = 0;
if( isascii(record.c.c_matname[0]) && isprint(record.c.c_matname[0]) ) {
m1 = 1;
if( record.c.c_matparm[0] )
m2 = 1;
}
printf("%d %d ", m1, m2 );
switch( record.c.c_inherit ) {
case DB_INH_HIGHER:
printf("%d ", DB_INH_HIGHER );
break;
default:
case DB_INH_LOWER:
printf("%d ", DB_INH_LOWER );
break;
}
(void)printf("\n"); /* Terminate w/ a newline */
if( m1 )
(void)printf("%.32s\n", CH(record.c.c_matname) );
if( m2 )
(void)printf("%.60s\n", CH(record.c.c_matparm) );
}
void
membdump() /* Print out Member record information */
{
register int i;
(void)printf("%c ", record.M.m_id ); /* M */
(void)printf("%c ", record.M.m_relation ); /* Boolean oper. */
(void)printf("%.16s ", name(record.M.m_instname) ); /* referred-to obj. */
for( i = 0; i < 16; i++ ) /* homogeneous transform matrix */
(void)printf("%.12e ", record.M.m_mat[i] );
(void)printf("%d ", 0 ); /* was COMGEOM solid # */
(void)printf("\n"); /* Terminate w/ nl */
}
void
arsadump() /* Print out ARS record information */
{
register int i;
register int length; /* Keep track of number of ARS B records */
(void)printf("%c ", record.a.a_id ); /* A */
(void)printf("%d ", record.a.a_type ); /* primitive type */
(void)printf("%.16s ", name(record.a.a_name) ); /* unique name */
(void)printf("%d ", record.a.a_m ); /* # of curves */
(void)printf("%d ", record.a.a_n ); /* # of points per curve */
(void)printf("%d ", record.a.a_curlen );/* # of granules per curve */
(void)printf("%d ", record.a.a_totlen );/* # of granules for ARS */
(void)printf("%.12e ", record.a.a_xmax ); /* max x coordinate */
(void)printf("%.12e ", record.a.a_xmin ); /* min x coordinate */
(void)printf("%.12e ", record.a.a_ymax ); /* max y coordinate */
(void)printf("%.12e ", record.a.a_ymin ); /* min y coordinate */
(void)printf("%.12e ", record.a.a_zmax ); /* max z coordinate */
(void)printf("%.12e ", record.a.a_zmin ); /* min z coordinate */
(void)printf("\n"); /* Terminate w/ a newline */
length = (int)record.a.a_totlen; /* Get # of ARS B records */
for( i = 0; i < length; i++ ) {
arsbdump();
}
}
void
arsbdump() /* Print out ARS B record information */
{
register int i;
/* Read in a member record for processing */
(void)fread( (char *)&record, sizeof record, 1, stdin );
(void)printf("%c ", record.b.b_id ); /* B */
(void)printf("%d ", record.b.b_type ); /* primitive type */
(void)printf("%d ", record.b.b_n ); /* current curve # */
(void)printf("%d ", record.b.b_ngranule ); /* current granule */
for( i = 0; i < 24; i++ ) { /* [8*3] vectors */
(void)printf("%.12e ", record.b.b_values[i] );
}
(void)printf("\n"); /* Terminate w/ a newline */
}
void
materdump() /* Print out material description record information */
{
(void)printf( "%c %d %d %d %d %d %d\n",
record.md.md_id, /* m */
record.md.md_flags, /* UNUSED */
record.md.md_low, /* low end of region IDs affected */
record.md.md_hi, /* high end of region IDs affected */
record.md.md_r,
record.md.md_g, /* color of regions: 0..255 */
record.md.md_b );
}
void
bspldump() /* Print out B-spline solid description record information */
{
(void)printf( "%c %.16s %d %.12e\n",
record.B.B_id, /* b */
name(record.B.B_name), /* unique name */
record.B.B_nsurf, /* # of surfaces in this solid */
record.B.B_resolution ); /* resolution of flatness */
}
void
bsurfdump() /* Print d-spline surface description record information */
{
register int i;
register float *vp;
int nbytes, count;
float *fp;
(void)printf( "%c %d %d %d %d %d %d %d %d %d\n",
record.d.d_id, /* D */
record.d.d_order[0], /* order of u and v directions */
record.d.d_order[1], /* order of u and v directions */
record.d.d_kv_size[0], /* knot vector size (u and v) */
record.d.d_kv_size[1], /* knot vector size (u and v) */
record.d.d_ctl_size[0], /* control mesh size (u and v) */
record.d.d_ctl_size[1], /* control mesh size (u and v) */
record.d.d_geom_type, /* geom type 3 or 4 */
record.d.d_nknots, /* # granules of knots */
record.d.d_nctls ); /* # granules of ctls */
/*
* The b_surf_head record is followed by
* d_nknots granules of knot vectors (first u, then v),
* and then by d_nctls granules of control mesh information.
* Note that neither of these have an ID field!
*
* B-spline surface record, followed by
* d_kv_size[0] floats,
* d_kv_size[1] floats,
* padded to d_nknots granules, followed by
* ctl_size[0]*ctl_size[1]*geom_type floats,
* padded to d_nctls granules.
*
* IMPORTANT NOTE: granule == sizeof(union record)
*/
/* Malloc and clear memory for the KNOT DATA and read it */
nbytes = record.d.d_nknots * sizeof(union record);
if( (vp = (float *)malloc(nbytes)) == (float *)0 ) {
(void)fprintf(stderr, "g2asc: spline knot malloc error\n");
exit(1);
}
fp = vp;
(void)bzero( (char *)fp, nbytes );
count = fread( (char *)fp, 1, nbytes, stdin );
if( count != nbytes ) {
(void)fprintf(stderr, "g2asc: spline knot read failure\n");
exit(1);
}
/* Print the knot vector information */
count = record.d.d_kv_size[0] + record.d.d_kv_size[1];
for( i = 0; i < count; i++ ) {
(void)printf("%.12e\n", *vp++);
}
/* Free the knot data memory */
(void)free( (char *)fp );
/* Malloc and clear memory for the CONTROL MESH data and read it */
nbytes = record.d.d_nctls * sizeof(union record);
if( (vp = (float *)malloc(nbytes)) == (float *)0 ) {
(void)fprintf(stderr, "g2asc: control mesh malloc error\n");
exit(1);
}
fp = vp;
(void)bzero( (char *)fp, nbytes );
count = fread( (char *)fp, 1, nbytes, stdin );
if( count != nbytes ) {
(void)fprintf(stderr, "g2asc: control mesh read failure\n");
exit(1);
}
/* Print the control mesh information */
count = record.d.d_ctl_size[0] * record.d.d_ctl_size[1] *
record.d.d_geom_type;
for( i = 0; i < count; i++ ) {
(void)printf("%.12e\n", *vp++);
}
/* Free the control mesh memory */
(void)free( (char *)fp );
}
/*
* N A M E
*
* Take a database name and null-terminate it,
* converting unprintable characters to something printable.
* Here we deal with NAMESIZE long names not being null-terminated.
*/
char *name( str )
char *str;
{
static char buf[NAMESIZE+2];
register char *ip = str;
register char *op = buf;
register int warn = 0;
while( op < &buf[NAMESIZE] ) {
if( *ip == '\0' ) break;
if( isascii(*ip) && isprint(*ip) && !isspace(*ip) ) {
*op++ = *ip++;
} else {
*op++ = '@';
ip++;
warn = 1;
}
}
*op = '\0';
if(warn) {
(void)fprintf(stderr,
"g2asc: Illegal char in object name, converted to '%s'\n",
buf );
}
if( op == buf ) {
/* Null input name */
(void)fprintf(stderr,
"g2asc: NULL object name converted to -=NULL=-\n");
return("-=NULL=-");
}
return(buf);
}
/*
* S T R C H O P
*
* Take a string and a length, and null terminate,
* converting unprintable characters to something printable.
*/
char *strchop( str, len )
char *str;
{
static char buf[1024];
register char *ip = str;
register char *op = buf;
register int warn = 0;
char *ep;
if( len > sizeof(buf)-2 ) len=sizeof(buf)-2;
ep = &buf[len-1]; /* Leave room for null */
while( op < ep ) {
if( *ip == '\0' ) break;
if( isascii(*ip) && (isprint(*ip) || isspace(*ip)) ) {
*op++ = *ip++;
} else {
*op++ = '@';
ip++;
warn = 1;
}
}
*op = '\0';
if(warn) {
(void)fprintf(stderr,
"g2asc: Illegal char in string, converted to '%s'\n",
buf );
}
if( op == buf ) {
/* Null input name */
(void)fprintf(stderr,
"g2asc: NULL string converted to -=STRING=-\n");
return("-=STRING=-");
}
return(buf);
}
/*** XXX temporary copy, until formal import library exists ***/
/*
* R T _ P I P E _ I M P O R T
*/
int
rt_pipe_import( pipe, rp, mat )
struct pipe_internal *pipe;
union record *rp;
register mat_t mat;
{
register struct exported_pipeseg *ep;
register struct wdb_pipeseg *psp;
struct wdb_pipeseg tmp;
/* Check record type */
if( rp->u_id != DBID_PIPE ) {
fprintf(stderr,"rt_pipe_import: defective record\n");
return(-1);
}
/* Count number of segments */
pipe->pipe_count = 0;
for( ep = &rp->pw.pw_data[0]; ; ep++ ) {
pipe->pipe_count++;
switch( (int)(ep->eps_type[0]) ) {
case WDB_PIPESEG_TYPE_END:
goto done;
case WDB_PIPESEG_TYPE_LINEAR:
case WDB_PIPESEG_TYPE_BEND:
break;
default:
return(-2); /* unknown segment type */
}
}
done: ;
if( pipe->pipe_count <= 1 )
return(-3); /* Not enough for 1 pipe! */
/*
* Walk the array of segments in reverse order,
* allocating a linked list of segments in internal format,
* using exactly the same structures as libwdb.
*/
RT_LIST_INIT( &pipe->pipe_segs.l );
for( ep = &rp->pw.pw_data[pipe->pipe_count-1]; ep >= &rp->pw.pw_data[0]; ep-- ) {
tmp.ps_type = (int)ep->eps_type[0];
ntohd( tmp.ps_start, ep->eps_start, 3 );
ntohd( &tmp.ps_id, ep->eps_id, 1 );
ntohd( &tmp.ps_od, ep->eps_od, 1 );
/* Apply modeling transformations */
psp = (struct wdb_pipeseg *)calloc( 1, sizeof(struct wdb_pipeseg) );
psp->ps_type = tmp.ps_type;
MAT4X3PNT( psp->ps_start, mat, tmp.ps_start );
if( psp->ps_type == WDB_PIPESEG_TYPE_BEND ) {
ntohd( tmp.ps_bendcenter, ep->eps_bendcenter, 3 );
MAT4X3PNT( psp->ps_bendcenter, mat, tmp.ps_bendcenter );
} else {
VSETALL( psp->ps_bendcenter, 0 );
}
psp->ps_id = tmp.ps_id / mat[15];
psp->ps_od = tmp.ps_od / mat[15];
RT_LIST_APPEND( &pipe->pipe_segs.l, &psp->l );
}
return(0); /* OK */
}
/* R T _ P A R T_ I M P O R T
*
*/
int
rt_part_import( part, rp, mat )
struct part_internal *part;
union record *rp;
register mat_t mat;
{
point_t v;
vect_t h;
double vrad;
double hrad;
fastf_t maxrad, minrad;
/* Check record type */
if( rp->u_id != DBID_PARTICLE ) {
fprintf(stderr,"rt_part_import: defective record\n");
return(-1);
}
/* Convert from database to internal format */
ntohd( v, rp->part.p_v, 3 );
ntohd( h, rp->part.p_h, 3 );
ntohd( &vrad, rp->part.p_vrad, 1 );
ntohd( &hrad, rp->part.p_hrad, 1 );
/* Apply modeling transformations */
MAT4X3PNT( part->part_V, mat, v );
MAT4X3PNT( part->part_H, mat, h );
if( (part->part_vrad = vrad / mat[15]) < 0 )
return(-2);
if( (part->part_hrad = hrad / mat[15]) < 0 )
return(-2);
if( part->part_vrad > part->part_hrad ) {
maxrad = part->part_vrad;
minrad = part->part_hrad;
} else {
maxrad = part->part_hrad;
minrad = part->part_vrad;
}
if( maxrad <= 0 )
return(-4);
if( MAGSQ( part->part_H ) * 1000000 < maxrad * maxrad) {
/* Height vector is insignificant, particle is a sphere */
part->part_vrad = part->part_hrad = maxrad;
VSETALL( part->part_H, 0 ); /* sanity */
part->part_type = RT_PARTICLE_TYPE_SPHERE;
return(0); /* OK */
}
if( (maxrad - minrad) / maxrad < 0.001 ) {
/* radii are nearly equal, particle is a cylinder (lozenge) */
part->part_vrad = part->part_hrad = maxrad;
part->part_type = RT_PARTICLE_TYPE_CYLINDER;
return(0); /* OK */
}
part->part_type = RT_PARTICLE_TYPE_CONE;
return(0); /* OK */
}
-64
View File
@@ -1,64 +0,0 @@
.TH PIX2ASC 1 BRL/CAD
.SH NAME
pix2asc,
asc2pix \- encode and decode color pixel files
.SH SYNOPSIS
.B pix2asc
< file.pix > file.a_pix
.br
.B asc2pix
< file.a_pix > file.pix
.SH DESCRIPTION
.I Pix2asc
and
.I asc2pix
are simple filters which convert color
.IR pix (5)
files from their binary form to a portable ASCII form, and back.
.I Pix2asc
reads the binary file on standard in and writes ASCII on standard out.
.I Asc2pix
does the reverse.
.PP
The binary file consists of a sequence
of three-tuples of
.B unsigned chars
representing the
red, green, and blue intensities for each pixel.
The ASCII version of the file has
one RGB pixel per newline-terminated line, with each
pixel represented as six hexadecimal digits.
.PP
When moving
.IR pix (5)
files between UNIX systems
via tape (see
.IR tar (1)
and
.IR cpio (1))
or via network (see
.IR rcp (1)
and
.IR ftp (1)),
this conversion to ASCII is unnecessary,
as all UNIX files are byte streams, regardless of the underlying hardware.
However, when transporting images to non-UNIX machines,
these tools are invaluable.
Note that
.IR rt (1)
can directly generate the ASCII form of an image file using the
.B \-O
flag, allowing it to be easily used on non-UNIX systems.
.SH SEE ALSO
brlcad(1), pix(5)
.SH AUTHOR
Michael John Muuss
.SH SOURCE
SECAD/VLD Computing Consortium, Bldg 394
.br
The U. S. Army Ballistic Research Laboratory
.br
Aberdeen Proving Ground, Maryland 21005
.SH "BUG REPORTS"
Reports of bugs or problems should be submitted via electronic
mail to <CAD@BRL.MIL>.
-39
View File
@@ -1,39 +0,0 @@
/*
* P I X 2 A S C . C
*
* Author -
* Michael John Muuss
*
* Source -
* SECAD/VLD Computing Consortium, Bldg 394
* The U. S. Army Ballistic Research Laboratory
* Aberdeen Proving Ground, Maryland 21005
*
* Copyright Notice -
* This software is Copyright (C) 1985 by the United States Army.
* All rights reserved.
*/
#ifndef lint
static char RCSid[] = "@(#)$Header$ (BRL)";
#endif
#include <stdio.h>
unsigned char pix[3]; /* RGB of one pixel */
char map[18] = "0123456789ABCDEFx";
main()
{
while( !feof(stdin) &&
fread( (char *)pix, sizeof(pix), 1, stdin) == 1 ) {
putc( map[pix[0]>>4], stdout );
putc( map[pix[0]&0xF], stdout );
putc( map[pix[1]>>4], stdout );
putc( map[pix[1]&0xF], stdout );
putc( map[pix[2]>>4], stdout );
putc( map[pix[2]&0xF], stdout );
putc( '\n', stdout );
}
exit(0);
}

Some files were not shown because too many files have changed in this diff Show More