mirror of
https://github.com/sheumann/dmake.git
synced 2025-04-09 14:39:25 +00:00
GNO dmake 1.0.0 sources, converted to LF line endings.
This commit is contained in:
commit
48f940a1d9
248
dmake/LICENSE
Normal file
248
dmake/LICENSE
Normal file
@ -0,0 +1,248 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 1, February 1989
|
||||
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The license agreements of most software companies try to keep users
|
||||
at the mercy of those companies. By contrast, our General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. The
|
||||
General Public License applies to the Free Software Foundation's
|
||||
software and to any other program whose authors commit to using it.
|
||||
You can use it for your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Specifically, the General Public License is designed to make
|
||||
sure that you have the freedom to give away or sell copies of free
|
||||
software, that you receive source code or can get it if you want it,
|
||||
that you can change the software or use pieces of it in new free
|
||||
programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of a such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must tell them their rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any program or other work which
|
||||
contains a notice placed by the copyright holder saying it may be
|
||||
distributed under the terms of this General Public License. The
|
||||
"Program", below, refers to any such program or work, and a "work based
|
||||
on the Program" means either the Program or any work containing the
|
||||
Program or a portion of it, either verbatim or with modifications. Each
|
||||
licensee is addressed as "you".
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's source
|
||||
code as you receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice and
|
||||
disclaimer of warranty; keep intact all the notices that refer to this
|
||||
General Public License and to the absence of any warranty; and give any
|
||||
other recipients of the Program a copy of this General Public License
|
||||
along with the Program. You may charge a fee for the physical act of
|
||||
transferring a copy.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion of
|
||||
it, and copy and distribute such modifications under the terms of Paragraph
|
||||
1 above, provided that you also do the following:
|
||||
|
||||
a) cause the modified files to carry prominent notices stating that
|
||||
you changed the files and the date of any change; and
|
||||
|
||||
b) cause the whole of any work that you distribute or publish, that
|
||||
in whole or in part contains the Program or any part thereof, either
|
||||
with or without modifications, to be licensed at no charge to all
|
||||
third parties under the terms of this General Public License (except
|
||||
that you may choose to grant warranty protection to some or all
|
||||
third parties, at your option).
|
||||
|
||||
c) If the modified program normally reads commands interactively when
|
||||
run, you must cause it, when started running for such interactive use
|
||||
in the simplest and most usual way, to print or display an
|
||||
announcement including an appropriate copyright notice and a notice
|
||||
that there is no warranty (or else, saying that you provide a
|
||||
warranty) and that users may redistribute the program under these
|
||||
conditions, and telling the user how to view a copy of this General
|
||||
Public License.
|
||||
|
||||
d) You may charge a fee for the physical act of transferring a
|
||||
copy, and you may at your option offer warranty protection in
|
||||
exchange for a fee.
|
||||
|
||||
Mere aggregation of another independent work with the Program (or its
|
||||
derivative) on a volume of a storage or distribution medium does not bring
|
||||
the other work under the scope of these terms.
|
||||
|
||||
3. You may copy and distribute the Program (or a portion or derivative of
|
||||
it, under Paragraph 2) in object code or executable form under the terms of
|
||||
Paragraphs 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of
|
||||
Paragraphs 1 and 2 above; or,
|
||||
|
||||
b) accompany it with a written offer, valid for at least three
|
||||
years, to give any third party free (except for a nominal charge
|
||||
for the cost of distribution) a complete machine-readable copy of the
|
||||
corresponding source code, to be distributed under the terms of
|
||||
Paragraphs 1 and 2 above; or,
|
||||
|
||||
c) accompany it with the information you received as to where the
|
||||
corresponding source code may be obtained. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form alone.)
|
||||
|
||||
Source code for a work means the preferred form of the work for making
|
||||
modifications to it. For an executable file, complete source code means
|
||||
all the source code for all modules it contains; but, as a special
|
||||
exception, it need not include source code for modules which are standard
|
||||
libraries that accompany the operating system on which the executable
|
||||
file runs, or for standard header files or definitions files that
|
||||
accompany that operating system.
|
||||
|
||||
4. You may not copy, modify, sublicense, distribute or transfer the
|
||||
Program except as expressly provided under this General Public License.
|
||||
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
|
||||
the Program is void, and will automatically terminate your rights to use
|
||||
the Program under this License. However, parties who have received
|
||||
copies, or rights to use copies, from you under this General Public
|
||||
License will not have their licenses terminated so long as such parties
|
||||
remain in full compliance.
|
||||
|
||||
5. By copying, distributing or modifying the Program (or any work based
|
||||
on the Program) you indicate your acceptance of this license to do so,
|
||||
and all its terms and conditions.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the original
|
||||
licensor to copy, distribute or modify the Program subject to these
|
||||
terms and conditions. You may not impose any further restrictions on the
|
||||
recipients' exercise of the rights granted herein.
|
||||
|
||||
7. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of the license which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
the license, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
8. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to humanity, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these
|
||||
terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest to
|
||||
attach them to the start of each source file to most effectively convey
|
||||
the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19xx name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the
|
||||
appropriate parts of the General Public License. Of course, the
|
||||
commands you use may be called something other than `show w' and `show
|
||||
c'; they could even be mouse-clicks or menu items--whatever suits your
|
||||
program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
program `Gnomovision' (a program to direct compilers to make passes
|
||||
at assemblers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
219
dmake/_install
Normal file
219
dmake/_install
Normal file
@ -0,0 +1,219 @@
|
||||
INSTALLATION INSTRUCTIONS
|
||||
|
||||
This file contains the instructions required to install and create the
|
||||
appropriate version of dmake.
|
||||
|
||||
NOTE: If you use dmake to bootstrap a NEW DISTRIBUTED version or to remake
|
||||
it after applying a PATCH, it may be NECESSARY to use the batch
|
||||
script instead of dmake as a patch may incorporate changes to the
|
||||
makefile.mk file and associated config.mk files that cannot be
|
||||
handled by earlier versions of dmake. The use of the batch files
|
||||
is the ONLY supported method of making a new release or update
|
||||
version.
|
||||
|
||||
NOTE: If you do not plan to use the MAKESTARTUP variable in your
|
||||
environment, change the value of the variable in the file
|
||||
"./unix/startup.h" BEFORE you bootstrap this package.
|
||||
|
||||
NOTE: NAME_MAX is used in sysintf.c to limit the name of a file name
|
||||
component before performing a stat operation. If you have problems
|
||||
with file name lengths make certain that NAME_MAX is correctly set.
|
||||
|
||||
NAME_MAX is set either in limits.h or in unistd.h (for POSIX systems)
|
||||
or in stdio.h. If it is not set anywhere then dmake's own "posix.h"
|
||||
file will define a reasonable default value, this may or may not be
|
||||
reasonable for your system. If you have trouble with long file names
|
||||
then hunt down the NAME_MAX definition.
|
||||
|
||||
NOTE: This file should really be rewritten :-)
|
||||
|
||||
|
||||
|
||||
MAKING THE PROPER VERSION
|
||||
|
||||
The list of available versions of dmake has grown quite large. The best
|
||||
method to determine what versions are available for your configuration is to
|
||||
simply issue the command 'make' in the source root directory. Below is a
|
||||
partial list of the available versions to give an idea of what is supported.
|
||||
Note that this copy of the list is not maintained up to date.
|
||||
|
||||
bsd43 - Generic BSD 4.3 (eg, true BSD, apollo, Sun OS4, SGI etc)
|
||||
bsd43uw - Generic BSD 4.3 at U of Waterloo
|
||||
bsd43vf - Generic BSD with no vfprintf in its library (use this
|
||||
target if you are missing the vfprintf function in your
|
||||
C library)
|
||||
sysvr3 - Generic SysV R3 UNIX
|
||||
sysvr1 - Generic SysV R1 UNIX
|
||||
386ix - 386/ix (SysV R3), not tested
|
||||
dynix - Sequent Symmetry dynix
|
||||
ultrix - Ultrix 3.0 system
|
||||
mips - Any MIPS box
|
||||
os2msc60 - OS/2 with MSC 6.0
|
||||
tos - Atari-ST using GCC as compiler
|
||||
tcc - DOS with tcc 2.0
|
||||
tccswp - swapping DOS version with tcc 2.0
|
||||
msc60 - DOS with MSC 6.0
|
||||
msc60swp - swapping DOS version with MSC 6.0
|
||||
|
||||
The file 'makefile' understands these targets and runs the appropriate script
|
||||
to create the correct version.
|
||||
|
||||
The source code is organized as follows:
|
||||
|
||||
dmake [source for all common functions]
|
||||
|
|
||||
|
|
||||
----------------------------
|
||||
| | | |
|
||||
unix tos os2 msdos [source for OS specific functions]
|
||||
| | |
|
||||
-------------------- mscdos -------------------
|
||||
| | | | | |
|
||||
386ix bsd43 sysvr[134] tccdos bccdos mscdos [source for OSRELEASE
|
||||
| specific functions]
|
||||
--------
|
||||
| |
|
||||
uw vf [source for OSENVIRONMENT specific functions]
|
||||
|
||||
|
||||
Each of the directories (eg. bsd43, mscdos, tccdos, and sysvr3) contain source
|
||||
that is specific to that release of the OS (and possibly C-library)
|
||||
To make the appropriate versions of dmake, simply type the command
|
||||
|
||||
'make system'
|
||||
|
||||
where system is one of the supplied possibilities. Note that if you are using
|
||||
an earlier version of dmake to make a new version from scratch then you must
|
||||
use the command:
|
||||
|
||||
'dmake -f makefile system'
|
||||
|
||||
as dmake by default first reads makefile.mk and would thus use the wrong
|
||||
makefile for bootstrapping purposes.
|
||||
|
||||
The bootstrapping of dmake is accomplished by running a shell script with the
|
||||
appropriate compile commands hard coded.
|
||||
|
||||
(NOTE: If you are using MSDOS then, you will actually be using the make.bat
|
||||
scriptfile to make the correct version of dmake for MSDOS. If you
|
||||
are running a SHELL other than command.com, you may have to perform
|
||||
some extra work to invoke the batch file.
|
||||
|
||||
Make sure you read the readme/msdos file before attempting to make the
|
||||
MSDOS version, as it contains important configuration and limitation
|
||||
information.)
|
||||
|
||||
The making of dmake, echoes the commands being executed, and should proceed
|
||||
relatively error free. Ignore ANY warnings produced by the compile
|
||||
They have all be verified and are spurious noise.
|
||||
|
||||
UNIX SYSV R3 AND GETCWD
|
||||
|
||||
Some versions of UNIX SysV R3 and Xenix use the popen call to capture the
|
||||
output of pwd when invoking the C library function getcwd(). These versions
|
||||
of the function cause dmake to terminate with the "lost a child" message
|
||||
due to the fact that the parent dmake process may catch the pwd and not
|
||||
recognize it as a child. For systems that have this problem use the version
|
||||
of dmake that supplies its own getcwd function. The settings are:
|
||||
|
||||
OS = unix
|
||||
OSRELEASE = sysvr3
|
||||
OSENVIRONMENT = pwd
|
||||
|
||||
It is directly available through the 'makefile' by typing one of:
|
||||
|
||||
make sysvr3pwd
|
||||
make xenixpwd
|
||||
|
||||
both include the getcwd code but the xenixpwd target compiles for a Xenix
|
||||
system.
|
||||
|
||||
|
||||
UNIX and "limits.h"
|
||||
|
||||
Some compilers do not yet provide the "limits.h" file, if yours is one of
|
||||
these then simply copy the file "namemax.h" in the source root directory to
|
||||
"limits.h". Make sure the length of a file name is correctly set in
|
||||
"limits.h" as it is processed prior to "namemax.h".
|
||||
|
||||
|
||||
STARTUP FILE
|
||||
|
||||
dmake requires the loading of a startup file when it is invoked. The
|
||||
path for the startup file is set in the file 'startup.h' found in the
|
||||
appropriate system sub-directories. You may override the value of the
|
||||
path variable compiled-in by creating a file at the root source directory
|
||||
called startup.h and inserting into that file a definition that is like
|
||||
the definition found in the supplied startup.h files. Alternatively you
|
||||
can modify the MAKESTARTUP environment variable to point at the location
|
||||
of your startup.mk file.
|
||||
|
||||
|
||||
INSTALLATION
|
||||
|
||||
To install dmake you must copy the executable to where your system
|
||||
locates executables, and you must place a copy of startup.mk (found in the
|
||||
root source directory after the build is successfuly completed) into a location
|
||||
corresponding to the value of the MAKESTARTUP macro or environment variable.
|
||||
You are free to customize the contents of startup.mk.
|
||||
|
||||
To make dmake again, (using itself), you will have to set three environment
|
||||
variables. See the files in readme/options for their names and their legal
|
||||
values. Once set you can invoke dmake to make itself.
|
||||
|
||||
|
||||
DOCUMENTATION
|
||||
|
||||
All documentation for dmake appears under the man directory.
|
||||
The file dmake.tf included in this distribution contains the troff
|
||||
source for the man page. You must typeset it using the -man macros.
|
||||
If you cannot typeset it, the file dmake.p is a version that has been
|
||||
typeset for a normal dumb terminal. The file dmake.p contains control
|
||||
characters. The file dmake.nc is a version of the man page that has
|
||||
all of the control characters stripped.
|
||||
|
||||
|
||||
CREATING A NEW VERSION
|
||||
|
||||
To create yet another version of dmake you should follow the following steps.
|
||||
|
||||
The sysvr3 version as sent is the base version, all dmake versions must provide
|
||||
the equivalent of the functions defined in the sysvr3 directory, and MUST
|
||||
provide the same semantics (MSDOS archive lib searches are an exception since
|
||||
we cannot search libraries for timestamps in MSDOS, Actually the MKS version
|
||||
of dmake does this, I don't have the inclination to add this code though).
|
||||
|
||||
1. Create a new directory for the version you will be making at the level
|
||||
that is appropriate. If it is a new OS then add the dir at the top level,
|
||||
if it is a new version of UNIX then add it below the unix directory.
|
||||
|
||||
2. Copy the files from the unix and unix/sysvr3 directories to the new dir.
|
||||
(Or from any other directory sub-tree that is more appropriate)
|
||||
|
||||
3. Not all OS/OSRELEASE combinations are compatible so in order to make
|
||||
dmake on each, the particular directory may contain C-source for functions
|
||||
present in the SVID SysV R3 distribution which are used by dmake but are
|
||||
not supplied by the C-library in the target system. For example the bsd43
|
||||
directory contains source for tempnam.c since it is not provided with
|
||||
the BSD C-library. Before writing a new version of the source file
|
||||
check the other directories to see if one already exists.
|
||||
|
||||
4. Under some systems the standard include files may be missing or incorrect.
|
||||
eg. under BSD stdarg.h and string.h. If this is the case
|
||||
you should create the proper .h file in the proper directory.
|
||||
This works as expected as the compile line includes the flag -Idir
|
||||
where dir is the configuration dir, (bsd43 for example) and any
|
||||
standard include files will be searched for in dir before the compiler
|
||||
looks in the normal places (if you have a sane compiler :-).
|
||||
|
||||
5. Modify dmake.sh to contain the appropriate C compiler flags and link command
|
||||
and to include any specific C files that you have had to add for this
|
||||
version of dmake, and run the result through the shell.
|
||||
(make the same changes to config.mk so that once you have a working copy of
|
||||
dmake you can use it to bring itself up to date)
|
||||
|
||||
6. Send me the changes :-) so that I can incorporate them into future
|
||||
distributions.
|
||||
|
||||
7. This should be all that you require to create a new version of dmake.
|
||||
If you have any questions send e-mail to dvadura@plg.uwaterloo.ca
|
71
dmake/alloc.h
Normal file
71
dmake/alloc.h
Normal file
@ -0,0 +1,71 @@
|
||||
/* RCS -- $Header: /u/dvadura/src/generic/dmake/src/RCS/alloc.h,v 1.2 1992/04/07 04:42:46 dvadura Exp $
|
||||
-- SYNOPSIS -- macros for allocating memory.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- A somewhat nicer interface to malloc and calloc.
|
||||
-- Here we standardise the calling convention with a common macro
|
||||
-- interface.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: alloc.h,v $
|
||||
* Revision 1.2 1992/04/07 04:42:46 dvadura
|
||||
* Added a !defined(_SIZE_T_) to satisfy Silicon Graphics IRIX.
|
||||
*
|
||||
* Revision 1.1 1992/01/24 03:26:54 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ALLOC_h
|
||||
#define ALLOC_h
|
||||
|
||||
/* DO NOT CHANGE these! These are the definitions that the make source
|
||||
* uses for allocating memory. They must be defined for make to compile
|
||||
* properly.
|
||||
*/
|
||||
|
||||
/* This is the only place that we define size_t now. This should be more
|
||||
* than enough! */
|
||||
#if __STDC__
|
||||
#else
|
||||
# if !defined(_TYPES_) && !defined(M_XENIX) && !defined(atarist) && !defined(_MPW) && !defined(_SIZE_T) && !defined(_SIZE_T_)
|
||||
# if defined(MSDOS) || defined(__MSDOS__)
|
||||
# undef size_t
|
||||
typedef unsigned size_t;
|
||||
# else
|
||||
typedef long size_t;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define usizeof(t) (size_t)sizeof(t)
|
||||
|
||||
#define FREE(p) free((char*)(p))
|
||||
#define MALLOC(n, t) (t*) malloc((unsigned int)(n)*usizeof(t))
|
||||
#define CALLOC(n, t) (t*) calloc((unsigned int)(n), usizeof(t))
|
||||
|
||||
#define TALLOC(p, n, t) if ((p = CALLOC(n, t)) == (t*)0) {No_ram();}
|
||||
|
||||
#endif
|
||||
|
55
dmake/basename.c
Normal file
55
dmake/basename.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/basename.c,v 1.1 1992/01/24 03:26:56 dvadura Exp $
|
||||
-- SYNOPSIS -- return pointer to last pathname component
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- take a file name like /fred/foo/hoe/mary.k, and return the 'mary.k'
|
||||
-- portion
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: basename.c,v $
|
||||
* Revision 1.1 1992/01/24 03:26:56 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
PUBLIC char*
|
||||
basename( path )
|
||||
char *path;
|
||||
{
|
||||
char *p;
|
||||
char *q;
|
||||
|
||||
if( *(q = path) ) {
|
||||
for(; *(p=_strpbrk(q, DirBrkStr)) != '\0'; q = p+1 );
|
||||
if( !*q ) {
|
||||
for( p=q-1; p != path; --p )
|
||||
if( strchr( DirBrkStr, *p ) == NIL(char) ) return( p+1 );
|
||||
return( strchr(DirBrkStr, *p)?path:(p+1) );
|
||||
}
|
||||
path = q;
|
||||
}
|
||||
return( path );
|
||||
}
|
497
dmake/dag.c
Normal file
497
dmake/dag.c
Normal file
@ -0,0 +1,497 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dag.c,v 1.1 1992/01/24 03:26:55 dvadura Exp $
|
||||
-- SYNOPSIS -- Routines to construct the internal dag.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- This file contains all the routines that are responsible for
|
||||
-- defining and manipulating all objects used by the make facility.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: dag.c,v $
|
||||
* Revision 1.1 1992/01/24 03:26:55 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
|
||||
PUBLIC HASHPTR
|
||||
Get_name( name, tab, define )/*
|
||||
===============================
|
||||
Look to see if the name is defined, if it is then return
|
||||
a pointer to its node, if not return NIL(HASH).
|
||||
If define is TRUE and the name is not found it will be added. */
|
||||
|
||||
char *name; /* name we are looking for */
|
||||
HASHPTR *tab; /* the hash table to look in */
|
||||
int define; /* TRUE => add to table */
|
||||
{
|
||||
register HASHPTR hp;
|
||||
register char *p;
|
||||
uint16 hv;
|
||||
uint32 hash_key;
|
||||
|
||||
DB_ENTER( "Get_name" );
|
||||
DB_PRINT( "name", ("Looking for %s", name) );
|
||||
|
||||
hp = Search_table( tab, name, &hv, &hash_key );
|
||||
|
||||
if( hp == NIL(HASH) && define ) {
|
||||
/* Check to make sure that CELL name contains only printable chars */
|
||||
for( p=name; *p; p++ )
|
||||
if( !isprint(*p) && !iswhite(*p) && *p != '\n' )
|
||||
Fatal( "Name contains non-printable character [0x%02x]", *p );
|
||||
|
||||
TALLOC( hp, 1, HASH ); /* allocate a cell and add it in */
|
||||
|
||||
hp->ht_name = _strdup( name );
|
||||
hp->ht_hash = hash_key;
|
||||
hp->ht_next = tab[ hv ];
|
||||
tab[ hv ] = hp;
|
||||
|
||||
DB_PRINT( "name", ("Adding %s", name) );
|
||||
}
|
||||
|
||||
DB_PRINT( "name",("Returning: [%s,%lu]",
|
||||
(hp == NIL(HASH)) ? "":hp->ht_name, hv) );
|
||||
DB_RETURN( hp );
|
||||
}
|
||||
|
||||
|
||||
PUBLIC HASHPTR
|
||||
Search_table( tab, name, phv, phkey )
|
||||
HASHPTR *tab;
|
||||
char *name;
|
||||
uint16 *phv;
|
||||
uint32 *phkey;
|
||||
{
|
||||
HASHPTR hp;
|
||||
|
||||
*phv = Hash( name, phkey );
|
||||
|
||||
for( hp = tab[ *phv ]; hp != NIL(HASH); hp = hp->ht_next )
|
||||
if( hp->ht_hash == *phkey
|
||||
&& !strcmp(hp->ht_name, name) )
|
||||
break;
|
||||
|
||||
return( hp );
|
||||
}
|
||||
|
||||
|
||||
PUBLIC HASHPTR
|
||||
Def_macro( name, value, flags )/*
|
||||
=================================
|
||||
This routine is used to define a macro, and it's value.
|
||||
The flags indicates if it is a permanent macro or if it's value
|
||||
can be redefined. A flags of M_PRECIOUS means it is a precious
|
||||
macro and cannot be further redefined. If the flags flag also
|
||||
contains the M_MULTI bit it means that the macro can be redefined
|
||||
multiple times and no warning of the redefinitions should be issued.
|
||||
Once a macro's VAR flags are set they are preserved through all future
|
||||
macro definitions.
|
||||
|
||||
Macro definitions that have one of the variable bits set are treated
|
||||
specially. In each case the hash table entry var field points at the
|
||||
global variable that can be set by assigning to the macro.
|
||||
|
||||
bit valued global vars must be computed when the macro value is changed.
|
||||
char valued global vars must have the first char of ht_value copied to
|
||||
them. string valued global vars have the same value as ht_value and should
|
||||
just have the new value of ht_value copied to them. */
|
||||
|
||||
char *name; /* macro name to define */
|
||||
char *value; /* macro value to set */
|
||||
int flags; /* initial ht_flags */
|
||||
{
|
||||
register HASHPTR hp;
|
||||
register char *p, *q;
|
||||
|
||||
DB_ENTER( "Def_macro" );
|
||||
DB_PRINT( "mac", ("Defining macro %s = %s, %x", name, value, flags) );
|
||||
|
||||
/* check to see if name is in the table, if so then just overwrite
|
||||
the previous definition. Otherwise allocate a new node, and
|
||||
stuff it in the hash table, at the front of any linked list */
|
||||
|
||||
if( Readenv ) flags |= M_LITERAL|M_EXPANDED;
|
||||
|
||||
hp = Get_name( name, Macs, TRUE );
|
||||
|
||||
if( (hp->ht_flag & M_PRECIOUS) && !(flags & M_FORCE) ) {
|
||||
Warning( "Macro `%s' cannot be redefined", name );
|
||||
DB_RETURN( hp );
|
||||
}
|
||||
|
||||
/* Make sure we don't export macros whose names contain legal macro
|
||||
* assignment operators, since we can't do proper quoting in the
|
||||
* environment. */
|
||||
if( *_strpbrk(name, "*+:=") != '\0' ) flags |= M_NOEXPORT;
|
||||
|
||||
if( hp->ht_value != NIL(char) ) FREE( hp->ht_value );
|
||||
|
||||
if( (hp->ht_flag & M_USED) && !((flags | hp->ht_flag) & M_MULTI) )
|
||||
Warning( "Macro `%s' redefined after use", name );
|
||||
|
||||
if( (value != NIL(char)) && (*value) ) {
|
||||
/* strip out any \<nl> combinations where \ is the current CONTINUATION
|
||||
* char */
|
||||
|
||||
for( p = value; (p = strchr(p, CONTINUATION_CHAR)) != NIL(char); )
|
||||
if( p[1] == '\n' )
|
||||
strcpy( p, p+2 );
|
||||
else
|
||||
p++;
|
||||
|
||||
if( !(flags & M_LITERAL) ) {
|
||||
p = _strdup( _strspn( value, " \t" ) ); /* strip white space before */
|
||||
/* ... and after value */
|
||||
if( *p ) {
|
||||
for(q=p+strlen(p)-1; ((*q == ' ')||(*q == '\t')); q--);
|
||||
*++q = '\0';
|
||||
}
|
||||
flags &= ~M_LITERAL;
|
||||
}
|
||||
else
|
||||
p = _strdup( value ); /* take string literally */
|
||||
|
||||
if( !*p ) { /* check if result is "" */
|
||||
FREE( p );
|
||||
p = NIL(char);
|
||||
flags |= M_EXPANDED;
|
||||
}
|
||||
else if( *_strpbrk( p, "${}" ) == '\0' )
|
||||
flags |= M_EXPANDED;
|
||||
|
||||
hp->ht_value = p;
|
||||
}
|
||||
else
|
||||
hp->ht_value = NIL(char);
|
||||
|
||||
/* Assign the hash table flag less the M_MULTI flag, it is used only
|
||||
* to silence the warning. But carry it over if it was previously
|
||||
* defined in ht_flag, as this is a permanent M_MULTI variable. */
|
||||
|
||||
hp->ht_flag = (flags & ~(M_MULTI|M_FORCE)) |
|
||||
(hp->ht_flag & (M_VAR_MASK | M_MULTI));
|
||||
|
||||
/* Check for macro variables and make the necessary adjustment in the
|
||||
* corresponding global variables */
|
||||
|
||||
if( hp->ht_flag & M_VAR_MASK )
|
||||
if( !(flags & M_EXPANDED) )
|
||||
Error( "Macro variable '%s' must be assigned with :=", name );
|
||||
else switch( hp->ht_flag & M_VAR_MASK ) /* only one var type per var */
|
||||
{
|
||||
case M_VAR_STRING:
|
||||
*hp->MV_SVAR = hp->ht_value;
|
||||
break;
|
||||
|
||||
case M_VAR_CHAR:
|
||||
*hp->MV_CVAR = (hp->ht_value == NIL(char)) ? '\0':*hp->ht_value;
|
||||
break;
|
||||
|
||||
case M_VAR_INT: {
|
||||
int tvalue;
|
||||
if( hp->MV_IVAR == NIL(int) ) break; /* first time */
|
||||
|
||||
tvalue = atoi(hp->ht_value);
|
||||
if( hp->MV_IVAR == &Buffer_size ) {
|
||||
/* If Buffer_size is modified then make sure you change the
|
||||
* size of the real buffer as well. */
|
||||
tvalue = (tvalue < (BUFSIZ-2)) ? BUFSIZ : tvalue+2;
|
||||
if( Buffer_size == tvalue ) break;
|
||||
if( Buffer ) FREE(Buffer);
|
||||
if((Buffer=MALLOC(tvalue, char)) == NIL(char)) No_ram();
|
||||
*Buffer = '\0';
|
||||
}
|
||||
*hp->MV_IVAR = tvalue;
|
||||
|
||||
if( hp->MV_IVAR == &Max_proc || hp->MV_IVAR == &Max_proclmt ) {
|
||||
if( tvalue < 1 )
|
||||
Fatal( "Process limit value must be > 1" );
|
||||
|
||||
if( Max_proc > Max_proclmt )
|
||||
Fatal( "Specified # of processes exceeds limit of [%d]",
|
||||
Max_proclmt );
|
||||
}
|
||||
} break;
|
||||
|
||||
case M_VAR_BIT:
|
||||
/* Bit variables are set to 1 if ht_value is not NULL and 0
|
||||
* otherwise */
|
||||
|
||||
if( hp->ht_value == NIL(char) )
|
||||
*hp->MV_BVAR &= ~hp->MV_MASK;
|
||||
else
|
||||
*hp->MV_BVAR |= hp->MV_MASK;
|
||||
break;
|
||||
}
|
||||
|
||||
DB_RETURN( hp );
|
||||
}
|
||||
|
||||
|
||||
|
||||
PUBLIC CELLPTR
|
||||
Def_cell( name )/*
|
||||
==================
|
||||
Take a string passed in and define it as a cell
|
||||
If the cell exists then return a pointer to it. */
|
||||
char *name;
|
||||
{
|
||||
register HASHPTR hp;
|
||||
register CELLPTR cp;
|
||||
register CELLPTR lib;
|
||||
char *member;
|
||||
char *end;
|
||||
|
||||
DB_ENTER( "Def_cell" );
|
||||
|
||||
/* Check to see if the cell is a member of the form lib(member) or
|
||||
* lib((symbol)) and handle the cases appropriately.
|
||||
* What we do is we look at the target, if it is of the above two
|
||||
* forms we get the lib, and add the member/symbol to the list of
|
||||
* prerequisites for the library. If this is a symbol name def'n
|
||||
* we additionally add the attribute A_SYMBOL, so that stat can
|
||||
* try to do the right thing. */
|
||||
|
||||
if( ((member = strchr(name, '(')) != NIL(char)) &&
|
||||
((end = strrchr(member, ')')) != NIL(char)) &&
|
||||
(member > name) && (member[-1] != '$') &&
|
||||
(end > member+1) && (end[1] == '\0') )
|
||||
{
|
||||
*member++ = *end = '\0';
|
||||
|
||||
if( (*member == '(') && (member[strlen(member)-1] == ')') ) {
|
||||
member[ strlen(member)-1 ] = '\0';
|
||||
cp = Def_cell( member+1 );
|
||||
cp->ce_attr |= A_SYMBOL;
|
||||
}
|
||||
else
|
||||
cp = Def_cell( member );
|
||||
|
||||
lib = Def_cell( name );
|
||||
|
||||
Add_prerequisite( lib, cp, FALSE, FALSE );
|
||||
lib->ce_attr |= A_LIBRARY | A_COMPOSITE;
|
||||
|
||||
if( !Def_targets ) cp = lib;
|
||||
}
|
||||
else {
|
||||
hp = Get_name( name, Defs, TRUE );/* get the name from hash table */
|
||||
|
||||
if( hp->CP_OWNR == NIL(CELL) ) /* was it previously defined */
|
||||
{ /* NO, so define a new cell */
|
||||
DB_PRINT( "cell", ("Defining cell [%s]", name) );
|
||||
|
||||
TALLOC( cp, 1, CELL );
|
||||
hp->CP_OWNR = cp;
|
||||
cp->ce_name = hp;
|
||||
cp->ce_fname = hp->ht_name;
|
||||
}
|
||||
else /* YES, so return the old cell */
|
||||
{
|
||||
DB_PRINT( "cell", ("Getting cell [%s]", hp->ht_name) );
|
||||
cp = hp->CP_OWNR;
|
||||
}
|
||||
}
|
||||
|
||||
DB_RETURN( cp );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PUBLIC LINKPTR
|
||||
Add_prerequisite( cell, prq, head, force )/*
|
||||
============================================
|
||||
Add a dependency node to the dag. It adds it to the prerequisites,
|
||||
if any, of the cell and makes certain they are in linear order.
|
||||
If head == 1, then add to head of the prerequisite list, else
|
||||
add to tail. */
|
||||
CELLPTR cell;
|
||||
CELLPTR prq;
|
||||
int head;
|
||||
int force;
|
||||
{
|
||||
register LINKPTR lp, tlp;
|
||||
|
||||
DB_ENTER( "Add_prerequisite" );
|
||||
DB_PRINT( "cell", ("Defining prerequisite %s", prq->CE_NAME) );
|
||||
|
||||
if( (prq->ce_flag & (F_MAGIC | F_PERCENT)) && !force )
|
||||
Fatal( "Special target [%s] cannot be a prerequisite",
|
||||
prq->CE_NAME );
|
||||
|
||||
if( cell->ce_prq == NIL(LINK) ) { /* it's the first one */
|
||||
TALLOC( lp, 1, LINK );
|
||||
lp->cl_prq = prq;
|
||||
cell->ce_prq = lp;
|
||||
}
|
||||
else { /* search the list, checking for duplicates */
|
||||
for( lp = cell->ce_prq;
|
||||
(lp->cl_next != NIL(LINK)) && (lp->cl_prq != prq);
|
||||
lp = lp->cl_next );
|
||||
|
||||
/* If the prq is not found and we are at the last prq in the list,
|
||||
* allocate a new prq and place it into the list, insert it at the
|
||||
* head if head == 1, else we add it to the end. */
|
||||
|
||||
if( lp->cl_prq != prq ) {
|
||||
TALLOC( tlp, 1, LINK );
|
||||
tlp->cl_prq = prq;
|
||||
|
||||
if( head ) {
|
||||
tlp->cl_next = cell->ce_prq;
|
||||
cell->ce_prq = tlp;
|
||||
}
|
||||
else
|
||||
lp->cl_next = tlp;
|
||||
|
||||
lp = tlp;
|
||||
}
|
||||
}
|
||||
|
||||
DB_RETURN( lp );
|
||||
}
|
||||
|
||||
|
||||
|
||||
PUBLIC void
|
||||
Clear_prerequisites( cell )/*
|
||||
=============================
|
||||
Clear out the list of prerequisites, freeing all of the LINK nodes,
|
||||
and setting the list to NULL */
|
||||
CELLPTR cell;
|
||||
{
|
||||
LINKPTR lp, tlp;
|
||||
|
||||
DB_ENTER( "Clear_prerequisites" );
|
||||
DB_PRINT( "cell", ("Nuking prerequisites") );
|
||||
|
||||
if( cell == NIL(CELL) ) { DB_VOID_RETURN; }
|
||||
|
||||
for( lp=cell->ce_prq; lp != NIL(LINK); lp=tlp ) {
|
||||
tlp=lp->cl_next;
|
||||
FREE( lp );
|
||||
}
|
||||
|
||||
cell->ce_prq = NIL(LINK);
|
||||
|
||||
DB_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
PUBLIC int
|
||||
Test_circle( cp, fail )/*
|
||||
=========================
|
||||
Actually run through the graph */
|
||||
CELLPTR cp;
|
||||
int fail;
|
||||
{
|
||||
register LINKPTR lp;
|
||||
int res = 0;
|
||||
|
||||
DB_ENTER( "Test_circle" );
|
||||
DB_PRINT( "tc", ("checking [%s]", cp->CE_NAME) );
|
||||
|
||||
if( cp->ce_flag & F_MARK )
|
||||
if( fail )
|
||||
Fatal("Detected circular dependency in graph at [%s]", cp->CE_NAME);
|
||||
else
|
||||
DB_RETURN( 1 );
|
||||
|
||||
cp->ce_flag |= F_MARK;
|
||||
for( lp = cp->ce_prq; !res && lp != NIL(LINK); lp = lp->cl_next )
|
||||
res = Test_circle( lp->cl_prq, fail );
|
||||
cp->ce_flag ^= F_MARK;
|
||||
|
||||
DB_RETURN( res );
|
||||
}
|
||||
|
||||
|
||||
|
||||
PUBLIC STRINGPTR
|
||||
Def_recipe( rcp, sp, white_too, no_check )/*
|
||||
=============================================
|
||||
Take the recipe and add it to the list of recipes
|
||||
pointed to by sp. sp points to the last element.
|
||||
return a pointer to the new recipe. If white_too == TRUE add the
|
||||
recipe even if it contains only white space.
|
||||
If no_check is true then don't look for -@ at the start of the
|
||||
recipe line. */
|
||||
char *rcp;
|
||||
STRINGPTR sp;
|
||||
int white_too;
|
||||
int no_check;
|
||||
{
|
||||
register STRINGPTR nsp;
|
||||
register char *rp;
|
||||
|
||||
DB_ENTER( "Def_recipe" );
|
||||
DB_PRINT( "rul", ("Defining recipe %s", rcp) );
|
||||
|
||||
if( !white_too ) rcp = _strspn( rcp, " \t" );
|
||||
if( (rcp == NIL(char)) || (*rcp == 0 && !white_too) )
|
||||
DB_RETURN( sp ); /* return last recipe when new recipe not added */
|
||||
|
||||
rp = no_check ? rcp : _strspn( rcp, " \t@-+%" );
|
||||
|
||||
TALLOC( nsp, 1, STRING );
|
||||
nsp->st_string = _strdup( rp );
|
||||
|
||||
if( sp != NIL(STRING) ) sp->st_next = nsp;
|
||||
nsp->st_next = NIL(STRING);
|
||||
|
||||
if( !no_check ) nsp->st_attr |= Rcp_attribute( rcp );
|
||||
|
||||
DB_RETURN( nsp );
|
||||
}
|
||||
|
||||
|
||||
PUBLIC t_attr
|
||||
Rcp_attribute( rp )/*
|
||||
======================
|
||||
Look at the recipe and return the set of attributes that it defines. */
|
||||
char *rp;
|
||||
{
|
||||
t_attr flag = A_DEFAULT;
|
||||
int done = FALSE;
|
||||
|
||||
while( !done )
|
||||
switch( *rp++ )
|
||||
{
|
||||
case '@' : flag |= A_SILENT; break;
|
||||
case '-' : flag |= A_IGNORE; break;
|
||||
case '+' : flag |= A_SHELL; break;
|
||||
case '%' : flag |= A_SWAP; break;
|
||||
|
||||
case ' ' :
|
||||
case '\t': break;
|
||||
|
||||
default: done = TRUE; break;
|
||||
}
|
||||
|
||||
return(flag);
|
||||
}
|
75
dmake/db.h
Normal file
75
dmake/db.h
Normal file
@ -0,0 +1,75 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/db.h,v 1.1 1992/01/24 03:29:35 dvadura Exp $
|
||||
-- SYNOPSIS -- front end to DBUG macros.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- This is a front end to Fred Fish's DBUG macros. The intent was
|
||||
-- to provide an interface so that if you don't have the DBUG code
|
||||
-- you can still compile dmake, by undefining DBUG, if you do have
|
||||
-- the code then you can use Fred Fish's DBUG package. Originally
|
||||
-- the DBUG stuff was copyrighted, it is now in the public domain
|
||||
-- so the need for this is not as apparent.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: db.h,v $
|
||||
* Revision 1.1 1992/01/24 03:29:35 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DB_h
|
||||
#define DB_h
|
||||
|
||||
#ifdef DBUG
|
||||
|
||||
# include "dbug.h"
|
||||
|
||||
# define DB_ENTER(a1) DBUG_ENTER(a1)
|
||||
# define DB_RETURN(a1) DBUG_RETURN(a1)
|
||||
# define DB_VOID_RETURN DBUG_VOID_RETURN
|
||||
# define DB_EXECUTE(keyword, a1) DBUG_EXECUTE(keyword,a1)
|
||||
# define DB_PRINT(keyword,arglist) DBUG_PRINT(keyword,arglist)
|
||||
# define DB_PUSH(a1) DBUG_PUSH(a1)
|
||||
# define DB_POP() DBUG_POP()
|
||||
# define DB_PROCESS(a1) DBUG_PROCESS(a1)
|
||||
# define DB_FILE(file) DBUG_FILE(file)
|
||||
# define DB_SETJMP DBUG_SETJMP
|
||||
# define DB_LONGJMP DBUG_LONGJMP
|
||||
|
||||
#else
|
||||
|
||||
# define DB_ENTER(a1)
|
||||
# define DB_RETURN(a1) return (a1)
|
||||
# define DB_VOID_RETURN return
|
||||
# define DB_EXECUTE(keyword, a1)
|
||||
# define DB_PRINT(keyword,arglist)
|
||||
# define DB_PUSH(a1)
|
||||
# define DB_POP()
|
||||
# define DB_PROCESS(a1)
|
||||
# define DB_FILE(file)
|
||||
# define DB_SETJMP setjmp
|
||||
# define DB_LONGJMP longjmp
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
13
dmake/dbug/README
Normal file
13
dmake/dbug/README
Normal file
@ -0,0 +1,13 @@
|
||||
This directory contains two public domain debugging packages.
|
||||
|
||||
1. Fred Fishes DEBUG macros.
|
||||
2. Connor P. Cahills malloc library.
|
||||
|
||||
Descriptions of both can be found in their respective sub-directories. dbug
|
||||
for the DEBUG macros and malloc for the malloc library. I have left the
|
||||
malloc distribution intact as it comes from the net except for the changes
|
||||
noted in the _changes file.
|
||||
|
||||
I thank the authors for making them available for others to use.
|
||||
|
||||
-dennis
|
66
dmake/dbug/dbug.mk
Normal file
66
dmake/dbug/dbug.mk
Normal file
@ -0,0 +1,66 @@
|
||||
# Set the proper macros based on whether we are making the debugging version
|
||||
# or not. The valid parameters to this file are:
|
||||
#
|
||||
# DEBUG=1 ==> enable the making of the DBUG version
|
||||
# DBMALLOC=1 ==> enable DBUG version with extensive MALLOC checking
|
||||
#
|
||||
# DB_CFLAGS ==> CFLAGS is set to this value at the end if DEBUG=1
|
||||
# DB_LDFLAGS ==> LDFLAGS is set to this at the end if DEBUG=1
|
||||
# DB_LDLIBS ==> LDLIBS is set to this at end if DEBUG=1
|
||||
#
|
||||
# The non debug versions of the above three macros are:
|
||||
#
|
||||
# NDB_CFLAGS
|
||||
# NDB_LDFLAGS
|
||||
# NDB_LDLIBS
|
||||
#
|
||||
# One of the set of three should have values set appropriately prior to
|
||||
# sourcing this file.
|
||||
|
||||
.IF $(DEBUG)
|
||||
DBUG_SRC += dbug.c
|
||||
DB_CFLAGS += -Idbug/dbug
|
||||
|
||||
.SETDIR=dbug/dbug : $(DBUG_SRC)
|
||||
|
||||
# If DBMALLOC is requested (ie non-NULL) then include the sources for
|
||||
# compilation. BSD 4.3 needs the getwd.c source compiled in due to a bug
|
||||
# in the clib getwd routine.
|
||||
.IF $(DBMALLOC)
|
||||
# Serious bug in bsd43 getwd.c would free a string and then use its
|
||||
# value. The DBMALLOC code clears a string when it is free'd so the
|
||||
# value was no longer valid and the returned path for the current
|
||||
# directory was now completely wrong.
|
||||
.IF $(OSRELEASE) == bsd43
|
||||
GETWD_SRC += getwd.c
|
||||
.SETDIR=dbug : $(GETWD_SRC)
|
||||
.END
|
||||
|
||||
MLC_SRC += malloc.c free.c realloc.c calloc.c string.c\
|
||||
mlc_chk.c mlc_chn.c memory.c tostring.c m_perror.c\
|
||||
m_init.c mallopt.c dump.c
|
||||
|
||||
.SETDIR=dbug/malloc : $(MLC_SRC)
|
||||
|
||||
DB_CFLAGS += -Idbug/malloc
|
||||
.END
|
||||
|
||||
SRC += $(DBUG_SRC) $(MLC_SRC) $(GETWD_SRC)
|
||||
HDR += db.h
|
||||
|
||||
LDFLAGS += $(DB_LDFLAGS)
|
||||
LDLIBS += $(DB_LDLIBS)
|
||||
|
||||
SILENT := $(.SILENT)
|
||||
.SILENT := yes
|
||||
TARGET := db$(TARGET)
|
||||
OBJDIR := $(OBJDIR).dbg
|
||||
.SILENT := $(SILENT)
|
||||
|
||||
CFLAGS += $(DB_CFLAGS)
|
||||
.KEEP_STATE := _dbstate.mk
|
||||
.ELSE
|
||||
CFLAGS += $(NDB_CFLAGS)
|
||||
LDFLAGS += $(NDB_LDFLAGS)
|
||||
LDLIBS += $(NDB_LDLIBS)
|
||||
.END
|
6
dmake/dbug/dbug/README
Normal file
6
dmake/dbug/dbug/README
Normal file
@ -0,0 +1,6 @@
|
||||
To unpack the DBUG manual page please issue the following sequence of
|
||||
commands:
|
||||
|
||||
uudecode dbug.uue
|
||||
uncompress dbug.Z
|
||||
mv dbug dbug.p
|
1832
dmake/dbug/dbug/dbug.c
Normal file
1832
dmake/dbug/dbug/dbug.c
Normal file
File diff suppressed because it is too large
Load Diff
164
dmake/dbug/dbug/dbug.h
Normal file
164
dmake/dbug/dbug/dbug.h
Normal file
@ -0,0 +1,164 @@
|
||||
/******************************************************************************
|
||||
* *
|
||||
* N O T I C E *
|
||||
* *
|
||||
* Copyright Abandoned, 1987, Fred Fish *
|
||||
* *
|
||||
* *
|
||||
* This previously copyrighted work has been placed into the public *
|
||||
* domain by the author and may be freely used for any purpose, *
|
||||
* private or commercial. *
|
||||
* *
|
||||
* Because of the number of inquiries I was receiving about the use *
|
||||
* of this product in commercially developed works I have decided to *
|
||||
* simply make it public domain to further its unrestricted use. I *
|
||||
* specifically would be most happy to see this material become a *
|
||||
* part of the standard Unix distributions by AT&T and the Berkeley *
|
||||
* Computer Science Research Group, and a standard part of the GNU *
|
||||
* system from the Free Software Foundation. *
|
||||
* *
|
||||
* I would appreciate it, as a courtesy, if this notice is left in *
|
||||
* all copies and derivative works. Thank you. *
|
||||
* *
|
||||
* The author makes no warranty of any kind with respect to this *
|
||||
* product and explicitly disclaims any implied warranties of mer- *
|
||||
* chantability or fitness for any particular purpose. *
|
||||
* *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* FILE
|
||||
*
|
||||
* dbug.h user include file for programs using the dbug package
|
||||
*
|
||||
* SYNOPSIS
|
||||
*
|
||||
* #include <local/dbug.h>
|
||||
*
|
||||
* SCCS ID
|
||||
*
|
||||
* @(#)dbug.h 1.11 9/5/87
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* Programs which use the dbug package must include this file.
|
||||
* It contains the appropriate macros to call support routines
|
||||
* in the dbug runtime library.
|
||||
*
|
||||
* To disable compilation of the macro expansions define the
|
||||
* preprocessor symbol "DBUG_OFF". This will result in null
|
||||
* macros expansions so that the resulting code will be smaller
|
||||
* and faster. (The difference may be smaller than you think
|
||||
* so this step is recommended only when absolutely necessary).
|
||||
* In general, tradeoffs between space and efficiency are
|
||||
* decided in favor of efficiency since space is seldom a
|
||||
* problem on the new machines).
|
||||
*
|
||||
* All externally visible symbol names follow the pattern
|
||||
* "_db_xxx..xx_" to minimize the possibility of a dbug package
|
||||
* symbol colliding with a user defined symbol.
|
||||
*
|
||||
* The DBUG_<N> style macros are obsolete and should not be used
|
||||
* in new code. Macros to map them to instances of DBUG_PRINT
|
||||
* are provided for compatibility with older code. They may go
|
||||
* away completely in subsequent releases.
|
||||
*
|
||||
* AUTHOR
|
||||
*
|
||||
* Fred Fish
|
||||
* (Currently employed by Motorola Computer Division, Tempe, Az.)
|
||||
* hao!noao!mcdsun!fnf
|
||||
* (602) 438-3614
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Internally used dbug variables which must be global.
|
||||
*/
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
extern int _db_on_; /* TRUE if debug currently enabled */
|
||||
extern FILE *_db_fp_; /* Current debug output stream */
|
||||
extern char *_db_process_; /* Name of current process */
|
||||
extern int _db_keyword_ (); /* Accept/reject keyword */
|
||||
extern void _db_push_ (); /* Push state, set up new state */
|
||||
extern void _db_pop_ (); /* Pop previous debug state */
|
||||
extern void _db_enter_ (); /* New user function entered */
|
||||
extern void _db_return_ (); /* User function return */
|
||||
extern void _db_pargs_ (); /* Remember args for line */
|
||||
extern void _db_doprnt_ (); /* Print debug output */
|
||||
extern void _db_setjmp_ (); /* Save debugger environment */
|
||||
extern void _db_longjmp_ (); /* Restore debugger environment */
|
||||
# endif
|
||||
|
||||
|
||||
/*
|
||||
* These macros provide a user interface into functions in the
|
||||
* dbug runtime support library. They isolate users from changes
|
||||
* in the MACROS and/or runtime support.
|
||||
*
|
||||
* The symbols "__LINE__" and "__FILE__" are expanded by the
|
||||
* preprocessor to the current source file line number and file
|
||||
* name respectively.
|
||||
*
|
||||
* WARNING --- Because the DBUG_ENTER macro allocates space on
|
||||
* the user function's stack, it must precede any executable
|
||||
* statements in the user function.
|
||||
*
|
||||
*/
|
||||
|
||||
# ifdef DBUG_OFF
|
||||
# define DBUG_ENTER(a1)
|
||||
# define DBUG_MALLOC(a1)
|
||||
# define DBUG_RETURN(a1) return(a1)
|
||||
# define DBUG_VOID_RETURN return
|
||||
# define DBUG_EXECUTE(keyword,a1)
|
||||
# define DBUG_PRINT(keyword,arglist)
|
||||
# define DBUG_2(keyword,format) /* Obsolete */
|
||||
# define DBUG_3(keyword,format,a1) /* Obsolete */
|
||||
# define DBUG_4(keyword,format,a1,a2) /* Obsolete */
|
||||
# define DBUG_5(keyword,format,a1,a2,a3) /* Obsolete */
|
||||
# define DBUG_PUSH(a1)
|
||||
# define DBUG_POP()
|
||||
# define DBUG_PROCESS(a1)
|
||||
# define DBUG_FILE (stderr)
|
||||
# define DBUG_SETJMP setjmp
|
||||
# define DBUG_LONGJMP longjmp
|
||||
# else
|
||||
# define DBUG_ENTER(a) \
|
||||
auto char *_db_func_, *_db_file_; \
|
||||
int _db_level_; \
|
||||
_db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_)
|
||||
# define DBUG_MALLOC(a) \
|
||||
auto char *_db_func_, *_db_file_; \
|
||||
int _db_level_; \
|
||||
malloc_init();\
|
||||
_db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_)
|
||||
# define DBUG_LEAVE \
|
||||
(_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_))
|
||||
# define DBUG_RETURN(a1) return (DBUG_LEAVE, (a1))
|
||||
/* define DBUG_RETURN(a1) {DBUG_LEAVE; return(a1);} Alternate form */
|
||||
# define DBUG_VOID_RETURN DBUG_LEAVE; return
|
||||
# define DBUG_EXECUTE(keyword,a1) \
|
||||
{if (_db_on_) {if (_db_keyword_ (keyword)) { a1 }}}
|
||||
# define DBUG_PRINT(keyword,arglist) \
|
||||
{if (_db_on_) {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;}}
|
||||
# define DBUG_2(keyword,format) \
|
||||
DBUG_PRINT(keyword,(format)) /* Obsolete */
|
||||
# define DBUG_3(keyword,format,a1) \
|
||||
DBUG_PRINT(keyword,(format,a1)) /* Obsolete */
|
||||
# define DBUG_4(keyword,format,a1,a2) \
|
||||
DBUG_PRINT(keyword,(format,a1,a2)) /* Obsolete */
|
||||
# define DBUG_5(keyword,format,a1,a2,a3) \
|
||||
DBUG_PRINT(keyword,(format,a1,a2,a3)) /* Obsolete */
|
||||
# define DBUG_PUSH(a1) _db_push_ (a1)
|
||||
# define DBUG_POP() _db_pop_ ()
|
||||
# define DBUG_PROCESS(a1) (_db_process_ = a1)
|
||||
# define DBUG_FILE (_db_fp_)
|
||||
# define DBUG_SETJMP(a1) (_db_setjmp_ (), setjmp (a1))
|
||||
# define DBUG_LONGJMP(a1,a2) (_db_longjmp_ (), longjmp (a1, a2))
|
||||
# endif
|
||||
|
368
dmake/dbug/dbug/dbug.uue
Normal file
368
dmake/dbug/dbug/dbug.uue
Normal file
@ -0,0 +1,368 @@
|
||||
begin 650 dbug.Z
|
||||
M'YV,"@*"&$BPH,&#" T2 2$$1!401P0FG&AP" @H<MZ<D1.F#0@B9<34.7,F
|
||||
MC9LS%\.,61/F3!F)%&/*!"$F#\R9. <:D5.&# @C:>:@"4@481($1Y,Z0;"T
|
||||
M*14$3Z-*03"UZA,$5[,20;"U:Q4$7\,.03"V;%2H4),B19H5*]:F3)D6C1F$
|
||||
M39LW<^B *&.GC)P\(.!DW-@1!!F^9=B\@=.FC!N]CNVDR>BF\6,0=][(H8,&
|
||||
M,(@W9A0@Y%QFH)N.I06_D7QX#H@Y;QJ_UJP7M.&0(TN>!&%&91HV:>CD<3&P
|
||||
MRIPZ8=BPL3D:35 0=,*L*>.:]$ SFCU^-C,PS$#5A+7?<3X&S<#G(,:$@1-&
|
||||
M#)O2VT4?'//F<4;E)E'NQ5-F3!TZ:=0WD&V?D29'8(-QU(9K8;CA4QEX=&12
|
||||
M?M"A\1)")M'AUVELO!:=AML5:.&!$/;W'X7@*3@'<2!08>$<I0D'!W4#AH90
|
||||
MBAVY=L=O'8I1&D]F^,633W2\ 4(8KD&HH1P<WB8227ZY-H=)8\1HH7P&'?:D
|
||||
M2P<^Y\8;>K&W68C6E>@?@+OAV :+1438!ASON19?<^C)"!^!6N;FUWENC,%&
|
||||
M'8<-9%T8"!!J*!D((*JH& @PZNB1#KZ&P!R33JIHHHDZVFBC3NHIQQQ8%J0:
|
||||
M:SUA%IQYUH4%%EAP-:564E@@$.NL&^ 0 P*WYKI!#I_-R!&:*,V11UYEK#D7
|
||||
M14^X49IMUJGF7K$,S@';&&F$H:%/.W)V6U^*P8%B@CF&2I!)W;DQ4&23U6>9
|
||||
M7J9J"\(9;[SATWY+-MDIE)^"\!QGUHH[T&'<+E:JFG)J&"ET1H* 1AA]#00<
|
||||
M'72\-^"!('S)9[W)^:NO&WG)4<>ZU@;H!HLM.B<G>G4<E]QRIH'9'8)O/.L1
|
||||
M=@>2IC' B0E\X)1]EF:AOG.P\-F!UCI<!I+L"O5&'6S,ZZ/0&P/8AK6),7=0
|
||||
M;VW\5BW%V9I7(7P9;IC<T&<TF(8>(=<G-!G6>M=Q'6/040=/06O<H$_TV?=&
|
||||
MAV8H=@>9/ZM)4QD4WNL2&20GP2YZ86@,HQP!IDR0L^]IQYMF TT=]FD]?P=N
|
||||
M&XU]"O5X"8?!D\9UN '<="P7J3##I1U7'F\2 F=Z<)YU+>C/,(<WD(_Y::SY
|
||||
M8V&8U!/4=Y&1AAEI'#]T8+25ZGJ#8(ZXEQN24;8NBXIK_%QRL!T)L\Q"(V8N
|
||||
MS5]OF[.O0H_G6/J]*^B]G'?U-:_KD%Z?O;J.Z:6[=X))0]8 U##,I0YK6C/=
|
||||
MS7"#+Z%ASGP5,U*>\.6"8TTD6>FKWIX6YB"A?2%1'Q3#!^OP091\SUP0Z@B<
|
||||
M[L2=_$5-;&Q8X);\PB(A]"<,*2M-<$# DSC483(T"AN3QF:2MX$,0 *R3>-N
|
||||
M]#FAW4U?=)!3REH"'S*\@4819-=A9G0P 4'*,W.8$;4RAA#UL$<,6@,0%@ED
|
||||
MG?V8"(GFTE^Z*M,_J.WP>VRX0QB&93<[%(\-[9'8$W>DG'/QYTQ@BV.#/(,N
|
||||
M[?5O=T7[FL8$!T48L8$[A.R0F?ZCPY$-) GF"@,9E ='H?&L2E $VI$T1I\W
|
||||
MO0=$@5$)2UPR$-V)[S5B7%X:QC"0'%),B+VI$M2.I)Q)?DY.F"&/UW)X'G9E
|
||||
M\G?P&54:#C,O6TXI:X"4@PQS0R$SMB>-S5O10%STG'*:2RBF@T-ZZD,'CN0%
|
||||
M80,RD 4)\H5ZVO.>-RE(#(A3!2<D 0NJ]$X[15DLTZTA1$&@@@FHP)#$=(@)
|
||||
M[=&,M303S@H216,YD4D+0! #$+3@HA=%"!&$4(4C..1Q(&A"@Y#3H8S&Y EQ
|
||||
MB]F>9) #H<4@!SBP04BOEAW7V$:(32IB.S_6O[29RWT\V8M*O(:S;NWI=:!J
|
||||
M#N$H]H8[N$%H*6,IR^+D&F\^2V@T\\A/'P-#P]%08Z!\S<>F]A>A^4@]S/P@
|
||||
M&4(XPA(&U%Q '=L$N91*:;:&E?69$K'Z!!B59$1:O?)+R';32/X])FB0\LE;
|
||||
M<0BC5 :ECW\,9(R,M#+U.35?._0K%O,F6(.-P3.&Q4M4#])9@FTL?7- C1P=
|
||||
M^1B+8K0@+BJ-7.F* !(B "7L60D5]?4FO-"H/BQS&W#.@ :]A+$, W-,<H3S
|
||||
M&3=H;)/ BE^.A":C7:X,,&V FWFX6J$&<10&@?%+E1[C1 ?9#03)HXYSSY8:
|
||||
MZ;)!.%#KKGJ4XYD8H!>>()#!?WVU7CJ03 A6RU(9F.>&PKDME\SCI44$4P;5
|
||||
M5$E:F!-6&\2P-YI4#W#4*8UZK(L0'_&P)W"3GI'TX!<CZ<YBY6F02US3PQ\.
|
||||
M25 ):R-LYE8EP![&MC+)[77VYK?" >>=JKRE#W=YT($<!W2F\TR(=G>A^:SG
|
||||
MFP\+9XVH/)#=-JJNOXVE<%W"IJ6FY\IH?!A@1CPX[SDH#:S1*F"D^RR?8$YY
|
||||
ML:WSD?1B':G!QSO:U<YE,82]-TQG7C21\G.I988\% Y^1X*#:@)(M8&T<FH'
|
||||
M XZR[":',Q#UL1;-B9':]$:108<CJ'P-&JI:.#.D+FZF!L%[N&5I=M[GM@GI
|
||||
M6U4+0JZ7.;E8:6@!8>! GN\2!-/*HA@(4A8\EYKD,,2#(SR?[5T0*2LO%-HB
|
||||
M9T*-$R,]X3]P^$_Z_/BGXW)G90XDFAO 6 <QP(A=H(':=!*,D[QVR(^0T^R*
|
||||
M\DD1(S%!@#L\$JP#BV-?+UJ7O/PUNZ9<,=20 =<(<76?X+AOB!?$WP#7B\0'
|
||||
M;JZ!HG)ZN.R/+DMU[>QJ&PW<GHF_VY,8I<YN:70(MUXT71K=[5@.J&2>Q!HN
|
||||
MF\A:W" TK]C'?"2'E,MDY3YJZ=%F]QEPBUO6QJOEJ4PCVRG[1PX\><S/1961
|
||||
M"U=<U!=)F7DP!X?%7*RLABM<7BH-X)55=>L$P:ZI=2>2W^B%7'O-]H)Q>-^O
|
||||
M=QL$4N@)$./&Y7L-R.E):^?1M(._M3O(= ]W*<QE/A 4Y,6*_TG!Q'Q]FL;,
|
||||
M2^=E8)&0#],;IM$![H>/N;@[MO@D.YYM<IB7D# ' LO3X3!83P')<HOZ$RN/
|
||||
M)QR';W\X&!2//*>5*]00RYY=8<= NS8VRNB7Y#"U#EWZB4$?TN"EW78[O&&:
|
||||
MJ9=Y[_/6MUU&T;;S=*E& ^Q1D*;_(R0UJ7'VI%(WL%3]R(HIT0-<4X[B5*?O
|
||||
M!P4((( $6!54016O@A1-@ +V( )F 1G$14/: 4(0($66 0(@($:^!%<T8%$
|
||||
MH($9F(%"@ C6(*J$A9'@ IN((KJ((J^("MPA0MN((M@A91 8(:6!9D019(
|
||||
M@ ]^(,QZ$]KD111@ !%>(0G"!8XF(%3@ !-^(3O9Q"@A#$=(E0><T2FAD<\
|
||||
M(4J%13O8M#6UUC-P<'JC821W\4YJ$CJ0=4HZ='>ND57&9AW,\REZD7<GH3$:
|
||||
M4AX-YD/P\1ZFHRR(@UMYX"W[M1S#) (!=!EKIR'K,@<B0!"F4V4&441^<2U\
|
||||
M EM+@W,B)B^E431")%\H\GV/Q5T_0Q^',3\GAGR_42I/A%W.$UF%1S>F5SB3
|
||||
M]W2#=A IE#6 ^%KF92V,.(;P=!A+HHLU-R)6DAH9(3- 8W0$(606AF))54Y+
|
||||
M$C)],3I3YW)>$QR*Q7V.EAC*<X<(<1=)!8OPI1EW@GA0\T0*(S"NQE^%=W.H
|
||||
MQ"Q7PD0Q4SFJA&?TT1<WYB,T<XQ-IWIZ\5:Q02-%8B391$M%LD!CTRY>0WL4
|
||||
M)AE+,P<LLS&/8XD>0C6-:!K0121&XB,:PQ/UTQ,L A2>EE0==4+[H4(2(X_[
|
||||
M,H@LY#D9!V>26!!VB!)YB 9[6 >AMU,Y,0)4\B>!P@.7%R N@ 8^P&\Q,3RU
|
||||
M9SIG, 9.U&EVD *]ER%'TFECL /CMS 'H@),:0=;T 58Z5)[T'M<ER'<@0(B
|
||||
MT)5; -= (] (E0 9<X 8B\)1GX)5LF0)AB7\@\ (J0)8%H0(#$7CO9!MJ
|
||||
M I@$H0(O@)@(8I:U)P(]\)96I"QNV0-S*0)ZV7M]$(5\B1 D.3>E$0.,61 8
|
||||
M$9,- Q);0B%4,'PY^1(@)1-%T!>/(6?I>#!PZ(Y'8@9+ HD+YX=(]AJ(P1$Q
|
||||
MA"'32''YQ3N44RQ25TB#<SFIXQ-/1!]8UQ_7PB)!0(8'P1G/47890HJEH2QW
|
||||
M,)&4N!FETIB7<9&,V#_TDS+LXI$(<1C3)77;1A#)LBQB )&2 QM_(FW[8B37
|
||||
M!"> <1BO=(QM8#?*44-EH!O)]H8JXXY65"'?PQME\#=^]H:/\1M?XQD+TQ=X
|
||||
MF# \,2.15"87FE3/B%C!"1A^)C[@21,C 3UP\(9P4$$((60PDC<^<8:U<9^1
|
||||
M(R5[<R("TI^ST1BK]C>&$12:164:4XMT #6$8R"[DQ$CX34ZEHFH9(J;"#J/
|
||||
M%$QIE <LP$I;*&U*9'CX5BW/ D\F-@?94AZEDD0' AIFD&Z)ACH\HQ]M9!$(
|
||||
M4F%=1QVP470$\9E))0-WE9*NM"SG5DS-P1,QPIIIP(<5AY2=>1 ;-0/MYWX:
|
||||
M,U(E=5+TMU(+^:@% 5-%LG\T95/_YWXNY9-] I2E(92W1Y1&Z:@30943Y)8@
|
||||
M -8V7M*B0),Z915>9=2Z6R7D:M[F1,QMI5J"9:]-Y:=Z9?F20=GF990*:LE
|
||||
M@ >7:9=1"0**R9C+4WL3I'F)R*R/J99L":UR29?4NI9=D)G)^I>/*IB )U\A
|
||||
M<ICKNIBENCRD]Q%%$'^,V:W-&IF&41^E$9F7B:X9-0+.MSR:R9F<VJ=I4)*E
|
||||
M(0.CJ1 ,]!%&6J:KJ8>+JI.@\IHQ401F=I.M"57-)">BY$?$,V/E,B]X-K(-
|
||||
M$ATSIC&V1#=BQ"[X0P9YT'F[! )V("4?<K,J04!&94I4NHFGB!"KX1<6(DI"
|
||||
M WRQX2V )&TU!D2-6#Y(0JB]!"-0 Z\'L85LDV:XPZ1T, 8D\P3ZR$Q3UD84
|
||||
M5J)[.AO[*3(:LV0KL55'0P;5823)N2 ,.1L\)K3PH;58ACLG*SS%0SPFT;?4
|
||||
ME4SO U^SN$(#,0((P+B.FP8( +F2:P8(0+F6>RF*4@8(H+F<:[F56[E.E@<;
|
||||
MMC<B.XZNXYX'07K&8V<4\YP+MKJ_,[7SXD4'%V&"XI)R@B<,M$!3,B2B]S/P
|
||||
MJ+=G9BXF-C6!(I$+VUPL(XX_$K>:I3$UH5;!<:3,%VVF)H^EX;B-V[B2&[F1
|
||||
MZ[F7BRF9N[GDNV"?:[F[^FE1!$]3\[6H,H\'4;T[ZT5L5(J<Z%;B]B5ZT5D3
|
||||
M]J%YBF'YXG9W@(<FLWN\@UR>\;0@^4B70S$Z%AV/%WO%L2IA$80/."NR(BL$
|
||||
M,03&A*=OX'68\QSH8QTG, (GD!Y:V;-[,CV2=C1=TG$_,X=Y 5A_T@97]3M/
|
||||
M!T$0*B<P BT.DP;3 8EQ5)5H-%!_(<21=Q"ILX6P<1IE>F(=8WXB0S)^"A^2
|
||||
MBI*YJ+@LN5H&,45D1JD:F[ )L5$T,*FD>A"6*G\H57_W)\8#X:DR=2"AZG\Y
|
||||
M=<8]^9. DJI#^09%>92V&KA+:974VJL9197 FI6F8ZW%&JPX@:P#.RYF4*\?
|
||||
MB*^=J:_?"I7F*J[3NJMX>:Z,/!,C$'=O%GWXYY>CR:Z$"7V!=LKR^LCG$<D+
|
||||
M9J^4S)>6C);\.IG_:IET*; ]*<K*0\HXL9FNZL95# (S\+!-8([M*DI'BA$>
|
||||
M#,('8AQ4!,;47,UV[,8&L5$U8,9A7!!IC*D'PL:;*L9P#*K]=U-U_'Y&@ #K
|
||||
MW,Y)V$]QT10Z:!8VF!9#R!9ND15!6(,1:(!5$00( - "/<]DL81% (&C<&S
|
||||
M(M !'= -R( ,2( #.(!,@ 5?=$&C; #<04UQR,7.29N*FLNW&"[$5%/UT9>
|
||||
M!4YK!,P$T49>)D*]95=B-DOP$;W+-J<O\Y\2HXO4%&C)M$M#449+RTG5$<,]
|
||||
M2U%C$Z9"MV$T1!!I-32X5W"# S%^L4!WP3$#!4MMM''<YW&ET1@QUF!ST :D
|
||||
MN)V? S3>,ZCK4BK -S=3PBW#H1,+"YH@4,;[\C-*R=6Q1C,$+,)'G6\=HB;H
|
||||
M-Z^GFL<@H*K*P\>MZE+*.G\'XEI*PS0^P4P\H!C[]0)D\"1];*VM?,>%'2@B
|
||||
MD-DC490B,,SA",BX*LB<3,@Y8<A6^<DR,:R*C,G&*I:,R1,E02POK!>R>%]"
|
||||
MDP9X -LYH20;$C6T$U. 77LIX$1%D@;*7:N=F<9?4 1.0 5%( 6/.3R8*=PX
|
||||
M(=U0( 5/, 1%, 53$,AW::Z\K'[H@P+ +:LQL /Z@@>'O:N\9 (FP,E; -Q=
|
||||
MD,G\>@(M< +P#=PKL *:Y\B<BJ;!,3NI?=[ZO04Q<*X@8.!NK!Z55<(GH ,/
|
||||
M2Q'>7053@ 2U9P(+[I4-+@/GFM[8_#M;N ;<[5*;V9DMSI?K'>#RS0/T+>,#
|
||||
M7N 9#G\E]07?G035?<EGX(A"@Y9J&9=M^98E(.3Q7:[ZG0(FSI>]K1=O&4Q%
|
||||
MDMRXVMSF+>)X4.(KGE&U+ )QN<E1_N0Y\>+X)]U24 144 52X 2U!P-D3A'"
|
||||
MG.,44<PT0.=&\-?5TB$8H1$*DE*!2W/7G!!"U@8(8.B(;BB%4BC=*[EN@ "/
|
||||
M'NF\\6K\*2<P&UAI\,3H S->YV#K!EA0=C!01YF]PGU,J;XB>S"D$4?(=R*[
|
||||
MX7-,E"$4(H=ZGM3<L73F\25NT *+(6VGOCT\>>($L5$VP,W!3A#?[-B ;G_C
|
||||
MG+#E/%/G/*H:_1.349B%R@9"H[^[9"5%TUG8:U8'HM>!Q6E@H];]4YZ2 6AG
|
||||
M^[]I"U^I)4[C9#+]2B/ZNT >IW$9X1'6P;=<2UW?;J6P.#73X1HIZQ[-QEJ%
|
||||
M%*NJV+2FUDYPMN=+^1KY(3'K_L%ZFF&BRV'87JD>R!4E2((D^,XSJ((?5/((
|
||||
M\ 5MD17MS,[LO/+M#%::<6'I,S5CD!'[P1X<(S)SVYSVIQRZ9]H@4!?AH^T?
|
||||
M]S-X/"5)U$)M=+11S1NK^"_BFRF;XBAUT%M6/Q*_E?5GX ((P/5>CP8( /9B
|
||||
MKS%FD._I8]ECP_1[ GI%"GQ5'M>U)V3ZB/1X]=D]H3'&J$I]YJYSGX5QU$:B
|
||||
MK1_!^R]!X? B 4<WLWV:D0>ZUXSRSO9Y$QU%1$P=8AVJVV 4U\"2])X,Q%<T
|
||||
M?UCMHTR4_SH-(X?9P8%=X?$@;X(4#!8C?P0F7_(*+2NSCP5>W_5=?_M>K_M=
|
||||
M7_NU#V0Q(62IWQ4?S_HG^/JQ?_(&'801"!4&[<]4X>XU;R0F$59%731[M<(+
|
||||
MXS\^ SO7158WEC[B;BZ=5RJ(?NB'KNB&TNB1&^F0#NG<HQ?A]4XF9AWZ"!@R
|
||||
MC)T&(0+8I5F/&'3DXAWC[T2ZN2>==1A^8CI&E>I);!#\J,R+)")[TO]E2G._
|
||||
M6QK#K_K%+_(NN(+)S^,378 ':!7YC!4$+=XAJ(%/Z(1.^(1.Z(32;_.W:! N
|
||||
MD6S&ED-VICJ 41^HY"L^[3K5?_J W_E5C1#C433EGSZ"HT>N81+>=V@,^;NE
|
||||
M,?RJ7_PB[X(KF/P\/M$$^,Y/Z(1.^(,^Z(/2GQ'"(R\C5]0B-C=95X>=OR>+
|
||||
M6!K1&UN2\>IFRQ/XR<4%L8A_=C#OEETJ.J'H61IB(+O5E3Z1?Q\> CG@>!#L
|
||||
M(2VLZ!K!P2"=IKZ_6QK#K_K%+_(NN(+)S^,378 '6!4P&,],T?P,)?TVGV0Y
|
||||
M=#]O8$Q4"3_DAK$A@NOINRZ:/QY +3Y4CM15R,4%<;I7*G,B&>^E,?RJ7_PB
|
||||
M[X(KF/Q? /UI'H(:V/QKWOIL?H!5L<^?GV,.53"\D_W:U!PARCO.MV76<759
|
||||
MIW&4;FH+XQH^\CY;J*;0Z5X(P1-RPR0,@K/)H9, AM(KTVJ4/L4$41<M5;\A
|
||||
M!KC3KR,>;6+MR#(0 B>!6RKD<ASN5@9\J(C4J?/,.*-&PDR6W_E^X9W'7>40
|
||||
M3TGH81+>=V@N.W7><7V1$G3?'E883N=4CM0=T@(C0 8ZH!<=!:C'K#%"!E_H
|
||||
MG^B+OO[>Z^CO+^F3/G&QIK1GT& L5C"\(P(M, )DH -T\(@> CFOCB3=L4WX
|
||||
M$H;MU&$> CDGT5X^P1[20I _D_U$TVFHKC%H208Z0 >8*=4N#4)?%M-AQD.I
|
||||
MDZ)J)6FT,1!0BB98E.Y(*E(=/U*K'_*M7U(NN(+)S^,338#O_(1.Z(0_Z(,^
|
||||
M*/T9\;O;:3H XA_9Y"&0PUA.'"?_2'EE'QL$7!K#K_K%+_(NN(+)S^,378 '
|
||||
M6!4P&,],T?P,]?DN-G4D3 8GW#<M 8MT%B?70>EL.QJH5CBV1,)T<,)]TQ*_
|
||||
M6QI4CM1\0^E96-2.P4HK(SUH@*C0(4#4T3Y3-RB=ANH@( (Q4)<#(0(R4)<G
|
||||
M.Q B, ,B(*,'X01@ A_\(K,_X]U2X.,,%1T#GY)QTSH(0 <(0 <(0 =W@ !W
|
||||
M@ !W@ "9@0!O@ !O@ "<U6FHWCZG0L"QTQ_U 9V=IKX1'U9%$\4E'2E'!F\M
|
||||
MU*W/BQ#DAK&:YQA^8EP^02YBTC\O$A3,*%(1&_GWX2&0<Q)=A>G6?DMJ+P?'
|
||||
M"1\BT (C4)=D3V1559XV#6CTH1CG5&&F0S4^<62JG/U$TVFH+J,'P;&SD_U$
|
||||
MTVGJ&U 2?Q(2,ZPJ3#%]TQ)#IAQ5=?<E5ECFTNLB,S;7!YQB0C4^<62J_.OJ
|
||||
M&7*,=K,)*57O(I/G TA;/Q!3,)""ND(,PA,8WLW"[E$@< /&_G[)OL::VE)N
|
||||
M_.QR'.WI#/0XT0(C0 8Z0 <Z\ 9TW@(C0 8L8!(L ',Z\*;#HP-&H -,@)1.
|
||||
M ";PP2_L\I [.I%T]AXHV_E/U;,Z;VGF!4V)GV?O(5DH:K]ZTR%1O!LBT (C
|
||||
M( + 3Q&C][J8?[W<0>O(#?'C;TH9OS?T!9U<7! BX 0A4)>J5!*RF6@8GN-.
|
||||
M$ *RZN:"Z00MT%&"Z0(N0!R *IBBJ3'%O,UW71I4CM0M-?ZU)/K$M4(9N<,&
|
||||
M"B^0PQG:T=:?(I/+03). ";PP2]\)N]>XC+*XG6WLQP$7!H^\DYZA*()\Z#'
|
||||
M7>5[GNJRAW6T9Z/!H?/=<3H8<@;35RK(-Z#+,=@#B\=!N<=]W'N-C5*0O6J2
|
||||
M?=.IBO9L@-F:;92<W7NFZB>&'=J:C0:E/9670>5(W2$H0&XZR=HX@=N%OR=4
|
||||
M26XZV>4((>$N)=W4;=W8C994CM1LL-V,Z=U2X.,,A98,1@9U^9@,YA-Q>=Q5
|
||||
MON=UB;/)H9-.WN4QD:TH0&XZ"0(^P%$X+L;DII/6.N6UWB$H0&XZZ5$<%><S
|
||||
M8>;JY]U2X.,,A9917I>/&>6J%)=UB;/)H9-.WN4Q@>9JSN9NC@+DII-Q/A%S
|
||||
M+NP'4<PU0.<%D>?(#?%&0.ELV\T)49]'0@8DR[*E87D#Z>Z H;_KE/-1'7"P
|
||||
MH7D QFS@F)V\\])@IA_!1=/G43#;WTQ.UD[U<083Z1CT,3=4Y!KMN!R.,U1Q
|
||||
M YIX(R\4HCL(7%VET3]'_$3^NA^A)8J+0V*X:&:3/G%3/!!-D+@2 R&A)8I1
|
||||
M9$KB=21)8CHLPQ-RPR1<7!"N0QUFU(FR%B]P(#13 Q@FED-D@+^086:R8Q[<
|
||||
M>9X*3!T$#!]D2R"]*&D906D@,ORJ7_PB[X(KF/Q? /UI'H(:V/QKWOIL?H!5
|
||||
ML<^8,_RJ7_PB[X(KF/Q?8($56($ICQ4/./Q<D?Q? /UI'H(:V/QKWOIL?H!5
|
||||
M$82 ._WH1^=C# (X8.SOE^QKK*DMY<;/+L?1GLY 3P4=^4--4WA4CM0M14E>
|
||||
M!&CO;,'W_$\9/"NA2RQD#>I,VXF1HFD'I3O6<7T.@N&H-P:\Q.O'7>40/SPN
|
||||
MP$M4CM1LX *\U )-\R1(*60BT )-\R2/^.L,K'QL4#"\HQ@$Y< )HVE-UFLV
|
||||
M@Q ><Z&R<1R21AOE2 9,0R,C_#,O#6; )4M4Q":'Y.HV";\&0>5('=AG_3_K
|
||||
M%.IVQAVF3WT83N?'7>40WU& *JEE7 -(Z1+)1C5%O2R(IVI55?=.S[ @8 .#
|
||||
MG5&BZ5(.ZU(ZY5(R<.<N%0,"-NV<6LPZ)>S'7>40WU& *JEE7 .#[IF4'FNS
|
||||
MUG*GYANOCAYT]AY.XQGL(2V%8S.</T,U\S,G0 <GW#<M\5J6'[&1?Q\> CDG
|
||||
M,9)SG50W@(KPHZ0#$>6M9O;P<WT'(P)4CM0=\E$(,0)TH -&(JDR( +H9\V4
|
||||
M*NS9# *\\E&4*E+Q!\[+WL9N_.QR'.WI?.PRP0<$X0-4CM3#F5%\0!!\0! ^
|
||||
M0.5(/9P9Q0<$P0<$P0-4CM3#F5%\0! \0.5(/9P9Y; NQ0<$X0-4CM3#F5%\
|
||||
M0!!\0! ^0.5(/9P9Q0<$P0<$P0<$X0-4CM3#F5%\0!!\0!!\0! \0.5(/9P9
|
||||
MQ0<$P0<$P0-4CM3#F5%\0! \0.5(/9P9I5,NQ0/#,^V<6LPW0.<%0>5(W2$M
|
||||
M, )TH -&(JD.V\T)P;&STS]'[#J8PQ-RPR2\8?;>,?ZJ1&WJ88DUH3$GX ,G
|
||||
MK/GPTS]'##U428XGP ,GK/GP R&A)8I+"EANH"QQ4RK1JX\ LE\T83H[+\#N
|
||||
M[KZ%PYV/)=6H:Q!',R4L@QW/:;CG5&&F0S62!1@'61IX!L$7!OP404[5@6K+
|
||||
M@G@;HSSJH2'7SV=YKT>ISB?!L>>LU%D 1N5(S3=F?ZNNT^H@(@,AL-R7HQQ5
|
||||
M52K1NT0',:<2T]:?(I-G5DBN0^5(7?E&TNH@$@,A\+OP,3S&Y.>%\35QI*2Q
|
||||
M2!VF-V04(P,A<+*6MC+2 [\&0>5(W5+CWQUETVNVI&/]41_S\NMU-! S(*,'
|
||||
MD>?(#?%GIASE&1R6U$)M_2DRV3I&TNH@(@,A (LQ$ )=*E7FPA-RPR2E$OGW
|
||||
MP;Z!&_I _8^49__)H9.:/P,A8#>1 B':B#C3[@1@PNU\EO=>8H;64AX4TC]'
|
||||
MS)V7(0+#XP./V, $O+=E(#=, CU4*0(\H-V# U>5531])D#^./RJ7_PB[X(K
|
||||
MF/S3'8(:R/SU;-TAJ('0+P6 ._V8@20GME2E0B[#PUVH1B%ZY!KZ>SV:Y1-Y
|
||||
M4 8&YM3Z7Q!ZE+NJ@UJZ^51M]/D),_RJ7_PB[X(KF/P\/M$$^,Y/Z(1.^(,^
|
||||
MZ(.UA"2&5&J[P2_Z7Q >1R&3)1MT]AZ!6#+EY$I:QB]\]C.__DA'IO\%$=E-
|
||||
M TV>8_'24IY(<BZF,Y%( CW2DND2PX:C;Z4=7"7?2*>\D_^6UED -ORJ7_PB
|
||||
M[X(KF/P\/M$$^,Y/Z(1.^(,^Z(/G@4QZVC][OAQN)AE3\L2N@[E2KRDB<?6]
|
||||
M=09:'V8HH)U=95XFEAER<&A5N321$KWCF5U+E)W%4G8<<<0#,?RJ7_PB[X(K
|
||||
MF/P\/M$$^,Y/Z(1.^(,^Z(,H@ H@ H@ "XNNB&(@<(( <(( <(T&E:_UMV
|
||||
M@ !V@ !V@ !>B0!;@ !;@ .CBNX@BM=@ !=@ !=@ #GB@ I@ I@ ":=QY8
|
||||
MJCQ4,Y'=H9M/A:0BU?$CM?HAW_HEY8(KF/S3'8(:R/SU;-TAJ('0+P4H@ H
|
||||
M@ H@ !HB0 B@ B@ B</Z)ONCK[[V._OZ1+@((( ((( ((@)D(D ((D ((
|
||||
MH'F?S\?=+.P>=5[&_G[)OL::VE)N_.QR'.WI#/3U*6M(DT5EX)VGIA++@G@1
|
||||
M1'W&UDIK]'3U0<#P\7J0MQ=8IQDL,@54XH]4CM2!?=;=ZAK!P<4%$>75!5L0
|
||||
M#'MVAHY?$XU%'4VJE>E;6B,$?(X .2!_SSO#.+@M!3RO/@<UWQ%ZIB_<T6>9
|
||||
MX3B*ER-5^9TN(RQ]@@:405^!6#*28_F=OR?]V30XYK*0 R+!X5.(5UVP!<&P
|
||||
M9V>(1Y$:@K0X6RWI<P)O< )D#T@H,:PJS*<#X01@ A_\PBX6 P(G\ 8G3%QP
|
||||
MHF7P0WI\I_\%87MW WGG@G6:L=R^=@)O<,)W:S&_KI["UR Z>S>0EZ3H"(O>
|
||||
M<0)O<,+_HTB=IKZ9<S0<4[7EV4;EG\0& 7J)XP)% #4B0.5(W2$M, )TH -O
|
||||
MP **<09L+ZDR\(B8L31-@QF0 R(V,QJHMBR(]UHBH!AG 'HB@*!P55D$\LX6
|
||||
M?,__E,&S<A[F;KWU8>]_!%F!QJ!RQD.I0SNZ;;A'!3G9Y3J7!W,?:2W6PR_G
|
||||
M='M"0HI+PUP[K$KZ*SX!)!ND-4W;R+:$ML."ND+H9\W6;,W'+NP;%0,=]5&4
|
||||
M*E+Q!\[+WL9N_.QR'.WIC)3O_(1.Z(0�(ICQ4NS\ZH[X'%'_*M7U(NN(+)
|
||||
MS^,378 '6!4P&,],T?P,]= -R- #O8-E ?W@G<]8,>V%/GQF,]8WK6(P0P8I
|
||||
M!@*("#F/80:/F!=YL)*(=QY<7!#6,?RJ7_PB[X(KF/P\/M$%>(!5 8/QS!3-
|
||||
MSU"?S\?33@6<I1R[9DG4>;W<H:2\8?:U>[.?CQ?'.9,$D?_=T6GJ"T\GBOH>
|
||||
M6/PAW_HEY8(KF/P\/M$%>(!5 8/QS!3-SU"?3_T, @(O#68H,6^9$7LR>A!7
|
||||
M8"$P_!SSEAD2O!X@"EHPW(F=IKY0AV3U"Q\G0 8G0/: I!^7"(DT&;$$$?GW
|
||||
M01!1?!+#A"3C,L0B\%$(,0)DP +SEAFQ%P,L,&^9$7LRP (NX (NH -T4)?_
|
||||
M2'EE'QN%)YV7_F;@>!"?GS#/06?O$8@E4QJDQW?^8R$P[!<ZY!H6<P)D<,)]
|
||||
MTQ(;0\";J#<=$L6[ :1TMI*(QQMF/_JH[X'%'_*M7U(NN(+)S^,378 '6!4P
|
||||
M&,],T?Q4 +C3WZA!-HC>Q5].Y-//9&(>8R[U(4QW:S'SEAFQQ\4%4;O-0P;Y
|
||||
ME3#"Z!?$6$O;#P+SEAFQQR!)-25GT& 1MK(-3, B-C=9%R;):(\H8!WSEAFQ
|
||||
MQR D"CEDY1.]UD:?_P9)BG@_K"R-7S+OTRQG_4PFYC&A5#8FT3Y39S.<W[OE
|
||||
M.6^9$7N0!6"Y&'75-9&U>[/=P<0$ 1INMB3R!?P40:/]41_0V6GJ"T_>,?RJ
|
||||
M7_PB[X(KF/P\/M$%>(!5 8/QS!3-SU"?3_T,<I$1G,0&8<D>D@<[%U:1%,6O
|
||||
MKH[^^CS,F[X9F9"QSEZC[QA^8EP^02YBTC\O\ASAPR]\9B%K1F34*9/+ ;W]
|
||||
M,9 &-_'P\?FETVGJ:\#H@1Y#BK.W\[P(87],G2^&"3F/<6Z=ANI5&3MU(&G1
|
||||
M$XA!SP;ADT7PP2_Z7Q 6<_/ 02WL IY!EV0*S(I\]C/.!V(-W+Z.X_ G89T,
|
||||
MXNY4W:;<D1=Y\![<E1G/PQF(^AK5UR'#K_K%+_(NN(+)S^,378 '6!4P&,],
|
||||
MT?Q4 +C37[K1!"2*5:8@-Z<[G5IWZQUH,!*E$5;]@A!1?!(C.==)A0.J5E5%
|
||||
MO2R(I_FDQW<RBVJ>GL0*IMG63,W"GLT<!:@?1:DB%7_@O.QM[,;/+L?1GL['
|
||||
M+A-\ (F=-@<Z@-\D+JO'[%)\0! ^0.5(/9P9Q0<$P0<$P6!DH -.'RF22N5(
|
||||
M/9P9Q0<$P0<$X0-4CM3#F5%\0!!\0!!\0! ,1@8ZX/21 JA4CM3#F5%\0!!\
|
||||
M0!!\0! ^0.5(/9P9Q0<$P0<$P0<$P0<$P6!DH -.'RD=1>5(/9P9Q0<$P0<$
|
||||
MP0<$P0<$$>4Z ,6FITJBZ5)\0!!\0!!\0! \0.5(/9P9Q0<$P0<$P0<$$>4Z
|
||||
M ,6FITH.ZU)\0!!\0! \0.5(/9P9Q0<$P0<$$>4Z ,6FITHZY5)\0! \0.5(
|
||||
M/9P9I5,NQ0/#,^V<6LPX0.<%0>5(W2$M, )DH -TH -&<LS=3.@_HZ2\8?;6
|
||||
M,?RJ7_PB[X(KF/P\/M$%>(!5 8/QS!3-SU#2;_-))K_EF9"G[;Z%Y]7_2'DC
|
||||
M',.4[O<_/3O6\?EOD*1C<'7P?@468BXU>1YR0F?O0090<_@M([.H5@;'.9,$
|
||||
MH:0?O;Y%8QWOH9ONWFDFT3ZG G,;\WQ&!?P400425"R!E=6QDQC4>;W<4;LW
|
||||
M^_EXH?E*VJ41-]?CR"NJ5E4%PSM17DL6 L.E0>5('=AG?8N36&B'=K>6'[&1
|
||||
M?Q\> CF[(0(M, )DP )1K@-O( *#G5%4CM1LH -0;'HZ ,6FITJBZ5)4CM1L
|
||||
MH -0;'HZ ,6FITH.ZU)4CM1LH -0;'HZ ,6FITHZY5)4CM1LH -0;'HZ ,6F
|
||||
MITHR<.<N)0-W#O2<6LPY0.?'7>40WP(C0 8L$.4Z8"1W3JG"GLT<):D?1:DB
|
||||
M%7_@O.QM[,;/+L?1GLY KSBJ!!N-4:&WT;M'"F!TX_"$EW:O?C=XB&I_QG$%
|
||||
MPUDAQV@W._[/<V2J//[[-J/R_CUC@'Q'9B'8,G5M= )F<,*\ 4CZ,:PJ_$M_
|
||||
M#[\*]B1AV$X=YB&0<Q)4/-?CZ%_G43 'C'@@1O:U'MAG;;AQY#%Q9$LH;6L=
|
||||
MYB&0\^HB\%$(,0)DH -O2N5(S08Z8 0ZP 0Z\ 8B\+NE<0)&<,)]TQ+7HV_+
|
||||
M2B'8ZSA!Z_024_ZP2,),<,)]TQ+7HV\P>:&O7K\S21"#S_9!9W],773'GA-4
|
||||
MCM1LX )CH ,&D0,Z<-Q5ON<ZX/0.H@-.'RF22N5(/9SX1^5(S08N, 8Z8! Y
|
||||
MH /'7>5[K@-.[R ZX/21 JA4CM3#B7]4CM1LX )CH ,&D0,Z<-Q5ON<ZX/0.
|
||||
MH@-.'RD=1>5(/9SX1^5(S08N, 8ZH$\SH /'7>5[K@-0;'HZ ,6FITJB">.U
|
||||
MS@8N, 8ZH$\SH /'7>5[K@-0;'HZ ,6FITH."^.US@8N, 8ZH$\SH /'7>5[
|
||||
MK@-0;'HZ ,6FITHZY5( 2.<34<S^];!4CM0=T@(C0 8Z\*94CM1LH -&H -,
|
||||
MH -&<LS=3.@_HZ2OQ3P,>UZJ5E77SV<_(P(,1@:/^/D)<XN3&$=L#P(B0.5(
|
||||
MS08N, :/N&=.%K0_3)DX (O6(0)17MJG/?VJ1"[6$5NRP?9%,_A!%P,R@'[6
|
||||
M7,W"GLT<5<8?1:DB%7_@O.QM[,;/+L?1GLY(^81.Z(3O_- -^- -R- "#?U2
|
||||
MD 4(D 4(D 4(D 4@D/)8X?+LG%(0W8 ,/= [6!;0#][YC!5/Z(1...WD)"74
|
||||
M:6I/QE;T53"\X\4O.?KI,3=9%S'T1A"77YZ?CQ>O91TO#6; )4M4]+M?_>ZW
|
||||
MP6#!H?/D[IR10B[6X4L;XR>&S?:8*_6:(A)7WUMGH/6_Q?M%&?9A'_:\8?8/
|
||||
M?#>0YV9^8MB_1YV+/]C='7_37=W771PPPI'0X5#IXS$7*AO'(6FTD3GRPC0S
|
||||
MR:EM5/X@-ND39VK PUC@+Y)T7C*=V&GJB[CT3[5V @*(*(J[F9#8/*PJ+ <B
|
||||
M8,#P(=W4;=W8_?EFR)YT?J=5$BBC[T9G<J2CCD6]9C/8//X#H0;L>2[@_XKJ
|
||||
M./]ZT4HSR:EAH)M/U5FR]L$+>1A^8CI&!>\#P;'E0><Z#OO4;=W8+?TVC[A(
|
||||
MMJ&=Z.[N>_!BC.9JSN9NCCG2;05/D 1$\ 5ION9M+OTVWR_8O-64'FL0$G#<
|
||||
M"6H#(=W4;=U20.?2?U@$D4.(UC4P5Q" ECG64AX'+\9HKN9L[N;/H^.P;P5/
|
||||
MD 1$\ 5ION9MGCFI1>>F4DAP55F8\8>%TQC20D5R4O:Q@:38_-)@!ERR-%P>
|
||||
M<Z&R<1R21AOE2 9,LY-TCM!8H ,Z#OO4;=W8C9;:G9E;A^9JSN9NCJG0"1EF
|
||||
M!B&A)8KPUD* -OYTODZ"2]+Z 6C23=W6C=W2;_-[MOENW#]'S)VU%>^=V&GJ
|
||||
MJ_>\0VXZ2>< QA-RPR143.DZ7TNBSQ-RPR011.<XFQPZ61 HX'W3I'D$$=E-
|
||||
M4Q!DV]+P*\;2;05/D 1$\ 5ION9MGCFI%?^!.GO:A,WX0Q ;"A^0J!#Q]P5I
|
||||
MON9M;A":0><Z#OM6\ 1)0 1?D.9KWN:9DUJ7>$OC3^<_/3L+XQH6T[[E02'2
|
||||
M3=W6C=W2GQ%=BLWJB-)+NXI<X]'(!TCDDJTV@\V?CQ=5V8EQ(V<W72HH "$X
|
||||
M3TT_3^<(C04ZH..PG^9KWN:U1VXZ&>?X5P18H ,Z#OM6\ 1)0 1?D.9KWN;0
|
||||
M+1/>#=[B3=[% 2,<R7/^>'59QRYH"TT'+\:N&(@#$02W2XAC\^M9BCG:R<4)
|
||||
M^_G4[QK.>MYL69<5LC3,U4S+V5*H*\:^$B1QPS(+(VF \3_K)B)[$L4GP8R/
|
||||
M6@18H ,Z#OO?'=[C7=XACM[0G1,;WN$#,05EL+[>L:+9OS,?4AK1&VY",>OP
|
||||
M*\97EW5:%/69/?6-4O557_58?P9:[V0?<B>/43IQ9&_'+NP;%0/;_%&4*E+Q
|
||||
M!\[+WL9N_.QR'.WI#/0YL78K 8OOEEUUH$[6L:*+6!K,!HYN#/@1NTYZTR%1
|
||||
MG"9( B/06=0SR:F?SUF=IKZ_^]5XP2Z7YD5>/).<"J3O!EL?$CL0UCR2U843
|
||||
M1.?KI#<M%<6O?F(.CQB(5O:QT=+P*\:_SL!'9F $X01@ A_\PF<_XX??> 9T
|
||||
M#@(BT (C\(CDXAT*;VL=%L6[4;O-D\1BC"2^=GV1$G2__DCSKQ?N'^EO@ !O
|
||||
M@ !O@ !@@@!T@ !T@ !.9.<RA[2PHJN(2:J##^?7SJ=IKXRZL;.F!&^<M/#
|
||||
M!:3L@5@ )(J[F9#8O-75SB[#JL(4H_Z% KZ52P<(0 <(0 <(H"'EN[ER@ !R
|
||||
M@ !R@ .S#L@( (M, *EC<U1?!+,^*A%@ 4ZH..P#P4<[N$H$.+YO=\D[N1=
|
||||
M[E)%@ 4ZH..P#P4<[N%H208Z0 ?;3><(C04ZH..P#P4<[N%HN=U KQ#QQ^-/
|
||||
M 6#*5_F6-3(R!<["N[H6=/TQJEE)VF%8QV+&#O1L1+62=5ODET)B<UEIT[,
|
||||
MZV0?@D7\$D?A)A3E^4QMALT+.WWEJ8X6@QE_2"'/9&(E(9LRZL;"'W\\_@10
|
||||
M(/TVOS"N83&_KI[,^*A%@ 4ZH..P#P5/ 7/#?3>'']?8 1)P 0'73+P(=U&
|
||||
MD 1,<-#2;_-)ED/WDS#]2N<W#QS4HA=)\ )/4%WI$ZM*ZB%;:"S8K#BJE$,^
|
||||
M02XZ5G7(]E1(@J38K&$:+R<B<'DP]XCD* *7)R2/^%HV@\VO!WD@D 0O\ 0S
|
||||
M347,^*A%@ 4ZP!NU+-U&D 1,4 1"(P)$((KZT0925E4DYL9)\ )/$ )P#MTR
|
||||
M(=U%@ 5%, 158-WQ#A_270184 1#4 76G3FI=1[(E$.(EI#8[(I?1,3!P1%'
|
||||
M;!%6^KNED?]TGK[KHO<_$ZOSEAFQ!S4Y=#]O0.>GMK!\Y49G<KW<81T 7[O-
|
||||
MD\1BC"2PU1_U 9V=IKZ_^QR?;X;L2>?->=/E"5=(E#(3.5DY!#6K<XQTKN.P
|
||||
MW^,__OEO8$>+([+_$1LA4XCT=N")09WE:=.DQW?.9"'*HH]<=@)D< )TSAN
|
||||
MA!(+XQH6\^N/=&3L@@))X )%X +I.! B\%'8/ )DH -T\(B1?Q\> CDG\?-T
|
||||
MCM!8H ,Z#OM%@ 5%, 158-W?RF&;49='PF%C@@).#MWJ)]UN7C(A)OV@;[A)
|
||||
MY>;HT6MMQ!$G,9.<*@,M4 /IF%17EW41 Q@QHY]E "*#Y-&H*\8@6;0^02[>
|
||||
MX6IR,XX\X9NA1Q#SAZ38O*+>+04^SE"?S\?'+NP;%0/%_E&4*E+Q!\[+WL9N
|
||||
M_.QR'.WI#/3('G\\+@4^SE"8RI']NJR%D^Z%)P)FH*^EC<W (08<<<23/G&Q
|
||||
MYD76<7595X>[B\VLUQ%"(]U&D 1,4 2_"Q_YWQV=IKYTGF2 %JL@,&^9$7O'
|
||||
M"1\U6A\^\3UTWL#MZV0._^KJV$;K-)UA5!_?> 9TGK[K\L-Y03). ";PP2\R
|
||||
M&\/9T2_8',4E'2F_SL!'QBZ1V!W,Z:]T+OTVG[[K<K+PA?Z(7O557_4I4RF4
|
||||
MDA<(0 <(0 <($)"EX1A^8EP^81)T'DM91QJ"Q8R/6@18H ,Z#OL]_N-H60:@
|
||||
M49>/Z7PAPO;8\9R8&>?X5P18H ,Z#OL]_N-H:2=U^9AVHDK16I=T#ATNZ>1=
|
||||
M[E)%@ 4ZH..PW^,_CI9Y 0=U^9C1ZE$^ )=*GA=PT*78G!?JU (^P'-EX.30
|
||||
M/1/2/05JK@1- 7% 2,^02YPHA)4JV-E0 =J\"8HH'F3/G%LB\VND_^O 3OI
|
||||
M<W595X>=OR>+.).<^D2K;DAO!!\/?#>0IW!J\"9T?F8'ZOB,HQQ553!&8OF=
|
||||
MO\)O0.=07.5M> (Z6VGN \.E(=U,\ 1.< 1*T 100.?2;_-)ED/WDS FX7U!
|
||||
M;!VO!WET+FOU<09J\"8HH'F%R")#,#=9%S&%54A"U2 71N=3)MU3H.9*T 10
|
||||
MD#GL.2!C<'7RZ1PP/),'+EOC#XM%HV-5-_YT7C&@N!NSEAC,^*A%@ 4ZH..P
|
||||
M/P5JK@1- 6U%QF9^7/2S01/X 1'H 1- 7% 2,^02YPHA)4:QV*<1)J\"8H
|
||||
MH'F3/G%LB\WXD_\#03=5[H\/N:/@3N?H^6<+UT;0(4#PP7!M)&M(0^<Z#OM3
|
||||
MH.9*T 10@,0M;2%#[(HM#;]B_'J0YS#U<09J\"8HH'EG=J $X01@ A_EI?\)
|
||||
M>W59%S%2-OH#(=U,\ 1.< 1*T 10<&SO3N=07.7^N(B=*+.\DZ)E"[]B#$A(
|
||||
M)MU3H.9*T 10$/^8L31-TYQE)RV9_AYT#F##(_EQ!"-BPG;2/05JK@1- 5_
|
||||
MB\W2S01/X 1'H 1- 634SSY\CM2MJ&/9C/8G/T'XC$7*AO'(6FT48YDP#2E
|
||||
M0;8V@\WY#XF=IKY2_<M!DG4 PG8V@\WL4>W,^*A%@ 4ZH..PSP1/X 1'H 1-
|
||||
M 6U%QDL0&Z96<W"GLT<=0/&_G[)OL::VE)N_.QR'.WIC)3#SQ4&7?PAW_HE
|
||||
MY8(T2-!#D/)O$<],T?Q4 /W@G<]8<=$6;=$@\(1.Z(3-3P70+P4P&,\RZ((K
|
||||
M..VC%[&1?Q\> CF[\1PYQ)' *;.\LX@L1,#P >X$D>Z%-_RJ7_PB[X(KF/P\
|
||||
M/M$$^,Y/Z(1.^(,^Z(.9DUH&C!XUBO@(\61L15]%+6)SDW414UA^]!M'FOUM
|
||||
M.H8Z3XXV$W& I!_#JL+Y\M-,1V<[1WL%+S&DL28#$02=IKX:<V3KZQA^8EP^
|
||||
M02XGL 4G_$0GT 4G'(FE+C+) ?PX009;P +SEAFQ-P=M601.O'/_2'G78?:9
|
||||
M\^X$T35T3A"UVSSS,F^9$7OP'O2FP30=<F301^<$,6^9$7NN(4!PHF7\LK^%
|
||||
M-&^9$7L,<CK";DG4*9) GQ!$L 4LX&=M"1* A/\9!F'-<S\"]&>Z^52X3N<$
|
||||
MH:0_K"SYE3"O%'Y/1P8<81(R>N)4($ ZY!HE(9NO93"<D;LM!&@U6A])C,TH
|
||||
M0&XZN67^I4K^"IPVVO@?L7>F1^?CXAHLEA',2!%FL 4L,/YST);_-D $D?W*
|
||||
MUK,ZW]()@Z3"7KO-,R]'!F_<,?[P'@1"9Z@G?F2J/.D3I_/GX4I:5E[LLC)T
|
||||
M3A#CSR!)94G4*9) GQ-& .AR<%"X#N[A]W1!QY!TWM(_4_X@AK>:Z/02$_F!
|
||||
M>_#8;!V?;R1PA=/6H:3,^*A, .AR<%"X#N[A]W1!QY!TWM*\,_A.OW-!M]3[
|
||||
MA[UT?FRI=6;,MAO6H:3,^*CFHE)R<%"X#N[A]W1!QY!TWM*E.#=9IW&4;FHE
|
||||
MIW=CB') GQ-N/@5EP(<7:FQ+O7_G8F;_TOE5+>Q*^L.DOG:;X6!ZL4_Q7DY<
|
||||
M[,8YU(Y#1C% XA>.D6KA)@=E!R-RXCXD=N+93U6(=QZN(43/]2FETC5T/CEG
|
||||
MK:3,*&I;P *@UY:!]WO4F3[9WZ:(YR%;J.]O0.<MS3LAQVC-@VB@9\!5M'>F
|
||||
M1^<$H:1.IGB%X7JW)R0D$P0$T?/#>>*_SL!'QBYP!2.YBWA2C;K8K'UNKV(>
|
||||
M@GD&!O23LP4L@+;4T9;_-D $D?W*UK,ZW]()@Z3"7KO-@VAH2QTD$P2FP30M
|
||||
M=62G-^V/NE$Q@ /&_G[)OL::VE)N_.QR'.WI#/3.YDI:UEKL3AV_6TX,NF!,
|
||||
M0^<$L>F>8_'2@D4_S70\E#H$41Z_D<38C+;4P2). ";PP2_L@NO_TOE5+>Q*
|
||||
M^L.DSF;-Z>YR<&AW:S/"7OX@EAYSDW7L@K8#D>Y(*NPG 4GW#<M\;O(:/&(
|
||||
M5?Z(^T[M6QYTWM*\TQV=IKZB@B0P@F@ AJ3"/ORJ7_PB[X(KF/P\/M$%>(!6
|
||||
MD<]80=#B'8(:^(1.Z(1/Z(1.*/T9P8R/"@6 +@<'A>O@'GY/%W0,2><M_3/E
|
||||
M#V+I,3=9%R;LSB+)/,/"GD/M:+CFDD/8,G4 Q.ZUI$QT3A >PS&6YAQ-XSD6
|
||||
M+RU8Q"_L$HG$!!MT3A# LQO9'X@@X 1@PNU\AIR1J'7"CK:9PYY5R1$G41HC
|
||||
M_#/9KTW"'OGWX2&0LQOX8V*Q)"WEB3\V(^SE\1L^@;;4P8R/<PXA/DDC=J
|
||||
M0.ES-W76,?RJ7_PB[X(KF/P\/M$$^,Y/Z(1.^(,^Z(-T?FRI!4]T4P9\5HIS
|
||||
MDW5WYR!%A?C"/FLM)P:R!$\LEA$LDLSOE$/M*)]!?>+#K_K%+_(NN(+)S^,3
|
||||
M38#O_(1.Z(0_Z(,^F#GO7K4J!AW%4G8< 3G+0>>0>%_:7QK9OS,?LI,/2P=;
|
||||
MP ).T)9%X,02,_[KI#=\XS>"@FKY(:,G7NAA@ <"]#$5 XJ[<7*J5+O-D\38
|
||||
M'+U.T%X^07I\M[ZN(V P@'[6;,U _Z@;=5/&_G[)OL::VE)N_.QR'.WIC)0_
|
||||
MZ(,^"(/QS!3-3P5/Z(1.&/0-+=!!./Q<D5(0[8#WG 1/Z(1.2-#B'8(:>-$6
|
||||
M;=$7;=$6S= "'80&G?)8\<Y/Z(1...WU"6+E^$XYU(YG=D8J[5/<81TO#6;
|
||||
M)4O3C"$%DS#(%XF%)W<$-V7>41*RZ=/D0@>9D?AF$"19!QG8,T>-^+OE5!V#
|
||||
MZ%T.ZJ^)YD9G<O &T2QG32XBNC]T=!E(U8:#LZ$T,FE^D5SNA1"Q)1F[8?F=
|
||||
MOR=*RHLG%B19EW.K^+O(Z.<=@8I?$T<><U13-TW]XUU5Z 8RYQKD(J+[0T>7
|
||||
M@50S.2[LDC5SX",;BD7JV$9*>AXB6S:]9D9R$_Z]MD19NV!^X1BI!GH&#!]T
|
||||
MD!D# 21^X1BI!GIRPF9?$T>HFR7+$R19!R#&AGR1R)&W,8Q1ET)QPS)(51IR
|
||||
M5Q])RAU]EAF<KJ<THCSZ.&/ 3Q%!,! \T;3EZ<5@8^D)2C=T+RB@^.I(!1^;
|
||||
MCXN'Y*-#3""WE!YSDW7LTO=>A![(%XGSTA*!.\,((7<$9Y@\@9^NT?>!];OE
|
||||
MY!HX6K4+QC2U9"$DEIUY'XG5M;PF@3EA/6/ 3Q&*HTKZ6Z1F$&&FQ[[RLCR%
|
||||
MA4)X4/B%L_!/E9 88N[G"1L]5[_P,?[)X;<@!@(O#6; )4O3C! X5"3MZUW\
|
||||
MU3ZG G-XJXGK%"AA;;( 9K:? [V$LQO9'X@@D%94;DKBA<(R1B-WX!<Z9.YD
|
||||
MY1/DLD0'T?=)GSY00!M':A%#L+2K>" VW48XQ!FTUVM<1<#F=4ML _<@@ 15
|
||||
M%9QVY(8>0AEGP#*.01]S0T5$LOV4KS'@R3)-)3!XPXGK=*'VMUDW[8_9?R"?
|
||||
MCQ<-3,#P 3V;0;A2QL0$ET7EZ<+ T=3Q#A_),W));! +OR>1W33-F4-VICKX
|
||||
MCSD:@FV,A0>%_RU^GB/H9\W5+.S9'&#H]5&4*E+Q!\[+WL9N_.QR'.WIC)0$
|
||||
M/00,+= 66($5:- ,+=#-3P5/Z(1...U"]M)@!ERR-%R9(0=KX!H^\DZVY%H_
|
||||
MS70;.I,$(0)!1U'G3@:/^(\R!S6RXS5((BA*PND7+SKOXAB*-9P'$6YR4':5
|
||||
M=2)91AWE\[7Q/[S-^4)R$$SE:4TU#UTD=A 4=>[SXEIJ-3M(@K-!<7^"5^6N
|
||||
M$;U#\KHD;9/P:Q#K,6GY!B*?CQ?P5(@A-T9\0^DZK_E%&D: Y&C@F)V\D_T4
|
||||
M$^7P#@)/T$+TX=9E<)SHH1Y]$4GH4>\(L1YPXEUEFJV6W_E[HJ2JI-.>008?
|
||||
M,R/SDB&E0_9/CSYEEQ<M('<"DHN#"T? 3Q%]'AXZ(OK,U!CBB%K*\<%&=1V4
|
||||
MKO/Q-"($;%[PA?Z)ONB&P@8(P 8(P 8(H!P(P 8(P 8(H!@(\ 8(\ 8(\,$(
|
||||
M, 8(, 8(D'#/=--R1OK(6(\^S&R[81VO!WD:\])@!ERR1$6_^]5XH1>7)B!U
|
||||
6JTKA=5]I *"4_\%4D\0&T1CB.!Q$ 1VO
|
||||
|
||||
end
|
6
dmake/dbug/getwd.c
Normal file
6
dmake/dbug/getwd.c
Normal file
@ -0,0 +1,6 @@
|
||||
char *
|
||||
getwd(pathname)
|
||||
char *pathname;
|
||||
{
|
||||
return("delete this code if your getwd.c works correctly");
|
||||
}
|
77
dmake/dbug/malloc/Makefile
Normal file
77
dmake/dbug/malloc/Makefile
Normal file
@ -0,0 +1,77 @@
|
||||
#
|
||||
# (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
# You may copy, distribute, and use this software as long as this
|
||||
# copyright statement is not removed.
|
||||
#
|
||||
#
|
||||
# This is the Makefile for the malloc debugging library
|
||||
#
|
||||
# $Id: Makefile,v 1.5 90/08/29 22:34:27 cpcahil Exp $
|
||||
#
|
||||
CC=cc
|
||||
# for System V systems use this CFLAGS
|
||||
#CFLAGS=-g -DSYS5
|
||||
# else for BSD use:
|
||||
#CFLAGS=-g
|
||||
LINT=lint
|
||||
SHARCMD=shar -o mallocshar -l50 -x -a -n Malloclib
|
||||
SHELL=/bin/sh
|
||||
|
||||
LIB=libmalloc.a
|
||||
|
||||
SRCS= malloc.c \
|
||||
free.c \
|
||||
realloc.c \
|
||||
calloc.c \
|
||||
string.c \
|
||||
mlc_chk.c \
|
||||
mlc_chn.c \
|
||||
memory.c \
|
||||
tostring.c \
|
||||
m_perror.c \
|
||||
m_init.c \
|
||||
mallopt.c \
|
||||
dump.c
|
||||
|
||||
OBJS= malloc.o \
|
||||
free.o \
|
||||
realloc.o \
|
||||
calloc.o \
|
||||
string.o \
|
||||
mlc_chk.o \
|
||||
mlc_chn.o \
|
||||
memory.o \
|
||||
tostring.o \
|
||||
m_perror.o \
|
||||
m_init.o \
|
||||
mallopt.o \
|
||||
dump.o
|
||||
|
||||
TESTS=testmlc testmem
|
||||
|
||||
all: $(LIB) $(TESTS)
|
||||
|
||||
clean:
|
||||
rm -f $(TESTS) pgm $(LIB) *.o *.ln
|
||||
|
||||
sharfile:
|
||||
$(SHARCMD) Makefile README patchlevel *.[ch3]
|
||||
|
||||
$(LIB): $(OBJS)
|
||||
ar ru $(LIB) $(OBJS)
|
||||
-if test -s /bin/ranlib; then /bin/ranlib $(LIB); else exit 0; fi
|
||||
-if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(LIB); else exit 0; fi
|
||||
|
||||
testmlc: $(LIB) testmlc.o
|
||||
$(CC) -o $@ testmlc.o $(LIB)
|
||||
|
||||
testmem: $(LIB) testmem.o
|
||||
$(CC) -o $@ testmem.o $(LIB)
|
||||
|
||||
lint:
|
||||
$(LINT) $(CFLAGS) $(SRCS) testmlc.c testmem.c
|
||||
|
||||
|
||||
$(OBJS): malloc.h
|
||||
|
||||
tostring.o malloc.o dump.o: tostring.h
|
9
dmake/dbug/malloc/_changes
Normal file
9
dmake/dbug/malloc/_changes
Normal file
@ -0,0 +1,9 @@
|
||||
I made the following changes to the malloc package as found in
|
||||
comp.sources.unix:
|
||||
|
||||
1. created this file _changes.
|
||||
2. moved README to _readme (facilitates transfer to DOS and back to
|
||||
unix)
|
||||
3. renamed testmalloc.c, malloc_chk.c, and malloc_chn.c to testmlc.c,
|
||||
mlc_chk.c, and mlc_chn.c respectively. Again DOS has trouble with
|
||||
long basenames in filenames.
|
133
dmake/dbug/malloc/_readme
Normal file
133
dmake/dbug/malloc/_readme
Normal file
@ -0,0 +1,133 @@
|
||||
# (c) Copyright 1990 Conor P. Cahill. (uunet!virtech!cpcahil)
|
||||
# You may copy, distribute, and use this software as long as this
|
||||
# copyright statement is not removed.
|
||||
|
||||
This package is a collection of routines which are a drop-in replacement
|
||||
for the malloc(3), memory(3), string(3), and bstring(3) library functions.
|
||||
|
||||
The purpose of these programs is to aid the development and/or debugging
|
||||
of programs using these functions by providing a high level of consistancy
|
||||
checking whenever a malloc pointer is used. Due to this increased
|
||||
level of consistancy checking, these functions have a considerably larger
|
||||
overhead than the standard functions, but the extra checking should be
|
||||
well worth it in a development environment.
|
||||
|
||||
To use these functions all you need to do is compile the library and
|
||||
include it on your loader command line. You do not need to recompile
|
||||
your code, only a relink is necessary.
|
||||
|
||||
Features of this library:
|
||||
|
||||
1. The malloced area returned from each call to malloc is filled with
|
||||
non-null bytes. This should catch any use of uninitialized malloc
|
||||
area. The fill pattern for malloced area is 0x01.
|
||||
|
||||
2. When free is called numerous validity checks are made on the
|
||||
pointer it is passed. In addition, the data in the malloc block
|
||||
beyound the size requested on the initial malloc is checked to
|
||||
verify that it is still filled with the original fill characters.
|
||||
|
||||
This is usefull for catching things like:
|
||||
|
||||
ptr = malloc(5);
|
||||
ptr[5] = '\0';
|
||||
|
||||
/*
|
||||
* You should not that this will be caught when it is
|
||||
* freed not when it is done
|
||||
*/
|
||||
|
||||
And finally, the freed block is filled with a different fill pattern
|
||||
so that you can easily determine if you are still using free'd space.
|
||||
The fill pattern for free'd areas is 0x02.
|
||||
|
||||
This is usefull for catching things like:
|
||||
|
||||
ptr = malloc(20);
|
||||
|
||||
bptr = ptr+10;
|
||||
|
||||
/* do something usefule with bptr */
|
||||
|
||||
free(ptr);
|
||||
|
||||
/*
|
||||
* now try to do something useful with bptr, it should
|
||||
* be trashed enough that it would cause real problems
|
||||
* and when you went to debug the problem it would be
|
||||
* filled with 0x02's and you would then know to look
|
||||
* for something free'ing what bptr points to.
|
||||
*/
|
||||
|
||||
|
||||
3. Whenever a bstring(3)/string(3)/memory(3) function is called, it's
|
||||
parameters are checked as follows:
|
||||
|
||||
If they point somewhere in the malloc arena
|
||||
If the operation goes beyond requested malloc space
|
||||
call malloc_warning()
|
||||
|
||||
This is usefull for catching things like:
|
||||
|
||||
ptr = malloc(5);
|
||||
strcpy(ptr,"abcde");
|
||||
|
||||
|
||||
4. Malloc_warning() and malloc_fatal() are used when an error condition
|
||||
is detected. If the error is severe, malloc_fatal is called.
|
||||
Malloc_warning is used otherwise. The decision about what is fatal
|
||||
and what is a warning was made somewhat arbitrarily.
|
||||
|
||||
Warning messages include:
|
||||
|
||||
Calling free with a bad pointer
|
||||
Calling a bstring/string/memory (3) function which will go beyond
|
||||
the end of a malloc block (Note that the library function is
|
||||
not modified to refuse the operation. If malloc warnings are
|
||||
in the default IGNORE case, the operation will continue and
|
||||
at some point cause a real problem).
|
||||
|
||||
Fatal errors are:
|
||||
|
||||
Detectable corruption to the malloc chain.
|
||||
|
||||
|
||||
5. The operations to perform when an error is detected are specified at
|
||||
run time by the use of environment variables.
|
||||
|
||||
MALLOC_WARN - specifies the warning error message handling
|
||||
MALLOC_FATAL - specifies the fatal error handling
|
||||
|
||||
|
||||
When one of these error conditions occur you will get an error
|
||||
message and the handler will execute based upon what setting
|
||||
is in the environment variables. Currently understood settings
|
||||
are as follows:
|
||||
|
||||
0 - continue operations
|
||||
1 - drop core and exit
|
||||
2 - just exit
|
||||
3 - drop core, but continue executing. Core files will
|
||||
be placed into core.[PID].[counter] i.e: core.00123.001
|
||||
128 - dump malloc chain and continue
|
||||
129 - dump malloc chain, dump core, and exit
|
||||
130 - dump malloc chain, exit
|
||||
131 - dump malloc chain, dump core, continue processing
|
||||
|
||||
|
||||
There is an additional environment variable MALLOC_ERRFILE which
|
||||
is used to indicate the name of the file for error message output.
|
||||
|
||||
For example, to set up the session to generate a core file for
|
||||
every malloc warning, to drop core and exit on a malloc fatal, and
|
||||
to log all messages to the file "malloc_log" do the following:
|
||||
|
||||
MALLOC_WARN=131
|
||||
MALLOC_FATAL=1
|
||||
MALLOC_ERRFILE=malloc_log
|
||||
|
||||
export MALLOC_WARN MALLOC_FATAL MALLOC_ERRFILE
|
||||
|
||||
6. The function malloc_dump() is available to dump the malloc chain whenever
|
||||
you might want. It's only argument is a file descriptor to use to write
|
||||
the data. Review the code if you need to know what data is printed.
|
73
dmake/dbug/malloc/calloc.c
Normal file
73
dmake/dbug/malloc/calloc.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* Function: calloc()
|
||||
*
|
||||
* Purpose: to allocate and nullify a data area
|
||||
*
|
||||
* Arguments: nelem - number of elements
|
||||
* elsize - size of each element
|
||||
*
|
||||
* Returns: NULL - if malloc fails
|
||||
* or pointer to allocated space
|
||||
*
|
||||
* Narrative: determine size of area to malloc
|
||||
* malloc area.
|
||||
* if malloc succeeds
|
||||
* fill area with nulls
|
||||
* return ptr to malloc'd region
|
||||
*/
|
||||
#ifndef lint
|
||||
static char rcs_header[] = "$Id: calloc.c,v 1.1 1992/01/24 03:28:58 dvadura Exp $";
|
||||
#endif
|
||||
|
||||
char *
|
||||
calloc(nelem,elsize)
|
||||
unsigned int nelem;
|
||||
unsigned int elsize;
|
||||
{
|
||||
char * malloc();
|
||||
char * memset();
|
||||
char * ptr;
|
||||
unsigned int size;
|
||||
|
||||
size = elsize * nelem;
|
||||
|
||||
if( (ptr = malloc(size)) != NULL)
|
||||
{
|
||||
(void) memset(ptr,'\0',(int)size);
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: calloc.c,v $
|
||||
* Revision 1.1 1992/01/24 03:28:58 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.6 90/05/11 00:13:07 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.5 90/02/24 20:41:57 cpcahil
|
||||
* lint changes.
|
||||
*
|
||||
* Revision 1.4 90/02/24 17:25:47 cpcahil
|
||||
* changed $header to $id so full path isn't included.
|
||||
*
|
||||
* Revision 1.3 90/02/24 13:32:24 cpcahil
|
||||
* added function header. moved log to end of file.
|
||||
*
|
||||
* Revision 1.2 90/02/22 23:08:26 cpcahil
|
||||
* fixed rcs_header line
|
||||
*
|
||||
* Revision 1.1 90/02/22 23:07:38 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
111
dmake/dbug/malloc/debug.h
Normal file
111
dmake/dbug/malloc/debug.h
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* this include sets up some macro functions which can be used while */
|
||||
/* debugging the program, and then left in the code, but turned of by */
|
||||
/* just not defining "DEBUG". This way your production version of */
|
||||
/* the program will not be filled with bunches of debugging junk */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
/*
|
||||
* $Id: debug.h,v 1.1 1992/01/24 03:28:59 dvadura Exp $
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#if DEBUG == 1 /* if default level */
|
||||
#undef DEBUG
|
||||
#define DEBUG 100 /* use level 100 */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define DEBUG0(val,str)\
|
||||
{\
|
||||
if( DEBUG > val ) \
|
||||
fprintf(stderr,"%s(%d): %s\n",\
|
||||
__FILE__,__LINE__,str);\
|
||||
}
|
||||
#define DEBUG1(val,str,a1)\
|
||||
{\
|
||||
char _debugbuf[100];\
|
||||
if( DEBUG > val )\
|
||||
{\
|
||||
sprintf(_debugbuf,str,a1);\
|
||||
fprintf(stderr,"%s(%d): %s\n",\
|
||||
__FILE__,__LINE__,_debugbuf);\
|
||||
}\
|
||||
}
|
||||
|
||||
#define DEBUG2(val,str,a1,a2)\
|
||||
{\
|
||||
char _debugbuf[100];\
|
||||
if( DEBUG > val )\
|
||||
{\
|
||||
sprintf(_debugbuf,str,a1,a2);\
|
||||
fprintf(stderr,"%s(%d): %s\n",\
|
||||
__FILE__,__LINE__,_debugbuf);\
|
||||
}\
|
||||
}
|
||||
|
||||
#define DEBUG3(val,str,a1,a2,a3)\
|
||||
{\
|
||||
char _debugbuf[100];\
|
||||
if( DEBUG > val )\
|
||||
{\
|
||||
sprintf(_debugbuf,str,a1,a2,a3);\
|
||||
fprintf(stderr,"%s(%d): %s\n",\
|
||||
__FILE__,__LINE__,_debugbuf);\
|
||||
}\
|
||||
}
|
||||
|
||||
#define DEBUG4(val,str,a1,a2,a3,a4)\
|
||||
{\
|
||||
char _debugbuf[100];\
|
||||
if( DEBUG > val )\
|
||||
{\
|
||||
sprintf(_debugbuf,str,a1,a2,a3,a4);\
|
||||
fprintf(stderr,"%s(%d): %s\n",\
|
||||
__FILE__,__LINE__,_debugbuf);\
|
||||
}\
|
||||
}
|
||||
|
||||
#define DEBUG5(val,str,a1,a2,a3,a4,a5)\
|
||||
{\
|
||||
char _debugbuf[100];\
|
||||
if( DEBUG > val )\
|
||||
{\
|
||||
sprintf(_debugbuf,str,a1,a2,a3,a4,a5);\
|
||||
fprintf(stderr,"%s(%d): %s\n",\
|
||||
__FILE__,__LINE__,_debugbuf);\
|
||||
}\
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define DEBUG0(val,s)
|
||||
#define DEBUG1(val,s,a1)
|
||||
#define DEBUG2(val,s,a1,a2)
|
||||
#define DEBUG3(val,s,a1,a2,a3)
|
||||
#define DEBUG4(val,s,a1,a2,a3,a4)
|
||||
#define DEBUG5(val,s,a1,a2,a3,a4,a5)
|
||||
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
/*
|
||||
* $Log: debug.h,v $
|
||||
* Revision 1.1 1992/01/24 03:28:59 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.2 90/05/11 00:13:08 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.1 90/02/23 07:09:01 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
124
dmake/dbug/malloc/dump.c
Normal file
124
dmake/dbug/malloc/dump.c
Normal file
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "malloc.h"
|
||||
#include "tostring.h"
|
||||
|
||||
/*
|
||||
* Function: malloc_dump()
|
||||
*
|
||||
* Purpose: to dump a printed copy of the malloc chain and
|
||||
* associated data elements
|
||||
*
|
||||
* Arguments: fd - file descriptor to write data to
|
||||
*
|
||||
* Returns: nothing of any use
|
||||
*
|
||||
* Narrative: Just print out all the junk
|
||||
*
|
||||
* Notes: This function is implemented using low level calls because
|
||||
* of the likelyhood that the malloc tree is damaged when it
|
||||
* is called. (Lots of things in the c library use malloc and
|
||||
* we don't want to get into a catch-22).
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static
|
||||
char rcs_hdr[] = "$Id: dump.c,v 1.1 1992/01/24 03:29:01 dvadura Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
#define ERRSTR "I/O Error on malloc dump file descriptor\n"
|
||||
|
||||
#define WRITEOUT(fd,str,len) if( write(fd,str,(unsigned)len) != len ) \
|
||||
{ \
|
||||
(void) write(2,ERRSTR,\
|
||||
(unsigned)strlen(ERRSTR));\
|
||||
exit(120); \
|
||||
}
|
||||
|
||||
void
|
||||
malloc_dump(fd)
|
||||
int fd;
|
||||
{
|
||||
char buffer[512];
|
||||
void exit();
|
||||
int i;
|
||||
extern char * malloc_data_end;
|
||||
extern char * malloc_data_start;
|
||||
extern struct mlist * malloc_end;
|
||||
extern struct mlist malloc_start;
|
||||
struct mlist * ptr;
|
||||
|
||||
WRITEOUT(fd,"MALLOC CHAIN:\n",14);
|
||||
WRITEOUT(fd,"-------------------- START ----------------\n",44);
|
||||
|
||||
for(i=0; i < 80; i++)
|
||||
{
|
||||
buffer[i] = ' ';
|
||||
}
|
||||
|
||||
for(ptr = &malloc_start; ptr; ptr = ptr->next)
|
||||
{
|
||||
(void) tostring(buffer, (int)ptr, 8, B_HEX, '0');
|
||||
(void) tostring(buffer+9, (int)ptr->next, 8, B_HEX, '0');
|
||||
(void) tostring(buffer+18, (int)ptr->prev, 8, B_HEX, '0');
|
||||
(void) tostring(buffer+27, (int)ptr->flag, 10, B_HEX, '0');
|
||||
(void) tostring(buffer+38, (int)ptr->s.size, 8, B_DEC, ' ');
|
||||
(void) tostring(buffer+47, (int)ptr->s.size, 8, B_HEX, '0');
|
||||
(void) tostring(buffer+57, (int)ptr->data, 8, B_HEX, '0');
|
||||
buffer[46] = '(';
|
||||
buffer[55] = ')';
|
||||
buffer[65] = '\n';
|
||||
WRITEOUT(fd,buffer,66);
|
||||
}
|
||||
WRITEOUT(fd,"-------------------- DONE -----------------\n",44);
|
||||
|
||||
WRITEOUT(fd,"Malloc start: ",19);
|
||||
(void) tostring(buffer, (int) &malloc_start, 8, B_HEX, '0');
|
||||
buffer[8] = '\n';
|
||||
WRITEOUT(fd,buffer,9);
|
||||
|
||||
WRITEOUT(fd,"Malloc end: ", 19);
|
||||
(void) tostring(buffer, (int) malloc_end, 8, B_HEX, '0');
|
||||
buffer[8] = '\n';
|
||||
WRITEOUT(fd,buffer,9);
|
||||
|
||||
WRITEOUT(fd,"Malloc data start: ", 19);
|
||||
(void) tostring(buffer, (int) malloc_data_start, 8, B_HEX, '0');
|
||||
buffer[8] = '\n';
|
||||
WRITEOUT(fd,buffer,9);
|
||||
|
||||
WRITEOUT(fd,"Malloc data end: ", 19);
|
||||
(void) tostring(buffer, (int) malloc_data_end, 8, B_HEX, '0');
|
||||
buffer[8] = '\n';
|
||||
WRITEOUT(fd,buffer,9);
|
||||
|
||||
} /* malloc_dump(... */
|
||||
|
||||
|
||||
/*
|
||||
* $Log: dump.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:01 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.5 90/08/29 21:22:37 cpcahil
|
||||
* miscellaneous lint fixes
|
||||
*
|
||||
* Revision 1.4 90/05/11 00:13:08 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.3 90/02/24 21:50:07 cpcahil
|
||||
* lots of lint fixes
|
||||
*
|
||||
* Revision 1.2 90/02/24 17:27:48 cpcahil
|
||||
* changed $header to $Id to remove full path from rcs id string
|
||||
*
|
||||
* Revision 1.1 90/02/22 23:17:43 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
188
dmake/dbug/malloc/free.c
Normal file
188
dmake/dbug/malloc/free.c
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "malloc.h"
|
||||
#include "debug.h"
|
||||
|
||||
/*
|
||||
* Function: free()
|
||||
*
|
||||
* Purpose: to deallocate malloced data
|
||||
*
|
||||
* Arguments: ptr - pointer to data area to deallocate
|
||||
*
|
||||
* Returns: nothing of any value
|
||||
*
|
||||
* Narrative:
|
||||
* verify pointer is within malloc region
|
||||
* get mlist pointer from passed address
|
||||
* verify magic number
|
||||
* verify inuse flag
|
||||
* verify pointer connections with surrounding segments
|
||||
* turn off inuse flag
|
||||
* verify no data overrun into non-malloced area at end of segment
|
||||
* IF possible join segment with next segment
|
||||
* IF possible join segment with previous segment
|
||||
* Clear all data in segment (to make sure it isn't reused)
|
||||
*
|
||||
*/
|
||||
#ifndef lint
|
||||
static
|
||||
char rcs_hdr[] = "$Id: free.c,v 1.1 1992/01/24 03:29:02 dvadura Exp $";
|
||||
#endif
|
||||
|
||||
void
|
||||
free(cptr)
|
||||
char * cptr;
|
||||
{
|
||||
char * func = "free";
|
||||
int i;
|
||||
extern int malloc_checking;
|
||||
extern struct mlist * malloc_end;
|
||||
extern int malloc_errno;
|
||||
extern char * malloc_data_end;
|
||||
extern char * malloc_data_start;
|
||||
void malloc_join();
|
||||
void malloc_memset();
|
||||
struct mlist * oldptr;
|
||||
struct mlist * ptr;
|
||||
|
||||
/*
|
||||
* IF malloc chain checking is on, go do it.
|
||||
*/
|
||||
if( malloc_checking )
|
||||
{
|
||||
(void) malloc_chain_check(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* verify that cptr is within the malloc region...
|
||||
*/
|
||||
if( cptr < malloc_data_start || cptr > malloc_data_end )
|
||||
{
|
||||
malloc_errno = M_CODE_BAD_PTR;
|
||||
malloc_warning(func);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert pointer to mlist struct pointer. To do this we must
|
||||
* move the pointer backwards the correct number of bytes...
|
||||
*/
|
||||
|
||||
ptr = (struct mlist *) (cptr - M_SIZE);
|
||||
|
||||
if( (ptr->flag&M_MAGIC) != M_MAGIC )
|
||||
{
|
||||
malloc_errno = M_CODE_BAD_MAGIC;
|
||||
malloc_warning(func);
|
||||
return;
|
||||
}
|
||||
|
||||
if( ! (ptr->flag & M_INUSE) )
|
||||
{
|
||||
malloc_errno = M_CODE_NOT_INUSE;
|
||||
malloc_warning(func);
|
||||
return;
|
||||
}
|
||||
|
||||
if( (ptr->prev && (ptr->prev->next != ptr) ) ||
|
||||
(ptr->next && (ptr->next->prev != ptr) ) ||
|
||||
((ptr->next == NULL) && (ptr->prev == NULL)) )
|
||||
{
|
||||
malloc_errno = M_CODE_BAD_CONNECT;
|
||||
malloc_warning(func);
|
||||
return;
|
||||
}
|
||||
|
||||
ptr->flag &= ~M_INUSE;
|
||||
|
||||
/*
|
||||
* verify that the user did not overrun the requested number of bytes.
|
||||
*/
|
||||
for(i=ptr->r_size; i < ptr->s.size; i++)
|
||||
{
|
||||
if( ptr->data[i] != M_FILL )
|
||||
{
|
||||
malloc_errno = M_CODE_OVERRUN;
|
||||
malloc_warning(func);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG3(10,"pointers: prev: 0x%.7x, ptr: 0x%.7x, next: 0x%.7x",
|
||||
ptr->prev, ptr, ptr->next);
|
||||
|
||||
DEBUG3(10,"size: prev: %9d, ptr: %9d, next: %9d",
|
||||
ptr->prev->s.size, ptr->s.size, ptr->next->s.size);
|
||||
|
||||
DEBUG3(10,"flags: prev: 0x%.7x, ptr: 0x%.7x, next: 0x%.7x",
|
||||
ptr->prev->flag, ptr->flag, ptr->next->flag);
|
||||
|
||||
/*
|
||||
* check to see if this block can be combined with the next and/or
|
||||
* previous block. Since it may be joined with the previous block
|
||||
* we will save a pointer to the previous block and test to verify
|
||||
* if it is joined (it's next ptr will no longer point to ptr).
|
||||
*/
|
||||
malloc_join(ptr,ptr->next,0,0);
|
||||
|
||||
oldptr = ptr->prev;
|
||||
|
||||
malloc_join(ptr->prev, ptr,0,0);
|
||||
|
||||
if( oldptr->next != ptr )
|
||||
{
|
||||
DEBUG0(10,"Oldptr was changed");
|
||||
ptr = oldptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* fill this block with '\02's to ensure that nobody is using a
|
||||
* pointer to already freed data...
|
||||
*/
|
||||
malloc_memset(ptr->data,M_FREE_FILL,(int)ptr->s.size);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: free.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:02 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.9 90/08/29 21:22:48 cpcahil
|
||||
* miscellaneous lint fixes
|
||||
*
|
||||
* Revision 1.8 90/05/11 00:13:08 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.7 90/02/25 11:00:18 cpcahil
|
||||
* added support for malloc chain checking.
|
||||
*
|
||||
* Revision 1.6 90/02/24 21:50:18 cpcahil
|
||||
* lots of lint fixes
|
||||
*
|
||||
* Revision 1.5 90/02/24 17:29:13 cpcahil
|
||||
* changed $Header to $Id so full path wouldnt be included as part of rcs
|
||||
* id string
|
||||
*
|
||||
* Revision 1.4 90/02/24 15:15:32 cpcahil
|
||||
* 1. changed ALREADY_FREE errno to NOT_INUSE so that the same errno could
|
||||
* be used by both free and realloc (since it was the same error).
|
||||
* 2. fixed coding bug
|
||||
*
|
||||
* Revision 1.3 90/02/24 14:23:45 cpcahil
|
||||
* fixed malloc_warning calls
|
||||
*
|
||||
* Revision 1.2 90/02/24 13:59:10 cpcahil
|
||||
* added function header.
|
||||
* Modified calls to malloc_warning/malloc_fatal to use new code error messages
|
||||
* Added support for malloc_errno setting of error codes.
|
||||
*
|
||||
* Revision 1.1 90/02/22 23:17:43 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
103
dmake/dbug/malloc/m_init.c
Normal file
103
dmake/dbug/malloc/m_init.c
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "malloc.h"
|
||||
|
||||
/*
|
||||
* Function: malloc_init()
|
||||
*
|
||||
* Purpose: to initialize the pointers and variables use by the
|
||||
* malloc() debugging library
|
||||
*
|
||||
* Arguments: none
|
||||
*
|
||||
* Returns: nothing of any value
|
||||
*
|
||||
* Narrative: Just initialize all the needed variables. Use mallopt
|
||||
* to set options taken from the environment.
|
||||
*
|
||||
*/
|
||||
#ifndef lint
|
||||
static
|
||||
char rcs_hdr[] = "$Id: m_init.c,v 1.1 1992/01/24 03:29:03 dvadura Exp $";
|
||||
#endif
|
||||
|
||||
void
|
||||
malloc_init()
|
||||
{
|
||||
char * cptr;
|
||||
char * getenv();
|
||||
union malloptarg m;
|
||||
extern char * malloc_data_end;
|
||||
extern char * malloc_data_start;
|
||||
extern struct mlist * malloc_end;
|
||||
extern struct mlist malloc_start;
|
||||
char * sbrk();
|
||||
|
||||
/*
|
||||
* If already initialized...
|
||||
*/
|
||||
if( malloc_data_start != (char *) 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
malloc_data_start = sbrk(0);
|
||||
malloc_data_end = malloc_data_start;
|
||||
malloc_start.s.size = 0;
|
||||
malloc_end = &malloc_start;
|
||||
|
||||
if( (cptr=getenv("MALLOC_WARN")) != NULL )
|
||||
{
|
||||
m.i = atoi(cptr);
|
||||
(void) mallopt(MALLOC_WARN,m);
|
||||
}
|
||||
|
||||
if( (cptr=getenv("MALLOC_FATAL")) != NULL)
|
||||
{
|
||||
m.i = atoi(cptr);
|
||||
(void) mallopt(MALLOC_FATAL,m);
|
||||
}
|
||||
|
||||
if( (cptr=getenv("MALLOC_CKCHAIN")) != NULL)
|
||||
{
|
||||
m.i = atoi(cptr);
|
||||
(void) mallopt(MALLOC_CKCHAIN,m);
|
||||
}
|
||||
|
||||
if( (cptr=getenv("MALLOC_ERRFILE")) != NULL)
|
||||
{
|
||||
m.str = cptr;
|
||||
(void) mallopt(MALLOC_ERRFILE,m);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: m_init.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:03 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.6 90/08/29 22:23:21 cpcahil
|
||||
* fixed mallopt to use a union as an argument.
|
||||
*
|
||||
* Revision 1.5 90/08/29 21:22:50 cpcahil
|
||||
* miscellaneous lint fixes
|
||||
*
|
||||
* Revision 1.4 90/05/11 15:53:35 cpcahil
|
||||
* fixed bug in initialization code.
|
||||
*
|
||||
* Revision 1.3 90/05/11 00:13:08 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.2 90/02/24 21:50:20 cpcahil
|
||||
* lots of lint fixes
|
||||
*
|
||||
* Revision 1.1 90/02/24 17:10:53 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
93
dmake/dbug/malloc/m_perror.c
Normal file
93
dmake/dbug/malloc/m_perror.c
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static
|
||||
char rcsid[] = "$Id: m_perror.c,v 1.1 1992/01/24 03:29:04 dvadura Exp $";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* malloc errno error strings...
|
||||
*/
|
||||
|
||||
char *malloc_err_strings[] =
|
||||
{
|
||||
"No errors",
|
||||
"Malloc chain is corrupted, pointers out of order",
|
||||
"Malloc chain is corrupted, end before end pointer",
|
||||
"Pointer is not within malloc area",
|
||||
"Malloc region does not have valid magic number in header",
|
||||
"Pointers between this segment and ajoining segments are invalid",
|
||||
"Data has overrun beyond requested number of bytes",
|
||||
"Data in free'd area has been modified",
|
||||
"Data are is not in use (can't be freed or realloced)",
|
||||
"Unable to get additional memory from the system",
|
||||
"Pointer within malloc region, but outside of malloc data bounds",
|
||||
(char *) 0
|
||||
};
|
||||
|
||||
/*
|
||||
* Function: malloc_perror()
|
||||
*
|
||||
* Purpose: to print malloc_errno error message
|
||||
*
|
||||
* Arguments: str - string to print with error message
|
||||
*
|
||||
* Returns: nothing of any value
|
||||
*
|
||||
* Narrative:
|
||||
*/
|
||||
void
|
||||
malloc_perror(str)
|
||||
char * str;
|
||||
{
|
||||
extern int malloc_errno;
|
||||
register char * s;
|
||||
register char * t;
|
||||
|
||||
if( str && *str)
|
||||
{
|
||||
for(s=str; *s; s++)
|
||||
{
|
||||
/* do nothing */;
|
||||
}
|
||||
|
||||
(void) write(2,str,(unsigned)(s-str));
|
||||
(void) write(2,": ",(unsigned)2);
|
||||
}
|
||||
|
||||
t = malloc_err_strings[malloc_errno];
|
||||
|
||||
for(s=t; *s; s++)
|
||||
{
|
||||
/* do nothing */;
|
||||
}
|
||||
|
||||
(void) write(2,t,(unsigned)(s-t));
|
||||
|
||||
(void) write(2,"\n",(unsigned)1);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: m_perror.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:04 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.5 90/08/29 21:25:08 cpcahil
|
||||
* added additional error message that was missing (and
|
||||
* caused a core dump)
|
||||
*
|
||||
* Revision 1.4 90/05/11 00:13:08 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.3 90/02/24 21:50:21 cpcahil
|
||||
* lots of lint fixes
|
||||
*
|
||||
* Revision 1.2 90/02/24 17:39:55 cpcahil
|
||||
* 1. added function header
|
||||
* 2. added rcs id and log strings.
|
||||
*
|
||||
*/
|
223
dmake/dbug/malloc/malloc.3
Normal file
223
dmake/dbug/malloc/malloc.3
Normal file
@ -0,0 +1,223 @@
|
||||
.TH MALLOC 3 "" "" "1.0"
|
||||
.ds ]T
|
||||
.\"/*
|
||||
.\" * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
.\" * You may copy, distribute, and use this software as long as this
|
||||
.\" * copyright statement is not removed.
|
||||
.\" */
|
||||
.\" $Id: malloc.3,v 1.3 90/08/29 22:24:44 cpcahil Exp $
|
||||
.SH NAME
|
||||
malloc \t- debugging malloc library
|
||||
.SH SYNOPSIS
|
||||
.ft B
|
||||
.nf
|
||||
#include <malloc.h>
|
||||
|
||||
char * calloc(nelem,elsize);
|
||||
void free(ptr);
|
||||
char * malloc(size);
|
||||
int malloc_chain_check(flag);
|
||||
void malloc_dump(fd);
|
||||
int mallopt(cmd,val)
|
||||
char * realloc(ptr,size);
|
||||
|
||||
int cmd,fd,flag;
|
||||
unsigned elsize,nelem,size;
|
||||
char * ptr;
|
||||
union malloptarg val;
|
||||
|
||||
.fi
|
||||
.ft R
|
||||
.SH DESCRIPTION
|
||||
This malloc library is a replacement for the standard library to be used
|
||||
during software development/debugging. See the standard malloc(3) pages
|
||||
for more information on the use of the following functions:
|
||||
.nf
|
||||
.in +.5i
|
||||
calloc(), free(), malloc(), realloc()
|
||||
.in -.5i
|
||||
.fi
|
||||
.sp
|
||||
This library differs from the standard malloc library in the
|
||||
following ways:
|
||||
.P
|
||||
1. Each malloc segment contains a magic number so that free can
|
||||
verify that the pointer passed points to a valid malloc segment.
|
||||
.P
|
||||
2. Each malloc segment is filled with a non-zero pattern so that code that
|
||||
depends upon malloc segments being null will fail.
|
||||
.P
|
||||
3. The size of each segment will be at least 1 byte larger than requested
|
||||
and the extra bytes will be filled with a non-zero pattern. When free is
|
||||
called, it will verify that you did not go beyond the number of bytes
|
||||
you asked for.
|
||||
.P
|
||||
4. When a segment is freed, it will be filled with a different non-zero pattern
|
||||
to ensure that the program doesn't depend upon the use of already freed data.
|
||||
.P
|
||||
5. Whenever any of the string or memory functions (str*, b*, mem*) are
|
||||
called with a pointer that is within the malloc arena, the operation is
|
||||
checked to verify that it does not overrun the malloced segment. A failure
|
||||
of this check is considered a "warning level error" (described later) and
|
||||
is handled accordingly.
|
||||
.P
|
||||
7. Run time checking can include verification of the malloc chain at each
|
||||
and every call to one of the malloc functions or manually by calling the
|
||||
malloc_chain_check function.
|
||||
.P
|
||||
6. When a problem is found, the action taken is specified at runtime by
|
||||
environment variables or at compile time by the use of the mallopt()
|
||||
function.
|
||||
.P
|
||||
There are two arbitrary levels of errors, warning and fatal, that this
|
||||
library will detect. They are broken down as follows:
|
||||
.P
|
||||
.nf
|
||||
.in +.25i
|
||||
Warning messages include:
|
||||
.sp
|
||||
.in +.5i
|
||||
.ti -.25i
|
||||
Calling free with a bad pointer
|
||||
.br
|
||||
.ti -.25i
|
||||
Calling a bstring/string/memory (3) function which will go beyond
|
||||
the end of a malloc block. Note that the library function is
|
||||
not modified to refuse the operation.
|
||||
.sp
|
||||
.in -.5i
|
||||
Fatal errors are:
|
||||
.in +.5i
|
||||
.ti -.25i
|
||||
Detectable corruption to the malloc chain.
|
||||
.in -.5i
|
||||
.in -.25i
|
||||
.P
|
||||
The error handling for each level (warning or fatal) are specified using
|
||||
environment variables or mallopt(). The coding for the error handling is
|
||||
as follows:
|
||||
.sp
|
||||
.nf
|
||||
.in +.5i
|
||||
.ti -.25i
|
||||
0 - continue operations
|
||||
.ti -.25i
|
||||
1 - drop core and exit
|
||||
.ti -.25i
|
||||
2 - just exit
|
||||
.ti -.25i
|
||||
3 - drop core, but continue executing. Core files will
|
||||
be placed into core.[PID].[counter] i.e: core.00123.001
|
||||
.ti -.25i
|
||||
128 - dump malloc chain and continue
|
||||
.ti -.25i
|
||||
129 - dump malloc chain, dump core, and exit
|
||||
.ti -.25i
|
||||
130 - dump malloc chain, exit
|
||||
.ti -.25i
|
||||
131 - dump malloc chain, dump core, continue processing
|
||||
.in -.5i
|
||||
.P
|
||||
In addition error messages can be placed into an error file.
|
||||
.P
|
||||
\fBmalloc_opt\fP() is used to set the malloc debugging options. The
|
||||
following options can be set:
|
||||
.br
|
||||
.sp
|
||||
.in +.5i
|
||||
MALLOC_WARN - set the error handling for warning level errors. \fBval.i\fP is
|
||||
an integer that can contain any one of the following values:
|
||||
.sp
|
||||
.in +.5i
|
||||
M_HANDLE_IGNORE - ignore error
|
||||
.br
|
||||
M_HANDLE_ABORT - drop core and exit
|
||||
.br
|
||||
M_HANDLE_EXIT - just exit (no core drop)
|
||||
.br
|
||||
M_HANDLE_CORE - drop core, but keep on going
|
||||
.br
|
||||
.in -.5i
|
||||
.sp
|
||||
In addition, M_HANDLE_DUMP may be or'd in to cause a dump of the current
|
||||
malloc chain.
|
||||
.br
|
||||
.sp
|
||||
MALLOC_FATAL - set the error handling for fatal level errors. \fBval.i\fP is
|
||||
equivalent to \fBval.i\fP for MALLOC_WARN.
|
||||
.br
|
||||
.sp
|
||||
MALLOC_ERRFILE - set the destination for malloc error messages. \fBval.str\fP
|
||||
is a pointer to a character string containing the name of the file to be used
|
||||
for error messages.
|
||||
.br
|
||||
.sp
|
||||
MALLOC_CKCHAIN - set the malloc chain checking flag. If \fBval.i\fP is
|
||||
non-zero, chain checking at every call to malloc is turned on.
|
||||
.br
|
||||
.sp
|
||||
For example, to set up the session to generate a core file for
|
||||
every malloc warning, to drop core and exit on a malloc fatal, and
|
||||
to log all messages to the file "malloc_log" do the following:
|
||||
.sp
|
||||
.nf
|
||||
.in +.5i
|
||||
#include <malloc.h>
|
||||
malloc_opt(MALLOC_WARN,131);
|
||||
malloc_opt(MALLOC_FATAL,1);
|
||||
malloc_opt(MALLOC_ERRFILE,"malloc_log");
|
||||
.in -.5i
|
||||
.fi
|
||||
.in -.5i
|
||||
.sp
|
||||
\fBmalloc_opt\fP() can be used to set/alter the debugging options at any
|
||||
time.
|
||||
.P
|
||||
\fBmalloc_dump\fP() will dump a table of the malloc arena showing all
|
||||
allocated/freed segments and the first few bytes of data in each segment.
|
||||
\fBfd\fP is the file descriptor to write the data to.
|
||||
.P
|
||||
\fBmalloc_chain_check\fP() will check the status of the malloc arena.
|
||||
If \fBflag\fP is non-zero, an error found in the chain will cause a
|
||||
fatal error. \fBmalloc_chain_check\fP() returns zero when there are no
|
||||
problems found in the malloc chain, non-zero otherwise.
|
||||
.SH "ENVIRONMENT VARIABLES"
|
||||
Environment variables can be used to control error handling, error logging
|
||||
and malloc chain checking at run time. The following environment variables
|
||||
are used:
|
||||
.P
|
||||
MALLOC_WARN - specifies the error handling for warning errors
|
||||
.br
|
||||
MALLOC_FATAL - specifies the error handling for fatal errors
|
||||
.br
|
||||
MALLOC_ERRFILE - specifies the error log file for error messages.
|
||||
.br
|
||||
MALLOC_CKCHAIN - if 1, turns on malloc chain checking at every call to any
|
||||
of the malloc functions.
|
||||
.P
|
||||
For example, to set up the session to generate a core file for
|
||||
every malloc warning, to drop core and exit on a malloc fatal, and
|
||||
to log all messages to the file "malloc_log" do the following:
|
||||
.sp
|
||||
.nf
|
||||
.in +.5i
|
||||
MALLOC_WARN=131
|
||||
MALLOC_FATAL=1
|
||||
MALLOC_ERRFILE=malloc_log
|
||||
|
||||
export MALLOC_WARN MALLOC_FATAL MALLOC_ERRFILE
|
||||
.in -.5i
|
||||
.fi
|
||||
.SH WARNINGS
|
||||
This malloc library and it's associated string and memory functions are
|
||||
much less efficient than the standard functions due in part to the extra
|
||||
error checking. You do not want to use this library when generating a
|
||||
production (i.e. releasable) version of your software. It should only
|
||||
be used during development and testing.
|
||||
.SH SEE ALSO
|
||||
stat(2)
|
||||
.SH AUTHOR
|
||||
Conor P. Cahill
|
||||
Virtual Technologies Incorporated
|
||||
.sp
|
||||
uunet!virtech!cpcahil
|
654
dmake/dbug/malloc/malloc.c
Normal file
654
dmake/dbug/malloc/malloc.c
Normal file
@ -0,0 +1,654 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include "malloc.h"
|
||||
#include "tostring.h"
|
||||
|
||||
/*
|
||||
* Function: malloc()
|
||||
*
|
||||
* Purpose: memory allocator
|
||||
*
|
||||
* Arguments: size - size of data area needed
|
||||
*
|
||||
* Returns: pointer to allocated area, or NULL if unable
|
||||
* to allocate addtional data.
|
||||
*
|
||||
* Narrative:
|
||||
*
|
||||
*/
|
||||
#ifndef lint
|
||||
static
|
||||
char rcs_hdr[] = "$Id: malloc.c,v 1.1 1992/01/24 03:29:05 dvadura Exp $";
|
||||
#endif
|
||||
|
||||
extern int malloc_checking;
|
||||
char * malloc_data_start;
|
||||
char * malloc_data_end;
|
||||
struct mlist * malloc_end;
|
||||
int malloc_errfd = 2;
|
||||
int malloc_errno;
|
||||
int malloc_fatal_level = M_HANDLE_CORE;
|
||||
struct mlist malloc_start;
|
||||
int malloc_warn_level;
|
||||
void malloc_memset();
|
||||
|
||||
char *
|
||||
malloc(size)
|
||||
unsigned int size;
|
||||
{
|
||||
char * func = "malloc";
|
||||
char * getenv();
|
||||
void malloc_fatal();
|
||||
void malloc_init();
|
||||
void malloc_split();
|
||||
void malloc_warning();
|
||||
unsigned int need;
|
||||
struct mlist * oldptr;
|
||||
struct mlist * ptr;
|
||||
char * sbrk();
|
||||
|
||||
/*
|
||||
* If this is the first call to malloc...
|
||||
*/
|
||||
if( malloc_data_start == (char *) 0 )
|
||||
{
|
||||
malloc_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* If malloc chain checking is on, go do it.
|
||||
*/
|
||||
if( malloc_checking )
|
||||
{
|
||||
(void) malloc_chain_check(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* always make sure there is at least on extra byte in the malloc
|
||||
* area so that we can verify that the user does not overrun the
|
||||
* data area.
|
||||
*/
|
||||
size++;
|
||||
|
||||
/*
|
||||
* Now look for a free area of memory of size bytes...
|
||||
*/
|
||||
oldptr = NULL;
|
||||
for(ptr = &malloc_start; ; ptr = ptr->next)
|
||||
{
|
||||
/*
|
||||
* Since the malloc chain is a forward only chain, any
|
||||
* pointer that we get should always be positioned in
|
||||
* memory following the previous pointer. If this is not
|
||||
* so, we must have a corrupted chain.
|
||||
*/
|
||||
if( ptr )
|
||||
{
|
||||
if( IsLess(ptr,oldptr) )
|
||||
{
|
||||
malloc_errno = M_CODE_CHAIN_BROKE;
|
||||
malloc_fatal(func);
|
||||
return(NULL);
|
||||
}
|
||||
oldptr = ptr;
|
||||
}
|
||||
else if( oldptr != malloc_end )
|
||||
{
|
||||
/*
|
||||
* This should never happen. If it does, then
|
||||
* we got a real problem.
|
||||
*/
|
||||
malloc_errno = M_CODE_NO_END;
|
||||
malloc_fatal(func);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* if this element is already in use...
|
||||
*/
|
||||
if( ptr && ((ptr->flag & M_INUSE) != 0) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* if there isn't room for this block..
|
||||
*/
|
||||
if( ptr && (ptr->s.size < size) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If ptr is null, we have run out of memory and must sbrk more
|
||||
*/
|
||||
if( ptr == NULL )
|
||||
{
|
||||
need = (size + M_SIZE) * (size > 10*1024 ? 1:2);
|
||||
if( need < M_BLOCKSIZE )
|
||||
{
|
||||
need = M_BLOCKSIZE;
|
||||
}
|
||||
else if( need & (M_BLOCKSIZE-1) )
|
||||
{
|
||||
need &= ~(M_BLOCKSIZE-1);
|
||||
need += M_BLOCKSIZE;
|
||||
}
|
||||
ptr = (struct mlist *) sbrk((int)need);
|
||||
if( ptr == (struct mlist *) -1 )
|
||||
{
|
||||
malloc_errno = M_CODE_NOMORE_MEM;
|
||||
malloc_fatal(func);
|
||||
}
|
||||
malloc_data_end = sbrk((int)0);
|
||||
|
||||
ptr->prev = oldptr;
|
||||
ptr->next = (struct mlist *) 0;
|
||||
ptr->s.size = need - M_SIZE;
|
||||
ptr->flag = M_MAGIC;
|
||||
|
||||
oldptr->next = ptr;
|
||||
malloc_end = ptr;
|
||||
|
||||
|
||||
} /* if( ptr ==... */
|
||||
|
||||
/*
|
||||
* Now ptr points to a memory location that can store
|
||||
* this data, so lets go to work.
|
||||
*/
|
||||
|
||||
ptr->r_size = size; /* save requested size */
|
||||
ptr->flag |= M_INUSE;
|
||||
|
||||
/*
|
||||
* split off unneeded data area in this block, if possible...
|
||||
*/
|
||||
malloc_split(ptr);
|
||||
|
||||
/*
|
||||
* re-adjust the requested size so that it is what the user
|
||||
* actually requested...
|
||||
*/
|
||||
|
||||
ptr->r_size--;
|
||||
|
||||
/*
|
||||
* just to make sure that noone is misusing malloced
|
||||
* memory without initializing it, lets set it to
|
||||
* all '\01's. We call local_memset() because memset()
|
||||
* may be checking for malloc'd ptrs and this isn't
|
||||
* a malloc'd ptr yet.
|
||||
*/
|
||||
malloc_memset(ptr->data,M_FILL,(int)ptr->s.size);
|
||||
|
||||
return( ptr->data);
|
||||
|
||||
} /* for(... */
|
||||
|
||||
} /* malloc(... */
|
||||
|
||||
/*
|
||||
* Function: malloc_split()
|
||||
*
|
||||
* Purpose: to split a malloc segment if there is enough room at the
|
||||
* end of the segment that isn't being used
|
||||
*
|
||||
* Arguments: ptr - pointer to segment to split
|
||||
*
|
||||
* Returns: nothing of any use.
|
||||
*
|
||||
* Narrative:
|
||||
* get the needed size of the module
|
||||
* round the size up to appropriat boundry
|
||||
* calculate amount of left over space
|
||||
* if there is enough left over space
|
||||
* create new malloc block out of remainder
|
||||
* if next block is free
|
||||
* join the two blocks together
|
||||
* fill new empty block with free space filler
|
||||
* re-adjust pointers and size of current malloc block
|
||||
*
|
||||
*
|
||||
*
|
||||
* Mod History:
|
||||
* 90/01/27 cpcahil Initial revision.
|
||||
*/
|
||||
void
|
||||
malloc_split(ptr)
|
||||
struct mlist * ptr;
|
||||
{
|
||||
extern struct mlist * malloc_end;
|
||||
void malloc_join();
|
||||
int rest;
|
||||
int size;
|
||||
struct mlist * tptr;
|
||||
|
||||
size = ptr->r_size;
|
||||
|
||||
/*
|
||||
* roundup size to the appropriate boundry
|
||||
*/
|
||||
|
||||
M_ROUNDUP(size);
|
||||
|
||||
/*
|
||||
* figure out how much room is left in the array.
|
||||
* if there is enough room, create a new mlist
|
||||
* structure there.
|
||||
*/
|
||||
|
||||
if( ptr->s.size > size )
|
||||
{
|
||||
rest = ptr->s.size - size;
|
||||
}
|
||||
else
|
||||
{
|
||||
rest = 0;
|
||||
}
|
||||
|
||||
if( rest > (M_SIZE+M_RND) )
|
||||
{
|
||||
tptr = (struct mlist *) (ptr->data+size);
|
||||
tptr->prev = ptr;
|
||||
tptr->next = ptr->next;
|
||||
tptr->flag = M_MAGIC;
|
||||
tptr->s.size = rest - M_SIZE;
|
||||
|
||||
/*
|
||||
* If possible, join this segment with the next one
|
||||
*/
|
||||
|
||||
malloc_join(tptr, tptr->next,0,0);
|
||||
|
||||
if( tptr->next )
|
||||
{
|
||||
tptr->next->prev = tptr;
|
||||
}
|
||||
|
||||
malloc_memset(tptr->data,M_FREE_FILL, (int)tptr->s.size);
|
||||
|
||||
ptr->next = tptr;
|
||||
ptr->s.size = size;
|
||||
|
||||
if( malloc_end == ptr )
|
||||
{
|
||||
malloc_end = tptr;
|
||||
}
|
||||
}
|
||||
|
||||
} /* malloc_split(... */
|
||||
|
||||
/*
|
||||
* Function: malloc_join()
|
||||
*
|
||||
* Purpose: to join two malloc segments together (if possible)
|
||||
*
|
||||
* Arguments: ptr - pointer to segment to join to.
|
||||
* nextptr - pointer to next segment to join to ptr.
|
||||
*
|
||||
* Returns: nothing of any values.
|
||||
*
|
||||
* Narrative:
|
||||
*
|
||||
* Mod History:
|
||||
* 90/01/27 cpcahil Initial revision.
|
||||
*/
|
||||
void
|
||||
malloc_join(ptr,nextptr, inuse_override, fill_flag)
|
||||
struct mlist * ptr;
|
||||
struct mlist * nextptr;
|
||||
int inuse_override;
|
||||
int fill_flag;
|
||||
{
|
||||
unsigned int newsize;
|
||||
|
||||
if( ptr && ! (inuse_override || (ptr->flag & M_INUSE)) &&
|
||||
nextptr && ! (nextptr->flag & M_INUSE) &&
|
||||
((ptr->data+ptr->s.size) == (char *) nextptr) )
|
||||
{
|
||||
if( malloc_end == nextptr )
|
||||
{
|
||||
malloc_end = ptr;
|
||||
}
|
||||
ptr->next = nextptr->next;
|
||||
newsize = nextptr->s.size + M_SIZE;
|
||||
|
||||
/*
|
||||
* if we are to fill and this segment is in use,
|
||||
* fill in with M_FILL newly added space...
|
||||
*/
|
||||
|
||||
if(fill_flag && (ptr->flag & M_INUSE) )
|
||||
{
|
||||
malloc_memset(ptr->data+ptr->s.size,
|
||||
M_FILL, (int)(nextptr->s.size + M_SIZE));
|
||||
}
|
||||
|
||||
ptr->s.size += newsize;
|
||||
if( ptr->next )
|
||||
{
|
||||
ptr->next->prev = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
} /* malloc_join(... */
|
||||
|
||||
|
||||
/*
|
||||
* The following mess is just to ensure that the versions of these functions in
|
||||
* the current library are included (to make sure that we don't accidentaly get
|
||||
* the libc versions. (This is the lazy man's -u ld directive)
|
||||
*/
|
||||
|
||||
void free();
|
||||
int strcmp();
|
||||
int memcmp();
|
||||
char * realloc();
|
||||
|
||||
void (*malloc_void_funcs[])() =
|
||||
{
|
||||
free,
|
||||
};
|
||||
|
||||
int (*malloc_int_funcs[])() =
|
||||
{
|
||||
strcmp,
|
||||
memcmp,
|
||||
};
|
||||
|
||||
char * (*malloc_char_star_funcs[])() =
|
||||
{
|
||||
realloc,
|
||||
};
|
||||
|
||||
/*
|
||||
* This is malloc's own memset which is used without checking the parameters.
|
||||
*/
|
||||
|
||||
void
|
||||
malloc_memset(ptr,byte,len)
|
||||
char * ptr;
|
||||
char byte;
|
||||
int len;
|
||||
{
|
||||
|
||||
while(len-- > 0)
|
||||
{
|
||||
*ptr++ = byte;
|
||||
}
|
||||
|
||||
} /* malloc_memset(... */
|
||||
|
||||
/*
|
||||
* Function: malloc_fatal()
|
||||
*
|
||||
* Purpose: to display fatal error message and take approrpriate action
|
||||
*
|
||||
* Arguments: funcname - name of function calling this routine
|
||||
*
|
||||
* Returns: nothing of any value
|
||||
*
|
||||
* Narrative:
|
||||
*
|
||||
* Notes: This routine does not make use of any libc functions to build
|
||||
* and/or disply the error message. This is due to the fact that
|
||||
* we are probably at a point where malloc is having a real problem
|
||||
* and we don't want to call any function that may use malloc.
|
||||
*/
|
||||
void
|
||||
malloc_fatal(funcname)
|
||||
char * funcname;
|
||||
{
|
||||
char errbuf[128];
|
||||
void exit();
|
||||
void malloc_err_handler();
|
||||
extern char * malloc_err_strings[];
|
||||
extern int malloc_errno;
|
||||
extern int malloc_fatal_level;
|
||||
char * s;
|
||||
char * t;
|
||||
|
||||
s = errbuf;
|
||||
t = "Fatal error: ";
|
||||
while( *s = *t++)
|
||||
{
|
||||
s++;
|
||||
}
|
||||
t = funcname;
|
||||
while( *s = *t++)
|
||||
{
|
||||
s++;
|
||||
}
|
||||
|
||||
t = "(): ";
|
||||
while( *s = *t++)
|
||||
{
|
||||
s++;
|
||||
}
|
||||
|
||||
t = malloc_err_strings[malloc_errno];
|
||||
while( *s = *t++)
|
||||
{
|
||||
s++;
|
||||
}
|
||||
|
||||
*(s++) = '\n';
|
||||
|
||||
if( write(malloc_errfd,errbuf,(unsigned)(s-errbuf)) != (s-errbuf))
|
||||
{
|
||||
(void) write(2,"I/O error to error file\n",(unsigned)24);
|
||||
exit(110);
|
||||
}
|
||||
malloc_err_handler(malloc_fatal_level);
|
||||
|
||||
} /* malloc_fatal(... */
|
||||
|
||||
/*
|
||||
* Function: malloc_warning()
|
||||
*
|
||||
* Purpose: to display warning error message and take approrpriate action
|
||||
*
|
||||
* Arguments: funcname - name of function calling this routine
|
||||
*
|
||||
* Returns: nothing of any value
|
||||
*
|
||||
* Narrative:
|
||||
*
|
||||
* Notes: This routine does not make use of any libc functions to build
|
||||
* and/or disply the error message. This is due to the fact that
|
||||
* we are probably at a point where malloc is having a real problem
|
||||
* and we don't want to call any function that may use malloc.
|
||||
*/
|
||||
void
|
||||
malloc_warning(funcname)
|
||||
char * funcname;
|
||||
{
|
||||
char errbuf[128];
|
||||
void exit();
|
||||
void malloc_err_handler();
|
||||
extern char * malloc_err_strings[];
|
||||
extern int malloc_errno;
|
||||
extern int malloc_warn_level;
|
||||
char * s;
|
||||
char * t;
|
||||
|
||||
s = errbuf;
|
||||
t = "Warning: ";
|
||||
while( *s = *t++)
|
||||
{
|
||||
s++;
|
||||
}
|
||||
t = funcname;
|
||||
while( *s = *t++)
|
||||
{
|
||||
s++;
|
||||
}
|
||||
|
||||
t = "(): ";
|
||||
while( *s = *t++)
|
||||
{
|
||||
s++;
|
||||
}
|
||||
|
||||
t = malloc_err_strings[malloc_errno];
|
||||
while( *s = *t++)
|
||||
{
|
||||
s++;
|
||||
}
|
||||
|
||||
*(s++) = '\n';
|
||||
|
||||
if( write(malloc_errfd,errbuf,(unsigned)(s-errbuf)) != (s-errbuf))
|
||||
{
|
||||
(void) write(2,"I/O error to error file\n",(unsigned)24);
|
||||
exit(110);
|
||||
}
|
||||
|
||||
malloc_err_handler(malloc_warn_level);
|
||||
|
||||
} /* malloc_warning(... */
|
||||
|
||||
/*
|
||||
* Function: malloc_err_handler()
|
||||
*
|
||||
* Purpose: to take the appropriate action for warning and/or fatal
|
||||
* error conditions.
|
||||
*
|
||||
* Arguments: level - error handling level
|
||||
*
|
||||
* Returns: nothing of any value
|
||||
*
|
||||
* Narrative:
|
||||
*
|
||||
* Notes: This routine does not make use of any libc functions to build
|
||||
* and/or disply the error message. This is due to the fact that
|
||||
* we are probably at a point where malloc is having a real problem
|
||||
* and we don't want to call any function that may use malloc.
|
||||
*/
|
||||
void
|
||||
malloc_err_handler(level)
|
||||
{
|
||||
void exit();
|
||||
void malloc_dump();
|
||||
extern int malloc_errfd;
|
||||
|
||||
if( level & M_HANDLE_DUMP )
|
||||
{
|
||||
malloc_dump(malloc_errfd);
|
||||
}
|
||||
|
||||
switch( level & ~M_HANDLE_DUMP )
|
||||
{
|
||||
/*
|
||||
* If we are to drop a core file and exit
|
||||
*/
|
||||
case M_HANDLE_ABORT:
|
||||
(void) abort();
|
||||
break;
|
||||
|
||||
/*
|
||||
* If we are to exit..
|
||||
*/
|
||||
case M_HANDLE_EXIT:
|
||||
exit(200);
|
||||
break;
|
||||
|
||||
#ifndef __MSDOS__
|
||||
/*
|
||||
* If we are to dump a core, but keep going on our merry way
|
||||
*/
|
||||
case M_HANDLE_CORE:
|
||||
{
|
||||
int pid;
|
||||
|
||||
/*
|
||||
* fork so child can abort (and dump core)
|
||||
*/
|
||||
if( (pid = fork()) == 0 )
|
||||
{
|
||||
(void) write(2,"Child dumping core\n",
|
||||
(unsigned)9);
|
||||
(void) abort();
|
||||
}
|
||||
|
||||
/*
|
||||
* wait for child to finish dumping core
|
||||
*/
|
||||
while( wait((int *)0) != pid)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Move core file to core.pid.cnt so
|
||||
* multiple cores don't overwrite each
|
||||
* other.
|
||||
*/
|
||||
if( access("core",0) == 0 )
|
||||
{
|
||||
static int corecnt;
|
||||
char filenam[32];
|
||||
filenam[0] = 'c';
|
||||
filenam[1] = 'o';
|
||||
filenam[2] = 'r';
|
||||
filenam[3] = 'e';
|
||||
filenam[4] = '.';
|
||||
(void)tostring(filenam+5,getpid(),
|
||||
5, B_DEC, '0');
|
||||
filenam[10] = '.';
|
||||
(void)tostring(filenam+11,corecnt++,
|
||||
3, B_DEC, '0');
|
||||
filenam[14] = '\0';
|
||||
(void) unlink(filenam);
|
||||
if( link("core",filenam) == 0)
|
||||
{
|
||||
(void) unlink("core");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* If we are to just ignore the error and keep on processing
|
||||
*/
|
||||
case M_HANDLE_IGNORE:
|
||||
break;
|
||||
|
||||
} /* switch(... */
|
||||
|
||||
} /* malloc_err_handler(... */
|
||||
|
||||
/*
|
||||
* $Log: malloc.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:05 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.6 90/05/11 00:13:09 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.5 90/02/25 11:01:18 cpcahil
|
||||
* added support for malloc chain checking.
|
||||
*
|
||||
* Revision 1.4 90/02/24 21:50:21 cpcahil
|
||||
* lots of lint fixes
|
||||
*
|
||||
* Revision 1.3 90/02/24 14:51:18 cpcahil
|
||||
* 1. changed malloc_fatal and malloc_warn to use malloc_errno and be passed
|
||||
* the function name as a parameter.
|
||||
* 2. Added several function headers.
|
||||
* 3. Changed uses of malloc_fatal/warning to conform to new usage.
|
||||
*
|
||||
* Revision 1.2 90/02/23 18:05:23 cpcahil
|
||||
* fixed open of error log to use append mode.
|
||||
*
|
||||
* Revision 1.1 90/02/22 23:17:43 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
103
dmake/dbug/malloc/malloc.h
Normal file
103
dmake/dbug/malloc/malloc.h
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
/*
|
||||
* $Id: malloc.h,v 1.1 1992/01/24 03:29:06 dvadura Exp $
|
||||
*/
|
||||
struct mlist
|
||||
{
|
||||
struct mlist * next; /* next entry in chain */
|
||||
struct mlist * prev; /* prev entry in chain */
|
||||
int flag; /* inuse flag */
|
||||
unsigned int r_size; /* requested size */
|
||||
union
|
||||
{
|
||||
unsigned int size; /* actual size */
|
||||
double unused_just_for_alignment;
|
||||
} s;
|
||||
char data[4];
|
||||
};
|
||||
|
||||
#define M_SIZE ((int)(char *)((struct mlist *)0)->data)
|
||||
#define M_RND 0x08
|
||||
|
||||
#define M_INUSE 0x01
|
||||
#define M_MAGIC 0x03156100
|
||||
|
||||
#define M_BLOCKSIZE (1024*8)
|
||||
|
||||
#define M_FILL '\01'
|
||||
#define M_FREE_FILL '\02'
|
||||
|
||||
#define M_ROUNDUP(size) {\
|
||||
if( size & (M_RND-1) ) \
|
||||
{ \
|
||||
size &= ~(M_RND-1); \
|
||||
size += M_RND; \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Malloc warning/fatal error handler defines...
|
||||
*/
|
||||
#define M_HANDLE_DUMP 0x80 /* 128 */
|
||||
#define M_HANDLE_IGNORE 0
|
||||
#define M_HANDLE_ABORT 1
|
||||
#define M_HANDLE_EXIT 2
|
||||
#define M_HANDLE_CORE 3
|
||||
|
||||
/*
|
||||
* Mallopt commands and defaults
|
||||
*/
|
||||
|
||||
#define MALLOC_WARN 1 /* set malloc warning handling */
|
||||
#define MALLOC_FATAL 2 /* set malloc fatal handling */
|
||||
#define MALLOC_ERRFILE 3 /* specify malloc error file */
|
||||
#define MALLOC_CKCHAIN 4 /* turn on chain checking */
|
||||
union malloptarg
|
||||
{
|
||||
int i;
|
||||
char * str;
|
||||
};
|
||||
|
||||
/*
|
||||
* Malloc warning/fatal error codes
|
||||
*/
|
||||
|
||||
#define M_CODE_CHAIN_BROKE 1 /* malloc chain is broken */
|
||||
#define M_CODE_NO_END 2 /* chain end != endptr */
|
||||
#define M_CODE_BAD_PTR 3 /* pointer not in malloc area */
|
||||
#define M_CODE_BAD_MAGIC 4 /* bad magic number in header */
|
||||
#define M_CODE_BAD_CONNECT 5 /* chain poingers corrupt */
|
||||
#define M_CODE_OVERRUN 6 /* data overrun in malloc seg */
|
||||
#define M_CODE_REUSE 7 /* reuse of freed area */
|
||||
#define M_CODE_NOT_INUSE 8 /* pointer is not in use */
|
||||
#define M_CODE_NOMORE_MEM 9 /* no more memory available */
|
||||
#define M_CODE_OUTOF_BOUNDS 10 /* gone beyound bounds */
|
||||
|
||||
void malloc_warning();
|
||||
void malloc_fatal();
|
||||
void malloc_check_data();
|
||||
void malloc_check_str();
|
||||
void malloc_verify();
|
||||
|
||||
/*
|
||||
* $Log: malloc.h,v $
|
||||
* Revision 1.1 1992/01/24 03:29:06 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.4 90/08/29 22:23:38 cpcahil
|
||||
* fixed mallopt to use a union as an argument.
|
||||
*
|
||||
* Revision 1.3 90/05/11 11:04:10 cpcahil
|
||||
* took out some extraneous lines
|
||||
*
|
||||
* Revision 1.2 90/05/11 00:13:09 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.1 90/02/23 07:09:03 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
125
dmake/dbug/malloc/mallopt.c
Normal file
125
dmake/dbug/malloc/mallopt.c
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include "malloc.h"
|
||||
|
||||
/*
|
||||
* Function: mallopt()
|
||||
*
|
||||
* Purpose: to set options for the malloc debugging library
|
||||
*
|
||||
* Arguments: none
|
||||
*
|
||||
* Returns: nothing of any value
|
||||
*
|
||||
* Narrative:
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static
|
||||
char rcs_hdr[] = "$Id: mallopt.c,v 1.1 1992/01/24 03:29:07 dvadura Exp $";
|
||||
#endif
|
||||
|
||||
int
|
||||
mallopt(cmd,value)
|
||||
int cmd;
|
||||
union malloptarg value;
|
||||
{
|
||||
int i;
|
||||
extern int malloc_checking;
|
||||
extern char * malloc_data_start;
|
||||
extern int malloc_errfd;
|
||||
extern int malloc_fatal_level;
|
||||
void malloc_init();
|
||||
extern int malloc_warn_level;
|
||||
register char * s;
|
||||
|
||||
/*
|
||||
* If not initialized...
|
||||
*/
|
||||
if( malloc_data_start == (char *) 0)
|
||||
{
|
||||
malloc_init();
|
||||
}
|
||||
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
case MALLOC_WARN:
|
||||
malloc_warn_level = value.i;
|
||||
break;
|
||||
|
||||
case MALLOC_FATAL:
|
||||
malloc_fatal_level = value.i;
|
||||
break;
|
||||
|
||||
case MALLOC_CKCHAIN:
|
||||
malloc_checking = value.i;
|
||||
break;
|
||||
|
||||
case MALLOC_ERRFILE:
|
||||
|
||||
i = open(value.str,O_CREAT|O_APPEND|O_WRONLY,0666);
|
||||
if( i == -1 )
|
||||
{
|
||||
(void) write(2,
|
||||
"Unable to open malloc error file: ",
|
||||
(unsigned) 34);
|
||||
for(s=value.str; *s; s++)
|
||||
{
|
||||
/* do nothing */;
|
||||
}
|
||||
(void) write(2,value.str,
|
||||
(unsigned)(s-value.str));
|
||||
(void) write(2,"\n",(unsigned)1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( malloc_errfd != 2 )
|
||||
{
|
||||
(void) close(malloc_errfd);
|
||||
}
|
||||
malloc_errfd = i;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: mallopt.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:07 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.6 90/08/29 22:23:36 cpcahil
|
||||
* fixed mallopt to use a union as an argument.
|
||||
*
|
||||
* Revision 1.5 90/08/29 21:22:51 cpcahil
|
||||
* miscellaneous lint fixes
|
||||
*
|
||||
* Revision 1.4 90/05/11 00:13:10 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.3 90/02/25 11:03:26 cpcahil
|
||||
* changed to return int so that it agrees with l libmalloc.a's mallopt()
|
||||
*
|
||||
* Revision 1.2 90/02/25 11:01:21 cpcahil
|
||||
* added support for malloc chain checking.
|
||||
*
|
||||
* Revision 1.1 90/02/24 21:50:24 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
* Revision 1.1 90/02/24 17:10:53 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
225
dmake/dbug/malloc/memory.c
Normal file
225
dmake/dbug/malloc/memory.c
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static
|
||||
char rcs_hdr[] = "$Id: memory.c,v 1.1 1992/01/24 03:29:08 dvadura Exp $";
|
||||
#endif
|
||||
|
||||
void malloc_check_data();
|
||||
|
||||
char *
|
||||
memccpy(ptr1, ptr2, ch, len)
|
||||
register char * ptr1;
|
||||
register char * ptr2;
|
||||
int len;
|
||||
int ch;
|
||||
{
|
||||
int check;
|
||||
register int i;
|
||||
char * rtn;
|
||||
|
||||
/*
|
||||
* I know that the assignment could be done in the following, but
|
||||
* I wanted to perform a check before any assignment, so first I
|
||||
* determine the length, check the pointers and then do the assignment.
|
||||
*/
|
||||
for( i=0; (i < len) && (ptr2[i] != ch); i++)
|
||||
{
|
||||
}
|
||||
if( ptr2[i] == ch )
|
||||
{
|
||||
check = i+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
check = len;
|
||||
}
|
||||
|
||||
malloc_check_data("memccpy", ptr1, check);
|
||||
malloc_check_data("memccpy", ptr2, check);
|
||||
|
||||
/*
|
||||
* if we found the character...
|
||||
*/
|
||||
|
||||
if( i < len )
|
||||
{
|
||||
rtn = ptr1+i+1;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
rtn = (char *) 0;
|
||||
}
|
||||
|
||||
while( i-- )
|
||||
{
|
||||
*(ptr1++) = *(ptr2++);
|
||||
}
|
||||
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
char *
|
||||
memchr(ptr1,ch,len)
|
||||
register char * ptr1;
|
||||
register int ch;
|
||||
int len;
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i=0; (i < len) && (ptr1[i] != (char) ch); i++)
|
||||
{
|
||||
}
|
||||
|
||||
malloc_check_data("memchr", ptr1, i);
|
||||
|
||||
if( i < len )
|
||||
{
|
||||
return( ptr1+i );
|
||||
}
|
||||
else
|
||||
{
|
||||
return( (char *) 0);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
memcpy(ptr1, ptr2, len)
|
||||
register char * ptr1;
|
||||
register char * ptr2;
|
||||
register int len;
|
||||
{
|
||||
char * rtn = ptr1;
|
||||
|
||||
malloc_check_data("memcpy", ptr1, len);
|
||||
malloc_check_data("memcpy", ptr2, len);
|
||||
|
||||
/*
|
||||
* while the normal memcpy does not guarrantee that it will
|
||||
* handle overlapping memory correctly, we will try...
|
||||
*/
|
||||
if( ptr1 > ptr2 && ptr1 < (ptr2+len))
|
||||
{
|
||||
ptr1 += (len-1);
|
||||
ptr2 += (len-1);
|
||||
while( len-- > 0 )
|
||||
{
|
||||
*(ptr1--) = *(ptr2--);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while( len-- > 0 )
|
||||
{
|
||||
*(ptr1++) = *(ptr2++);
|
||||
}
|
||||
}
|
||||
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
int
|
||||
memcmp(ptr1, ptr2, len)
|
||||
register char * ptr1;
|
||||
register char * ptr2;
|
||||
register int len;
|
||||
{
|
||||
malloc_check_data("memcpy", ptr1, len);
|
||||
malloc_check_data("memcpy", ptr2, len);
|
||||
|
||||
while( --len >= 0 && (*ptr1 == *ptr2) )
|
||||
{
|
||||
ptr1++;
|
||||
ptr2++;
|
||||
}
|
||||
|
||||
/*
|
||||
* If stopped by len, return zero
|
||||
*/
|
||||
if( len < 0 )
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
return( *ptr1 - *ptr2 );
|
||||
}
|
||||
|
||||
char *
|
||||
memset(ptr1, ch, len)
|
||||
register char * ptr1;
|
||||
register int ch;
|
||||
register int len;
|
||||
{
|
||||
char * rtn = ptr1;
|
||||
|
||||
malloc_check_data("memcpy", ptr1, len);
|
||||
|
||||
while( len-- )
|
||||
{
|
||||
*(ptr1++) = ch;
|
||||
}
|
||||
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
char *
|
||||
bcopy(ptr2,ptr1,len)
|
||||
char * ptr2;
|
||||
char * ptr1;
|
||||
int len;
|
||||
{
|
||||
return(memcpy(ptr1,ptr2,len));
|
||||
}
|
||||
|
||||
char *
|
||||
bzero(ptr1,len)
|
||||
char * ptr1;
|
||||
int len;
|
||||
{
|
||||
return(memset(ptr1,'\0',len));
|
||||
}
|
||||
|
||||
int
|
||||
bcmp(ptr2, ptr1, len)
|
||||
char * ptr1;
|
||||
char * ptr2;
|
||||
int len;
|
||||
{
|
||||
return( memcmp(ptr1,ptr2,len) );
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: memory.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:08 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.7 90/08/29 21:27:58 cpcahil
|
||||
* fixed value of check in memccpy when character was not found.
|
||||
*
|
||||
* Revision 1.6 90/07/16 20:06:26 cpcahil
|
||||
* fixed several minor bugs found with Henry Spencer's string/mem tester
|
||||
* program.
|
||||
*
|
||||
*
|
||||
* Revision 1.5 90/05/11 15:39:36 cpcahil
|
||||
* fixed bug in memccpy().
|
||||
*
|
||||
* Revision 1.4 90/05/11 00:13:10 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.3 90/02/24 21:50:29 cpcahil
|
||||
* lots of lint fixes
|
||||
*
|
||||
* Revision 1.2 90/02/24 17:29:41 cpcahil
|
||||
* changed $Header to $Id so full path wouldnt be included as part of rcs
|
||||
* id string
|
||||
*
|
||||
* Revision 1.1 90/02/22 23:17:43 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
279
dmake/dbug/malloc/mlc_chk.c
Normal file
279
dmake/dbug/malloc/mlc_chk.c
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "malloc.h"
|
||||
#include "debug.h"
|
||||
|
||||
#ifndef lint
|
||||
static
|
||||
char rcs_hdr[] = "$Id: mlc_chk.c,v 1.1 1992/01/24 03:29:09 dvadura Exp $";
|
||||
#endif
|
||||
|
||||
extern struct mlist malloc_start;
|
||||
extern struct mlist * malloc_end;
|
||||
extern char * malloc_data_start;
|
||||
extern char * malloc_data_end;
|
||||
|
||||
/*
|
||||
* Function: malloc_in_arena()
|
||||
*
|
||||
* Purpose: to verify address is within malloc arena.
|
||||
*
|
||||
* Arguments: ptr - pointer to verify
|
||||
*
|
||||
* Returns: TRUE - if pointer is within malloc area
|
||||
* FALSE - otherwise
|
||||
*
|
||||
* Narrative:
|
||||
* IF pointer is >= malloc area start AND <= malloc area end
|
||||
* return TRUE
|
||||
* ELSE
|
||||
* return FALSE
|
||||
*
|
||||
* Mod History:
|
||||
* 90/01/24 cpcahil Initial revision.
|
||||
*/
|
||||
int
|
||||
malloc_in_arena(ptr)
|
||||
char * ptr;
|
||||
{
|
||||
extern char * malloc_data_start;
|
||||
extern char * malloc_data_end;
|
||||
int rtn = 0;
|
||||
|
||||
if( ptr >= malloc_data_start && ptr <= malloc_data_end )
|
||||
{
|
||||
rtn = 1;
|
||||
}
|
||||
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: malloc_check_str()
|
||||
*
|
||||
* Arguments: func - name of function calling this routine
|
||||
* str - pointer to area to check
|
||||
*
|
||||
* Purpose: to verify that if str is within the malloc arena, the data
|
||||
* it points to does not extend beyond the applicable region.
|
||||
*
|
||||
* Returns: Nothing of any use (function is void).
|
||||
*
|
||||
* Narrative:
|
||||
* IF pointer is within malloc arena
|
||||
* determin length of string
|
||||
* call malloc_verify() to verify data is withing applicable region
|
||||
* return
|
||||
*
|
||||
* Mod History:
|
||||
* 90/01/24 cpcahil Initial revision.
|
||||
* 90/01/29 cpcahil Added code to ignore recursive calls.
|
||||
*/
|
||||
void
|
||||
malloc_check_str(func,str)
|
||||
char * func;
|
||||
char * str;
|
||||
{
|
||||
static int layers;
|
||||
register char * s;
|
||||
|
||||
if( (layers++ == 0) && malloc_in_arena(str) )
|
||||
{
|
||||
for( s=str; *s; s++)
|
||||
{
|
||||
}
|
||||
|
||||
malloc_verify(func,str,s-str+1);
|
||||
}
|
||||
|
||||
layers--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: malloc_check_strn()
|
||||
*
|
||||
* Arguments: func - name of function calling this routine
|
||||
* str - pointer to area to check
|
||||
* len - max length of string
|
||||
*
|
||||
* Purpose: to verify that if str is within the malloc arena, the data
|
||||
* it points to does not extend beyond the applicable region.
|
||||
*
|
||||
* Returns: Nothing of any use (function is void).
|
||||
*
|
||||
* Narrative:
|
||||
* IF pointer is within malloc arena
|
||||
* determin length of string
|
||||
* call malloc_verify() to verify data is withing applicable region
|
||||
* return
|
||||
*
|
||||
* Mod History:
|
||||
* 90/01/24 cpcahil Initial revision.
|
||||
* 90/01/29 cpcahil Added code to ignore recursive calls.
|
||||
* 90/08/29 cpcahil added length (for strn* functions)
|
||||
*/
|
||||
void
|
||||
malloc_check_strn(func,str,len)
|
||||
char * func;
|
||||
char * str;
|
||||
int len;
|
||||
{
|
||||
register int i;
|
||||
static int layers;
|
||||
register char * s;
|
||||
|
||||
if( (layers++ == 0) && malloc_in_arena(str) )
|
||||
{
|
||||
for( s=str,i=0; (i < len) && *s; s++)
|
||||
{
|
||||
}
|
||||
|
||||
malloc_verify(func,str,s-str+1);
|
||||
}
|
||||
|
||||
layers--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: malloc_check_data()
|
||||
*
|
||||
* Arguments: func - name of function calling this routine
|
||||
* ptr - pointer to area to check
|
||||
* len - length to verify
|
||||
*
|
||||
* Purpose: to verify that if ptr is within the malloc arena, the data
|
||||
* it points to does not extend beyond the applicable region.
|
||||
*
|
||||
* Returns: Nothing of any use (function is void).
|
||||
*
|
||||
* Narrative:
|
||||
* IF pointer is within malloc arena
|
||||
* call malloc_verify() to verify data is withing applicable region
|
||||
* return
|
||||
*
|
||||
* Mod History:
|
||||
* 90/01/24 cpcahil Initial revision.
|
||||
* 90/01/29 cpcahil Added code to ignore recursive calls.
|
||||
*/
|
||||
void
|
||||
malloc_check_data(func,ptr,len)
|
||||
char * func;
|
||||
char * ptr;
|
||||
int len;
|
||||
{
|
||||
static int layers;
|
||||
|
||||
if( layers++ == 0 )
|
||||
{
|
||||
DEBUG3(40,"malloc_check_data(%s,0x%x,%d) called...",
|
||||
func,ptr,len);
|
||||
if( malloc_in_arena(ptr) )
|
||||
{
|
||||
DEBUG0(10,"pointer in malloc arena, verifying...");
|
||||
malloc_verify(func,ptr,len);
|
||||
}
|
||||
}
|
||||
|
||||
layers--;
|
||||
}
|
||||
|
||||
/*
|
||||
* Function: malloc_verify()
|
||||
*
|
||||
* Arguments: func - name of function calling the malloc check routines
|
||||
* ptr - pointer to area to check
|
||||
* len - length to verify
|
||||
*
|
||||
* Purpose: to verify that the data ptr points to does not extend beyond
|
||||
* the applicable malloc region. This function is only called
|
||||
* if it has been determined that ptr points into the malloc arena.
|
||||
*
|
||||
* Returns: Nothing of any use (function is void).
|
||||
*
|
||||
* Narrative:
|
||||
*
|
||||
* Mod History:
|
||||
* 90/01/24 cpcahil Initial revision.
|
||||
*/
|
||||
void
|
||||
malloc_verify(func,ptr,len)
|
||||
char * func;
|
||||
char * ptr;
|
||||
int len;
|
||||
{
|
||||
extern struct mlist * malloc_end;
|
||||
extern int malloc_errno;
|
||||
extern struct mlist malloc_start;
|
||||
struct mlist * mptr;
|
||||
|
||||
DEBUG3(40,"malloc_verify(%s,0x%x,%d) called...", func,ptr,len);
|
||||
/*
|
||||
* Find the malloc block that includes this pointer
|
||||
*/
|
||||
mptr = &malloc_start;
|
||||
while( mptr &&
|
||||
! (((char *)mptr < ptr) && ((mptr->data+mptr->s.size) > ptr) ) )
|
||||
{
|
||||
mptr = mptr->next;
|
||||
}
|
||||
|
||||
/*
|
||||
* if ptr was not in a malloc block, it must be part of
|
||||
* some direct sbrk() stuff, so just return.
|
||||
*/
|
||||
if( ! mptr )
|
||||
{
|
||||
DEBUG1(10,"ptr (0x%x) not found in malloc search", ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we have a valid malloc block that contains the indicated
|
||||
* pointer. We must verify that it is withing the requested block
|
||||
* size (as opposed to the real block size which is rounded up to
|
||||
* allow for correct alignment).
|
||||
*/
|
||||
|
||||
DEBUG4(60,"Checking 0x%x-0x%x, 0x%x-0x%x",
|
||||
ptr, ptr+len, mptr->data, mptr->data+mptr->r_size);
|
||||
|
||||
if( (ptr < mptr->data) || ((ptr+len) > (mptr->data+mptr->r_size)) )
|
||||
{
|
||||
DEBUG4(0,"pointer not within region 0x%x-0x%x, 0x%x-0x%x",
|
||||
ptr, ptr+len, mptr->data, mptr->data+mptr->r_size);
|
||||
|
||||
malloc_errno = M_CODE_OUTOF_BOUNDS;
|
||||
malloc_warning(func);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: mlc_chk.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:09 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.5 90/08/29 22:23:48 cpcahil
|
||||
* added new function to check on strings up to a specified length
|
||||
* and used it within several strn* functions.
|
||||
*
|
||||
* Revision 1.4 90/05/11 00:13:09 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.3 90/02/24 21:50:22 cpcahil
|
||||
* lots of lint fixes
|
||||
*
|
||||
* Revision 1.2 90/02/24 17:29:38 cpcahil
|
||||
* changed $Header to $Id so full path wouldnt be included as part of rcs
|
||||
* id string
|
||||
*
|
||||
* Revision 1.1 90/02/24 14:57:03 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
188
dmake/dbug/malloc/mlc_chn.c
Normal file
188
dmake/dbug/malloc/mlc_chn.c
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include "malloc.h"
|
||||
|
||||
/*
|
||||
* Function: malloc_chain_check()
|
||||
*
|
||||
* Purpose: to verify malloc chain is intact
|
||||
*
|
||||
* Arguments: todo - 0 - just check and return status
|
||||
* 1 - call malloc_warn if error detected
|
||||
*
|
||||
* Returns: 0 - malloc chain intact & no overflows
|
||||
* other - problems detected in malloc chain
|
||||
*
|
||||
* Narrative:
|
||||
*
|
||||
* Notes: If todo is non-zero the malloc_warn function, when called
|
||||
* may not return (i.e. it may exit)
|
||||
*
|
||||
*/
|
||||
#ifndef lint
|
||||
static
|
||||
char rcs_hdr[] = "$Id: mlc_chn.c,v 1.1 1992/01/24 03:29:10 dvadura Exp $";
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
malloc_chain_check(todo)
|
||||
int todo;
|
||||
{
|
||||
char * func = "malloc_chain_check";
|
||||
int i;
|
||||
extern char * malloc_data_start;
|
||||
extern char * malloc_data_end;
|
||||
extern struct mlist * malloc_end;
|
||||
extern int malloc_errno;
|
||||
extern struct mlist malloc_start;
|
||||
struct mlist * oldptr;
|
||||
struct mlist * ptr;
|
||||
int rtn = 0;
|
||||
|
||||
oldptr = &malloc_start;
|
||||
for(ptr = malloc_start.next; ; ptr = ptr->next)
|
||||
{
|
||||
/*
|
||||
* Since the malloc chain is a forward only chain, any
|
||||
* pointer that we get should always be positioned in
|
||||
* memory following the previous pointer. If this is not
|
||||
* so, we must have a corrupted chain.
|
||||
*/
|
||||
if( ptr )
|
||||
{
|
||||
if(ptr < oldptr )
|
||||
{
|
||||
malloc_errno = M_CODE_CHAIN_BROKE;
|
||||
if( todo )
|
||||
{
|
||||
malloc_fatal(func);
|
||||
}
|
||||
rtn++;
|
||||
break;
|
||||
}
|
||||
oldptr = ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( oldptr != malloc_end )
|
||||
{
|
||||
/*
|
||||
* This should never happen. If it does, then
|
||||
* we got a real problem.
|
||||
*/
|
||||
malloc_errno = M_CODE_NO_END;
|
||||
if( todo )
|
||||
{
|
||||
malloc_fatal(func);
|
||||
}
|
||||
rtn++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* verify that ptr is within the malloc region...
|
||||
* since we started within the malloc chain this should never
|
||||
* happen.
|
||||
*/
|
||||
|
||||
if( ((char *)ptr < malloc_data_start) ||
|
||||
((char *)ptr > malloc_data_end) )
|
||||
{
|
||||
malloc_errno = M_CODE_BAD_PTR;
|
||||
if( todo )
|
||||
{
|
||||
malloc_fatal(func);
|
||||
}
|
||||
rtn++;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* verify magic flag is set
|
||||
*/
|
||||
|
||||
if( (ptr->flag&M_MAGIC) != M_MAGIC )
|
||||
{
|
||||
malloc_errno = M_CODE_BAD_MAGIC;
|
||||
if( todo )
|
||||
{
|
||||
malloc_warning(func);
|
||||
}
|
||||
rtn++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* verify segments are correctly linked together
|
||||
*/
|
||||
|
||||
if( (ptr->prev && (ptr->prev->next != ptr) ) ||
|
||||
(ptr->next && (ptr->next->prev != ptr) ) ||
|
||||
((ptr->next == NULL) && (ptr->prev == NULL)) )
|
||||
{
|
||||
malloc_errno = M_CODE_BAD_CONNECT;
|
||||
if( todo )
|
||||
{
|
||||
malloc_warning(func);
|
||||
}
|
||||
rtn++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this segment is allocated
|
||||
*/
|
||||
|
||||
if( (ptr->flag & M_INUSE) != 0 )
|
||||
{
|
||||
/*
|
||||
* verify no overflow of data area
|
||||
*/
|
||||
|
||||
for(i=ptr->r_size; i < ptr->s.size; i++)
|
||||
{
|
||||
if( ptr->data[i] != M_FILL )
|
||||
{
|
||||
malloc_errno = M_CODE_OVERRUN;
|
||||
if( todo )
|
||||
{
|
||||
malloc_warning(func);
|
||||
}
|
||||
rtn++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* it's not allocated so */
|
||||
{
|
||||
/*
|
||||
* verify no reuse of freed data blocks
|
||||
*/
|
||||
|
||||
for(i=0; i < ptr->s.size; i++)
|
||||
{
|
||||
if( ptr->data[i] != M_FREE_FILL )
|
||||
{
|
||||
malloc_errno = M_CODE_REUSE;
|
||||
if( todo )
|
||||
{
|
||||
malloc_warning(func);
|
||||
}
|
||||
rtn++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* for(... */
|
||||
|
||||
return(rtn);
|
||||
|
||||
} /* malloc_chain_check(... */
|
1
dmake/dbug/malloc/patchlevel
Normal file
1
dmake/dbug/malloc/patchlevel
Normal file
@ -0,0 +1 @@
|
||||
3
|
215
dmake/dbug/malloc/realloc.c
Normal file
215
dmake/dbug/malloc/realloc.c
Normal file
@ -0,0 +1,215 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "malloc.h"
|
||||
|
||||
/*
|
||||
* Function: realloc()
|
||||
*
|
||||
* Purpose: to re-allocate a data area.
|
||||
*
|
||||
* Arguments: cptr - pointer to area to reallocate
|
||||
* size - size to change area to
|
||||
*
|
||||
* Returns: pointer to new area (may be same area)
|
||||
*
|
||||
* Narrative: verify pointer is within malloc region
|
||||
* obtain mlist pointer from cptr
|
||||
* verify magic number is correct
|
||||
* verify inuse flag is set
|
||||
* verify connection to adjoining segments is correct
|
||||
* save requested size
|
||||
* round-up size to appropriate boundry
|
||||
* IF size is bigger than what is in this segment
|
||||
* try to join next segment to this segment
|
||||
* IF size is less than what is is this segment
|
||||
* determine leftover amount of space
|
||||
* ELSE
|
||||
* allocate new segment of size bites
|
||||
* IF allocation failed
|
||||
* return NULL
|
||||
* copy previous data to new segment
|
||||
* free previous segment
|
||||
* return new pointer
|
||||
* split of extra space in this segment (if any)
|
||||
* clear bytes beyound what they had before
|
||||
* return pointer to data
|
||||
*/
|
||||
#ifndef lint
|
||||
static
|
||||
char rcs_hdr[] = "$Id: realloc.c,v 1.1 1992/01/24 03:29:11 dvadura Exp $";
|
||||
#endif
|
||||
|
||||
char *
|
||||
realloc(cptr,size)
|
||||
char * cptr;
|
||||
unsigned int size;
|
||||
{
|
||||
void free();
|
||||
char * func = "realloc";
|
||||
int i;
|
||||
char * malloc();
|
||||
extern int malloc_checking;
|
||||
extern struct mlist * malloc_end;
|
||||
extern int malloc_errno;
|
||||
extern char * malloc_data_end;
|
||||
extern char * malloc_data_start;
|
||||
void malloc_join();
|
||||
void malloc_memset();
|
||||
void malloc_split();
|
||||
char * memcpy();
|
||||
char * new_cptr;
|
||||
struct mlist * ptr;
|
||||
int r_size;
|
||||
|
||||
/*
|
||||
* IF malloc chain checking is on, go do it.
|
||||
*/
|
||||
if( malloc_checking )
|
||||
{
|
||||
(void) malloc_chain_check(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* verify that cptr is within the malloc region...
|
||||
*/
|
||||
if( cptr < malloc_data_start || cptr > malloc_data_end )
|
||||
{
|
||||
malloc_errno = M_CODE_BAD_PTR;
|
||||
malloc_warning(func);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* convert pointer to mlist struct pointer. To do this we must
|
||||
* move the pointer backwards the correct number of bytes...
|
||||
*/
|
||||
|
||||
ptr = (struct mlist *) (cptr - M_SIZE);
|
||||
|
||||
if( (ptr->flag&M_MAGIC) != M_MAGIC )
|
||||
{
|
||||
malloc_errno = M_CODE_BAD_MAGIC;
|
||||
malloc_warning(func);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if( ! (ptr->flag & M_INUSE) )
|
||||
{
|
||||
malloc_errno = M_CODE_NOT_INUSE ;
|
||||
malloc_warning(func);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if( (ptr->prev && (ptr->prev->next != ptr) ) ||
|
||||
(ptr->next && (ptr->next->prev != ptr) ) ||
|
||||
((ptr->next == NULL) && (ptr->prev == NULL)) )
|
||||
{
|
||||
malloc_errno = M_CODE_BAD_CONNECT;
|
||||
malloc_warning(func);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
r_size = ++size;
|
||||
|
||||
M_ROUNDUP(size);
|
||||
|
||||
if( size > ptr->s.size )
|
||||
{
|
||||
malloc_join(ptr,ptr->next,1,1);
|
||||
}
|
||||
|
||||
if( size > ptr->s.size )
|
||||
{
|
||||
/*
|
||||
* else we can't combine it, so lets allocate a new chunk,
|
||||
* copy the data and free the old chunk...
|
||||
*/
|
||||
new_cptr = malloc(size);
|
||||
|
||||
if( new_cptr == (char *) 0)
|
||||
{
|
||||
return(new_cptr);
|
||||
}
|
||||
|
||||
if( r_size < ptr->r_size )
|
||||
{
|
||||
i = r_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = ptr->r_size;
|
||||
}
|
||||
(void)memcpy(new_cptr,ptr->data,i);
|
||||
free(cptr);
|
||||
return(new_cptr);
|
||||
|
||||
} /* else... */
|
||||
|
||||
/*
|
||||
* save amount of real data in new segment (this will be used in the
|
||||
* memset later) and then save requested size of this segment.
|
||||
*/
|
||||
|
||||
if( ptr->r_size < r_size )
|
||||
{
|
||||
i = ptr->r_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = r_size;
|
||||
}
|
||||
|
||||
ptr->r_size = r_size;
|
||||
|
||||
/*
|
||||
* split off extra free space at end of this segment, if possible...
|
||||
*/
|
||||
|
||||
malloc_split(ptr);
|
||||
|
||||
malloc_memset( ptr->data+i, M_FILL, (int) (ptr->s.size - i));
|
||||
|
||||
return(ptr->data);
|
||||
|
||||
} /* realloc(... */
|
||||
|
||||
|
||||
/*
|
||||
* $Log: realloc.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:11 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.8 90/08/29 21:22:52 cpcahil
|
||||
* miscellaneous lint fixes
|
||||
*
|
||||
* Revision 1.7 90/05/11 00:13:10 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.6 90/02/25 11:01:20 cpcahil
|
||||
* added support for malloc chain checking.
|
||||
*
|
||||
* Revision 1.5 90/02/24 21:50:31 cpcahil
|
||||
* lots of lint fixes
|
||||
*
|
||||
* Revision 1.4 90/02/24 17:29:39 cpcahil
|
||||
* changed $Header to $Id so full path wouldnt be included as part of rcs
|
||||
* id string
|
||||
*
|
||||
* Revision 1.3 90/02/24 17:20:00 cpcahil
|
||||
* attempt to get rid of full path in rcs header.
|
||||
*
|
||||
* Revision 1.2 90/02/24 15:14:20 cpcahil
|
||||
* 1. added function header
|
||||
* 2. changed calls to malloc_warning to conform to new usage
|
||||
* 3. added setting of malloc_errno
|
||||
* 4. broke up bad pointer determination so that errno's would be more
|
||||
* descriptive
|
||||
*
|
||||
* Revision 1.1 90/02/22 23:17:43 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
563
dmake/dbug/malloc/string.c
Normal file
563
dmake/dbug/malloc/string.c
Normal file
@ -0,0 +1,563 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include "malloc.h"
|
||||
|
||||
#ifndef lint
|
||||
static
|
||||
char rcs_hdr[] = "$Id: string.c,v 1.1 1992/01/24 03:29:13 dvadura Exp $";
|
||||
#endif
|
||||
|
||||
int malloc_checking = 0;
|
||||
|
||||
char *
|
||||
strcat(str1,str2)
|
||||
register char * str1;
|
||||
register char * str2;
|
||||
{
|
||||
char * rtn;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* check pointers agains malloc region. The malloc* functions
|
||||
* will properly handle the case where a pointer does not
|
||||
* point into malloc space.
|
||||
*/
|
||||
malloc_checking = 1;
|
||||
|
||||
len = strlen(str2);
|
||||
malloc_check_str("strcat", str2);
|
||||
|
||||
len += strlen(str1) + 1;
|
||||
malloc_checking = 0;
|
||||
|
||||
malloc_check_data("strcat", str1, len);
|
||||
|
||||
rtn = str1;
|
||||
|
||||
while( *str1 )
|
||||
{
|
||||
str1++;
|
||||
}
|
||||
|
||||
while( (*str1 = *str2) != '\0' )
|
||||
{
|
||||
str1++;
|
||||
str2++;
|
||||
}
|
||||
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
char *
|
||||
strdup(str1)
|
||||
register char * str1;
|
||||
{
|
||||
char * malloc();
|
||||
char * rtn;
|
||||
register char * str2;
|
||||
|
||||
malloc_check_str("strdup", str1);
|
||||
|
||||
rtn = str2 = malloc((unsigned)strlen(str1)+1);
|
||||
|
||||
if( rtn != (char *) 0)
|
||||
{
|
||||
while( (*str2 = *str1) != '\0' )
|
||||
{
|
||||
str1++;
|
||||
str2++;
|
||||
}
|
||||
}
|
||||
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
char *
|
||||
strncat(str1,str2,len)
|
||||
register char * str1;
|
||||
register char * str2;
|
||||
register int len;
|
||||
{
|
||||
int len1;
|
||||
int len2;
|
||||
char * rtn;
|
||||
|
||||
malloc_check_strn("strncat", str2, len);
|
||||
|
||||
malloc_checking = 1;
|
||||
|
||||
len2 = strlen(str2) + 1;
|
||||
len1 = strlen(str1);
|
||||
|
||||
malloc_checking = 0;
|
||||
|
||||
|
||||
if( (len+1) < len2 )
|
||||
{
|
||||
len1 += len + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
len1 += len2;
|
||||
}
|
||||
malloc_check_data("strncat", str1, len1);
|
||||
|
||||
rtn = str1;
|
||||
|
||||
while( *str1 )
|
||||
{
|
||||
str1++;
|
||||
}
|
||||
|
||||
while( len-- && ((*str1++ = *str2++) != '\0') )
|
||||
{
|
||||
}
|
||||
|
||||
if( ! len )
|
||||
{
|
||||
*str1 = '\0';
|
||||
}
|
||||
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
int
|
||||
strcmp(str1,str2)
|
||||
register char * str1;
|
||||
register char * str2;
|
||||
{
|
||||
malloc_check_str("strcmp", str1);
|
||||
malloc_check_str("strcmp", str2);
|
||||
|
||||
while( *str1 && (*str1 == *str2) )
|
||||
{
|
||||
str1++;
|
||||
str2++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* in order to deal with the case of a negative last char of either
|
||||
* string when the other string has a null
|
||||
*/
|
||||
if( (*str2 == '\0') && (*str1 == '\0') )
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
else if( *str2 == '\0' )
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
else if( *str1 == '\0' )
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return( *str1 - *str2 );
|
||||
}
|
||||
|
||||
int
|
||||
strncmp(str1,str2,len)
|
||||
register char * str1;
|
||||
register char * str2;
|
||||
register int len;
|
||||
{
|
||||
malloc_check_strn("strncmp", str1, len);
|
||||
malloc_check_strn("strncmp", str2, len);
|
||||
|
||||
while( --len >= 0 && *str1 && (*str1 == *str2) )
|
||||
{
|
||||
str1++;
|
||||
str2++;
|
||||
}
|
||||
|
||||
if( len < 0 )
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
* in order to deal with the case of a negative last char of either
|
||||
* string when the other string has a null
|
||||
*/
|
||||
if( (*str2 == '\0') && (*str1 == '\0') )
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
else if( *str2 == '\0' )
|
||||
{
|
||||
return(1);
|
||||
}
|
||||
else if( *str1 == '\0' )
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
|
||||
return( *str1 - *str2 );
|
||||
}
|
||||
|
||||
char *
|
||||
strcpy(str1,str2)
|
||||
register char * str1;
|
||||
register char * str2;
|
||||
{
|
||||
char * rtn;
|
||||
int len;
|
||||
|
||||
malloc_checking = 1;
|
||||
len = strlen(str2) + 1;
|
||||
malloc_checking = 0;
|
||||
|
||||
malloc_check_data("strcpy", str1, len);
|
||||
malloc_check_data("strcpy", str2, len);
|
||||
|
||||
rtn = str1;
|
||||
|
||||
while( (*str1++ = *str2++) != '\0')
|
||||
{
|
||||
}
|
||||
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
char *
|
||||
strncpy(str1,str2,len)
|
||||
register char * str1;
|
||||
register char * str2;
|
||||
register int len;
|
||||
{
|
||||
extern int malloc_checking;
|
||||
char * rtn;
|
||||
|
||||
malloc_check_data("strncpy", str1, len);
|
||||
malloc_check_strn("strncpy", str2, len);
|
||||
|
||||
rtn = str1;
|
||||
|
||||
while((len-- > 0) && (*str1++ = *str2++) != '\0')
|
||||
{
|
||||
}
|
||||
while( (len-- > 0) )
|
||||
{
|
||||
*str1++ = '\0';
|
||||
}
|
||||
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
int
|
||||
strlen(str1)
|
||||
register char * str1;
|
||||
{
|
||||
register char * s;
|
||||
|
||||
if(! malloc_checking )
|
||||
{
|
||||
malloc_check_str("strlen", str1);
|
||||
}
|
||||
|
||||
for( s = str1; *s; s++)
|
||||
{
|
||||
}
|
||||
|
||||
return( s - str1 );
|
||||
}
|
||||
|
||||
char *
|
||||
strchr(str1,c)
|
||||
register char * str1;
|
||||
register int c;
|
||||
{
|
||||
malloc_check_str("strchr", str1);
|
||||
|
||||
while( *str1 && (*str1 != (char) c) )
|
||||
{
|
||||
str1++;
|
||||
}
|
||||
|
||||
if(*str1 != (char) c)
|
||||
{
|
||||
str1 = (char *) 0;
|
||||
}
|
||||
|
||||
return(str1);
|
||||
}
|
||||
|
||||
char *
|
||||
strrchr(str1,c)
|
||||
register char * str1;
|
||||
register int c;
|
||||
{
|
||||
register char * rtn = (char *) 0;
|
||||
|
||||
malloc_check_str("strrchr", str1);
|
||||
|
||||
while( *str1 )
|
||||
{
|
||||
if(*str1 == (char) c )
|
||||
{
|
||||
rtn = str1;
|
||||
}
|
||||
str1++;
|
||||
}
|
||||
|
||||
if( *str1 == (char) c)
|
||||
{
|
||||
rtn = str1;
|
||||
}
|
||||
|
||||
return(rtn);
|
||||
}
|
||||
|
||||
char *
|
||||
index(str1,c)
|
||||
char * str1;
|
||||
char c;
|
||||
{
|
||||
return( strchr(str1,c) );
|
||||
}
|
||||
|
||||
char *
|
||||
rindex(str1,c)
|
||||
char * str1;
|
||||
char c;
|
||||
{
|
||||
return( strrchr(str1,c) );
|
||||
}
|
||||
|
||||
char *
|
||||
strpbrk(str1,str2)
|
||||
register char * str1;
|
||||
register char * str2;
|
||||
{
|
||||
register char * tmp;
|
||||
|
||||
malloc_check_str("strpbrk", str1);
|
||||
malloc_check_str("strpbrk", str2);
|
||||
|
||||
while(*str1)
|
||||
{
|
||||
for( tmp=str2; *tmp && *tmp != *str1; tmp++)
|
||||
{
|
||||
}
|
||||
if( *tmp )
|
||||
{
|
||||
break;
|
||||
}
|
||||
str1++;
|
||||
}
|
||||
|
||||
if( ! *str1 )
|
||||
{
|
||||
str1 = (char *) 0;
|
||||
}
|
||||
|
||||
return(str1);
|
||||
}
|
||||
|
||||
int
|
||||
strspn(str1,str2)
|
||||
register char * str1;
|
||||
register char * str2;
|
||||
{
|
||||
register char * tmp;
|
||||
char * orig = str1;
|
||||
|
||||
malloc_check_str("strspn", str1);
|
||||
malloc_check_str("strspn", str2);
|
||||
|
||||
while(*str1)
|
||||
{
|
||||
for( tmp=str2; *tmp && *tmp != *str1; tmp++)
|
||||
{
|
||||
}
|
||||
if(! *tmp )
|
||||
{
|
||||
break;
|
||||
}
|
||||
str1++;
|
||||
}
|
||||
|
||||
return( (int) (str1 - orig) );
|
||||
}
|
||||
|
||||
int
|
||||
strcspn(str1,str2)
|
||||
register char * str1;
|
||||
register char * str2;
|
||||
{
|
||||
register char * tmp;
|
||||
char * orig = str1;
|
||||
|
||||
malloc_check_str("strcspn", str1);
|
||||
malloc_check_str("strcspn", str2);
|
||||
|
||||
while(*str1)
|
||||
{
|
||||
for( tmp=str2; *tmp && *tmp != *str1; tmp++)
|
||||
{
|
||||
}
|
||||
if( *tmp )
|
||||
{
|
||||
break;
|
||||
}
|
||||
str1++;
|
||||
}
|
||||
|
||||
return( (int) (str1 - orig) );
|
||||
}
|
||||
|
||||
/*
|
||||
* strtok() source taken from that posted to comp.lang.c by Chris Torek
|
||||
* in Jan 1990.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by the University of California, Berkeley. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get next token from string s (NULL on 2nd, 3rd, etc. calls),
|
||||
* where tokens are nonempty strings separated by runs of
|
||||
* chars from delim. Writes NULs into s to end tokens. delim need not
|
||||
* remain constant from call to call.
|
||||
*
|
||||
* Modified by cpc: changed variable names to conform with naming
|
||||
* conventions used in rest of code. Added malloc pointer
|
||||
* check calls.
|
||||
*/
|
||||
char *
|
||||
strtok(str1, str2)
|
||||
char * str1;
|
||||
char * str2;
|
||||
{
|
||||
static char * last;
|
||||
char * strtoken();
|
||||
|
||||
if( str1 )
|
||||
{
|
||||
malloc_check_str("strtok", str1);
|
||||
last = str1;
|
||||
}
|
||||
malloc_check_str("strtok", str2);
|
||||
|
||||
return (strtoken(&last, str2, 1));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get next token from string *stringp, where tokens are (possibly empty)
|
||||
* strings separated by characters from delim. Tokens are separated
|
||||
* by exactly one delimiter iff the skip parameter is false; otherwise
|
||||
* they are separated by runs of characters from delim, because we
|
||||
* skip over any initial `delim' characters.
|
||||
*
|
||||
* Writes NULs into the string at *stringp to end tokens.
|
||||
* delim will usually, but need not, remain constant from call to call.
|
||||
* On return, *stringp points past the last NUL written (if there might
|
||||
* be further tokens), or is NULL (if there are definitely no more tokens).
|
||||
*
|
||||
* If *stringp is NULL, strtoken returns NULL.
|
||||
*/
|
||||
char *
|
||||
strtoken(stringp, delim, skip)
|
||||
register char **stringp;
|
||||
register char *delim;
|
||||
int skip;
|
||||
{
|
||||
register char *s;
|
||||
register char *spanp;
|
||||
register int c, sc;
|
||||
char *tok;
|
||||
|
||||
if ((s = *stringp) == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (skip) {
|
||||
/*
|
||||
* Skip (span) leading delimiters (s += strspn(s, delim)).
|
||||
*/
|
||||
cont:
|
||||
c = *s;
|
||||
for (spanp = delim; (sc = *spanp++) != 0;) {
|
||||
if (c == sc) {
|
||||
s++;
|
||||
goto cont;
|
||||
}
|
||||
}
|
||||
if (c == 0) { /* no token found */
|
||||
*stringp = NULL;
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
|
||||
* Note that delim must have one NUL; we stop if we see that, too.
|
||||
*/
|
||||
for (tok = s;;) {
|
||||
c = *s++;
|
||||
spanp = delim;
|
||||
do {
|
||||
if ((sc = *spanp++) == c) {
|
||||
if (c == 0)
|
||||
s = NULL;
|
||||
else
|
||||
s[-1] = 0;
|
||||
*stringp = s;
|
||||
return (tok);
|
||||
}
|
||||
} while (sc != 0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: string.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:13 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.7 90/08/29 22:24:19 cpcahil
|
||||
* added new function to check on strings up to a specified length
|
||||
* and used it within several strn* functions.
|
||||
*
|
||||
* Revision 1.6 90/07/16 20:06:56 cpcahil
|
||||
* fixed several minor bugs found with Henry Spencer's string/mem function
|
||||
* tester program.
|
||||
*
|
||||
* Revision 1.5 90/06/10 14:59:49 cpcahil
|
||||
* Fixed a couple of bugs in strncpy & strdup
|
||||
*
|
||||
* Revision 1.4 90/05/11 00:13:10 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.3 90/02/24 21:50:32 cpcahil
|
||||
* lots of lint fixes
|
||||
*
|
||||
* Revision 1.2 90/02/24 17:29:40 cpcahil
|
||||
* changed $Header to $Id so full path wouldnt be included as part of rcs
|
||||
* id string
|
||||
*
|
||||
* Revision 1.1 90/02/22 23:17:44 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
646
dmake/dbug/malloc/testmem.c
Normal file
646
dmake/dbug/malloc/testmem.c
Normal file
@ -0,0 +1,646 @@
|
||||
/*
|
||||
* This stuff is all stolen (with permission, since it was in the public
|
||||
* domain) from Henry Spencer's string and memory library. Thanks Henry.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Test program for string(3) routines.
|
||||
*
|
||||
* Note that at least one Bell Labs implementation of the string
|
||||
* routines flunks a couple of these tests -- the ones which test
|
||||
* behavior on "negative" characters.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
char * index();
|
||||
char * rindex();
|
||||
|
||||
#define STREQ(a, b) (strcmp((a), (b)) == 0)
|
||||
|
||||
char *it = "<UNSET>"; /* Routine name for message routines. */
|
||||
int waserror = 0; /* For exit status. */
|
||||
|
||||
char uctest[] = "\004\203"; /* For testing signedness of chars. */
|
||||
int charsigned; /* Result. */
|
||||
|
||||
/*
|
||||
- check - complain if condition is not true
|
||||
*/
|
||||
void
|
||||
check(thing, number)
|
||||
int thing;
|
||||
int number; /* Test number for error message. */
|
||||
{
|
||||
if (!thing) {
|
||||
printf("%s flunked test %d\n", it, number);
|
||||
waserror = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
- equal - complain if first two args don't strcmp as equal
|
||||
*/
|
||||
void
|
||||
equal(a, b, number)
|
||||
char *a;
|
||||
char *b;
|
||||
int number; /* Test number for error message. */
|
||||
{
|
||||
check(a != NULL && b != NULL && STREQ(a, b), number);
|
||||
}
|
||||
|
||||
char one[50];
|
||||
char two[50];
|
||||
|
||||
#ifdef UNIXERR
|
||||
#define ERR 1
|
||||
#endif
|
||||
#ifdef BERKERR
|
||||
#define ERR 1
|
||||
#endif
|
||||
#ifdef ERR
|
||||
int f;
|
||||
extern char *sys_errlist[];
|
||||
extern int sys_nerr;
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* ARGSUSED */
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
/*
|
||||
* First, establish whether chars are signed.
|
||||
*/
|
||||
if (uctest[0] < uctest[1])
|
||||
charsigned = 0;
|
||||
else
|
||||
charsigned = 1;
|
||||
|
||||
/*
|
||||
* Then, do the rest of the work. Split into two functions because
|
||||
* some compilers get unhappy about a single immense function.
|
||||
*/
|
||||
first();
|
||||
second();
|
||||
|
||||
exit((waserror) ? 1 : 0);
|
||||
}
|
||||
|
||||
first()
|
||||
{
|
||||
/*
|
||||
* Test strcmp first because we use it to test other things.
|
||||
*/
|
||||
it = "strcmp";
|
||||
check(strcmp("", "") == 0, 1); /* Trivial case. */
|
||||
check(strcmp("a", "a") == 0, 2); /* Identity. */
|
||||
check(strcmp("abc", "abc") == 0, 3); /* Multicharacter. */
|
||||
check(strcmp("abc", "abcd") < 0, 4); /* Length mismatches. */
|
||||
check(strcmp("abcd", "abc") > 0, 5);
|
||||
check(strcmp("abcd", "abce") < 0, 6); /* Honest miscompares. */
|
||||
check(strcmp("abce", "abcd") > 0, 7);
|
||||
check(strcmp("a\203", "a") > 0, 8); /* Tricky if char signed. */
|
||||
if (charsigned) /* Sign-bit comparison. */
|
||||
check(strcmp("a\203", "a\003") < 0, 9);
|
||||
else
|
||||
check(strcmp("a\203", "a\003") > 0, 9);
|
||||
check(strcmp("a", "a\203") < 0, 10); /* Tricky if char signed. */
|
||||
|
||||
/*
|
||||
* Test strcpy next because we need it to set up other tests.
|
||||
*/
|
||||
it = "strcpy";
|
||||
check(strcpy(one, "abcd") == one, 1); /* Returned value. */
|
||||
equal(one, "abcd", 2); /* Basic test. */
|
||||
|
||||
(void) strcpy(one, "x");
|
||||
equal(one, "x", 3); /* Writeover. */
|
||||
equal(one+2, "cd", 4); /* Wrote too much? */
|
||||
|
||||
(void) strcpy(two, "hi there");
|
||||
(void) strcpy(one, two);
|
||||
equal(one, "hi there", 5); /* Basic test encore. */
|
||||
equal(two, "hi there", 6); /* Stomped on source? */
|
||||
|
||||
(void) strcpy(one, "");
|
||||
equal(one, "", 7); /* Boundary condition. */
|
||||
|
||||
/*
|
||||
* strcat
|
||||
*/
|
||||
it = "strcat";
|
||||
(void) strcpy(one, "ijk");
|
||||
check(strcat(one, "lmn") == one, 1); /* Returned value. */
|
||||
equal(one, "ijklmn", 2); /* Basic test. */
|
||||
|
||||
(void) strcpy(one, "x");
|
||||
(void) strcat(one, "yz");
|
||||
equal(one, "xyz", 3); /* Writeover. */
|
||||
equal(one+4, "mn", 4); /* Wrote too much? */
|
||||
|
||||
(void) strcpy(one, "gh");
|
||||
(void) strcpy(two, "ef");
|
||||
(void) strcat(one, two);
|
||||
equal(one, "ghef", 5); /* Basic test encore. */
|
||||
equal(two, "ef", 6); /* Stomped on source? */
|
||||
|
||||
(void) strcpy(one, "");
|
||||
(void) strcat(one, "");
|
||||
equal(one, "", 7); /* Boundary conditions. */
|
||||
(void) strcpy(one, "ab");
|
||||
(void) strcat(one, "");
|
||||
equal(one, "ab", 8);
|
||||
(void) strcpy(one, "");
|
||||
(void) strcat(one, "cd");
|
||||
equal(one, "cd", 9);
|
||||
|
||||
/*
|
||||
* strncat - first test it as strcat, with big counts, then
|
||||
* test the count mechanism.
|
||||
*/
|
||||
it = "strncat";
|
||||
(void) strcpy(one, "ijk");
|
||||
check(strncat(one, "lmn", 99) == one, 1); /* Returned value. */
|
||||
equal(one, "ijklmn", 2); /* Basic test. */
|
||||
|
||||
(void) strcpy(one, "x");
|
||||
(void) strncat(one, "yz", 99);
|
||||
equal(one, "xyz", 3); /* Writeover. */
|
||||
equal(one+4, "mn", 4); /* Wrote too much? */
|
||||
|
||||
(void) strcpy(one, "gh");
|
||||
(void) strcpy(two, "ef");
|
||||
(void) strncat(one, two, 99);
|
||||
equal(one, "ghef", 5); /* Basic test encore. */
|
||||
equal(two, "ef", 6); /* Stomped on source? */
|
||||
|
||||
(void) strcpy(one, "");
|
||||
(void) strncat(one, "", 99);
|
||||
equal(one, "", 7); /* Boundary conditions. */
|
||||
(void) strcpy(one, "ab");
|
||||
(void) strncat(one, "", 99);
|
||||
equal(one, "ab", 8);
|
||||
(void) strcpy(one, "");
|
||||
(void) strncat(one, "cd", 99);
|
||||
equal(one, "cd", 9);
|
||||
|
||||
(void) strcpy(one, "ab");
|
||||
(void) strncat(one, "cdef", 2);
|
||||
equal(one, "abcd", 10); /* Count-limited. */
|
||||
|
||||
(void) strncat(one, "gh", 0);
|
||||
equal(one, "abcd", 11); /* Zero count. */
|
||||
|
||||
(void) strncat(one, "gh", 2);
|
||||
equal(one, "abcdgh", 12); /* Count and length equal. */
|
||||
|
||||
/*
|
||||
* strncmp - first test as strcmp with big counts, then test
|
||||
* count code.
|
||||
*/
|
||||
it = "strncmp";
|
||||
check(strncmp("", "", 99) == 0, 1); /* Trivial case. */
|
||||
check(strncmp("a", "a", 99) == 0, 2); /* Identity. */
|
||||
check(strncmp("abc", "abc", 99) == 0, 3); /* Multicharacter. */
|
||||
check(strncmp("abc", "abcd", 99) < 0, 4); /* Length unequal. */
|
||||
check(strncmp("abcd", "abc", 99) > 0, 5);
|
||||
check(strncmp("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
|
||||
check(strncmp("abce", "abcd", 99) > 0, 7);
|
||||
check(strncmp("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
|
||||
if (charsigned) /* Sign-bit comparison. */
|
||||
check(strncmp("a\203", "a\003", 2) < 0, 9);
|
||||
else
|
||||
check(strncmp("a\203", "a\003", 2) > 0, 9);
|
||||
check(strncmp("abce", "abcd", 3) == 0, 10); /* Count limited. */
|
||||
check(strncmp("abce", "abc", 3) == 0, 11); /* Count == length. */
|
||||
check(strncmp("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
|
||||
check(strncmp("abc", "def", 0) == 0, 13); /* Zero count. */
|
||||
|
||||
/*
|
||||
* strncpy - testing is a bit different because of odd semantics
|
||||
*/
|
||||
it = "strncpy";
|
||||
check(strncpy(one, "abc", 4) == one, 1); /* Returned value. */
|
||||
equal(one, "abc", 2); /* Did the copy go right? */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) strncpy(one, "xyz", 2);
|
||||
equal(one, "xycdefgh", 3); /* Copy cut by count. */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) strncpy(one, "xyz", 3); /* Copy cut just before NUL. */
|
||||
equal(one, "xyzdefgh", 4);
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) strncpy(one, "xyz", 4); /* Copy just includes NUL. */
|
||||
equal(one, "xyz", 5);
|
||||
equal(one+4, "efgh", 6); /* Wrote too much? */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) strncpy(one, "xyz", 5); /* Copy includes padding. */
|
||||
equal(one, "xyz", 7);
|
||||
equal(one+4, "", 8);
|
||||
equal(one+5, "fgh", 9);
|
||||
|
||||
(void) strcpy(one, "abc");
|
||||
(void) strncpy(one, "xyz", 0); /* Zero-length copy. */
|
||||
equal(one, "abc", 10);
|
||||
|
||||
(void) strncpy(one, "", 2); /* Zero-length source. */
|
||||
equal(one, "", 11);
|
||||
equal(one+1, "", 12);
|
||||
equal(one+2, "c", 13);
|
||||
|
||||
(void) strcpy(one, "hi there");
|
||||
(void) strncpy(two, one, 9);
|
||||
equal(two, "hi there", 14); /* Just paranoia. */
|
||||
equal(one, "hi there", 15); /* Stomped on source? */
|
||||
|
||||
/*
|
||||
* strlen
|
||||
*/
|
||||
it = "strlen";
|
||||
check(strlen("") == 0, 1); /* Empty. */
|
||||
check(strlen("a") == 1, 2); /* Single char. */
|
||||
check(strlen("abcd") == 4, 3); /* Multiple chars. */
|
||||
|
||||
/*
|
||||
* strchr
|
||||
*/
|
||||
it = "strchr";
|
||||
check(strchr("abcd", 'z') == NULL, 1); /* Not found. */
|
||||
(void) strcpy(one, "abcd");
|
||||
check(strchr(one, 'c') == one+2, 2); /* Basic test. */
|
||||
check(strchr(one, 'd') == one+3, 3); /* End of string. */
|
||||
check(strchr(one, 'a') == one, 4); /* Beginning. */
|
||||
check(strchr(one, '\0') == one+4, 5); /* Finding NUL. */
|
||||
(void) strcpy(one, "ababa");
|
||||
check(strchr(one, 'b') == one+1, 6); /* Finding first. */
|
||||
(void) strcpy(one, "");
|
||||
check(strchr(one, 'b') == NULL, 7); /* Empty string. */
|
||||
check(strchr(one, '\0') == one, 8); /* NUL in empty string. */
|
||||
|
||||
/*
|
||||
* index - just like strchr
|
||||
*/
|
||||
it = "index";
|
||||
check(index("abcd", 'z') == NULL, 1); /* Not found. */
|
||||
(void) strcpy(one, "abcd");
|
||||
check(index(one, 'c') == one+2, 2); /* Basic test. */
|
||||
check(index(one, 'd') == one+3, 3); /* End of string. */
|
||||
check(index(one, 'a') == one, 4); /* Beginning. */
|
||||
check(index(one, '\0') == one+4, 5); /* Finding NUL. */
|
||||
(void) strcpy(one, "ababa");
|
||||
check(index(one, 'b') == one+1, 6); /* Finding first. */
|
||||
(void) strcpy(one, "");
|
||||
check(index(one, 'b') == NULL, 7); /* Empty string. */
|
||||
check(index(one, '\0') == one, 8); /* NUL in empty string. */
|
||||
|
||||
/*
|
||||
* strrchr
|
||||
*/
|
||||
it = "strrchr";
|
||||
check(strrchr("abcd", 'z') == NULL, 1); /* Not found. */
|
||||
(void) strcpy(one, "abcd");
|
||||
check(strrchr(one, 'c') == one+2, 2); /* Basic test. */
|
||||
check(strrchr(one, 'd') == one+3, 3); /* End of string. */
|
||||
check(strrchr(one, 'a') == one, 4); /* Beginning. */
|
||||
check(strrchr(one, '\0') == one+4, 5); /* Finding NUL. */
|
||||
(void) strcpy(one, "ababa");
|
||||
check(strrchr(one, 'b') == one+3, 6); /* Finding last. */
|
||||
(void) strcpy(one, "");
|
||||
check(strrchr(one, 'b') == NULL, 7); /* Empty string. */
|
||||
check(strrchr(one, '\0') == one, 8); /* NUL in empty string. */
|
||||
|
||||
/*
|
||||
* rindex - just like strrchr
|
||||
*/
|
||||
it = "rindex";
|
||||
check(rindex("abcd", 'z') == NULL, 1); /* Not found. */
|
||||
(void) strcpy(one, "abcd");
|
||||
check(rindex(one, 'c') == one+2, 2); /* Basic test. */
|
||||
check(rindex(one, 'd') == one+3, 3); /* End of string. */
|
||||
check(rindex(one, 'a') == one, 4); /* Beginning. */
|
||||
check(rindex(one, '\0') == one+4, 5); /* Finding NUL. */
|
||||
(void) strcpy(one, "ababa");
|
||||
check(rindex(one, 'b') == one+3, 6); /* Finding last. */
|
||||
(void) strcpy(one, "");
|
||||
check(rindex(one, 'b') == NULL, 7); /* Empty string. */
|
||||
check(rindex(one, '\0') == one, 8); /* NUL in empty string. */
|
||||
}
|
||||
|
||||
second()
|
||||
{
|
||||
/*
|
||||
* strpbrk - somewhat like strchr
|
||||
*/
|
||||
it = "strpbrk";
|
||||
check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
|
||||
(void) strcpy(one, "abcd");
|
||||
check(strpbrk(one, "c") == one+2, 2); /* Basic test. */
|
||||
check(strpbrk(one, "d") == one+3, 3); /* End of string. */
|
||||
check(strpbrk(one, "a") == one, 4); /* Beginning. */
|
||||
check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
|
||||
check(strpbrk(one, "cb") == one+1, 6); /* Multiple search. */
|
||||
(void) strcpy(one, "abcabdea");
|
||||
check(strpbrk(one, "b") == one+1, 7); /* Finding first. */
|
||||
check(strpbrk(one, "cb") == one+1, 8); /* With multiple search. */
|
||||
check(strpbrk(one, "db") == one+1, 9); /* Another variant. */
|
||||
(void) strcpy(one, "");
|
||||
check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
|
||||
check(strpbrk(one, "") == NULL, 11); /* Both strings empty. */
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* strstr - somewhat like strchr
|
||||
*/
|
||||
it = "strstr";
|
||||
check(strstr("abcd", "z") == NULL, 1); /* Not found. */
|
||||
check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
|
||||
(void) strcpy(one, "abcd");
|
||||
check(strstr(one, "c") == one+2, 3); /* Basic test. */
|
||||
check(strstr(one, "bc") == one+1, 4); /* Multichar. */
|
||||
check(strstr(one, "d") == one+3, 5); /* End of string. */
|
||||
check(strstr(one, "cd") == one+2, 6); /* Tail of string. */
|
||||
check(strstr(one, "abc") == one, 7); /* Beginning. */
|
||||
check(strstr(one, "abcd") == one, 8); /* Exact match. */
|
||||
check(strstr(one, "abcde") == NULL, 9); /* Too long. */
|
||||
check(strstr(one, "de") == NULL, 10); /* Past end. */
|
||||
check(strstr(one, "") == one+4, 11); /* Finding empty. */
|
||||
(void) strcpy(one, "ababa");
|
||||
check(strstr(one, "ba") == one+1, 12); /* Finding first. */
|
||||
(void) strcpy(one, "");
|
||||
check(strstr(one, "b") == NULL, 13); /* Empty string. */
|
||||
check(strstr(one, "") == one, 14); /* Empty in empty string. */
|
||||
(void) strcpy(one, "bcbca");
|
||||
check(strstr(one, "bca") == one+2, 15); /* False start. */
|
||||
(void) strcpy(one, "bbbcabbca");
|
||||
check(strstr(one, "bbca") == one+1, 16); /* With overlap. */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* strspn
|
||||
*/
|
||||
it = "strspn";
|
||||
check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
|
||||
check(strspn("abcba", "ab") == 2, 2); /* Partial. */
|
||||
check(strspn("abc", "qx") == 0, 3); /* None. */
|
||||
check(strspn("", "ab") == 0, 4); /* Null string. */
|
||||
check(strspn("abc", "") == 0, 5); /* Null search list. */
|
||||
|
||||
/*
|
||||
* strcspn
|
||||
*/
|
||||
it = "strcspn";
|
||||
check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
|
||||
check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
|
||||
check(strcspn("abc", "abc") == 0, 3); /* None. */
|
||||
check(strcspn("", "ab") == 0, 4); /* Null string. */
|
||||
check(strcspn("abc", "") == 3, 5); /* Null search list. */
|
||||
|
||||
/*
|
||||
* strtok - the hard one
|
||||
*/
|
||||
it = "strtok";
|
||||
(void) strcpy(one, "first, second, third");
|
||||
equal(strtok(one, ", "), "first", 1); /* Basic test. */
|
||||
equal(one, "first", 2);
|
||||
equal(strtok((char *)NULL, ", "), "second", 3);
|
||||
equal(strtok((char *)NULL, ", "), "third", 4);
|
||||
check(strtok((char *)NULL, ", ") == NULL, 5);
|
||||
(void) strcpy(one, ", first, ");
|
||||
equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
|
||||
check(strtok((char *)NULL, ", ") == NULL, 7);
|
||||
(void) strcpy(one, "1a, 1b; 2a, 2b");
|
||||
equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
|
||||
equal(strtok((char *)NULL, "; "), "1b", 9);
|
||||
equal(strtok((char *)NULL, ", "), "2a", 10);
|
||||
(void) strcpy(two, "x-y");
|
||||
equal(strtok(two, "-"), "x", 11); /* New string before done. */
|
||||
equal(strtok((char *)NULL, "-"), "y", 12);
|
||||
check(strtok((char *)NULL, "-") == NULL, 13);
|
||||
(void) strcpy(one, "a,b, c,, ,d");
|
||||
equal(strtok(one, ", "), "a", 14); /* Different separators. */
|
||||
equal(strtok((char *)NULL, ", "), "b", 15);
|
||||
equal(strtok((char *)NULL, " ,"), "c", 16); /* Permute list too. */
|
||||
equal(strtok((char *)NULL, " ,"), "d", 17);
|
||||
check(strtok((char *)NULL, ", ") == NULL, 18);
|
||||
check(strtok((char *)NULL, ", ") == NULL, 19); /* Persistence. */
|
||||
(void) strcpy(one, ", ");
|
||||
check(strtok(one, ", ") == NULL, 20); /* No tokens. */
|
||||
(void) strcpy(one, "");
|
||||
check(strtok(one, ", ") == NULL, 21); /* Empty string. */
|
||||
(void) strcpy(one, "abc");
|
||||
equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
|
||||
check(strtok((char *)NULL, ", ") == NULL, 23);
|
||||
(void) strcpy(one, "abc");
|
||||
equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
|
||||
check(strtok((char *)NULL, "") == NULL, 25);
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) strcpy(one, "a,b,c");
|
||||
equal(strtok(one, ","), "a", 26); /* Basics again... */
|
||||
equal(strtok((char *)NULL, ","), "b", 27);
|
||||
equal(strtok((char *)NULL, ","), "c", 28);
|
||||
check(strtok((char *)NULL, ",") == NULL, 29);
|
||||
equal(one+6, "gh", 30); /* Stomped past end? */
|
||||
equal(one, "a", 31); /* Stomped old tokens? */
|
||||
equal(one+2, "b", 32);
|
||||
equal(one+4, "c", 33);
|
||||
|
||||
/*
|
||||
* memcmp
|
||||
*/
|
||||
it = "memcmp";
|
||||
check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
|
||||
check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
|
||||
check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */
|
||||
check(memcmp("abce", "abcd", 4) > 0, 4);
|
||||
check(memcmp("alph", "beta", 4) < 0, 5);
|
||||
if (charsigned) /* Sign-bit comparison. */
|
||||
check(memcmp("a\203", "a\003", 2) < 0, 6);
|
||||
else
|
||||
check(memcmp("a\203", "a\003", 2) > 0, 6);
|
||||
check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
|
||||
check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
|
||||
|
||||
/*
|
||||
* memchr
|
||||
*/
|
||||
it = "memchr";
|
||||
check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
|
||||
(void) strcpy(one, "abcd");
|
||||
check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */
|
||||
check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */
|
||||
check(memchr(one, 'a', 4) == one, 4); /* Beginning. */
|
||||
check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */
|
||||
(void) strcpy(one, "ababa");
|
||||
check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */
|
||||
check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
|
||||
check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */
|
||||
(void) strcpy(one, "a\203b");
|
||||
check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */
|
||||
|
||||
/*
|
||||
* memcpy
|
||||
*
|
||||
* Note that X3J11 says memcpy must work regardless of overlap.
|
||||
* The SVID says it might fail.
|
||||
*/
|
||||
it = "memcpy";
|
||||
check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */
|
||||
equal(one, "abc", 2); /* Did the copy go right? */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) memcpy(one+1, "xyz", 2);
|
||||
equal(one, "axydefgh", 3); /* Basic test. */
|
||||
|
||||
(void) strcpy(one, "abc");
|
||||
(void) memcpy(one, "xyz", 0);
|
||||
equal(one, "abc", 4); /* Zero-length copy. */
|
||||
|
||||
(void) strcpy(one, "hi there");
|
||||
(void) strcpy(two, "foo");
|
||||
(void) memcpy(two, one, 9);
|
||||
equal(two, "hi there", 5); /* Just paranoia. */
|
||||
equal(one, "hi there", 6); /* Stomped on source? */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) memcpy(one+1, one, 9);
|
||||
equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) memcpy(one+1, one+2, 7);
|
||||
equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) memcpy(one, one, 9);
|
||||
equal(one, "abcdefgh", 9); /* 100% overlap. */
|
||||
|
||||
/*
|
||||
* memccpy - first test like memcpy, then the search part
|
||||
*
|
||||
* The SVID, the only place where memccpy is mentioned, says
|
||||
* overlap might fail, so we don't try it. Besides, it's hard
|
||||
* to see the rationale for a non-left-to-right memccpy.
|
||||
*/
|
||||
it = "memccpy";
|
||||
check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
|
||||
equal(one, "abc", 2); /* Did the copy go right? */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) memccpy(one+1, "xyz", 'q', 2);
|
||||
equal(one, "axydefgh", 3); /* Basic test. */
|
||||
|
||||
(void) strcpy(one, "abc");
|
||||
(void) memccpy(one, "xyz", 'q', 0);
|
||||
equal(one, "abc", 4); /* Zero-length copy. */
|
||||
|
||||
(void) strcpy(one, "hi there");
|
||||
(void) strcpy(two, "foo");
|
||||
(void) memccpy(two, one, 'q', 9);
|
||||
equal(two, "hi there", 5); /* Just paranoia. */
|
||||
equal(one, "hi there", 6); /* Stomped on source? */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) strcpy(two, "horsefeathers");
|
||||
check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */
|
||||
equal(one, "abcdefgh", 8); /* Source intact? */
|
||||
equal(two, "abcdefeathers", 9); /* Copy correct? */
|
||||
|
||||
(void) strcpy(one, "abcd");
|
||||
(void) strcpy(two, "bumblebee");
|
||||
check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */
|
||||
equal(two, "aumblebee", 11);
|
||||
check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */
|
||||
equal(two, "abcdlebee", 13);
|
||||
(void) strcpy(one, "xyz");
|
||||
check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */
|
||||
equal(two, "xbcdlebee", 15);
|
||||
|
||||
/*
|
||||
* memset
|
||||
*/
|
||||
it = "memset";
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */
|
||||
equal(one, "axxxefgh", 2); /* Basic test. */
|
||||
|
||||
(void) memset(one+2, 'y', 0);
|
||||
equal(one, "axxxefgh", 3); /* Zero-length set. */
|
||||
|
||||
(void) memset(one+5, 0, 1);
|
||||
equal(one, "axxxe", 4); /* Zero fill. */
|
||||
equal(one+6, "gh", 5); /* And the leftover. */
|
||||
|
||||
(void) memset(one+2, 010045, 1);
|
||||
equal(one, "ax\045xe", 6); /* Unsigned char convert. */
|
||||
|
||||
/*
|
||||
* bcopy - much like memcpy
|
||||
*
|
||||
* Berklix manual is silent about overlap, so don't test it.
|
||||
*/
|
||||
it = "bcopy";
|
||||
(void) bcopy("abc", one, 4);
|
||||
equal(one, "abc", 1); /* Simple copy. */
|
||||
|
||||
(void) strcpy(one, "abcdefgh");
|
||||
(void) bcopy("xyz", one+1, 2);
|
||||
equal(one, "axydefgh", 2); /* Basic test. */
|
||||
|
||||
(void) strcpy(one, "abc");
|
||||
(void) bcopy("xyz", one, 0);
|
||||
equal(one, "abc", 3); /* Zero-length copy. */
|
||||
|
||||
(void) strcpy(one, "hi there");
|
||||
(void) strcpy(two, "foo");
|
||||
(void) bcopy(one, two, 9);
|
||||
equal(two, "hi there", 4); /* Just paranoia. */
|
||||
equal(one, "hi there", 5); /* Stomped on source? */
|
||||
|
||||
/*
|
||||
* bzero
|
||||
*/
|
||||
it = "bzero";
|
||||
(void) strcpy(one, "abcdef");
|
||||
bzero(one+2, 2);
|
||||
equal(one, "ab", 1); /* Basic test. */
|
||||
equal(one+3, "", 2);
|
||||
equal(one+4, "ef", 3);
|
||||
|
||||
(void) strcpy(one, "abcdef");
|
||||
bzero(one+2, 0);
|
||||
equal(one, "abcdef", 4); /* Zero-length copy. */
|
||||
|
||||
/*
|
||||
* bcmp - somewhat like memcmp
|
||||
*/
|
||||
it = "bcmp";
|
||||
check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
|
||||
check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
|
||||
check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
|
||||
check(bcmp("abce", "abcd", 4) != 0, 4);
|
||||
check(bcmp("alph", "beta", 4) != 0, 5);
|
||||
check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
|
||||
check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
|
||||
|
||||
#ifdef ERR
|
||||
/*
|
||||
* strerror - VERY system-dependent
|
||||
*/
|
||||
it = "strerror";
|
||||
f = open("/", 1); /* Should always fail. */
|
||||
check(f < 0 && errno > 0 && errno < sys_nerr, 1);
|
||||
equal(strerror(errno), sys_errlist[errno], 2);
|
||||
#ifdef UNIXERR
|
||||
equal(strerror(errno), "Is a directory", 3);
|
||||
#endif
|
||||
#ifdef BERKERR
|
||||
equal(strerror(errno), "Permission denied", 3);
|
||||
#endif
|
||||
#endif
|
||||
}
|
176
dmake/dbug/malloc/testmlc.c
Normal file
176
dmake/dbug/malloc/testmlc.c
Normal file
@ -0,0 +1,176 @@
|
||||
/* NOT copyright by SoftQuad Inc. -- msb, 1988 */
|
||||
#ifndef lint
|
||||
static char *SQ_SccsId = "@(#)mtest3.c 1.2 88/08/25";
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
/*
|
||||
** looptest.c -- intensive allocator tester
|
||||
**
|
||||
** Usage: looptest
|
||||
**
|
||||
** History:
|
||||
** 4-Feb-1987 rtech!daveb
|
||||
*/
|
||||
|
||||
# ifdef SYS5
|
||||
# define random rand
|
||||
# else
|
||||
# include <sys/vadvise.h>
|
||||
# endif
|
||||
|
||||
# include <stdio.h>
|
||||
# include <signal.h>
|
||||
# include <setjmp.h>
|
||||
|
||||
# define MAXITER 1000000 /* main loop iterations */
|
||||
# define MAXOBJS 1000 /* objects in pool */
|
||||
# define BIGOBJ 90000 /* max size of a big object */
|
||||
# define TINYOBJ 80 /* max size of a small object */
|
||||
# define BIGMOD 100 /* 1 in BIGMOD is a BIGOBJ */
|
||||
# define STATMOD 10000 /* interation interval for status */
|
||||
|
||||
main( argc, argv )
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
register int **objs; /* array of objects */
|
||||
register int *sizes; /* array of object sizes */
|
||||
register int n; /* iteration counter */
|
||||
register int i; /* object index */
|
||||
register int size; /* object size */
|
||||
register int r; /* random number */
|
||||
|
||||
int objmax; /* max size this iteration */
|
||||
int cnt; /* number of allocated objects */
|
||||
int nm = 0; /* number of mallocs */
|
||||
int nre = 0; /* number of reallocs */
|
||||
int nal; /* number of allocated objects */
|
||||
int nfre; /* number of free list objects */
|
||||
long alm; /* memory in allocated objects */
|
||||
long frem; /* memory in free list */
|
||||
long startsize; /* size at loop start */
|
||||
long endsize; /* size at loop exit */
|
||||
long maxiter = 0; /* real max # iterations */
|
||||
|
||||
extern char end; /* memory before heap */
|
||||
char *calloc();
|
||||
char *malloc();
|
||||
char *sbrk();
|
||||
long atol();
|
||||
|
||||
# ifndef SYS5
|
||||
/* your milage may vary... */
|
||||
vadvise( VA_ANOM );
|
||||
# endif
|
||||
|
||||
if (argc > 1)
|
||||
maxiter = atol (argv[1]);
|
||||
if (maxiter <= 0)
|
||||
maxiter = MAXITER;
|
||||
|
||||
printf("MAXITER %d MAXOBJS %d ", maxiter, MAXOBJS );
|
||||
printf("BIGOBJ %d, TINYOBJ %d, nbig/ntiny 1/%d\n",
|
||||
BIGOBJ, TINYOBJ, BIGMOD );
|
||||
fflush( stdout );
|
||||
|
||||
if( NULL == (objs = (int **)calloc( MAXOBJS, sizeof( *objs ) ) ) )
|
||||
{
|
||||
fprintf(stderr, "Can't allocate memory for objs array\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if( NULL == ( sizes = (int *)calloc( MAXOBJS, sizeof( *sizes ) ) ) )
|
||||
{
|
||||
fprintf(stderr, "Can't allocate memory for sizes array\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* as per recent discussion on net.lang.c, calloc does not
|
||||
** necessarily fill in NULL pointers...
|
||||
*/
|
||||
for( i = 0; i < MAXOBJS; i++ )
|
||||
objs[ i ] = NULL;
|
||||
|
||||
startsize = sbrk(0) - &end;
|
||||
printf( "Memory use at start: %d bytes\n", startsize );
|
||||
fflush(stdout);
|
||||
|
||||
printf("Starting the test...\n");
|
||||
fflush(stdout);
|
||||
for( n = 0; n < maxiter ; n++ )
|
||||
{
|
||||
if( !(n % STATMOD) )
|
||||
{
|
||||
printf("%d iterations\n", n);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/* determine object of interst and it's size */
|
||||
|
||||
r = random();
|
||||
objmax = ( r % BIGMOD ) ? TINYOBJ : BIGOBJ;
|
||||
size = r % objmax;
|
||||
i = r % (MAXOBJS - 1);
|
||||
|
||||
/* either replace the object of get a new one */
|
||||
|
||||
if( objs[ i ] == NULL )
|
||||
{
|
||||
objs[ i ] = (int *)malloc( size );
|
||||
nm++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* don't keep bigger objects around */
|
||||
if( size > sizes[ i ] )
|
||||
{
|
||||
objs[ i ] = (int *)realloc( objs[ i ], size );
|
||||
nre++;
|
||||
}
|
||||
else
|
||||
{
|
||||
free( objs[ i ] );
|
||||
objs[ i ] = (int *)malloc( size );
|
||||
nm++;
|
||||
}
|
||||
}
|
||||
|
||||
sizes[ i ] = size;
|
||||
if( objs[ i ] == NULL )
|
||||
{
|
||||
printf("\nCouldn't allocate %d byte object!\n",
|
||||
size );
|
||||
break;
|
||||
}
|
||||
} /* for() */
|
||||
|
||||
printf( "\n" );
|
||||
cnt = 0;
|
||||
for( i = 0; i < MAXOBJS; i++ )
|
||||
if( objs[ i ] )
|
||||
cnt++;
|
||||
|
||||
printf( "Did %d iterations, %d objects, %d mallocs, %d reallocs\n",
|
||||
n, cnt, nm, nre );
|
||||
printf( "Memory use at end: %d bytes\n", sbrk(0) - &end );
|
||||
fflush( stdout );
|
||||
|
||||
/* free all the objects */
|
||||
for( i = 0; i < MAXOBJS; i++ )
|
||||
if( objs[ i ] != NULL )
|
||||
free( objs[ i ] );
|
||||
|
||||
endsize = sbrk(0) - &end;
|
||||
printf( "Memory use after free: %d bytes\n", endsize );
|
||||
fflush( stdout );
|
||||
|
||||
if( startsize != endsize )
|
||||
printf("startsize %d != endsize %d\n", startsize, endsize );
|
||||
|
||||
free( objs );
|
||||
free( sizes );
|
||||
|
||||
malloc_dump(2);
|
||||
exit( 0 );
|
||||
}
|
||||
|
151
dmake/dbug/malloc/tostring.c
Normal file
151
dmake/dbug/malloc/tostring.c
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
#include "tostring.h"
|
||||
|
||||
/*
|
||||
* Function: tostring()
|
||||
*
|
||||
* Purpose: to convert an integer to an ascii display string
|
||||
*
|
||||
* Arguments: buf - place to put the
|
||||
* val - integer to convert
|
||||
* len - length of output field (0 if just enough to hold data)
|
||||
* base - base for number conversion (only works for base <= 16)
|
||||
* fill - fill char when len > # digits
|
||||
*
|
||||
* Returns: length of string
|
||||
*
|
||||
* Narrative: IF fill character is non-blank
|
||||
* Determine base
|
||||
* If base is HEX
|
||||
* add "0x" to begining of string
|
||||
* IF base is OCTAL
|
||||
* add "0" to begining of string
|
||||
*
|
||||
* While value is greater than zero
|
||||
* use val % base as index into xlation str to get cur char
|
||||
* divide val by base
|
||||
*
|
||||
* Determine fill-in length
|
||||
*
|
||||
* Fill in fill chars
|
||||
*
|
||||
* Copy in number
|
||||
*
|
||||
*
|
||||
* Mod History:
|
||||
* 90/01/24 cpcahil Initial revision.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static
|
||||
char rcs_hdr[] = "$Id: tostring.c,v 1.1 1992/01/24 03:29:16 dvadura Exp $";
|
||||
#endif
|
||||
|
||||
#define T_LEN 10
|
||||
|
||||
int
|
||||
tostring(buf,val,len,base,fill)
|
||||
int base;
|
||||
char * buf;
|
||||
char fill;
|
||||
int len;
|
||||
int val;
|
||||
|
||||
{
|
||||
char * bufstart = buf;
|
||||
int i = T_LEN;
|
||||
char * xbuf = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
char tbuf[T_LEN];
|
||||
|
||||
/*
|
||||
* if we are filling with non-blanks, make sure the
|
||||
* proper start string is added
|
||||
*/
|
||||
if( fill != ' ' )
|
||||
{
|
||||
switch(base)
|
||||
{
|
||||
case B_HEX:
|
||||
*(buf++) = '0';
|
||||
*(buf++) = 'x';
|
||||
if( len )
|
||||
{
|
||||
len -= 2;
|
||||
}
|
||||
break;
|
||||
case B_OCTAL:
|
||||
*(buf++) = fill;
|
||||
if( len )
|
||||
{
|
||||
len--;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while( val > 0 )
|
||||
{
|
||||
tbuf[--i] = xbuf[val % base];
|
||||
val = val / base;
|
||||
}
|
||||
|
||||
if( len )
|
||||
{
|
||||
len -= (T_LEN - i);
|
||||
|
||||
if( len > 0 )
|
||||
{
|
||||
while(len-- > 0)
|
||||
{
|
||||
*(buf++) = fill;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* string is too long so we must truncate
|
||||
* off some characters. We do this the easiest
|
||||
* way by just incrementing i. This means the
|
||||
* most significant digits are lost.
|
||||
*/
|
||||
while( len++ < 0 )
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while( i < T_LEN )
|
||||
{
|
||||
*(buf++) = tbuf[i++];
|
||||
}
|
||||
|
||||
return( (int) (buf - bufstart) );
|
||||
|
||||
} /* tostring(... */
|
||||
|
||||
/*
|
||||
* $Log: tostring.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:16 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.4 90/05/11 00:13:11 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.3 90/02/24 21:50:33 cpcahil
|
||||
* lots of lint fixes
|
||||
*
|
||||
* Revision 1.2 90/02/24 17:29:42 cpcahil
|
||||
* changed $Header to $Id so full path wouldnt be included as part of rcs
|
||||
* id string
|
||||
*
|
||||
* Revision 1.1 90/02/22 23:17:44 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
25
dmake/dbug/malloc/tostring.h
Normal file
25
dmake/dbug/malloc/tostring.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).
|
||||
* You may copy, distribute, and use this software as long as this
|
||||
* copyright statement is not removed.
|
||||
*/
|
||||
/*
|
||||
* $Id: tostring.h,v 1.1 1992/01/24 03:29:17 dvadura Exp $
|
||||
*/
|
||||
#define B_BIN 2
|
||||
#define B_DEC 10
|
||||
#define B_HEX 16
|
||||
#define B_OCTAL 8
|
||||
|
||||
/*
|
||||
* $Log: tostring.h,v $
|
||||
* Revision 1.1 1992/01/24 03:29:17 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
* Revision 1.2 90/05/11 00:13:11 cpcahil
|
||||
* added copyright statment
|
||||
*
|
||||
* Revision 1.1 90/02/23 07:09:05 cpcahil
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
818
dmake/dmake.c
Normal file
818
dmake/dmake.c
Normal file
@ -0,0 +1,818 @@
|
||||
/* RCS -- $Header: /u/dvadura/src/generic/dmake/src/RCS/dmake.c,v 1.3 1992/04/07 04:42:46 dvadura Exp $
|
||||
-- SYNOPSIS -- The main program.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
--
|
||||
-- dmake [-#dbug_string] [ options ]
|
||||
-- [ macro definitions ] [ target ... ]
|
||||
--
|
||||
-- This file contains the main command line parser for the
|
||||
-- make utility. The valid flags recognized are as follows:
|
||||
--
|
||||
-- -f file - use file as the makefile
|
||||
-- -C file - duplicate console output to file (MSDOS only)
|
||||
-- -K file - .KEEP_STATE file
|
||||
-- -#dbug_string - dump out debugging info, see below
|
||||
-- -v{dfimt} - verbose, print what we are doing, as we do it.
|
||||
--
|
||||
-- options: (can be catenated, ie -irn == -i -r -n)
|
||||
--
|
||||
-- -A - enable AUGMAKE special target mapping
|
||||
-- -B - enable non-use of TABS to start recipe lines
|
||||
-- -c - use non-standard comment scanning
|
||||
-- -i - ignore errors
|
||||
-- -n - trace and print, do not execute commands
|
||||
-- -t - touch, update dates without executing commands
|
||||
-- -T - do not apply transitive closure on inference rules
|
||||
-- -r - don't use internal rules
|
||||
-- -s - do your work silently
|
||||
-- -S - force Sequential make, overrides -P
|
||||
-- -q - check if target is up to date. Does not
|
||||
-- do anything. Returns 0 if up to date, -1
|
||||
-- otherwise.
|
||||
-- -p - print out a version of the makefile
|
||||
-- -P# - set value of MAXPROCESS
|
||||
-- -E - define environment strings as macros
|
||||
-- -e - as -E but done after parsing makefile
|
||||
-- -u - force unconditional update of target
|
||||
-- -k - make all independent targets even if errors
|
||||
-- -V - print out this make version number
|
||||
-- -M - Microsoft make compatibility, (* disabled *)
|
||||
-- -h - print out usage info
|
||||
-- -x - export macro defs to environment
|
||||
-- -X - ignore #! lines found in makefile
|
||||
--
|
||||
-- NOTE: - #ddbug_string is only availabe for versions of dmake that
|
||||
-- have been compiled with -DDBUG switch on. Not the case for
|
||||
-- distributed versions. Any such versions must be linked
|
||||
-- together with a version of Fred Fish's debug code.
|
||||
--
|
||||
-- NOTE: - in order to compile the code the include file stddef.h
|
||||
-- must be shipped with the bundled code.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: dmake.c,v $
|
||||
* Revision 1.3 1992/04/07 04:42:46 dvadura
|
||||
* Gnuiffied the source, and prettied up some of the output for -h.
|
||||
*
|
||||
* Revision 1.2 1992/04/01 03:31:03 dvadura
|
||||
* changed use of #elif to satisfy broken compilers.
|
||||
*
|
||||
* Revision 1.1 1992/01/24 03:26:58 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
/* Set this flag to one, and the global variables in vextern.h will not
|
||||
* be defined as 'extern', instead they will be defined as global vars
|
||||
* when this module is compiled. */
|
||||
#define _DEFINE_GLOBALS_ 1
|
||||
|
||||
#include "extern.h"
|
||||
#include "patchlvl.h"
|
||||
#include "version.h"
|
||||
|
||||
#ifndef MSDOS
|
||||
#define USAGE \
|
||||
"Usage:\n%s [-P#] [-{f|K} file] [-v{dfimt}] [-ABceEhiknpqrsStTuVxX]\n"
|
||||
#define USAGE2 \
|
||||
"%s [macro[*][+][:]=value ...] [target ...]\n"
|
||||
#else
|
||||
#define USAGE \
|
||||
"Usage:\n%s [-P#] [-{f|C|K} file] [-v{dfimt}] [-ABceEhiknpqrsStTuVxX]\n"
|
||||
#define USAGE2 \
|
||||
"%s [macro[*][+][:]=value ...] [target ...]\n"
|
||||
#endif
|
||||
|
||||
#if __STDC__ == 1 && !defined(__GNUC__)
|
||||
void Fatal(char *fmt, ...);
|
||||
void Warning(char *fmt, ...);
|
||||
#endif
|
||||
|
||||
static char *sccid = "Copyright (c) 1990,1991 by Dennis Vadura";
|
||||
static char _warn = TRUE; /* warnings on by default */
|
||||
|
||||
static void _do_VPATH();
|
||||
static void _do_ReadEnvironment();
|
||||
#if !defined(__GNUC__)
|
||||
static void _do_f_flag ANSI((char, char *, char **));
|
||||
#else
|
||||
static void _do_f_flag ANSI((int, char *, char **));
|
||||
#endif
|
||||
|
||||
PUBLIC void
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
#ifdef MSDOS
|
||||
char* std_fil_name = NIL(char);
|
||||
#endif
|
||||
|
||||
char* fil_name = NIL(char);
|
||||
char* state_name = NIL(char);
|
||||
char* cmdmacs;
|
||||
char* targets;
|
||||
FILE* mkfil;
|
||||
int ex_val;
|
||||
int m_export;
|
||||
|
||||
DB_ENTER("main");
|
||||
|
||||
/* Initialize Global variables to their default values */
|
||||
Prolog(argc, argv);
|
||||
Create_macro_vars();
|
||||
Catch_signals(Quit);
|
||||
|
||||
Def_macro( "MAKECMD", Pname, M_PRECIOUS|M_NOEXPORT );
|
||||
Pname = basename(Pname);
|
||||
|
||||
DB_PROCESS(Pname);
|
||||
(void) setvbuf(stdout, NULL, _IOLBF, BUFSIZ); /* stdout line buffered */
|
||||
|
||||
Continue = FALSE;
|
||||
Comment = FALSE;
|
||||
Get_env = FALSE;
|
||||
Force = FALSE;
|
||||
Target = FALSE;
|
||||
If_expand = FALSE;
|
||||
Listing = FALSE;
|
||||
Readenv = FALSE;
|
||||
Rules = TRUE;
|
||||
Trace = FALSE;
|
||||
Touch = FALSE;
|
||||
Check = FALSE;
|
||||
Microsoft = FALSE;
|
||||
Makemkf = FALSE;
|
||||
No_exec = FALSE;
|
||||
m_export = FALSE;
|
||||
cmdmacs = NIL(char);
|
||||
targets = NIL(char);
|
||||
|
||||
Verbose = V_NONE;
|
||||
Transitive = TRUE;
|
||||
Nest_level = 0;
|
||||
Line_number = 0;
|
||||
Suppress_temp_file = FALSE;
|
||||
|
||||
while( --argc > 0 ) {
|
||||
register char *p;
|
||||
char *q;
|
||||
|
||||
if( *(p = *++argv) == '-' ) {
|
||||
if( p[1] == '\0' ) Fatal("Missing option letter");
|
||||
|
||||
/* copy options to Buffer for $(MFLAGS), strip 'f' and 'C'*/
|
||||
q = strchr(Buffer, '\0');
|
||||
while (*p != '\0') {
|
||||
char c = (*q++ = *p++);
|
||||
if( c == 'f' || c == 'C' ) q--;
|
||||
}
|
||||
|
||||
if( *(q-1) == '-' )
|
||||
q--;
|
||||
else
|
||||
*q++ = ' ';
|
||||
|
||||
*q = '\0';
|
||||
|
||||
for( p = *argv+1; *p; p++) switch (*p) {
|
||||
case 'f':
|
||||
_do_f_flag( 'f', *++argv, &fil_name ); argc--;
|
||||
break;
|
||||
|
||||
#if defined(MSDOS) && !defined(OS2)
|
||||
case 'C':
|
||||
_do_f_flag( 'C', *++argv, &std_fil_name ); argc--;
|
||||
Hook_std_writes( std_fil_name );
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'K':
|
||||
_do_f_flag( 'K', *++argv, &state_name ); argc--;
|
||||
Def_macro(".KEEP_STATE", state_name, M_EXPANDED|M_PRECIOUS);
|
||||
break;
|
||||
|
||||
case 'k': Continue = TRUE; break;
|
||||
case 'c': Comment = TRUE; break;
|
||||
case 'p': Listing = TRUE; break;
|
||||
case 'r': Rules = FALSE; break;
|
||||
case 'n': Trace = TRUE; break;
|
||||
case 't': Touch = TRUE; break;
|
||||
case 'q': Check = TRUE; break;
|
||||
case 'u': Force = TRUE; break;
|
||||
case 'x': m_export = TRUE; break;
|
||||
case 'X': No_exec = TRUE; break;
|
||||
case 'T': Transitive = FALSE; break;
|
||||
case 'e': Get_env = 'e'; break;
|
||||
case 'E': Get_env = 'E'; break;
|
||||
|
||||
case 'V': Version(); Quit(NIL(CELL)); break;
|
||||
case 'A': Def_macro("AUGMAKE", "y", M_EXPANDED); break;
|
||||
case 'B': Def_macro(".NOTABS", "y", M_EXPANDED); break;
|
||||
case 'i': Def_macro(".IGNORE", "y", M_EXPANDED); break;
|
||||
case 's': Def_macro(".SILENT", "y", M_EXPANDED); break;
|
||||
case 'S': Def_macro(".SEQUENTIAL", "y", M_EXPANDED); break;
|
||||
|
||||
case 'v':
|
||||
if( p[-1] != '-' ) Usage(TRUE);
|
||||
while( p[1] ) switch( *++p ) {
|
||||
case 'd': Verbose |= V_PRINT_DIR; break;
|
||||
case 'f': Verbose |= V_FILE_IO; break;
|
||||
case 'i': Verbose |= V_INFER; break;
|
||||
case 'm': Verbose |= V_MAKE; break;
|
||||
case 't': Verbose |= V_LEAVE_TMP; break;
|
||||
|
||||
default: Usage(TRUE); break;
|
||||
}
|
||||
if( !Verbose ) Verbose = V_ALL;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
if( p[1] ) {
|
||||
Def_macro( "MAXPROCESS", p+1, M_MULTI|M_EXPANDED );
|
||||
p += strlen(p)-1;
|
||||
}
|
||||
else
|
||||
Fatal( "Missing number for -P flag" );
|
||||
break;
|
||||
|
||||
#ifdef DBUG
|
||||
case '#':
|
||||
DB_PUSH(p+1);
|
||||
p += strlen(p)-1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'h': Usage(FALSE); break;
|
||||
case 0: break; /* lone - */
|
||||
default: Usage(TRUE); break;
|
||||
}
|
||||
}
|
||||
else if( (q = strchr(p, '=')) != NIL(char) ) {
|
||||
cmdmacs = _stradd( cmdmacs, _strdup2(p), TRUE );
|
||||
Parse_macro( p, (q[-1]!='+')?M_PRECIOUS:M_DEFAULT );
|
||||
}
|
||||
else {
|
||||
register CELLPTR cp;
|
||||
targets = _stradd( targets, _strdup(p), TRUE );
|
||||
Add_prerequisite(Root, cp = Def_cell(p), FALSE, FALSE);
|
||||
cp->ce_flag |= F_TARGET;
|
||||
cp->ce_attr |= A_FRINGE;
|
||||
Target = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Def_macro( "MAKEMACROS", cmdmacs, M_PRECIOUS|M_NOEXPORT );
|
||||
Def_macro( "MAKETARGETS", targets, M_PRECIOUS|M_NOEXPORT );
|
||||
if( cmdmacs != NIL(char) ) FREE(cmdmacs);
|
||||
if( targets != NIL(char) ) FREE(targets);
|
||||
|
||||
Def_macro( "MFLAGS", Buffer, M_PRECIOUS|M_NOEXPORT );
|
||||
Def_macro( "%", "$@", M_PRECIOUS|M_NOEXPORT );
|
||||
|
||||
if( *Buffer ) Def_macro( "MAKEFLAGS", Buffer+1, M_PRECIOUS|M_NOEXPORT );
|
||||
|
||||
_warn = FALSE; /* disable warnings for builtin rules */
|
||||
ex_val = Target; /* make sure we don't mark any */
|
||||
Target = TRUE; /* of the default rules as */
|
||||
Make_rules(); /* potential targets */
|
||||
_warn = TRUE;
|
||||
|
||||
if( Rules ) {
|
||||
char *fname;
|
||||
|
||||
if( (mkfil=Search_file("MAKESTARTUP", &fname)) != NIL(FILE) ) {
|
||||
Parse(mkfil);
|
||||
Def_macro( "MAKESTARTUP", fname, M_EXPANDED|M_MULTI );
|
||||
mkfil = NIL(FILE);
|
||||
}
|
||||
else
|
||||
Fatal( "Configuration file `%s' not found", fname );
|
||||
}
|
||||
|
||||
Target = ex_val;
|
||||
|
||||
if( Get_env == 'E' ) _do_ReadEnvironment();
|
||||
|
||||
if( fil_name != NIL(char) )
|
||||
mkfil = Openfile( fil_name, FALSE, TRUE );
|
||||
else {
|
||||
/* Search .MAKEFILES dependent list looking for a makefile.
|
||||
*/
|
||||
register CELLPTR cp;
|
||||
register LINKPTR lp;
|
||||
|
||||
cp = Def_cell( ".MAKEFILES" );
|
||||
|
||||
if( (lp = cp->CE_PRQ) != NIL(LINK) ) {
|
||||
int s_n, s_t, s_q;
|
||||
|
||||
s_n = Trace;
|
||||
s_t = Touch;
|
||||
s_q = Check;
|
||||
|
||||
Trace = Touch = Check = FALSE;
|
||||
Makemkf = Wait_for_completion = TRUE;
|
||||
mkfil = NIL(FILE);
|
||||
|
||||
for(; lp != NIL(LINK) && mkfil == NIL(FILE); lp=lp->cl_next) {
|
||||
if( lp->cl_prq->ce_attr & A_FRINGE ) continue;
|
||||
|
||||
mkfil = Openfile( lp->cl_prq->CE_NAME, FALSE, FALSE );
|
||||
|
||||
if( mkfil == NIL(FILE) &&
|
||||
Make(lp->cl_prq, NIL(CELL)) != -1 )
|
||||
mkfil = Openfile( lp->cl_prq->CE_NAME, FALSE, FALSE );
|
||||
}
|
||||
|
||||
Trace = s_n;
|
||||
Touch = s_t;
|
||||
Check = s_q;
|
||||
Makemkf = Wait_for_completion = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if( mkfil != NIL(FILE) ) {
|
||||
char *f = Filename();
|
||||
char *p;
|
||||
|
||||
if( strcmp(f, "stdin") == 0 ) f = "-";
|
||||
p = _stradd( "-f", f, FALSE );
|
||||
Def_macro( "MAKEFILE", p, M_PRECIOUS|M_NOEXPORT );
|
||||
Parse( mkfil );
|
||||
}
|
||||
else if( !Rules )
|
||||
Fatal( "No `makefile' present" );
|
||||
|
||||
if( Nest_level ) Fatal( "Missing .END for .IF" );
|
||||
if( Get_env == 'e' ) _do_ReadEnvironment();
|
||||
|
||||
_do_VPATH(); /* kludge it up with .SOURCE */
|
||||
|
||||
if( Listing ) Dump(); /* print out the structures */
|
||||
if( Trace ) Glob_attr &= ~A_SILENT; /* make sure we see the trace */
|
||||
|
||||
if( !Target )
|
||||
Fatal( "No target" );
|
||||
else {
|
||||
Test_circle( Root, TRUE );
|
||||
Check_circle_dfa();
|
||||
}
|
||||
|
||||
Push_dir( Start_dir, ".SETDIR", (int)(Glob_attr & A_IGNORE ));
|
||||
|
||||
if( m_export ) {
|
||||
int i;
|
||||
|
||||
for( i=0; i<HASH_TABLE_SIZE; ++i ) {
|
||||
HASHPTR hp = Macs[i];
|
||||
|
||||
while( hp ) {
|
||||
if( !(hp->ht_flag & M_NOEXPORT) && hp->ht_value != NIL(char) )
|
||||
if( Write_env_string(hp->ht_name, hp->ht_value) != 0 )
|
||||
Warning( "Could not export %s", hp->ht_name );
|
||||
hp = hp->ht_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( Buffer != NIL(char) ) {FREE( Buffer ); Buffer = NIL(char);}
|
||||
if( Trace ) Def_macro(".SEQUENTIAL", "y", M_EXPANDED);
|
||||
if( Glob_attr & A_SEQ ) Def_macro( "MAXPROCESS", "1", M_EXPANDED|M_FORCE );
|
||||
|
||||
ex_val = Make_targets();
|
||||
|
||||
Pop_dir( (Glob_attr & A_IGNORE) != 0 );
|
||||
Clear_signals();
|
||||
Epilog(ex_val); /* Does not return -- EVER */
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_do_f_flag( flag, name, fname )
|
||||
char flag;
|
||||
char *name;
|
||||
char **fname;
|
||||
{
|
||||
if( *fname == NIL(char) ) {
|
||||
if( name != NIL(char) ) {
|
||||
*fname = name;
|
||||
} else
|
||||
Fatal("No file name for -%c", flag);
|
||||
} else
|
||||
Fatal("Only one `-%c file' allowed", flag);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_do_ReadEnvironment()
|
||||
{
|
||||
t_attr saveattr = Glob_attr;
|
||||
|
||||
Glob_attr |= A_SILENT;
|
||||
ReadEnvironment();
|
||||
Glob_attr = saveattr;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_do_VPATH()
|
||||
{
|
||||
HASHPTR hp;
|
||||
char *_rl[2];
|
||||
extern char **Rule_tab;
|
||||
|
||||
hp = GET_MACRO("VPATH");
|
||||
if( hp == NIL(HASH) ) return;
|
||||
|
||||
_rl[0] = ".SOURCE :^ $(VPATH:s/:/ /)";
|
||||
_rl[1] = NIL(char);
|
||||
|
||||
Rule_tab = _rl;
|
||||
Parse( NIL(FILE) );
|
||||
}
|
||||
|
||||
|
||||
/* The file table and pointer to the next FREE slot for use by both
|
||||
Openfile and Closefile. Each open stacks the new file onto the open
|
||||
file stack, and a corresponding close will close the passed file, and
|
||||
return the next file on the stack. The maximum number of nested
|
||||
include files is limited by the value of MAX_INC_DEPTH */
|
||||
|
||||
static struct {
|
||||
FILE *file; /* file pointer */
|
||||
char *name; /* name of file */
|
||||
int numb; /* line number */
|
||||
} ftab[ MAX_INC_DEPTH ];
|
||||
|
||||
static int next_file_slot = 0;
|
||||
|
||||
/* Set the proper macro value to reflect the depth of the .INCLUDE directives.
|
||||
*/
|
||||
static void
|
||||
_set_inc_depth()
|
||||
{
|
||||
char buf[10];
|
||||
sprintf( buf, "%d", next_file_slot );
|
||||
Def_macro( "INCDEPTH", buf, M_MULTI|M_NOEXPORT );
|
||||
}
|
||||
|
||||
|
||||
PUBLIC FILE *
|
||||
Openfile(name, mode, err)/*
|
||||
===========================
|
||||
This routine opens a file for input or output depending on mode.
|
||||
If the file name is `-' then it returns standard input.
|
||||
The file is pushed onto the open file stack. */
|
||||
char *name;
|
||||
int mode;
|
||||
int err;
|
||||
{
|
||||
FILE *fil;
|
||||
|
||||
DB_ENTER("Openfile");
|
||||
|
||||
if( name == NIL(char) || !*name )
|
||||
if( !err )
|
||||
DB_RETURN(NIL(FILE));
|
||||
else
|
||||
Fatal( "Openfile: NIL filename" );
|
||||
|
||||
if( next_file_slot == MAX_INC_DEPTH )
|
||||
Fatal( "Too many open files. Max nesting level is %d.", MAX_INC_DEPTH);
|
||||
|
||||
DB_PRINT( "io", ("Opening file [%s], in slot %d", name, next_file_slot) );
|
||||
|
||||
if( strcmp("-", name) == 0 ) {
|
||||
name = "stdin";
|
||||
fil = stdin;
|
||||
}
|
||||
else
|
||||
fil = fopen( name, mode ? "w":"r" );
|
||||
|
||||
if( Verbose & V_FILE_IO )
|
||||
printf( "%s: Openning [%s] for %s", Pname, name, mode?"write":"read" );
|
||||
|
||||
if( fil == NIL(FILE) ) {
|
||||
if( Verbose & V_FILE_IO ) printf( " (fail)\n" );
|
||||
if( err )
|
||||
Fatal( mode ? "Cannot open file %s for write" : "File %s not found",
|
||||
name );
|
||||
}
|
||||
else {
|
||||
if( Verbose & V_FILE_IO ) printf( " (success)\n" );
|
||||
ftab[next_file_slot].file = fil;
|
||||
ftab[next_file_slot].numb = Line_number;
|
||||
ftab[next_file_slot++].name = _strdup(name);
|
||||
Line_number = 0;
|
||||
_set_inc_depth();
|
||||
}
|
||||
|
||||
DB_RETURN(fil);
|
||||
}
|
||||
|
||||
|
||||
PUBLIC FILE *
|
||||
Closefile()/*
|
||||
=============
|
||||
This routine is used to close the last file opened. This forces make
|
||||
to open files in a last open first close fashion. It returns the
|
||||
file pointer to the next file on the stack, and NULL if the stack is empty.*/
|
||||
{
|
||||
DB_ENTER("Closefile");
|
||||
|
||||
if( !next_file_slot )
|
||||
DB_RETURN( NIL(FILE) );
|
||||
|
||||
if( ftab[--next_file_slot].file != stdin ) {
|
||||
DB_PRINT( "io", ("Closing file in slot %d", next_file_slot) );
|
||||
|
||||
if( Verbose & V_FILE_IO )
|
||||
printf( "%s: Closing [%s]\n", Pname, ftab[next_file_slot].name );
|
||||
|
||||
fclose( ftab[next_file_slot].file );
|
||||
FREE( ftab[next_file_slot].name );
|
||||
}
|
||||
|
||||
_set_inc_depth();
|
||||
|
||||
if( next_file_slot > 0 ) {
|
||||
Line_number = ftab[next_file_slot].numb;
|
||||
DB_RETURN( ftab[next_file_slot-1].file );
|
||||
}
|
||||
else
|
||||
Line_number = 0;
|
||||
|
||||
DB_RETURN( NIL(FILE) );
|
||||
}
|
||||
|
||||
|
||||
PUBLIC FILE *
|
||||
Search_file( macname, rname )
|
||||
char *macname;
|
||||
char **rname;
|
||||
{
|
||||
HASHPTR hp;
|
||||
FILE *fil = NIL(FILE);
|
||||
char *fname;
|
||||
char *ename = NIL(char);
|
||||
|
||||
/* order of precedence is:
|
||||
*
|
||||
* MACNAME from command line (precious is marked)
|
||||
* ... via MACNAME:=filename definition.
|
||||
* MACNAME from environment
|
||||
* MACNAME from builtin rules (not precious)
|
||||
*/
|
||||
|
||||
if( (hp = GET_MACRO(macname)) != NIL(HASH) )
|
||||
ename = fname = Expand(hp->ht_value);
|
||||
|
||||
if( hp->ht_flag & M_PRECIOUS ) fil = Openfile(fname, FALSE, FALSE);
|
||||
|
||||
if( fil == NIL(FILE) ) {
|
||||
fname=Expand(Read_env_string(macname));
|
||||
if( fil = Openfile(fname, FALSE, FALSE) ) FREE(ename);
|
||||
}
|
||||
|
||||
if( fil == NIL(FILE) && hp != NIL(HASH) )
|
||||
fil = Openfile(fname=ename, FALSE, FALSE);
|
||||
|
||||
if( rname ) *rname = fname;
|
||||
|
||||
return(fil);
|
||||
}
|
||||
|
||||
|
||||
PUBLIC char *
|
||||
Filename()/*
|
||||
============
|
||||
Return name of file on top of stack */
|
||||
{
|
||||
return( next_file_slot==0 ? NIL(char) : ftab[next_file_slot-1].name );
|
||||
}
|
||||
|
||||
|
||||
PUBLIC int
|
||||
Nestlevel()/*
|
||||
=============
|
||||
Return the file nesting level */
|
||||
{
|
||||
return( next_file_slot );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** print error message from variable arg list
|
||||
*/
|
||||
|
||||
static int errflg = TRUE;
|
||||
static int warnflg = FALSE;
|
||||
|
||||
static void
|
||||
errargs(fmt, args)
|
||||
char *fmt;
|
||||
va_list args;
|
||||
{
|
||||
int warn = _warn && warnflg && !(Glob_attr & A_SILENT);
|
||||
|
||||
if( errflg || warn ) {
|
||||
char *f = Filename();
|
||||
|
||||
fprintf( stderr, "%s: ", Pname );
|
||||
if( f != NIL(char) ) fprintf(stderr, "%s: line %d: ", f, Line_number);
|
||||
|
||||
if( errflg )
|
||||
fprintf(stderr, "Error -- ");
|
||||
else if( warn )
|
||||
fprintf(stderr, "Warning -- ");
|
||||
|
||||
vfprintf( stderr, fmt, args );
|
||||
putc( '\n', stderr );
|
||||
if( errflg && !Continue ) Quit( NIL(CELL) );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Print error message and abort
|
||||
*/
|
||||
#if __STDC__ == 1 && !defined(__GNUC__)
|
||||
void
|
||||
Fatal(char *fmt, ...)
|
||||
#else
|
||||
#if defined(_MPW)
|
||||
Fatal(char *fmt, va_alist)
|
||||
va_dcl
|
||||
#else
|
||||
int
|
||||
Fatal(fmt, va_alist)
|
||||
char *fmt;
|
||||
va_dcl;
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
Continue = FALSE;
|
||||
errargs(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/*
|
||||
** error message and exit (unless -k)
|
||||
*/
|
||||
#if __STDC__ == 1 && !defined(__GNUC__)
|
||||
void
|
||||
Error (char *fmt, ...)
|
||||
#else
|
||||
#if defined(_MPW)
|
||||
Error(char *fmt, va_alist)
|
||||
va_dcl
|
||||
#else
|
||||
int
|
||||
Error(fmt, va_alist)
|
||||
char* fmt;
|
||||
va_dcl;
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
errargs(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** non-fatal message
|
||||
*/
|
||||
#if __STDC__ == 1 && !defined(__GNUC__)
|
||||
void
|
||||
Error(char *fmt, ...)
|
||||
#else
|
||||
#if defined(_MPW)
|
||||
Error(char *fmt, va_alist)
|
||||
va_dcl
|
||||
#else
|
||||
int
|
||||
Warning(fmt, va_alist)
|
||||
char *fmt;
|
||||
va_dcl;
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
warnflg = TRUE;
|
||||
errflg = FALSE;
|
||||
errargs(fmt, args);
|
||||
errflg = TRUE;
|
||||
warnflg = FALSE;
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
PUBLIC void
|
||||
No_ram()
|
||||
{
|
||||
Fatal( "No more memory" );
|
||||
}
|
||||
|
||||
|
||||
PUBLIC
|
||||
|
||||
Usage( eflag )
|
||||
int eflag;
|
||||
{
|
||||
register char *p;
|
||||
char *fill;
|
||||
|
||||
fill = _strdup(Pname);
|
||||
for(p=fill; *p; p++) *p=' ';
|
||||
|
||||
if( eflag ) {
|
||||
fprintf(stderr, USAGE, Pname);
|
||||
fprintf(stderr, USAGE2, fill);
|
||||
}
|
||||
else {
|
||||
printf(USAGE, Pname);
|
||||
fprintf(stderr, USAGE2, fill);
|
||||
puts(" -P# - set max number of child processes for parallel make");
|
||||
puts(" -f file - use file as the makefile");
|
||||
#ifdef MSDOS
|
||||
puts(" -C [+]file - duplicate console output to file, ('+' => append)");
|
||||
#endif
|
||||
puts(" -K file - use file as the .KEEP_STATE file");
|
||||
puts(" -v{dfimt} - verbose, indicate what we are doing, (-v => -vdimt)");
|
||||
puts(" d => dump change of directory info only" );
|
||||
puts(" f => dump file open/close info only" );
|
||||
puts(" i => dump inference information only" );
|
||||
puts(" m => dump make of target information only" );
|
||||
puts(" t => keep temporary files when done\n" );
|
||||
|
||||
puts("Options: (can be catenated, ie -irn == -i -r -n)");
|
||||
puts(" -A - enable AUGMAKE special target mapping");
|
||||
puts(" -B - enable the use of spaces instead of tabs to start recipes");
|
||||
puts(" -c - use non standard comment scanning");
|
||||
puts(" -E - define environment strings as macros");
|
||||
puts(" -e - same as -E but done after parsing makefile");
|
||||
puts(" -h - print out usage info");
|
||||
puts(" -i - ignore errors");
|
||||
puts(" -k - make independent targets, even if errors");
|
||||
puts(" -n - trace and print, do not execute commands");
|
||||
puts(" -p - print out a version of the makefile");
|
||||
puts(" -q - check if target is up to date. Does not do");
|
||||
puts(" anything. Returns 0 if up to date, 1 otherwise");
|
||||
puts(" -r - don't use internal rules");
|
||||
puts(" -s - do your work silently");
|
||||
puts(" -S - disable parallel (force sequential) make, overrides -P");
|
||||
puts(" -t - touch, update time stamps without executing commands");
|
||||
puts(" -T - do not apply transitive closure on inference rules");
|
||||
puts(" -u - force unconditional update of target");
|
||||
puts(" -V - print out version number");
|
||||
puts(" -x - export macro values to environment");
|
||||
puts(" -X - ignore #! lines at start of makefile");
|
||||
}
|
||||
|
||||
Quit(NIL(CELL));
|
||||
}
|
||||
|
||||
|
||||
PUBLIC
|
||||
Version()
|
||||
{
|
||||
extern char **Rule_tab;
|
||||
char **p;
|
||||
|
||||
printf("%s - %s, ", Pname, sccid);
|
||||
printf("Version %s, PL %d\n\n", VERSION, PATCHLEVEL);
|
||||
|
||||
puts("Default Configuration:");
|
||||
for (p=Rule_tab; *p != NIL(char); p++)
|
||||
printf("\t%s\n", *p);
|
||||
}
|
183
dmake/dmake.h
Normal file
183
dmake/dmake.h
Normal file
@ -0,0 +1,183 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dmake.h,v 1.1 1992/01/24 03:26:50 dvadura Exp $
|
||||
-- SYNOPSIS -- global defines for dmake.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- All the interesting bits and flags that dmake uses are defined here.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: dmake.h,v $
|
||||
* Revision 1.1 1992/01/24 03:26:50 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DMAKE_INCLUDED_
|
||||
#define _DMAKE_INCLUDED_
|
||||
|
||||
#define MAX_INC_DEPTH 10 /* max of ten nested include files */
|
||||
#define MAX_COND_DEPTH 20 /* max nesting level of conditionals */
|
||||
#define ERROR_EXIT_VALUE 255 /* return code of aborted make */
|
||||
#define CONTINUATION_CHAR '\\' /* line continuation \<nl> */
|
||||
#define DEF_ESCAPE_CHAR '\\' /* escape char for used chars */
|
||||
#define ESCAPE_CHAR *Escape_char
|
||||
#define COMMENT_CHAR '#' /* start of comment chars */
|
||||
#define TGT_DEP_SEP ':' /* separator for targets and dependents */
|
||||
#define CONDSTART '.' /* start of conditional token eg .IF */
|
||||
#define DEF_MAKE_PNAME "dmake"/* default name to use as name of make */
|
||||
|
||||
|
||||
/* ............... Hashing function constants ......................... */
|
||||
#define HASH_TABLE_SIZE 200 /* See hash.c for description */
|
||||
|
||||
|
||||
/* Bit flags for cells and macro definitions. */
|
||||
#define M_DEFAULT 0x0000 /* default flag value */
|
||||
#define M_MARK 0x0001 /* mark for circularity checks */
|
||||
#define M_PRECIOUS 0x0002 /* keep macro, same as A_PRE... */
|
||||
#define M_MULTI 0x0004 /* multiple redefinitions ok! */
|
||||
#define M_EXPANDED 0x0008 /* macro has been assigned */
|
||||
#define M_USED 0x0010 /* macro has been expanded */
|
||||
#define M_LITERAL 0x0020 /* don't strip w/s on macro def */
|
||||
#define M_NOEXPORT 0x0040 /* don't export macro for -x */
|
||||
#define M_FORCE 0x0080 /* Force a macro redefinition */
|
||||
#define M_VAR_BIT 0x1000 /* macro bit variable */
|
||||
#define M_VAR_CHAR 0x2000 /* macro char variable */
|
||||
#define M_VAR_STRING 0x4000 /* macro string variable */
|
||||
#define M_VAR_INT 0x8000 /* macro integer variable */
|
||||
|
||||
#define M_VAR_MASK 0xf000 /* macro variable mask */
|
||||
|
||||
|
||||
|
||||
/* Global and target attribute flag definitions.
|
||||
* If you change the values of these or re-order them make appropriate changes
|
||||
* in dump.c so that the output of dmake -p matches the attribute info for a
|
||||
* target. */
|
||||
|
||||
#define A_DEFAULT 0x00000 /* default flag value */
|
||||
#define A_PRECIOUS 0x00001 /* object is precious */
|
||||
#define A_SILENT 0x00002 /* don't echo commands */
|
||||
#define A_LIBRARY 0x00004 /* target is an archive */
|
||||
#define A_EPILOG 0x00008 /* insert shell epilog code */
|
||||
#define A_PROLOG 0x00010 /* insert shell prolog code */
|
||||
#define A_IGNORE 0x00020 /* ignore errors */
|
||||
#define A_SYMBOL 0x00040 /* lib member is a symbol */
|
||||
#define A_NOINFER 0x00080 /* no trans closure from cell */
|
||||
#define A_UPDATEALL 0x00100 /* all targets of rule modified */
|
||||
#define A_SEQ 0x00200 /* sequential make attribute */
|
||||
#define A_SETDIR 0x00400 /* cd to dir when making target */
|
||||
#define A_SHELL 0x00800 /* run the recipe using a shell */
|
||||
#define A_SWAP 0x01000 /* swap on exec. */
|
||||
#define A_MKSARGS 0x02000 /* use MKS argument swapping */
|
||||
#define A_PHONY 0x04000 /* .PHONY attribute */
|
||||
#define A_NOSTATE 0x08000 /* don't track state for me */
|
||||
#define MAX_ATTR A_NOSTATE /* highest valid attribute */
|
||||
#define A_LIBRARYM 0x10000 /* target is an archive member */
|
||||
#define A_FRINGE 0x20000 /* cell is on the fringe */
|
||||
#define A_COMPOSITE 0x40000 /* member of lib(targ) name */
|
||||
#define A_FFNAME 0x80000 /* if set, free ce_fname in stat*/
|
||||
#define A_UPDATED 0x100000 /* Used to mark cell as updated */
|
||||
#define A_ROOT 0x200000 /* True if it is a root prereq */
|
||||
|
||||
|
||||
/* Global and target bit flag definitions */
|
||||
|
||||
#define F_DEFAULT 0x0000 /* default flag value */
|
||||
#define F_MARK 0x0001 /* circularity check mark */
|
||||
#define F_MULTI 0x0002 /* multiple rules for target */
|
||||
#define F_SINGLE 0x0004 /* exec rules one/prerequisite */
|
||||
#define F_TARGET 0x0008 /* marks a target */
|
||||
#define F_RULES 0x0010 /* indicates target has rules */
|
||||
#define F_GROUP 0x0020 /* indicates that rules are to */
|
||||
/* fed to the shell as a group */
|
||||
|
||||
#define F_TRANS 0x0040 /* same as F_STAT not used tgthr*/
|
||||
#define F_STAT 0x0040 /* target already stated */
|
||||
#define F_VISITED 0x0080 /* target scheduled for make */
|
||||
#define F_USED 0x0080 /* used in releparse.c */
|
||||
#define F_SPECIAL 0x0100 /* marks a special target */
|
||||
#define F_DFA 0x0200 /* bit for marking added DFA */
|
||||
#define F_EXPLICIT 0x0400 /* explicit target in makefile */
|
||||
#define F_PERCENT 0x0800 /* marks a target as a % rule */
|
||||
#define F_REMOVE 0x1000 /* marks an intermediate target */
|
||||
#define F_MAGIC 0x2000 /* marks a magic target */
|
||||
#define F_INFER 0x4000 /* target is result of inference*/
|
||||
#define F_MADE 0x8000 /* target is manufactured */
|
||||
|
||||
|
||||
/* Definitions for the Parser states */
|
||||
#define NORMAL_SCAN 0 /* normal processing state */
|
||||
#define RULE_SCAN 1 /* scan of rule text */
|
||||
|
||||
/* definitions for macro operator types */
|
||||
#define M_OP_EQ 1 /* macro operation is '=' */
|
||||
#define M_OP_CL 2 /* macro operation is ':=' */
|
||||
#define M_OP_PL 3 /* macro operation is '+=' */
|
||||
#define M_OP_PLCL 4 /* macro operation is '+:='*/
|
||||
#define M_OP_DF 5 /* macro operation is '*=' */
|
||||
#define M_OP_DFCL 6 /* macro operation is '*:='*/
|
||||
|
||||
/* definitions for rule operator types */
|
||||
#define R_OP_CL 1 /* rule operation is ':' */
|
||||
#define R_OP_DCL 2 /* rule operation is '::' */
|
||||
#define R_OP_BG 4 /* rule operation is ':!' */
|
||||
#define R_OP_UP 8 /* rule operation is ':^' */
|
||||
#define R_OP_MI 16 /* rule operation is ':-' */
|
||||
|
||||
/* definitions for modifier application in Apply_modifiers in expand.c */
|
||||
#define SUFFIX_FLAG 1 /* defines for macro modifier code */
|
||||
#define DIRECTORY_FLAG 2
|
||||
#define FILE_FLAG 4
|
||||
|
||||
/* special target definitions for use inside dmake */
|
||||
#define ST_IF 1
|
||||
#define ST_ELSE 2
|
||||
#define ST_END 3
|
||||
#define ST_REST 4 /* remaining special targets */
|
||||
#define ST_INCLUDE 5
|
||||
#define ST_SOURCE 7
|
||||
#define ST_EXPORT 8
|
||||
#define ST_IMPORT 9
|
||||
#define ST_ELIF 10
|
||||
#define ST_KEEP 11
|
||||
|
||||
/* Flags for controling use of -v switch */
|
||||
#define V_NONE 0x00
|
||||
#define V_LEAVE_TMP 0x01
|
||||
#define V_PRINT_DIR 0x02
|
||||
#define V_INFER 0x04
|
||||
#define V_MAKE 0x08
|
||||
#define V_FILE_IO 0x10
|
||||
#define V_ALL (V_LEAVE_TMP | V_PRINT_DIR | V_INFER | V_MAKE |\
|
||||
V_FILE_IO)
|
||||
|
||||
/* Macro definitions for use inside dmake */
|
||||
#define SET_TOKEN(A, B) (A)->tk_str = (B); (A)->tk_cchar = *(B);\
|
||||
(A)->tk_quote = 1;
|
||||
#define CLEAR_TOKEN(A) *(A)->tk_str = (A)->tk_cchar
|
||||
#define GET_MACRO(A) Get_name(A, Macs, FALSE)
|
||||
#define iswhite(C) ((C == ' ') || (C == '\t'))
|
||||
|
||||
#endif
|
||||
|
209
dmake/dmdump.c
Normal file
209
dmake/dmdump.c
Normal file
@ -0,0 +1,209 @@
|
||||
/* RCS -- $Header: /u/dvadura/src/generic/dmake/src/RCS/dmdump.c,v 1.2 1992/04/07 04:42:46 dvadura Exp $
|
||||
-- SYNOPSIS -- dump the internal dag to stdout.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- This file contains the routine that is called to dump a version of
|
||||
-- the digested makefile to the standard output. May be useful perhaps
|
||||
-- to the ordinary user, and invaluable for debugging make.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: dmdump.c,v $
|
||||
* Revision 1.2 1992/04/07 04:42:46 dvadura
|
||||
* Deleted define of unused variable.
|
||||
*
|
||||
* Revision 1.1 1992/01/24 03:28:51 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
#define M_TEST (M_PRECIOUS | M_VAR_MASK)
|
||||
|
||||
static void dump_name ANSI((HASHPTR, int));
|
||||
static void dump_normal_target ANSI((CELLPTR, int));
|
||||
static void dump_prerequisites ANSI((LINKPTR, int, int, int));
|
||||
|
||||
|
||||
PUBLIC void
|
||||
Dump()/*
|
||||
======== Dump onto standard output the digested makefile. Note that
|
||||
the form of the dump is not representative of the contents
|
||||
of the original makefile contents at all */
|
||||
{
|
||||
HASHPTR hp;
|
||||
int i;
|
||||
|
||||
DB_ENTER( "Dump" );
|
||||
|
||||
puts( "# Dump of dmake macro variables:" );
|
||||
for( i=0; i<HASH_TABLE_SIZE; i++)
|
||||
for( hp=Macs[i]; hp != NIL(HASH); hp = hp->ht_next ) {
|
||||
int flag = hp->ht_flag;
|
||||
|
||||
printf( "%s ", hp->ht_name );
|
||||
if( flag & M_EXPANDED ) putchar( ':' );
|
||||
printf( "= " );
|
||||
if( hp->ht_value != NIL(char) ) printf( "%s",hp->ht_value );
|
||||
if( flag & M_PRECIOUS )
|
||||
printf( "\t # PRECIOUS " );
|
||||
putchar( '\n' );
|
||||
}
|
||||
|
||||
puts( "\n#====================================" );
|
||||
puts( "# Dump of targets:\n" );
|
||||
|
||||
for( i=0; i<HASH_TABLE_SIZE; i++ )
|
||||
for( hp = Defs[i]; hp != NIL(HASH); hp = hp->ht_next )
|
||||
if( !(hp->CP_OWNR->ce_flag & F_PERCENT) ) {
|
||||
if( Root->ce_prq && hp->CP_OWNR == Root->ce_prq->cl_prq )
|
||||
puts( "# ******* FIRST TARGET ********" );
|
||||
dump_normal_target( hp->CP_OWNR, hp->CP_OWNR->ce_flag );
|
||||
}
|
||||
|
||||
puts( "\n#====================================" );
|
||||
puts( "# Dump of inference graph\n" );
|
||||
|
||||
for( i=0; i<HASH_TABLE_SIZE; i++ )
|
||||
for( hp = Defs[i]; hp != NIL(HASH); hp = hp->ht_next )
|
||||
if( (hp->CP_OWNR->ce_flag & F_PERCENT) &&
|
||||
!(hp->CP_OWNR->ce_flag & F_MAGIC) )
|
||||
dump_normal_target( hp->CP_OWNR, hp->CP_OWNR->ce_flag );
|
||||
|
||||
DB_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PUBLIC void
|
||||
Dump_recipe( sp )/*
|
||||
===================
|
||||
Given a string pointer print the recipe line out */
|
||||
STRINGPTR sp;
|
||||
{
|
||||
char *st;
|
||||
char *nl;
|
||||
|
||||
if( sp == NIL(STRING) ) return;
|
||||
|
||||
putchar( '\t' );
|
||||
if( sp->st_attr & A_SILENT ) putchar( '@' );
|
||||
if( sp->st_attr & A_IGNORE ) putchar( '-' );
|
||||
if( sp->st_attr & A_SHELL ) putchar( '+' );
|
||||
if( sp->st_attr & A_SWAP ) putchar( '%' );
|
||||
|
||||
st = sp->st_string;
|
||||
for( nl=strchr(st,'\n'); nl != NIL( char); nl=strchr(st,'\n') ) {
|
||||
*nl = '\0';
|
||||
printf( "%s\\\n", st );
|
||||
*nl = '\n';
|
||||
st = nl+1;
|
||||
}
|
||||
printf( "%s\n", st );
|
||||
}
|
||||
|
||||
|
||||
static char *_attrs[] = { ".PRECIOUS", ".SILENT", ".LIBRARY",
|
||||
".EPILOG", ".PROLOG", ".IGNORE", ".SYMBOL", ".NOINFER",
|
||||
".UPDATEALL", ".SEQUENTIAL", ".SETDIR=", ".USESHELL", ".SWAP", ".MKSARGS",
|
||||
".PHONY", ".NOSTATE" };
|
||||
|
||||
static void
|
||||
dump_normal_target( cp, flag )/*
|
||||
================================
|
||||
Dump in makefile like format the dag information */
|
||||
CELLPTR cp;
|
||||
int flag;
|
||||
{
|
||||
register STRINGPTR sp;
|
||||
t_attr attr;
|
||||
unsigned int k;
|
||||
|
||||
DB_ENTER( "dump_normal_target" );
|
||||
|
||||
if( !(cp->ce_flag & F_TARGET) && !cp->ce_attr ) { DB_VOID_RETURN; }
|
||||
|
||||
if( cp->ce_flag & F_MULTI ) {
|
||||
int tflag = cp->ce_prq->cl_prq->ce_flag;
|
||||
if( !(cp->ce_flag & F_PERCENT) ) tflag |= F_MULTI;
|
||||
dump_prerequisites(cp->ce_prq, FALSE, TRUE, tflag);
|
||||
}
|
||||
else {
|
||||
dump_name( cp->ce_name, FALSE );
|
||||
|
||||
for( k=0, attr=1; attr <= MAX_ATTR; attr <<= 1, k++ )
|
||||
if( cp->ce_attr & attr ) {
|
||||
printf( "%s%s ", _attrs[k],
|
||||
(attr != A_SETDIR) ? "" : (cp->ce_dir?cp->ce_dir:"") );
|
||||
}
|
||||
|
||||
putchar( ':' );
|
||||
|
||||
if( flag & F_MULTI ) putchar( ':' );
|
||||
if( flag & F_SINGLE ) putchar( '!' );
|
||||
putchar( ' ' );
|
||||
|
||||
dump_prerequisites( cp->ce_prq, FALSE, FALSE, F_DEFAULT);
|
||||
dump_prerequisites( cp->ce_indprq, TRUE, FALSE, F_DEFAULT);
|
||||
|
||||
putchar( '\n' );
|
||||
if( cp->ce_flag & F_GROUP ) puts( "[" );
|
||||
for( sp = cp->ce_recipe; sp != NIL(STRING); sp = sp->st_next )
|
||||
Dump_recipe( sp );
|
||||
if( cp->ce_flag & F_GROUP ) puts( "]" );
|
||||
|
||||
putchar( '\n' );
|
||||
}
|
||||
|
||||
DB_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dump_prerequisites( lp, quote, recurse, flag )
|
||||
LINKPTR lp;
|
||||
int quote;
|
||||
int recurse;
|
||||
int flag;
|
||||
{
|
||||
for( ; lp; lp=lp->cl_next )
|
||||
if( recurse )
|
||||
dump_normal_target(lp->cl_prq, flag);
|
||||
else if( lp->cl_prq )
|
||||
dump_name(lp->cl_prq->ce_name, quote);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dump_name( hp, quote )/*
|
||||
========================
|
||||
print out a name */
|
||||
HASHPTR hp;
|
||||
int quote;
|
||||
{
|
||||
if( quote ) putchar('\'');
|
||||
printf( "%s", hp->ht_name );
|
||||
if( quote ) putchar('\'');
|
||||
putchar(' ');
|
||||
}
|
302
dmake/dmstring.c
Normal file
302
dmake/dmstring.c
Normal file
@ -0,0 +1,302 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/dmstring.c,v 1.1 1992/01/24 03:29:38 dvadura Exp $
|
||||
-- SYNOPSIS -- string handling code
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- Routines to handle string manipulation. This code is not specific
|
||||
-- to dmake and has/and will be used in other programs. The string
|
||||
-- "" is considered the NULL string, if NIL(char) is received instead
|
||||
-- undefined results may occurr. (In reality NIL(char) is checked for
|
||||
-- but in general it is not safe to assume NIL(char) == NULL)
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: dmstring.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:38 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
PUBLIC char *
|
||||
_strjoin( src, data, n, fr )/*
|
||||
==============================
|
||||
Join data to src according to value of n.
|
||||
|
||||
n = -1 - return strcat( src, data )
|
||||
n >= 0 - return strncat( src, data, n )
|
||||
|
||||
FREE original src if fr == TRUE, else leave it alone */
|
||||
|
||||
char *src;
|
||||
char *data;
|
||||
int n;
|
||||
int fr;
|
||||
{
|
||||
char *t;
|
||||
int l;
|
||||
int flag = FALSE;
|
||||
|
||||
DB_ENTER( "_strjoin" );
|
||||
|
||||
if( src == NIL(char) ) { src = ""; flag = TRUE; }
|
||||
if( data == NIL(char) ) data = "";
|
||||
DB_PRINT( "str", ("Joining [%s] [%s] %d", src, data, n) );
|
||||
|
||||
if( n == -1 ) n = strlen( data );
|
||||
|
||||
l = strlen( src ) + n + 1;
|
||||
if( (t = MALLOC( l, char )) == NIL(char) ) No_ram();
|
||||
|
||||
strcpy( t, src );
|
||||
if (n) strncat( t, data, n );
|
||||
t[ l-1 ] = '\0';
|
||||
|
||||
if( !flag && fr ) FREE( src );
|
||||
|
||||
DB_PRINT( "str", ("Result [%s]", t) );
|
||||
DB_RETURN( t );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PUBLIC char *
|
||||
_stradd( src, data, fr )/*
|
||||
==========================
|
||||
append data to src with space in between if src is not NIL(char) or ""
|
||||
and free both src and data if fr == TRUE, otherwise leave them be */
|
||||
|
||||
char *src;
|
||||
char *data;
|
||||
int fr;
|
||||
{
|
||||
char *t;
|
||||
int l;
|
||||
int sflag;
|
||||
int dflag;
|
||||
|
||||
DB_ENTER( "_stradd" );
|
||||
|
||||
sflag = dflag = fr;
|
||||
|
||||
if( src == NIL(char) ) { src = ""; sflag = FALSE; }
|
||||
if( data == NIL(char) ) { data = ""; dflag = FALSE; }
|
||||
DB_PRINT( "str", ("Adding [%s] [%s] %d", src, data, fr) );
|
||||
|
||||
l = strlen(src) + strlen(data) + 1;
|
||||
if( *src ) l++;
|
||||
|
||||
if( (t = MALLOC( l, char )) == NIL(char) ) No_ram();
|
||||
|
||||
strcpy( t, src );
|
||||
|
||||
if( *data )
|
||||
{
|
||||
if( *src ) strcat( t, " " );
|
||||
strcat( t, data );
|
||||
}
|
||||
|
||||
if( sflag ) FREE( src );
|
||||
if( dflag ) FREE( data );
|
||||
|
||||
DB_PRINT( "str", ("Result [%s]", t) );
|
||||
DB_RETURN( t );
|
||||
}
|
||||
|
||||
|
||||
|
||||
PUBLIC char *
|
||||
_strapp( src1, src2 )/*
|
||||
=======================
|
||||
Append two strings together, and return the result with a space between
|
||||
the two strings. FREE the first string if it is not NIL and always
|
||||
leave the second string be. */
|
||||
char *src1;
|
||||
char *src2;
|
||||
{
|
||||
src2 = _stradd( src1, src2, FALSE );
|
||||
if( src1 != NIL(char) ) FREE( src1 );
|
||||
return( src2 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef DBUG
|
||||
#ifdef _strdup
|
||||
#undef _strdup
|
||||
#endif
|
||||
#endif
|
||||
PUBLIC char *
|
||||
_strdup( str )/*
|
||||
================ Duplicate the contents of a string, by using malloc */
|
||||
char *str;
|
||||
{
|
||||
char *t;
|
||||
|
||||
if( str == NIL(char) ) return( NIL(char) );
|
||||
|
||||
if( (t = MALLOC( strlen( str )+1, char )) == NIL(char) ) No_ram();
|
||||
strcpy( t, str );
|
||||
|
||||
return( t );
|
||||
}
|
||||
|
||||
|
||||
|
||||
PUBLIC char *
|
||||
_strdup2( str )/*
|
||||
=================
|
||||
This function is used solely to properly quote command line arguments when
|
||||
they are reinserted int MAKEMACROS so that they can be used further in
|
||||
a processing line. */
|
||||
char *str;
|
||||
{
|
||||
char *t;
|
||||
size_t size;
|
||||
size_t alloced;
|
||||
char *tmp;
|
||||
char *dest;
|
||||
int seen_equal = 0;
|
||||
|
||||
if(str == NIL(char)) return(NIL(char));
|
||||
size = strlen(str) + 1;
|
||||
alloced = size + 2; /* for two quotes */
|
||||
|
||||
for(tmp = str; *tmp; tmp++)
|
||||
if(*tmp == '"')
|
||||
alloced++;
|
||||
|
||||
if((t = MALLOC(alloced, char)) == NIL(char)) No_ram();
|
||||
|
||||
for(tmp = str, dest = t; *tmp; tmp++, dest++) {
|
||||
if(*tmp == '=' && !seen_equal) {
|
||||
seen_equal = 1;
|
||||
*dest++ = *tmp;
|
||||
*dest = '"';
|
||||
continue;
|
||||
}
|
||||
if(*tmp == '"')
|
||||
*dest++ = '\\';
|
||||
*dest = *tmp;
|
||||
}
|
||||
|
||||
if(!seen_equal)
|
||||
Fatal("_strdup2 invoked without argument of form x=y\n");
|
||||
|
||||
*dest++ = '"';
|
||||
*dest = 0;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PUBLIC char *
|
||||
_strpbrk( s1, s2 )/*
|
||||
====================
|
||||
find first occurence of char in s2 in string s1.
|
||||
Returns a pointer to the first occurrence. NOTE '\0' is considered part
|
||||
of s2 and a pointer to it is returned if no other chars match. */
|
||||
|
||||
char *s1;
|
||||
char *s2;
|
||||
{
|
||||
register char *t;
|
||||
|
||||
if( s1 == NIL(char) || s2 == NIL(char) ) return( "" );
|
||||
|
||||
for( t=s1; *t && (strchr( s2, *t ) == NIL(char)); t++ );
|
||||
return( t );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PUBLIC char *
|
||||
_strspn( s1, s2 )/*
|
||||
===================
|
||||
return pointer to first char in s1 that does not belong to s2.
|
||||
Returns the pointer if match found, else returns pointer to null char
|
||||
in s1. (ie. "" ) */
|
||||
|
||||
char *s1;
|
||||
char *s2;
|
||||
{
|
||||
register char *t;
|
||||
|
||||
if( s1 == NIL(char) || s2 == NIL(char) ) return( "" );
|
||||
|
||||
for( t=s1; *t && (strchr( s2, *t ) != NIL(char)); t++ );
|
||||
return( t );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PUBLIC char *
|
||||
_strstr( s1, s2 )/*
|
||||
================== find first occurrence in s1 of s2 */
|
||||
char *s1;
|
||||
char *s2;
|
||||
{
|
||||
register char *s;
|
||||
register char *p;
|
||||
register char *r;
|
||||
|
||||
if( s1 != NIL(char) && s2 != NIL(char) )
|
||||
for( s=s1; *s; s++ )
|
||||
if( *s == *s2 )
|
||||
{
|
||||
for( r=s+1, p = s2+1; *p && (*r == *p); r++, p++ );
|
||||
if( !*p ) return( s );
|
||||
}
|
||||
|
||||
return( NIL(char) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
PUBLIC char *
|
||||
_substr( s, e )/*
|
||||
=================
|
||||
Return the string between the two pointers s and e, not including the
|
||||
char that e points to. NOTE: This routine assumes that s and e point
|
||||
into the same string. */
|
||||
|
||||
char *s;
|
||||
char *e;
|
||||
{
|
||||
char save;
|
||||
int len = e-s;
|
||||
|
||||
if( len < 0 || len > strlen(s) )
|
||||
Fatal( "Internal Error: _substr fails consistency test" );
|
||||
|
||||
save = *e;
|
||||
*e = '\0';
|
||||
s = _strdup( s );
|
||||
*e = save;
|
||||
|
||||
return( s );
|
||||
}
|
921
dmake/expand.c
Normal file
921
dmake/expand.c
Normal file
@ -0,0 +1,921 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/expand.c,v 1.1 1992/01/24 03:27:03 dvadura Exp $
|
||||
-- SYNOPSIS -- macro expansion code.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
--
|
||||
-- This routine handles all the necessary junk that deals with macro
|
||||
-- expansion. It understands the following syntax. If a macro is
|
||||
-- not defined it expands to NULL, and {} are synonyms for ().
|
||||
--
|
||||
-- $$ - expands to $
|
||||
-- {{ - expands to {
|
||||
-- }} - expands to }
|
||||
-- $A - expands to whatever the macro A is defined as
|
||||
-- $(AA) - expands to whatever the macro AA is defined as
|
||||
-- $($(A)) - represents macro indirection
|
||||
-- <+...+> - get mapped to $(mktmp ...)
|
||||
--
|
||||
-- following macro is recognized
|
||||
--
|
||||
-- string1{ token_list }string2
|
||||
--
|
||||
-- and expands to string1 prepended to each element of token_list and
|
||||
-- string2 appended to each of the resulting tokens from the first
|
||||
-- operation. If string2 is of the form above then the result is
|
||||
-- the cross product of the specified (possibly modified) token_lists.
|
||||
--
|
||||
-- The folowing macro modifiers are defined and expanded:
|
||||
--
|
||||
-- $(macro:modifier_list:modifier_list:...)
|
||||
--
|
||||
-- where modifier_list a combination of:
|
||||
--
|
||||
-- D or d - Directory portion of token including separator
|
||||
-- F or f - File portion of token including suffix
|
||||
-- B or b - basename portion of token not including suffix
|
||||
-- T or t - for tokenization
|
||||
--
|
||||
-- or a single
|
||||
-- S or s - pattern substitution (simple)
|
||||
--
|
||||
-- NOTE: Modifiers are applied once the macro value has been found.
|
||||
-- Thus the construct $($(test):s/joe/mary/) is defined and
|
||||
-- modifies the value of $($(test))
|
||||
--
|
||||
-- Also the construct $(m:d:f) is not the same as $(m:df)
|
||||
-- the first applies d to the value of $(m) and then
|
||||
-- applies f to the value of that whereas the second form
|
||||
-- applies df to the value of $(m).
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: expand.c,v $
|
||||
* Revision 1.1 1992/01/24 03:27:03 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
/* Microsoft BRAINDAMAGE ALERT!!!!
|
||||
* This #ifdef is here only to satisfy stupid bugs in MSC5.0 and MSC5.1
|
||||
* it isn't needed for anything else. It turns loop optimization off. */
|
||||
#if defined(_MSC_VER)
|
||||
#include "optoff.h"
|
||||
#endif
|
||||
|
||||
static char* _scan_token ANSI((char*, char**));
|
||||
static char* _scan_macro ANSI((char*, char**));
|
||||
static char* _scan_brace ANSI((char*, char**, int*));
|
||||
static char* _cross_prod ANSI((char*, char*));
|
||||
|
||||
|
||||
PUBLIC char *
|
||||
Expand( src )/*
|
||||
===============
|
||||
This is the driver routine for the expansion, it identifies non-white
|
||||
space tokens and gets the _scan_token routine to figure out if they should
|
||||
be treated in a special way. */
|
||||
|
||||
char *src; /* pointer to source string */
|
||||
{
|
||||
char *tmp; /* pointer to temporary str */
|
||||
char *res; /* pointer to result string */
|
||||
char *start; /* pointer to start of token */
|
||||
|
||||
DB_ENTER( "Expand" );
|
||||
DB_PRINT( "exp", ("Expanding [%s]", src) );
|
||||
|
||||
res = _strdup( "" );
|
||||
if( src == NIL(char) ) DB_RETURN( res );
|
||||
|
||||
while( *src ) {
|
||||
char *ks, *ke;
|
||||
|
||||
/* Here we find the next non white space token in the string
|
||||
* and find it's end, with respect to non-significant white space. */
|
||||
|
||||
start = _strspn( src, " \t\n" );
|
||||
res = _strjoin( res, src, start-src, TRUE );
|
||||
if( !(*start) ) break;
|
||||
|
||||
/* START <+...+> KLUDGE */
|
||||
if( (ks=_strstr(start,"<+")) && (ke=_strstr(ks,"+>")) ){
|
||||
char *t1, *t2;
|
||||
|
||||
res = _strjoin( res, t2=Expand(t1=_substr(start,ks)), -1, TRUE);
|
||||
FREE(t1); FREE(t2);
|
||||
|
||||
t1 = _substr(ks+2, ke+1); t1[ke-ks-2] = ')';
|
||||
t2 = _strjoin( "$(mktmp ", t1, -1,FALSE);
|
||||
FREE(t1);
|
||||
res = _strjoin( res, t2=Expand(t2), -1, TRUE);
|
||||
FREE(t2);
|
||||
src = ke+2;
|
||||
}
|
||||
/* END <+...+> KLUDGE */
|
||||
else {
|
||||
res = _strjoin( res, tmp = _scan_token( start, &src ), -1, TRUE );
|
||||
FREE( tmp );
|
||||
}
|
||||
}
|
||||
|
||||
DB_PRINT( "exp", ("Returning [%s]", res) );
|
||||
DB_RETURN( res );
|
||||
}
|
||||
|
||||
|
||||
PUBLIC char *
|
||||
Apply_edit( src, pat, subst, fr, anchor )/*
|
||||
===========================================
|
||||
Take the src string and apply the pattern substitution. ie. look for
|
||||
occurrences of pat in src and replace each occurrence with subst. This is
|
||||
NOT a regular expressions pattern substitution, it's just not worth it.
|
||||
|
||||
if anchor == TRUE then the src pattern match must be at the end of a token.
|
||||
ie. this is for SYSV compatibility and is only used for substitutions of
|
||||
the caused by $(macro:pat=sub). So if src = "fre.o.k june.o" then
|
||||
$(src:.o=.a) results in "fre.o.k june.a", and $(src:s/.o/.a) results in
|
||||
"fre.a.k june.a" */
|
||||
|
||||
char *src; /* the source string */
|
||||
char *pat; /* pattern to find */
|
||||
char *subst; /* substitute string */
|
||||
int fr; /* if TRUE free src */
|
||||
int anchor; /* if TRUE anchor */
|
||||
{
|
||||
char *res;
|
||||
char *p;
|
||||
char *s;
|
||||
int l;
|
||||
|
||||
DB_ENTER( "Apply_edit" );
|
||||
|
||||
if( !*pat ) DB_RETURN( src ); /* do nothing if pat is NULL */
|
||||
|
||||
DB_PRINT( "mod", ("Source str: [%s]", src) );
|
||||
DB_PRINT( "mod", ("Replacing [%s], with [%s]", pat, subst) );
|
||||
|
||||
s = src;
|
||||
l = strlen( pat );
|
||||
if( (p = _strstr( s, pat )) != NIL(char) ) {
|
||||
res = _strdup( "" );
|
||||
do {
|
||||
if( anchor )
|
||||
if( !*(p+l) || (strchr(" \t", *(p+l)) != NIL(char)) )
|
||||
res = _strjoin( _strjoin( res, s, p-s, TRUE ), subst, -1, TRUE );
|
||||
else
|
||||
res = _strjoin( res, s, p+l-s, TRUE );
|
||||
else
|
||||
res = _strjoin( _strjoin( res, s, p-s, TRUE ), subst, -1, TRUE );
|
||||
|
||||
s = p + l;
|
||||
}
|
||||
while( (p = _strstr( s, pat )) != NIL(char) );
|
||||
|
||||
res = _strjoin( res, s, -1, TRUE );
|
||||
if( fr ) FREE( src );
|
||||
}
|
||||
else
|
||||
res = src;
|
||||
|
||||
|
||||
DB_PRINT( "mod", ("Result [%s]", res) );
|
||||
DB_RETURN( res );
|
||||
}
|
||||
|
||||
|
||||
PUBLIC void
|
||||
Map_esc( tok )/*
|
||||
================
|
||||
Map an escape sequence and replace it by it's corresponding character
|
||||
value. It is assumed that tok points at the initial \, the esc
|
||||
sequence in the original string is replaced and the value of tok
|
||||
is not modified. */
|
||||
char *tok;
|
||||
{
|
||||
if( strchr( "\"\\vantbrf01234567", tok[1] ) ) {
|
||||
switch( tok[1] ) {
|
||||
case 'a' : *tok = 0x07; break;
|
||||
case 'b' : *tok = '\b'; break;
|
||||
case 'f' : *tok = '\f'; break;
|
||||
case 'n' : *tok = '\n'; break;
|
||||
case 'r' : *tok = '\r'; break;
|
||||
case 't' : *tok = '\t'; break;
|
||||
case 'v' : *tok = 0x0b; break;
|
||||
case '\\': *tok = '\\'; break;
|
||||
case '\"': *tok = '\"'; break;
|
||||
|
||||
default: {
|
||||
register int i = 0;
|
||||
register int j = 0;
|
||||
for( ; i<2 && isdigit(tok[2]); i++ ) {
|
||||
j = (j << 3) + (tok[1] - '0');
|
||||
strcpy( tok+1, tok+2 );
|
||||
}
|
||||
j = (j << 3) + (tok[1] - '0');
|
||||
*tok = j;
|
||||
}
|
||||
}
|
||||
strcpy( tok+1, tok+2 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PUBLIC char*
|
||||
Apply_modifiers( mod, src )/*
|
||||
=============================
|
||||
This routine applies the appropriate modifiers to the string src
|
||||
and returns the proper result string */
|
||||
|
||||
int mod;
|
||||
char *src;
|
||||
{
|
||||
char *s;
|
||||
char *e;
|
||||
TKSTR str;
|
||||
|
||||
DB_ENTER( "Apply_modifiers" );
|
||||
|
||||
if( mod == (SUFFIX_FLAG | DIRECTORY_FLAG | FILE_FLAG) )
|
||||
DB_RETURN( src );
|
||||
|
||||
SET_TOKEN( &str, src );
|
||||
DB_PRINT( "mod", ("Source string [%s]", src) );
|
||||
|
||||
while( *(s = Get_token( &str, "", FALSE )) != '\0' ) {
|
||||
/* search for the directory portion of the filename. If the
|
||||
* DIRECTORY_FLAG is set, then we want to keep the directory portion
|
||||
* othewise throw it away and blank out to the end of the token */
|
||||
|
||||
if( (e = basename(s)) != s)
|
||||
if( !(mod & DIRECTORY_FLAG) ) {
|
||||
strcpy(s, e);
|
||||
e = s+(str.tk_str-e);
|
||||
for(; e != str.tk_str; e++)
|
||||
*e = ' ';
|
||||
}
|
||||
else
|
||||
s = e;
|
||||
|
||||
/* search for the suffix, if there is none, treat it as a NULL suffix.
|
||||
* if no file name treat it as a NULL file name. same copy op as
|
||||
* for directory case above */
|
||||
|
||||
e = strrchr( s, '.' ); /* NULL suffix if e=0 */
|
||||
if( e == NIL(char) ) e = s+strlen(s);
|
||||
|
||||
if( !(mod & FILE_FLAG) ) {
|
||||
strcpy( s, e );
|
||||
e = s+(str.tk_str-e);
|
||||
for( ; e != str.tk_str; e++ ) *e = ' ';
|
||||
}
|
||||
else
|
||||
s = e;
|
||||
|
||||
/* The last and final part. This is the suffix case, if we don't want
|
||||
* it then just erase to the end of the token. */
|
||||
|
||||
if( s != NIL(char) )
|
||||
if( !(mod & SUFFIX_FLAG) )
|
||||
for( ; s != str.tk_str; s++ ) *s = ' ';
|
||||
}
|
||||
|
||||
/* delete the extra white space, it looks ugly */
|
||||
for( s = src, e = NIL(char); *s; s++ )
|
||||
if( *s == ' ' || *s == '\t' || *s == '\n' ) {
|
||||
if( e == NIL(char) )
|
||||
e = s;
|
||||
}
|
||||
else {
|
||||
if( e != NIL(char) ) {
|
||||
if( e+1 < s ) {
|
||||
strcpy( e+1, s );
|
||||
s = e+1;
|
||||
*e = ' ';
|
||||
}
|
||||
e = NIL(char);
|
||||
}
|
||||
}
|
||||
|
||||
if( e != NIL(char) )
|
||||
if( e < s )
|
||||
strcpy( e, s );
|
||||
|
||||
DB_PRINT( "mod", ("Result string [%s]", src) );
|
||||
DB_RETURN( src );
|
||||
}
|
||||
|
||||
|
||||
PUBLIC char*
|
||||
Tokenize( src, separator )/*
|
||||
============================
|
||||
Tokenize the input of src and join each token found together with
|
||||
the next token separated by the separator string.
|
||||
|
||||
When doing the tokenization, <sp>, <tab>, <nl>, and \<nl> all
|
||||
constitute white space. */
|
||||
|
||||
char *src;
|
||||
char *separator;
|
||||
{
|
||||
TKSTR tokens;
|
||||
char *tok;
|
||||
char *res;
|
||||
int first = TRUE;
|
||||
|
||||
DB_ENTER( "Tokenize" );
|
||||
|
||||
SET_TOKEN( &tokens, src );
|
||||
|
||||
|
||||
/* map the escape codes in the separator string first */
|
||||
|
||||
for(tok=separator; (tok = strchr(tok,ESCAPE_CHAR)) != NIL(char); tok++)
|
||||
Map_esc( tok );
|
||||
|
||||
DB_PRINT( "exp", ("Separator [%s]", separator) );
|
||||
|
||||
/* Build the token list */
|
||||
res = _strdup( "" );
|
||||
while( *(tok = Get_token( &tokens, "", FALSE )) != '\0' ) {
|
||||
DB_PRINT( "exp", ("Tokenizing [%s]", tok) );
|
||||
|
||||
if( first ) {
|
||||
FREE( res );
|
||||
res = _strdup( tok );
|
||||
first = FALSE;
|
||||
}
|
||||
else {
|
||||
char *x;
|
||||
res = _strjoin(res, x =_strjoin(separator, tok, -1, FALSE), -1, TRUE);
|
||||
FREE( x );
|
||||
}
|
||||
}
|
||||
|
||||
FREE( src );
|
||||
DB_RETURN( res );
|
||||
}
|
||||
|
||||
|
||||
static char*
|
||||
_scan_token( s, ps )/*
|
||||
======================
|
||||
This routine scans the token characters one at a time and identifies
|
||||
macros starting with $( and ${ and calls _scan_macro to expand their
|
||||
value. the string1{ token_list }string2 expansion is also handled.
|
||||
In this case a temporary result is maintained so that we can take it's
|
||||
cross product with any other token_lists that may possibly appear. */
|
||||
|
||||
char *s; /* pointer to start of src string */
|
||||
char **ps; /* pointer to start pointer */
|
||||
{
|
||||
char *res; /* pointer to result */
|
||||
char *start; /* pointer to start of prefix */
|
||||
int crossproduct = 0; /* if 1 then computing X-prod */
|
||||
|
||||
start = s;
|
||||
res = _strdup( "" );
|
||||
while( 1 )
|
||||
switch( *s ) {
|
||||
/* Termination, We halt at seeing a space or a tab or end of string.
|
||||
* We return the value of the result with any new macro's we scanned
|
||||
* or if we were computing cross_products then we return the new
|
||||
* cross_product.
|
||||
* NOTE: Once we start computing cross products it is impossible to
|
||||
* stop. ie. the semantics are such that once a {} pair is
|
||||
* seen we compute cross products until termination. */
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
case '\0':
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
*ps = s;
|
||||
if( !crossproduct )
|
||||
tmp = _strjoin( res, start, (s-start), TRUE );
|
||||
else
|
||||
{
|
||||
tmp = _substr( start, s );
|
||||
tmp = _cross_prod( res, tmp );
|
||||
}
|
||||
return( tmp );
|
||||
}
|
||||
|
||||
case '$':
|
||||
case '{':
|
||||
{
|
||||
/* Handle if it's a macro or if it's a {} construct.
|
||||
* The results of a macro expansion are handled differently based
|
||||
* on whether we have seen a {} beforehand. */
|
||||
|
||||
char *tmp;
|
||||
tmp = _substr( start, s ); /* save the prefix */
|
||||
|
||||
if( *s == '$' ) {
|
||||
start = _scan_macro( s+1, &s );
|
||||
|
||||
if( crossproduct )
|
||||
res = _cross_prod( res, _strjoin( tmp, start, -1, TRUE ) );
|
||||
else {
|
||||
res = _strjoin(res,tmp = _strjoin(tmp,start,-1,TRUE),-1,TRUE);
|
||||
FREE( tmp );
|
||||
}
|
||||
FREE( start );
|
||||
}
|
||||
else if( strchr("{ \t",s[1]) == NIL(char) ){
|
||||
int ok;
|
||||
start = _scan_brace( s+1, &s, &ok );
|
||||
|
||||
if( ok ) {
|
||||
res = _cross_prod( res, _cross_prod(tmp, start) );
|
||||
crossproduct = TRUE;
|
||||
}
|
||||
else {
|
||||
res =_strjoin(res,tmp=_strjoin(tmp,start,-1,TRUE),-1,TRUE);
|
||||
FREE( start );
|
||||
FREE( tmp );
|
||||
}
|
||||
}
|
||||
else { /* handle the {{ case */
|
||||
res = _strjoin( res, start, (s-start+1), TRUE );
|
||||
s += (s[1]=='{')?2:1;
|
||||
FREE( tmp );
|
||||
}
|
||||
|
||||
start = s;
|
||||
}
|
||||
break;
|
||||
|
||||
case '}':
|
||||
if( s[1] != '}' ) {
|
||||
/* error malformed macro expansion */
|
||||
s++;
|
||||
}
|
||||
else { /* handle the }} case */
|
||||
res = _strjoin( res, start, (s-start+1), TRUE );
|
||||
s += 2;
|
||||
start = s;
|
||||
}
|
||||
break;
|
||||
|
||||
default: s++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static char*
|
||||
_scan_macro( s, ps )/*
|
||||
======================
|
||||
This routine scans a macro use and expands it to the value. It
|
||||
returns the macro's expanded value and modifies the pointer into the
|
||||
src string to point at the first character after the macro use.
|
||||
The types of uses recognized are:
|
||||
|
||||
$$ - expands to $
|
||||
$(name) - expands to value of name
|
||||
${name} - same as above
|
||||
$($(name)) - recurses on macro names (any level)
|
||||
and
|
||||
$(func[,args ...] [data])
|
||||
and
|
||||
$(name:modifier_list:modifier_list:...)
|
||||
|
||||
see comment for Expand for description of valid modifiers.
|
||||
|
||||
NOTE that once a macro name bounded by ( or { is found only
|
||||
the appropriate terminator (ie. ( or } is searched for. */
|
||||
|
||||
char *s; /* pointer to start of src string */
|
||||
char **ps; /* pointer to start pointer */
|
||||
{
|
||||
char sdelim; /* start of macro delimiter */
|
||||
char edelim; /* corresponding end macro delim */
|
||||
char *start; /* start of prefix */
|
||||
char *macro_name; /* temporary macro name */
|
||||
char *recurse_name; /* recursive macro name */
|
||||
char *result; /* result for macro expansion */
|
||||
int bflag = 0; /* brace flag, ==0 => $A type macro */
|
||||
int done = 0; /* != 0 => done macro search */
|
||||
int lev = 0; /* brace level */
|
||||
int mflag = 0; /* != 0 => modifiers present in mac */
|
||||
int fflag = 0; /* != 0 => GNU style function */
|
||||
HASHPTR hp; /* hash table pointer for macros */
|
||||
|
||||
DB_ENTER( "_scan_macro" );
|
||||
|
||||
/* Check for the simple $ at end of line case */
|
||||
if( !*s ) {
|
||||
*ps = s;
|
||||
DB_RETURN( _strdup("") );
|
||||
}
|
||||
|
||||
if( *s == '$' ) { /* Take care of the simple $$ case. */
|
||||
*ps = s+1;
|
||||
DB_RETURN( _strdup("$") );
|
||||
}
|
||||
|
||||
sdelim = *s; /* set and remember start/end delim */
|
||||
if( sdelim == '(' )
|
||||
edelim = ')';
|
||||
else
|
||||
edelim = '}';
|
||||
|
||||
start = s; /* build up macro name, find its end*/
|
||||
while( !done ) {
|
||||
switch( *s ) {
|
||||
case '(': /* open macro brace */
|
||||
case '{':
|
||||
if( *s == sdelim ) {
|
||||
lev++;
|
||||
bflag++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ':': /* halt at modifier */
|
||||
if( lev == 1 ) {
|
||||
done = TRUE;
|
||||
mflag = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
fflag = 1;
|
||||
break;
|
||||
|
||||
case '\0': /* check for null */
|
||||
*ps = s;
|
||||
if( lev ) {
|
||||
done = TRUE;
|
||||
bflag = 0;
|
||||
s = start;
|
||||
}
|
||||
break;
|
||||
|
||||
case ')': /* close macro brace */
|
||||
case '}':
|
||||
if( *s == edelim && lev ) --lev;
|
||||
/*FALLTHROUGH*/
|
||||
|
||||
default:
|
||||
done = !lev;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
||||
/* Check if this is a $A type macro. If so then we have to
|
||||
* handle it a little differently. */
|
||||
if( bflag )
|
||||
macro_name = _substr( start+1, s-1 );
|
||||
else
|
||||
macro_name = _substr( start, s );
|
||||
|
||||
/* Check to see if the macro name contains spaces, if so then treat it
|
||||
* as a GNU style function invocation and call the function mapper to
|
||||
* deal with it. */
|
||||
if( fflag )
|
||||
result = Exec_function(macro_name);
|
||||
else {
|
||||
/* Check if the macro is a recursive macro name, if so then
|
||||
* EXPAND the name before expanding the value */
|
||||
if( strchr( macro_name, '$' ) != NIL(char) ) {
|
||||
recurse_name = Expand( macro_name );
|
||||
FREE( macro_name );
|
||||
macro_name = recurse_name;
|
||||
}
|
||||
|
||||
/* Code to do value expansion goes here, NOTE: macros whose assign bit
|
||||
is one have been evaluated and assigned, they contain no further
|
||||
expansions and thus do not need their values expanded again. */
|
||||
|
||||
if( (hp = GET_MACRO( macro_name )) != NIL(HASH) ) {
|
||||
if( hp->ht_flag & M_MARK )
|
||||
Fatal( "Detected circular macro [%s]", hp->ht_name );
|
||||
|
||||
/* for M_MULTI macro variable assignments */
|
||||
If_multi = hp->ht_flag & M_MULTI;
|
||||
|
||||
if( !(hp->ht_flag & M_EXPANDED) ) {
|
||||
hp->ht_flag |= M_MARK;
|
||||
result = Expand( hp->ht_value );
|
||||
hp->ht_flag ^= M_MARK;
|
||||
}
|
||||
else if( hp->ht_value != NIL(char) )
|
||||
result = _strdup( hp->ht_value );
|
||||
else
|
||||
result = _strdup( "" );
|
||||
|
||||
/*
|
||||
* Mark macros as used only if we are not expanding them for
|
||||
* the purpose of a .IF test, so we can warn about redef after use*/
|
||||
|
||||
if( !If_expand ) hp->ht_flag |= M_USED;
|
||||
}
|
||||
else
|
||||
result = _strdup( "" );
|
||||
}
|
||||
|
||||
if( mflag ) {
|
||||
char separator;
|
||||
int modifier_list = 0;
|
||||
int aug_mod = FALSE;
|
||||
char *pat1;
|
||||
char *pat2;
|
||||
char *p;
|
||||
|
||||
/* Yet another brain damaged AUGMAKE kludge. We should accept the
|
||||
* AUGMAKE bullshit of $(f:pat=sub) form of macro expansion. In
|
||||
* order to do this we will forgo the normal processing if the
|
||||
* AUGMAKE solution pans out, otherwise we will try to process the
|
||||
* modifiers ala dmake.
|
||||
*
|
||||
* So we look for = in modifier string.
|
||||
* If found we process it and not do the normal stuff */
|
||||
|
||||
for( p=s; *p && *p != '=' && *p != edelim; p++ );
|
||||
|
||||
if( *p == '=' ) {
|
||||
pat1 = _substr( s, p );
|
||||
for( s=p=p+1; (*p != edelim); p++ );
|
||||
|
||||
pat2 = _substr( s, p );
|
||||
|
||||
if( !Augmake ) {
|
||||
char *tmp = pat2;
|
||||
pat2 = Expand(pat2);
|
||||
FREE(tmp);
|
||||
}
|
||||
|
||||
result = Apply_edit( result, pat1, pat2, TRUE, TRUE );
|
||||
FREE( pat1 );
|
||||
FREE( pat2 );
|
||||
s = p;
|
||||
aug_mod = TRUE;
|
||||
}
|
||||
|
||||
if( !aug_mod )
|
||||
while( *s && *s != edelim ) { /* while not at end of macro */
|
||||
switch( *s++ ) {
|
||||
case 'b':
|
||||
case 'B': modifier_list |= FILE_FLAG; break;
|
||||
|
||||
case 'd':
|
||||
case 'D': modifier_list |= DIRECTORY_FLAG; break;
|
||||
|
||||
case 'f':
|
||||
case 'F': modifier_list |= FILE_FLAG | SUFFIX_FLAG; break;
|
||||
|
||||
case 'S':
|
||||
case 's':
|
||||
if( modifier_list ) {
|
||||
Warning( "Edit modifier must appear alone, ignored");
|
||||
modifier_list = 0;
|
||||
}
|
||||
else {
|
||||
separator = *s++;
|
||||
for( p=s; *p != separator && *p != edelim; p++ );
|
||||
|
||||
if( *p == edelim )
|
||||
Warning("Syntax error in edit pattern, ignored");
|
||||
else {
|
||||
char *t1, *t2;
|
||||
pat1 = _substr( s, p );
|
||||
for(s=p=p+1; (*p != separator) && (*p != edelim); p++ );
|
||||
pat2 = _substr( s, p );
|
||||
t1 = Expand(pat1); FREE(pat1);
|
||||
t2 = Expand(pat2); FREE(pat2);
|
||||
result = Apply_edit( result, t1, t2, TRUE, FALSE );
|
||||
FREE( t1 );
|
||||
FREE( t2 );
|
||||
}
|
||||
s = p;
|
||||
}
|
||||
/* find the end of the macro spec, or the start of a new
|
||||
* modifier list for further processing of the result */
|
||||
|
||||
for( ; (*s != edelim) && (*s != ':'); s++ );
|
||||
if( *s == ':' ) s++;
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
case 't':
|
||||
if( modifier_list ) {
|
||||
Warning( "Tokenize modifier must appear alone, ignored");
|
||||
modifier_list = 0;
|
||||
}
|
||||
else {
|
||||
char *msg = "Separator string must be quoted";
|
||||
|
||||
separator = *s++;
|
||||
|
||||
if( separator != '\"' )
|
||||
Warning( msg );
|
||||
else {
|
||||
/* we change the semantics to allow $(v:t")") */
|
||||
for (p = s; *p && *p != separator; p++)
|
||||
if (*p == '\\')
|
||||
if (p[1] == '\\' || p[1] == '"')
|
||||
p++;
|
||||
if( *p == 0 )
|
||||
Fatal( "Unterminated separator string" );
|
||||
else {
|
||||
pat1 = _substr( s, p );
|
||||
result = Tokenize( result, pat1 );
|
||||
FREE( pat1 );
|
||||
}
|
||||
s = p;
|
||||
}
|
||||
|
||||
/* find the end of the macro spec, or the start of a new
|
||||
* modifier list for further processing of the result */
|
||||
|
||||
for( ; (*s != edelim) && (*s != ':'); s++ );
|
||||
if( *s == ':' ) s++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ':':
|
||||
if( modifier_list ) {
|
||||
result = Apply_modifiers( modifier_list, result );
|
||||
modifier_list = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Warning( "Illegal modifier in macro, ignored" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( modifier_list ) /* apply modifier */
|
||||
result = Apply_modifiers( modifier_list, result );
|
||||
|
||||
s++;
|
||||
}
|
||||
|
||||
*ps = s;
|
||||
FREE( macro_name );
|
||||
DB_RETURN( result );
|
||||
}
|
||||
|
||||
|
||||
static char*
|
||||
_scan_brace( s, ps, flag )/*
|
||||
============================
|
||||
This routine scans for { token_list } pairs. It expands the value of
|
||||
token_list by calling Expand on it. Token_list may be anything at all.
|
||||
Note that the routine count's ballanced parentheses. This means you
|
||||
cannot have something like { fred { joe }, if that is what you really
|
||||
need the write it as { fred {{ joe }, flag is set to 1 if all ok
|
||||
and to 0 if the braces were unballanced. */
|
||||
|
||||
char *s;
|
||||
char **ps;
|
||||
int *flag;
|
||||
{
|
||||
char *t;
|
||||
char *start;
|
||||
char *res;
|
||||
int lev = 1;
|
||||
int done = 0;
|
||||
|
||||
DB_ENTER( "_scan_brace" );
|
||||
|
||||
start = s;
|
||||
while( !done )
|
||||
switch( *s++ ) {
|
||||
case '{':
|
||||
if( *s == '{' ) break; /* ignore {{ */
|
||||
lev++;
|
||||
break;
|
||||
|
||||
case '}':
|
||||
if( *s == '}' ) break; /* ignore }} */
|
||||
if( lev )
|
||||
if( --lev == 0 ) done = TRUE;
|
||||
break;
|
||||
|
||||
case '$':
|
||||
if( *s == '{' || *s == '}' ) {
|
||||
if( (t = strchr(s,'}')) != NIL(char) )
|
||||
s = t;
|
||||
s++;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\0':
|
||||
if( lev ) {
|
||||
done = TRUE;
|
||||
s--;
|
||||
/* error malformed macro expansion */
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
start = _substr( start, (lev) ? s : s-1 );
|
||||
|
||||
if( lev ) {
|
||||
/* Braces were not ballanced so just return the string.
|
||||
* Do not expand it. */
|
||||
|
||||
res = _strjoin( "{", start, -1, FALSE );
|
||||
*flag = 0;
|
||||
}
|
||||
else {
|
||||
*flag = 1;
|
||||
res = Expand( start );
|
||||
|
||||
if( (t = _strspn( res, " \t" )) != res ) strcpy( res, t );
|
||||
}
|
||||
|
||||
FREE( start ); /* this is ok! start is assigned a _substr above */
|
||||
*ps = s;
|
||||
|
||||
DB_RETURN( res );
|
||||
}
|
||||
|
||||
|
||||
static char*
|
||||
_cross_prod( x, y )/*
|
||||
=====================
|
||||
Given two strings x and y compute the cross-product of the tokens found
|
||||
in each string. ie. if x = "a b" and y = "c d" return "ac ad bc bd".
|
||||
|
||||
NOTE: buf will continue to grow until it is big enough to handle
|
||||
all cross product requests. It is never freed! (maybe I
|
||||
will fix this someday) */
|
||||
|
||||
char *x;
|
||||
char *y;
|
||||
{
|
||||
static char *buf;
|
||||
static int buf_siz = 0;
|
||||
char *brkx;
|
||||
char *brky;
|
||||
char *cy;
|
||||
char *cx;
|
||||
char *res;
|
||||
int i;
|
||||
|
||||
if( *x && *y ) {
|
||||
res = _strdup( "" ); cx = x;
|
||||
while( *cx ) {
|
||||
cy = y;
|
||||
brkx = _strpbrk( cx, " \t\n" );
|
||||
if( (brkx-cx == 2) && *cx == '\"' && *(cx+1) == '\"' ) cx = brkx;
|
||||
|
||||
while( *cy ) {
|
||||
brky = _strpbrk( cy, " \t\n" );
|
||||
if( (brky-cy == 2) && *cy == '\"' && *(cy+1) == '\"' ) cy = brky;
|
||||
i = brkx-cx + brky-cy + 2;
|
||||
|
||||
if( i > buf_siz ) { /* grow buf to the correct size */
|
||||
if( buf != NIL(char) ) FREE( buf );
|
||||
if( (buf = MALLOC( i, char )) == NIL(char)) No_ram();
|
||||
buf_siz = i;
|
||||
}
|
||||
|
||||
strncpy( buf, cx, (i = brkx-cx) );
|
||||
buf[i] = '\0';
|
||||
if (brky-cy > 0) strncat( buf, cy, brky-cy );
|
||||
buf[i+(brky-cy)] = '\0';
|
||||
strcat( buf, " " );
|
||||
res = _strjoin( res, buf, -1, TRUE );
|
||||
cy = _strspn( brky, " \t\n" );
|
||||
}
|
||||
cx = _strspn( brkx, " \t\n" );
|
||||
}
|
||||
|
||||
FREE( x );
|
||||
res[ strlen(res)-1 ] = '\0';
|
||||
}
|
||||
else
|
||||
res = _strjoin( x, y, -1, TRUE );
|
||||
|
||||
FREE( y );
|
||||
return( res );
|
||||
}
|
78
dmake/extern.h
Normal file
78
dmake/extern.h
Normal file
@ -0,0 +1,78 @@
|
||||
/* RCS -- $Header: /u/dvadura/src/generic/dmake/src/RCS/extern.h,v 1.2 1992/04/07 04:42:46 dvadura Exp $
|
||||
-- SYNOPSIS -- external declarations for dmake functions.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- ANSI is a macro that allows the proper handling of ANSI style
|
||||
-- function declarations.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: extern.h,v $
|
||||
* Revision 1.2 1992/04/07 04:42:46 dvadura
|
||||
* Changed namemax.h to posix.h.
|
||||
*
|
||||
* Revision 1.1 1992/01/24 03:26:52 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EXTERN_h
|
||||
#define EXTERN_h
|
||||
|
||||
/* Define this for the RS/6000 if it breaks something then we have to put a
|
||||
* #ifdef around it. */
|
||||
#if defined(rs6000)
|
||||
#define _POSIX_SOURCE
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#if defined (_MPW)
|
||||
# include <types.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# include <sys/types.h>
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include "itypes.h"
|
||||
#include "stdmacs.h"
|
||||
#include "alloc.h"
|
||||
#include "db.h"
|
||||
#include "dmake.h"
|
||||
#include "struct.h"
|
||||
#include "vextern.h"
|
||||
#include "public.h"
|
||||
|
||||
/* Include this last as it invalidates some functions that are defined
|
||||
* externally above and turns them into no-ops. Have to do this after
|
||||
* the extern declarations however. */
|
||||
#include "config.h"
|
||||
#include "posix.h"
|
||||
|
||||
#endif
|
||||
|
356
dmake/function.c
Normal file
356
dmake/function.c
Normal file
@ -0,0 +1,356 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/function.c,v 1.1 1992/01/24 03:27:00 dvadura Exp $
|
||||
-- SYNOPSIS -- GNU style functions for dmake.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- All GNU stule functions understood by dmake are implemented in this
|
||||
-- file. Currently the only such function is $(mktmp ...) which is
|
||||
-- not part of GNU-make is an extension provided by dmake.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: function.c,v $
|
||||
* Revision 1.1 1992/01/24 03:27:00 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
static char *_exec_mktmp ANSI((char *, char *, char *));
|
||||
static char *_exec_subst ANSI((char *, char *, char *));
|
||||
static char *_exec_iseq ANSI((char *, char *, char *, int));
|
||||
static char *_exec_sort ANSI((char *));
|
||||
static char *_exec_shell ANSI((char *));
|
||||
static int _mystrcmp ANSI((CONST PVOID, CONST PVOID));
|
||||
|
||||
|
||||
PUBLIC char *
|
||||
Exec_function(buf)/*
|
||||
====================
|
||||
Execute the function given by the value of args.
|
||||
|
||||
So far mktmp is the only valid function, anything else elicits and error
|
||||
message. It is my hope to support the GNU style functions in this portion
|
||||
of the code at some time in the future. */
|
||||
char *buf;
|
||||
{
|
||||
char *fname;
|
||||
char *args;
|
||||
char *mod1;
|
||||
char *mod2 = NIL(char);
|
||||
char *res = NIL(char);
|
||||
|
||||
/* This must succeed since the presence of ' ', \t or \n is what
|
||||
* determines if this functions is called in the first place. */
|
||||
fname = _substr(buf, args=_strpbrk(buf," \t\n"));
|
||||
|
||||
if( (mod1 = strchr(fname,',')) != NIL(char) ){
|
||||
*mod1 = '\0';
|
||||
mod1++;
|
||||
|
||||
if( (mod2 = strchr(mod1,',')) != NIL(char) ){
|
||||
*mod2 = '\0';
|
||||
mod2++;
|
||||
}
|
||||
}
|
||||
|
||||
switch( *fname ) {
|
||||
case 'e':
|
||||
if(strncmp(fname,"eq",2) == 0) res = _exec_iseq(mod1,mod2,args,TRUE);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if( strncmp(fname,"mktmp", 5) == 0 ) res = _exec_mktmp(mod1,mod2,args);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if( strncmp(fname,"null", 4) == 0 )
|
||||
res = _exec_iseq(mod1,NIL(char),args,TRUE);
|
||||
break;
|
||||
|
||||
case '!':
|
||||
if(strncmp(fname,"!null",5) == 0)
|
||||
res = _exec_iseq(mod1,NIL(char),args,FALSE);
|
||||
if(strncmp(fname,"!eq",3) == 0) res = _exec_iseq(mod1,mod2,args,FALSE);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if(strncmp(fname,"sort",4) == 0) res = _exec_sort(args);
|
||||
else if(strncmp(fname,"shell",5)==0) res = _exec_shell(args);
|
||||
else if(strncmp(fname,"strip",5)==0) res = Tokenize(Expand(args)," ");
|
||||
else if(strncmp(fname,"subst",5)==0) res = _exec_subst(mod1,mod2,args);
|
||||
break;
|
||||
|
||||
default:
|
||||
Warning( "Function '%s' not implemented at this time", fname );
|
||||
}
|
||||
|
||||
if( res == NIL(char) ) res = _strdup("");
|
||||
|
||||
FREE(fname);
|
||||
return(res);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
_exec_mktmp( file, text, data )
|
||||
char *file;
|
||||
char *text;
|
||||
char *data;
|
||||
{
|
||||
register char *p;
|
||||
char *tmpname;
|
||||
char *name;
|
||||
FILE *tmpfile = NIL(FILE);
|
||||
|
||||
/* This is only a test of the recipe line so prevent the tempfile side
|
||||
* effects. */
|
||||
if( Suppress_temp_file ) return(NIL(char));
|
||||
|
||||
name = Current_target ? Current_target->CE_NAME:"makefile text";
|
||||
|
||||
if( file && *file ) {
|
||||
char *newtmp;
|
||||
|
||||
/* This call to Get_temp sets TMPFILE for subsequent expansion of file.
|
||||
* DO NOT DELETE IT! */
|
||||
Get_temp( &newtmp, "", FALSE ); FREE(newtmp);
|
||||
tmpname = Expand(file);
|
||||
|
||||
if( *tmpname ) {
|
||||
if( (tmpfile = fopen(tmpname, "w")) == NIL(FILE) )
|
||||
Open_temp_error( tmpname, name );
|
||||
|
||||
Def_macro("TMPFILE", tmpname, M_EXPANDED|M_MULTI);
|
||||
Link_temp( Current_target, tmpfile, tmpname );
|
||||
}
|
||||
else
|
||||
FREE(tmpname);
|
||||
}
|
||||
|
||||
if( !tmpfile )
|
||||
tmpfile = Start_temp( "", Current_target, &tmpname );
|
||||
|
||||
if( !text || !*text ) text = tmpname;
|
||||
data = Expand(_strspn(data, " \t\n"));
|
||||
|
||||
for(p=strchr(data,'\n'); p; p=strchr(p,'\n')) {
|
||||
char *q = _strspn(++p," \t");
|
||||
strcpy(p,q);
|
||||
}
|
||||
|
||||
Append_line( data, FALSE, tmpfile, name, FALSE, TRUE );
|
||||
Close_temp( Current_target, tmpfile );
|
||||
FREE(data);
|
||||
|
||||
return( Expand(text) );
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
_exec_iseq( lhs, rhs, data, eq )
|
||||
char *lhs;
|
||||
char *rhs;
|
||||
char *data;
|
||||
int eq;
|
||||
{
|
||||
char *l = Expand(lhs);
|
||||
char *r = Expand(rhs);
|
||||
char *i = _strspn(data, " \t\n");
|
||||
char *e = strchr(i, ' ');
|
||||
char *res = NIL(char);
|
||||
int val = strcmp(l,r);
|
||||
|
||||
if( (!val && eq) || (val && !eq) ) {
|
||||
if( e != NIL(char) ) *e = '\0';
|
||||
res = Expand(i);
|
||||
}
|
||||
else if( e != NIL(char) ) {
|
||||
e = _strspn(e," \t\n");
|
||||
if( *e ) res = Expand(e);
|
||||
}
|
||||
|
||||
FREE(l);
|
||||
FREE(r);
|
||||
return(res);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
_exec_sort( args )
|
||||
char *args;
|
||||
{
|
||||
char *res = NIL(char);
|
||||
char *data = Expand(args);
|
||||
char **tokens = NIL(char *);
|
||||
char *p;
|
||||
char *white = " \t\n";
|
||||
int j;
|
||||
int i = 0;
|
||||
|
||||
for( i=0,p=_strspn(data,white); *p; p=_strspn(_strpbrk(p,white),white),i++);
|
||||
|
||||
if( i != 0 ) {
|
||||
TALLOC(tokens, i, char *);
|
||||
|
||||
for( i=0,p=_strspn(data,white); *p; p=_strspn(p,white),i++){
|
||||
tokens[i] = p;
|
||||
p = _strpbrk(p,white);
|
||||
if( *p ) *p++ = '\0';
|
||||
}
|
||||
|
||||
qsort( tokens, i, sizeof(char *), _mystrcmp );
|
||||
|
||||
for( j=0; j<i; j++ ) res = _strapp(res, tokens[j]);
|
||||
FREE(data);
|
||||
FREE(tokens);
|
||||
}
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_mystrcmp( p, q )
|
||||
CONST PVOID p;
|
||||
CONST PVOID q;
|
||||
{
|
||||
return(strcmp(*((CONST char **)p),*((CONST char **)q)));
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
_exec_subst( pat, subst, data )
|
||||
char *pat;
|
||||
char *subst;
|
||||
char *data;
|
||||
{
|
||||
char *res;
|
||||
|
||||
pat = Expand(pat);
|
||||
subst = Expand(subst);
|
||||
res = Apply_edit( Expand(data), pat, subst, TRUE, FALSE );
|
||||
FREE(pat);
|
||||
FREE(subst);
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
_exec_shell( data )
|
||||
char *data;
|
||||
{
|
||||
extern char *tempnam();
|
||||
static int nestlevel = 0;
|
||||
static int org_out;
|
||||
static int bsize;
|
||||
static char *buffer;
|
||||
static char *tmpnm;
|
||||
static FILE *tmp;
|
||||
|
||||
int wait = Wait_for_completion;
|
||||
uint16 vflag = Verbose;
|
||||
int tflag = Trace;
|
||||
char *res = NIL(char);
|
||||
CELL cell;
|
||||
STRING rcp;
|
||||
HASH cname;
|
||||
|
||||
if( Suppress_temp_file ) return(NIL(char));
|
||||
|
||||
/* Set the temp CELL used for building prerequisite candidates to
|
||||
* all zero so that we don't have to keep initializing all the
|
||||
* fields. */
|
||||
{
|
||||
register char *s = (char *) &cell;
|
||||
register int n = sizeof(CELL);
|
||||
while( n ) { *s++ = '\0'; n--; }
|
||||
}
|
||||
rcp.st_string = _strspn(data, " \t+-%@");
|
||||
rcp.st_attr = Rcp_attribute( data );
|
||||
rcp.st_next = NIL(STRING);
|
||||
cname.ht_name = "Shell escape";
|
||||
cell.ce_name = &cname;
|
||||
cell.ce_fname = cname.ht_name;
|
||||
cell.ce_recipe = &rcp;
|
||||
cell.ce_flag = F_TARGET|F_RULES;
|
||||
cell.ce_attr = A_PHONY|A_SILENT;
|
||||
|
||||
if( nestlevel == 0 ) {
|
||||
tmpnm = tempnam(NIL(char),"mk");
|
||||
org_out = dup(1);
|
||||
|
||||
if( (tmp = fopen(tmpnm, "w+")) == NIL(FILE) )
|
||||
Open_temp_error( tmpnm, cname.ht_name );
|
||||
|
||||
close(1);
|
||||
dup( fileno(tmp) );
|
||||
|
||||
bsize = (Buffer_size < BUFSIZ)?BUFSIZ:Buffer_size;
|
||||
buffer = MALLOC(bsize,char);
|
||||
}
|
||||
|
||||
Wait_for_completion = TRUE;
|
||||
Verbose = V_NONE;
|
||||
Trace = FALSE;
|
||||
nestlevel++;
|
||||
Exec_commands( &cell );
|
||||
nestlevel--;
|
||||
Trace = tflag;
|
||||
Verbose = vflag;
|
||||
Wait_for_completion = wait;
|
||||
|
||||
/* Now we have to read the temporary file, get the tokens and return them
|
||||
* as a string. */
|
||||
rewind(tmp);
|
||||
while( fgets(buffer, bsize, tmp) ) {
|
||||
char *p = strchr(buffer, '\n');
|
||||
|
||||
if( p == NIL(char) )
|
||||
res = _strjoin(res,buffer,-1,TRUE);
|
||||
else {
|
||||
*p = '\0';
|
||||
res = _strapp(res,buffer);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(tmp);
|
||||
if( nestlevel == 0 ) {
|
||||
Remove_file(tmpnm);
|
||||
close(1);
|
||||
dup(org_out);
|
||||
close(org_out);
|
||||
FREE(tmpnm);
|
||||
FREE(buffer);
|
||||
}
|
||||
else {
|
||||
if( (tmp = fopen(tmpnm, "w+")) == NIL(FILE) )
|
||||
Open_temp_error( tmpnm, cname.ht_name );
|
||||
|
||||
close(1);
|
||||
dup( fileno(tmp) );
|
||||
}
|
||||
|
||||
return(res);
|
||||
}
|
531
dmake/getinp.c
Normal file
531
dmake/getinp.c
Normal file
@ -0,0 +1,531 @@
|
||||
/* RCS -- $Header: /u/dvadura/src/generic/dmake/src/RCS/getinp.c,v 1.2 1992/04/07 04:42:46 dvadura Exp $
|
||||
-- SYNOPSIS -- handle reading of input.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- The code in this file reads the input from the specified stream
|
||||
-- into the provided buffer of size Buffer_size. In doing so it deletes
|
||||
-- comments. Comments are delimited by the #, and
|
||||
-- <nl> character sequences. An exception is \# which
|
||||
-- is replaced by # in the input. Line continuations are signalled
|
||||
-- at the end of a line and are recognized inside comments.
|
||||
-- The line continuation is always <\><nl>.
|
||||
--
|
||||
-- If the file to read is NIL(FILE) then the Get_line routine returns the
|
||||
-- next rule from the builtin rule table if there is one.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: getinp.c,v $
|
||||
* Revision 1.2 1992/04/07 04:42:46 dvadura
|
||||
* Minor clean up and a check for -X flag on the execution of #! lines.
|
||||
*
|
||||
* Revision 1.1 1992/01/24 03:27:56 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
#define IS_WHITE(A) ((A == ' ') || (A == '\t') || (A == '\n') || (A == '\r'))
|
||||
#define SCAN_WHITE(A) \
|
||||
while( IS_WHITE(*A) ) A++;
|
||||
|
||||
static int _is_conditional ANSI((char*));
|
||||
static int _handle_conditional ANSI((int, TKSTRPTR));
|
||||
|
||||
static int rule_ind = 0; /* index of rule when reading Rule_tab */
|
||||
static int skip = FALSE; /* if true the skip input */
|
||||
|
||||
|
||||
PUBLIC int
|
||||
Get_line( buf, fil )/*
|
||||
======================
|
||||
Read a line of input from the file stripping
|
||||
off comments. The routine returns TRUE if EOF */
|
||||
char *buf;
|
||||
FILE *fil;
|
||||
{
|
||||
extern char **Rule_tab;
|
||||
register char *p;
|
||||
register char *c;
|
||||
char *q;
|
||||
char *buf_org;
|
||||
static int ignore = FALSE;
|
||||
int cont = FALSE;
|
||||
int pos = 0;
|
||||
int res;
|
||||
|
||||
DB_ENTER( "Get_line" );
|
||||
|
||||
if( fil == NIL(FILE) ) {
|
||||
/* Reading the internal rule table. Set the rule_index to zero.
|
||||
* This way ReadEnvironment works as expected every time. */
|
||||
|
||||
while( (p = Rule_tab[ rule_ind++ ]) != NIL(char) )
|
||||
/* The last test in this if '*p != '~', handles the environment
|
||||
* passing conventions used by MKS to pass arguments. We want to
|
||||
* skip those environment entries. */
|
||||
if( !Readenv || (Readenv && (strchr(p,'=') != NIL(char)) && *p!='~')){
|
||||
strcpy( buf, p );
|
||||
|
||||
DB_PRINT( "io", ("Returning [%s]", buf) );
|
||||
DB_RETURN( FALSE );
|
||||
}
|
||||
|
||||
rule_ind = 0;
|
||||
|
||||
DB_PRINT( "io", ("Done Ruletab") );
|
||||
DB_RETURN( TRUE );
|
||||
}
|
||||
|
||||
buf_org = buf;
|
||||
|
||||
do_again:
|
||||
do {
|
||||
p = buf+pos;
|
||||
if(feof( fil ) || (fgets( p, Buffer_size-pos, fil ) == NIL(char)))
|
||||
DB_RETURN( TRUE );
|
||||
|
||||
Line_number++;
|
||||
|
||||
/* ignore input if ignore flag set and line ends in a continuation
|
||||
character. */
|
||||
q = p+strlen(p)-2;
|
||||
if( q<p ) q=p;
|
||||
|
||||
/* ignore each RETURN at the end of a line before any further
|
||||
* processing */
|
||||
if( q[0] == '\r' && q[1] == '\n' ) {
|
||||
q[0] = '\n';
|
||||
q[1] = '\0';
|
||||
q--;
|
||||
}
|
||||
/* you also have to deal with END_OF_FILE chars to process raw
|
||||
* DOS-Files. Normally they are the last chars in file, but after
|
||||
* working on these file with vi, there is an additional NEWLINE
|
||||
* after the last END_OF_FILE. So if the second last char in the
|
||||
* actual line is END_OF_FILE, you can skip the last char. Then
|
||||
* you can search the line back until you find no more END_OF_FILE
|
||||
* and nuke each you found by string termination. */
|
||||
if( q[0] == '\032' )
|
||||
q--;
|
||||
while( q[1] == '\032' ) {
|
||||
q[1] = '\0';
|
||||
q--;
|
||||
}
|
||||
|
||||
if( ignore ) {
|
||||
if( q[0] != CONTINUATION_CHAR || q[1] != '\n' ) ignore = FALSE;
|
||||
*p = '\0';
|
||||
continue;
|
||||
}
|
||||
|
||||
c = Do_comment(p, &q, Group || (*buf == '\t'));
|
||||
|
||||
/* Does the end of the line end in a continuation sequence? */
|
||||
|
||||
if( (q[0] == CONTINUATION_CHAR) && (q[1] == '\n')) {
|
||||
/* If the continuation was at the end of a comment then ignore the
|
||||
* next input line, (or lines until we get one ending in just <nl>)
|
||||
* else it's a continuation, so build the input line from several
|
||||
* text lines on input. The maximum size of this is governened by
|
||||
* Buffer_size */
|
||||
if( q != p && q[-1] == CONTINUATION_CHAR ) {
|
||||
strcpy( q, q+1 );
|
||||
q--;
|
||||
cont = FALSE;
|
||||
}
|
||||
else if( c != NIL(char) )
|
||||
ignore = TRUE;
|
||||
else
|
||||
cont = TRUE;
|
||||
}
|
||||
else {
|
||||
cont = FALSE;
|
||||
}
|
||||
|
||||
q = ( c == NIL(char) ) ? q+2 : c;
|
||||
pos += q-p;
|
||||
}
|
||||
while( (cont || !*buf) && (pos <= Buffer_size) );
|
||||
|
||||
if( buf[ pos-1 ] == '\n' )
|
||||
buf[ --pos ] = '\0';
|
||||
else
|
||||
if( pos == Buffer_size-1 )
|
||||
Fatal( "Input line too long, increase MAXLINELENGTH" );
|
||||
|
||||
|
||||
/* Now that we have the next line of input to make, we should check to
|
||||
* see if it is a conditional expression. If it is then process it,
|
||||
* otherwise pass it on to the parser. */
|
||||
|
||||
if( *(p = _strspn(buf, " \t\r\n")) == CONDSTART ) {
|
||||
TKSTR token;
|
||||
|
||||
SET_TOKEN( &token, p );
|
||||
|
||||
p = Get_token( &token, "", FALSE );
|
||||
|
||||
if( (res = _is_conditional( p )) ) /* ignore non control special */
|
||||
{ /* targets */
|
||||
res = _handle_conditional( res, &token );
|
||||
skip = TRUE;
|
||||
}
|
||||
else {
|
||||
CLEAR_TOKEN( &token );
|
||||
res = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if( skip ) {
|
||||
buf = buf_org; /* ignore line just read in */
|
||||
pos = 0;
|
||||
skip = res;
|
||||
goto do_again;
|
||||
}
|
||||
|
||||
DB_PRINT( "io", ("Returning [%s]", buf) );
|
||||
DB_RETURN( FALSE );
|
||||
}
|
||||
|
||||
|
||||
PUBLIC char *
|
||||
Do_comment(str, pend, keep)/*
|
||||
=============================
|
||||
Search the input string looking for comment chars. If it contains
|
||||
comment chars then NUKE the remainder of the line, if the comment
|
||||
char is preceeded by \ then shift the remainder of the line left
|
||||
by one char. */
|
||||
char *str;
|
||||
char **pend;
|
||||
int keep;
|
||||
{
|
||||
char *c = str;
|
||||
|
||||
while( (c = strchr(c, COMMENT_CHAR)) != NIL(char) ) {
|
||||
if( Comment || State == NORMAL_SCAN )
|
||||
if( c != str && c[-1] == ESCAPE_CHAR ) {
|
||||
strcpy( c-1, c ); /* copy it left, due to \# */
|
||||
if( pend ) (*pend)--; /* shift tail pointer left */
|
||||
}
|
||||
else {
|
||||
if( !No_exec
|
||||
&& c == str
|
||||
&& c[1] == '!'
|
||||
&& Line_number == 1
|
||||
&& Nestlevel() == 1 ) {
|
||||
char *cmnd;
|
||||
|
||||
cmnd = Expand(c+2);
|
||||
cmnd[strlen(cmnd)-1] = '\0'; /* strip last newline */
|
||||
Current_target = Root;
|
||||
Swap_on_exec = TRUE;
|
||||
Wait_for_completion = TRUE;
|
||||
Do_cmnd(cmnd, FALSE, TRUE, Current_target, FALSE, FALSE, TRUE);
|
||||
}
|
||||
|
||||
*c = '\0'; /* a true comment so break */
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if( keep )
|
||||
c = NIL(char);
|
||||
else
|
||||
*c = '\0';
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(c);
|
||||
}
|
||||
|
||||
|
||||
PUBLIC char *
|
||||
Get_token( string, brk, anchor )/*
|
||||
==================================
|
||||
Return the next token in string.
|
||||
Returns empty string when no more tokens in string.
|
||||
brk is a list of chars that also cause breaks in addition to space and
|
||||
tab, but are themselves returned as tokens. if brk is NULL then the
|
||||
remainder of the line is returned as a single token.
|
||||
|
||||
anchor if 1, says break on chars in the brk list, but only if
|
||||
the entire token begins with the first char of the brk list, if
|
||||
0 then any char of brk will cause a break to occurr.
|
||||
|
||||
If anchor is 2, then break only seeing the first char in the break
|
||||
list allowing only chars in the break list to form the prefix. */
|
||||
|
||||
TKSTRPTR string;
|
||||
char *brk;
|
||||
int anchor;
|
||||
{
|
||||
register char *s;
|
||||
register char *curp;
|
||||
register char *t;
|
||||
int done = FALSE;
|
||||
char space[10];
|
||||
|
||||
DB_ENTER( "Get_token" );
|
||||
|
||||
s = string->tk_str; /* Get string parameters */
|
||||
*s = string->tk_cchar; /* ... and strip leading w/s */
|
||||
|
||||
SCAN_WHITE( s );
|
||||
|
||||
DB_PRINT( "tok", ("What's left [%s]", s) );
|
||||
|
||||
if( !*s ) {
|
||||
DB_PRINT( "tok", ("Returning NULL token") );
|
||||
DB_RETURN( "" );
|
||||
}
|
||||
|
||||
|
||||
/* Build the space list. space contains all those chars that may possibly
|
||||
* cause breaks. This includes the brk list as well as white space. */
|
||||
|
||||
if( brk != NIL(char) ) {
|
||||
strcpy( space, " \t\r\n" );
|
||||
strcat( space, brk );
|
||||
}
|
||||
else {
|
||||
space[0] = 0xff; /* a char we know will not show up */
|
||||
space[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
/* Handle processing of quoted tokens. Note that this is disabled if
|
||||
* brk is equal to NIL */
|
||||
|
||||
while( *s == '\"' && ((brk != NIL(char)) || !string->tk_quote) ) {
|
||||
s++;
|
||||
if( string->tk_quote ) {
|
||||
curp = s-1;
|
||||
do { curp = strchr( curp+1, '\"' ); }
|
||||
while( (curp != NIL(char)) && (*(curp+1) == '\"'));
|
||||
|
||||
if( curp == NIL(char) ) Fatal( "Unmatched quote in token" );
|
||||
string->tk_quote = !string->tk_quote;
|
||||
|
||||
/* Check for "" case, and if found ignore it */
|
||||
if( curp == s ) continue;
|
||||
goto found_token;
|
||||
}
|
||||
else
|
||||
SCAN_WHITE( s );
|
||||
|
||||
string->tk_quote = !string->tk_quote;
|
||||
}
|
||||
|
||||
|
||||
/* Check for a token break character at the beginning of the token.
|
||||
* If found return the next set of break chars as a token. */
|
||||
|
||||
if( anchor == 2 && brk != NIL(char) ) {
|
||||
curp = s;
|
||||
while( *curp && (strchr(brk,*curp)!=NIL(char)) && (*curp!=*brk) ) curp++;
|
||||
done = (*brk == *curp++);
|
||||
}
|
||||
else if( (brk != NIL(char)) && (strchr( brk, *s ) != NIL(char)) ) {
|
||||
curp = _strspn( s, brk );
|
||||
done = (anchor == 0) ? TRUE :
|
||||
((anchor == 1)?(*s == *brk) : (*brk == curp[-1]));
|
||||
}
|
||||
|
||||
|
||||
/* Scan for the next token in the list and return it less the break char
|
||||
* that was used to terminate the token. It will possibly be returned in
|
||||
* the next call to Get_token */
|
||||
|
||||
if( !done ) {
|
||||
SCAN_WHITE( s );
|
||||
|
||||
t = s;
|
||||
do {
|
||||
done = TRUE;
|
||||
curp = _strpbrk(t, space);
|
||||
|
||||
if( anchor && *curp && !IS_WHITE( *curp ) )
|
||||
if( ((anchor == 1)?*curp:_strspn(curp,brk)[-1]) != *brk ) {
|
||||
t++;
|
||||
done = FALSE;
|
||||
}
|
||||
}
|
||||
while( !done );
|
||||
|
||||
if( (curp == s) && (strchr(brk, *curp) != NIL(char)) ) curp++;
|
||||
}
|
||||
|
||||
found_token:
|
||||
string->tk_str = curp;
|
||||
string->tk_cchar = *curp;
|
||||
*curp = '\0';
|
||||
|
||||
DB_PRINT( "tok", ("Returning [%s]", s) );
|
||||
DB_RETURN( s );
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_is_conditional( tg )/*
|
||||
=======================
|
||||
Look at tg and return it's value if it is a conditional identifier
|
||||
otherwise return 0. */
|
||||
char *tg;
|
||||
{
|
||||
DB_ENTER( "_is_conditional" );
|
||||
|
||||
tg++;
|
||||
switch( *tg ) {
|
||||
case 'I': if( !strcmp( tg, "IF" )) DB_RETURN( ST_IF ); break;
|
||||
|
||||
case 'E':
|
||||
if( !strcmp( tg, "END" )) DB_RETURN( ST_END );
|
||||
else if( !strcmp( tg, "ENDIF")) DB_RETURN( ST_END );
|
||||
else if( !strcmp( tg, "ELSE" )) DB_RETURN( ST_ELSE );
|
||||
else if( !strcmp( tg, "ELIF" )) DB_RETURN( ST_ELIF );
|
||||
break;
|
||||
}
|
||||
|
||||
DB_RETURN( 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define SEEN_END 0x00
|
||||
#define SEEN_IF 0x01
|
||||
#define SEEN_ELSE 0x02
|
||||
#define SEEN_ELIF 0x04
|
||||
|
||||
#define ACCEPT_IF 0x10
|
||||
#define ACCEPT_ELIF 0x20
|
||||
|
||||
static int
|
||||
_handle_conditional( opcode, tg )/*
|
||||
===================================
|
||||
Perform the necessary processing for .IF conditinal targets.
|
||||
Someday this should be modified to do bracketted expressions ala
|
||||
CPP... sigh */
|
||||
int opcode;
|
||||
TKSTRPTR tg;
|
||||
{
|
||||
static short action[MAX_COND_DEPTH];
|
||||
static char ifcntl[MAX_COND_DEPTH];
|
||||
char *tok, *lhs, *rhs, *op, *expr;
|
||||
int result;
|
||||
|
||||
DB_ENTER( "_handle_conditional" );
|
||||
|
||||
switch( opcode ) {
|
||||
case ST_ELIF:
|
||||
if( !(ifcntl[Nest_level] & SEEN_IF) || (ifcntl[Nest_level]&SEEN_ELSE) )
|
||||
Fatal(".ELIF without a preceeding .IF" );
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case ST_IF:
|
||||
if( opcode == ST_IF && (Nest_level+1) == MAX_COND_DEPTH )
|
||||
Fatal( ".IF .ELSE ... .END nesting too deep" );
|
||||
|
||||
If_expand = TRUE;
|
||||
expr = Expand( Get_token( tg, NIL(char), FALSE ));
|
||||
If_expand = FALSE;
|
||||
lhs = _strspn( expr, " \t" );
|
||||
if( !*lhs ) lhs = NIL(char);
|
||||
|
||||
if( (op = _strstr( lhs, "==" )) == NIL(char) )
|
||||
op = _strstr( lhs, "!=" );
|
||||
|
||||
if( op == NIL(char) )
|
||||
result = (lhs != NIL(char));
|
||||
else {
|
||||
op[1] = op[0];
|
||||
if( lhs != op ) {
|
||||
for( tok = op-1; (tok != lhs) && ((*tok == ' ')||(*tok == '\t'));
|
||||
tok-- );
|
||||
tok[1] = '\0';
|
||||
}
|
||||
else
|
||||
lhs = NIL(char);
|
||||
|
||||
op++;
|
||||
rhs = _strspn( op+1, " \t" );
|
||||
if( !*rhs ) rhs = NIL(char);
|
||||
|
||||
if( (rhs == NIL(char)) || (lhs == NIL(char)) )
|
||||
result = (rhs == lhs) ? TRUE : FALSE;
|
||||
else {
|
||||
tok = rhs + strlen( rhs );
|
||||
for( tok=tok-1; (tok != lhs) && ((*tok == ' ')||(*tok == '\t'));
|
||||
tok--);
|
||||
tok[1] = '\0';
|
||||
|
||||
result = (strcmp( lhs, rhs ) == 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
if( *op == '!' ) result = !result;
|
||||
}
|
||||
|
||||
if( expr != NIL(char) ) FREE( expr );
|
||||
|
||||
if( opcode == ST_IF ) {
|
||||
Nest_level++;
|
||||
action[Nest_level] = 1;
|
||||
}
|
||||
ifcntl[Nest_level] |= (opcode==ST_IF)?SEEN_IF:SEEN_ELIF;
|
||||
|
||||
if( result ) {
|
||||
if( !(ifcntl[Nest_level] & (ACCEPT_IF|ACCEPT_ELIF)) ) {
|
||||
action[ Nest_level ] = action[ Nest_level-1 ];
|
||||
ifcntl[Nest_level] |= (opcode==ST_IF)?ACCEPT_IF:ACCEPT_ELIF;
|
||||
}
|
||||
else
|
||||
action[Nest_level] = 1;
|
||||
}
|
||||
else
|
||||
action[Nest_level] = 1;
|
||||
break;
|
||||
|
||||
case ST_ELSE:
|
||||
if( Nest_level <= 0 ) Fatal( ".ELSE without .IF" );
|
||||
if( ifcntl[Nest_level] & SEEN_ELSE )
|
||||
Fatal( "Missing .IF or .ELIF before .ELSE" );
|
||||
|
||||
if( ifcntl[Nest_level] & (ACCEPT_IF|ACCEPT_ELIF) )
|
||||
action[Nest_level] = 1;
|
||||
else if( action[ Nest_level-1 ] != 1 )
|
||||
action[ Nest_level ] ^= 0x1; /* flip between 0 and 1 */
|
||||
|
||||
ifcntl[Nest_level] |= SEEN_ELSE;
|
||||
break;
|
||||
|
||||
case ST_END:
|
||||
ifcntl[Nest_level] = SEEN_END;
|
||||
Nest_level--;
|
||||
if( Nest_level < 0 ) Fatal( "Unmatched .END[IF]" );
|
||||
break;
|
||||
}
|
||||
|
||||
DB_RETURN( action[ Nest_level ] );
|
||||
}
|
61
dmake/hash.c
Normal file
61
dmake/hash.c
Normal file
@ -0,0 +1,61 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/hash.c,v 1.1 1992/01/24 03:27:06 dvadura Exp $
|
||||
-- SYNOPSIS -- hashing function for hash tables.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- Hash an identifier. The hashing function works by computing the sum
|
||||
-- of each char and the previous hash value multiplied by 129. Finally the
|
||||
-- length of the identifier is added in. This way the hash depends on the
|
||||
-- chars as well as the length, and appears to be sufficiently unique,
|
||||
-- and is FAST to COMPUTE, unlike the previous hash function...
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: hash.c,v $
|
||||
* Revision 1.1 1992/01/24 03:27:06 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
PUBLIC uint16
|
||||
Hash( id, phv )/*
|
||||
=================
|
||||
This function computes the identifier's hash value and returns the hash
|
||||
value modulo the key size as well as the full hash value. The reason
|
||||
for returning both is so that hash table searches can be sped up. You
|
||||
compare hash keys instead and compare strings only for those whose 32-bit
|
||||
hash keys match. (not many) */
|
||||
|
||||
char *id;
|
||||
uint32 *phv;
|
||||
{
|
||||
register char *p = id;
|
||||
register uint32 hash = (uint32) 0;
|
||||
|
||||
while( *p ) hash = (hash << 7) + hash + (uint32) (*p++);
|
||||
*phv = hash = hash + (uint32) (p-id);
|
||||
|
||||
return( (uint16) (hash % HASH_TABLE_SIZE) );
|
||||
}
|
||||
|
172
dmake/imacs.c
Normal file
172
dmake/imacs.c
Normal file
@ -0,0 +1,172 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/imacs.c,v 1.1 1992/01/24 03:29:55 dvadura Exp $
|
||||
-- SYNOPSIS -- define default internal macros.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- This file adds to the internal macro tables the set of default
|
||||
-- internal macros, and for those that are accessible internally via
|
||||
-- variables creates these variables, and initializes them to point
|
||||
-- at the default values of these macros.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: imacs.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:55 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
static void _set_int_var ANSI((char *, char *, int, int *));
|
||||
static void _set_string_var ANSI((char *, char *, int, char **));
|
||||
static void _set_bit_var ANSI((char *, char *, int));
|
||||
|
||||
/*
|
||||
** Arrange to parse the strings stored in Rules[]
|
||||
*/
|
||||
PUBLIC void
|
||||
Make_rules()
|
||||
{
|
||||
Parse(NIL(FILE));
|
||||
}
|
||||
|
||||
|
||||
#define M_FLAG M_DEFAULT | M_EXPANDED
|
||||
|
||||
/*
|
||||
** Add to the macro table all of the internal macro variables plus
|
||||
** create secondary variables which will give access to their values
|
||||
** easily, both when needed and when the macro value is modified.
|
||||
** The latter is accomplished by providing a flag in the macro and a field
|
||||
** which gives a pointer to the value if it is a char or string macro value
|
||||
** and a mask representing the bit of the global flag register that is affected
|
||||
** by this macro's value.
|
||||
*/
|
||||
PUBLIC void
|
||||
Create_macro_vars()
|
||||
{
|
||||
static char* switchar;
|
||||
char swchar[2];
|
||||
|
||||
swchar[0] = Get_switch_char(), swchar[1] = '\0';
|
||||
_set_string_var("SWITCHAR", swchar, M_PRECIOUS, &switchar);
|
||||
_set_string_var("DIRSEPSTR", (*swchar=='/')?"\\":"/",M_PRECIOUS,&DirSepStr);
|
||||
_set_string_var("DIRBRKSTR", DirBrkStr, M_PRECIOUS, &DirBrkStr);
|
||||
swchar[0] = DEF_ESCAPE_CHAR, swchar[1] = '\0';
|
||||
_set_string_var(".ESCAPE_PREFIX", swchar, M_FLAG, &Escape_char);
|
||||
|
||||
_set_bit_var(".SILENT", "", A_SILENT );
|
||||
_set_bit_var(".IGNORE", "", A_IGNORE );
|
||||
_set_bit_var(".PRECIOUS", "", A_PRECIOUS);
|
||||
_set_bit_var(".EPILOG", "", A_EPILOG );
|
||||
_set_bit_var(".PROLOG", "", A_PROLOG );
|
||||
_set_bit_var(".NOINFER", "", A_NOINFER );
|
||||
_set_bit_var(".SEQUENTIAL","",A_SEQ );
|
||||
_set_bit_var(".USESHELL", "", A_SHELL );
|
||||
_set_bit_var(".SWAP", "", A_SWAP );
|
||||
_set_bit_var(".MKSARGS", "", A_MKSARGS );
|
||||
|
||||
Glob_attr = A_DEFAULT; /* set all flags to NULL */
|
||||
|
||||
_set_string_var("SHELL", "", M_DEFAULT, &Shell );
|
||||
_set_string_var("SHELLFLAGS", " ", M_DEFAULT, &Shell_flags );
|
||||
_set_string_var("GROUPSHELL", "", M_DEFAULT, &GShell );
|
||||
_set_string_var("GROUPFLAGS", " ", M_DEFAULT, &GShell_flags);
|
||||
_set_string_var("SHELLMETAS", "", M_DEFAULT, &Shell_metas );
|
||||
_set_string_var("GROUPSUFFIX", "", M_DEFAULT, &Grp_suff );
|
||||
_set_string_var("PREP", "0", M_DEFAULT, &Prep );
|
||||
_set_string_var("AUGMAKE",NIL(char), M_DEFAULT, &Augmake );
|
||||
_set_string_var(".KEEP_STATE", "", M_DEFAULT, &Keep_state );
|
||||
_set_string_var(".NOTABS", "", M_MULTI, &Notabs );
|
||||
|
||||
_set_string_var(".SETDIR", "", M_DEFAULT|M_NOEXPORT, &Start_dir );
|
||||
_set_string_var("MAKEDIR",Get_current_dir(),M_PRECIOUS|M_NOEXPORT,&Makedir);
|
||||
_set_string_var("PWD", Makedir, M_DEFAULT|M_NOEXPORT, &Pwd);
|
||||
_set_string_var("TMD", "", M_DEFAULT|M_NOEXPORT, &Tmd);
|
||||
|
||||
Def_macro("NULL", "", M_PRECIOUS|M_NOEXPORT|M_FLAG);
|
||||
|
||||
_set_int_var( "MAXLINELENGTH", "0", M_DEFAULT|M_NOEXPORT, &Buffer_size );
|
||||
(void) Def_macro("MAXLINELENGTH", "0", M_FLAG | M_DEFAULT);
|
||||
|
||||
/* set MAXPROCESSLIMIT high initially so that it allows MAXPROCESS to
|
||||
* change from command line. */
|
||||
_set_int_var( "MAXPROCESSLIMIT", "100", M_DEFAULT|M_NOEXPORT, &Max_proclmt );
|
||||
_set_int_var( "MAXPROCESS", "1", M_DEFAULT|M_NOEXPORT, &Max_proc );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Define an integer variable value, and set up the macro.
|
||||
*/
|
||||
static void
|
||||
_set_int_var(name, val, flag, var)
|
||||
char *name;
|
||||
char *val;
|
||||
int flag;
|
||||
int *var;
|
||||
{
|
||||
HASHPTR hp;
|
||||
|
||||
hp = Def_macro(name, val, M_FLAG | flag);
|
||||
hp->ht_flag |= M_VAR_INT | M_MULTI;
|
||||
hp->MV_IVAR = var;
|
||||
*var = atoi(val);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Define a string variables value, and set up the macro.
|
||||
*/
|
||||
static void
|
||||
_set_string_var(name, val, flag, var)
|
||||
char *name;
|
||||
char *val;
|
||||
int flag;
|
||||
char **var;
|
||||
{
|
||||
HASHPTR hp;
|
||||
|
||||
hp = Def_macro(name, val, M_FLAG | flag);
|
||||
hp->ht_flag |= M_VAR_STRING | M_MULTI;
|
||||
hp->MV_SVAR = var;
|
||||
*var = hp->ht_value;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Define a bit variable value, and set up the macro.
|
||||
*/
|
||||
static void
|
||||
_set_bit_var(name, val, mask)
|
||||
char *name;
|
||||
char *val;
|
||||
int mask;
|
||||
{
|
||||
HASHPTR hp;
|
||||
|
||||
hp = Def_macro(name, val, M_FLAG);
|
||||
hp->ht_flag |= M_VAR_BIT | M_MULTI;
|
||||
hp->MV_MASK = mask;
|
||||
hp->MV_BVAR = &Glob_attr;
|
||||
}
|
822
dmake/infer.c
Normal file
822
dmake/infer.c
Normal file
@ -0,0 +1,822 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/infer.c,v 1.1 1992/01/24 03:27:21 dvadura Exp $
|
||||
-- SYNOPSIS -- infer how to make a target.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- This file contains the code to infer a recipe, and possibly some new
|
||||
-- prerequisites for a target which dmake does not know how to make, or
|
||||
-- has no explicit recipe.
|
||||
--
|
||||
-- The inference fails if no path through the inference graph can be
|
||||
-- found by which we can make the target.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: infer.c,v $
|
||||
* Revision 1.1 1992/01/24 03:27:21 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
/* attributes that get transfered from the % start cell to the inferred
|
||||
* cells. */
|
||||
|
||||
#define A_TRANSFER (A_EPILOG | A_PRECIOUS | A_SILENT | A_SHELL | A_SETDIR |\
|
||||
A_SEQ | A_LIBRARY | A_IGNORE | A_PROLOG | A_SWAP |\
|
||||
A_NOSTATE )
|
||||
|
||||
|
||||
/* Define local static functions */
|
||||
static DFALINKPTR _dfa_subset ANSI((DFALINKPTR, DFASETPTR));
|
||||
static void _free_dfas ANSI((DFALINKPTR));
|
||||
static int _count_dots ANSI((char *));
|
||||
static char * _build_name ANSI((char *, char *, char *));
|
||||
static void _free_icells ANSI(());
|
||||
static ICELLPTR _union_iset ANSI((ICELLPTR, ICELLPTR));
|
||||
static ICELLPTR _add_iset ANSI((ICELLPTR,ICELLPTR,CELLPTR,DFALINKPTR,
|
||||
CELLPTR,int,int,char *,char *, int));
|
||||
static ICELLPTR _derive_prerequisites ANSI((ICELLPTR, ICELLPTR *));
|
||||
static char * _dump_inf_chain ANSI((ICELLPTR, int, int));
|
||||
|
||||
static int _prep = -1; /* Integer value of Prep variable */
|
||||
|
||||
|
||||
PUBLIC void
|
||||
Infer_recipe( cp, setdirroot )/*
|
||||
================================
|
||||
Perform a breadth-first search of the inference graph and return if
|
||||
possible an inferred set of prerequisites for making the current target.
|
||||
*/
|
||||
CELLPTR cp;
|
||||
CELLPTR setdirroot;
|
||||
{
|
||||
ICELLPTR nomatch, match;
|
||||
|
||||
DB_ENTER("Infer_recipe");
|
||||
|
||||
if( cp->ce_attr & A_NOINFER ) {DB_VOID_RETURN;}
|
||||
if( _prep == -1 ) _prep = atoi(Prep); /* _dfa_subset needs _prep */
|
||||
|
||||
match = NIL(ICELL);
|
||||
nomatch = _add_iset( NIL(ICELL), NIL(ICELL), NIL(CELL), NIL(DFALINK),
|
||||
setdirroot, _prep+_count_dots(cp->CE_NAME), 0,
|
||||
_strdup(cp->CE_NAME), NIL(char),
|
||||
cp->ce_time != (time_t)0L);
|
||||
|
||||
/* Make sure we try whole heartedly to infer at least one suffix */
|
||||
if( nomatch->ic_dmax == 0 ) ++nomatch->ic_dmax;
|
||||
|
||||
DB_EXECUTE( "inf", _dump_iset("nomatch",nomatch); );
|
||||
|
||||
while( nomatch != NIL(ICELL) ) {
|
||||
ICELLPTR new_nomatch = NIL(ICELL);
|
||||
ICELLPTR ic, pmatch, mmatch;
|
||||
CELLPTR prereq;
|
||||
int first;
|
||||
|
||||
for( ic=nomatch; ic != NIL(ICELL); ic=ic->ic_next ) {
|
||||
int ipush = FALSE;
|
||||
|
||||
if( ic->ic_dir ) ipush = Push_dir(ic->ic_dir, ic->ic_name, FALSE);
|
||||
match = _union_iset(match, _derive_prerequisites(ic, &new_nomatch));
|
||||
if( ipush ) Pop_dir(FALSE);
|
||||
}
|
||||
|
||||
DB_EXECUTE( "inf", _dump_iset("match",match); );
|
||||
DB_EXECUTE( "inf", _dump_iset("nomatch",new_nomatch); );
|
||||
|
||||
/* We have now deduced the two sets MATCH and NOMATCH. MATCH holds the
|
||||
* set of edges that we encountered that matched. If this set is empty
|
||||
* then we can apply transitive closure (if enabled) to the elements of
|
||||
* NOMATCH to see if we can find some other method to make the target.
|
||||
*
|
||||
* If MATCH is non-empty, we have found a method for making the target.
|
||||
* It is the shortest method for doing so (ie. uses fewest number of
|
||||
* steps). If MATCH contains more than one element then we have a
|
||||
* possible ambiguity.
|
||||
*/
|
||||
if( match == NIL(ICELL) ) {
|
||||
nomatch = new_nomatch;
|
||||
if( Transitive ) continue;
|
||||
goto all_done;
|
||||
}
|
||||
|
||||
/* Ok, we have a set of possible matches in MATCH, we should check the
|
||||
* set for ambiguity. If more than one inference path exists of the
|
||||
* same depth, then we may issue an ambigous inference error message.
|
||||
*
|
||||
* The message is suppressed if MATCH contains two elements and one of
|
||||
* them is the empty-prerequisite-rule. In this case we ignore the
|
||||
* ambiguity and take the rule that infers the prerequisite.
|
||||
*
|
||||
* Also if there are any chains that rely on a non-existant prerequisite
|
||||
* that may get made because it has a recipe then we prefer any that
|
||||
* rely on existing final prerequisites over those that we have to make.
|
||||
*
|
||||
* NOTE: May turn this around at some point.
|
||||
*/
|
||||
|
||||
/* Split out those that have to be made from those that end in
|
||||
* prerequisites that already exist. */
|
||||
pmatch = mmatch = NIL(ICELL);
|
||||
for(; match; match = ic ) {
|
||||
ic = match->ic_next;
|
||||
match->ic_next = NIL(ICELL);
|
||||
|
||||
if( match->ic_exists )
|
||||
pmatch = _union_iset(pmatch, match);
|
||||
else
|
||||
mmatch = _union_iset(mmatch, match);
|
||||
}
|
||||
|
||||
if( pmatch )
|
||||
match = pmatch;
|
||||
else
|
||||
match = mmatch;
|
||||
|
||||
/* Make sure it is unique */
|
||||
if( match->ic_next != NIL(ICELL) ) {
|
||||
int dump = (match->ic_next->ic_next != NIL(ICELL));
|
||||
|
||||
/* Check for definite ambiguity */
|
||||
if( !dump )
|
||||
if( (match->ic_meta->ce_prq && match->ic_next->ic_meta->ce_prq) ||
|
||||
(!match->ic_meta->ce_prq && !match->ic_next->ic_meta->ce_prq) )
|
||||
dump = TRUE;
|
||||
else if(!match->ic_meta->ce_prq && match->ic_next->ic_meta->ce_prq )
|
||||
match = match->ic_next;
|
||||
|
||||
if( dump ) {
|
||||
int count = 1;
|
||||
|
||||
Continue = TRUE;
|
||||
Error( "Ambiguous inference chains for target '%s'", cp->CE_NAME );
|
||||
for( ic=match; ic; ic=ic->ic_next )
|
||||
(void) _dump_inf_chain(ic, TRUE, count++);
|
||||
Fatal( "resolve ambiguity before proceeding.");
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
|
||||
/* MATCH now points at the derived recipe. We must now take cp, and
|
||||
* construct the correct graph so that the make may proceed. */
|
||||
|
||||
if( Verbose & V_INFER ) {
|
||||
char *tmp = _dump_inf_chain(match, TRUE, FALSE);
|
||||
printf("%s: Inferring prerequistes and recipes using:\n%s: ... %s\n",
|
||||
Pname, Pname, tmp );
|
||||
FREE(tmp);
|
||||
}
|
||||
|
||||
pmatch = NIL(ICELL);
|
||||
prereq = NIL(CELL);
|
||||
first = TRUE;
|
||||
|
||||
while( match ) {
|
||||
CELLPTR infcell=NIL(CELL);
|
||||
|
||||
/* Compute the inferred prerequisite first. */
|
||||
if( match->ic_name ) {
|
||||
if( match->ic_meta )
|
||||
infcell = Def_cell( match->ic_name );
|
||||
else
|
||||
infcell = cp;
|
||||
|
||||
infcell->ce_flag |= F_TARGET;
|
||||
|
||||
if( infcell != cp ) {
|
||||
infcell->ce_flag |= F_INFER;
|
||||
if( !first ) infcell->ce_flag |= F_REMOVE;
|
||||
}
|
||||
|
||||
if( !match->ic_flag )
|
||||
infcell->ce_attr |= A_NOINFER;
|
||||
|
||||
first = FALSE;
|
||||
}
|
||||
|
||||
/* Add global prerequisites from previous rule if there are any and
|
||||
* the recipe. */
|
||||
if( pmatch ) {
|
||||
CELLPTR imeta = pmatch->ic_meta;
|
||||
LINKPTR lp;
|
||||
|
||||
infcell->ce_per = pmatch->ic_dfa->dl_per;
|
||||
infcell->ce_attr |= (imeta->ce_attr & A_TRANSFER);
|
||||
|
||||
if( !(infcell->ce_flag & F_RULES) ) {
|
||||
infcell->ce_flag |= (imeta->ce_flag&(F_SINGLE|F_GROUP))|F_RULES;
|
||||
infcell->ce_recipe = imeta->ce_recipe;
|
||||
}
|
||||
|
||||
pmatch->ic_dfa->dl_per = NIL(char);
|
||||
|
||||
/* If infcell already had a directory set then modify it based on
|
||||
* whether it was the original cell or some intermediary. */
|
||||
if( imeta->ce_dir )
|
||||
if( infcell->ce_dir && infcell == cp ) {
|
||||
/* cp->ce_dir was set and we have pushed the directory prior
|
||||
* to calling this routine. We should therefore pop it and
|
||||
* push the new concatenated directory required by the
|
||||
* inference. */
|
||||
infcell->ce_dir=_strdup(Build_path(infcell->ce_dir,
|
||||
imeta->ce_dir));
|
||||
}
|
||||
else
|
||||
infcell->ce_dir = imeta->ce_dir;
|
||||
|
||||
for( lp=imeta->ce_indprq; lp != NIL(LINK); lp=lp->cl_next ) {
|
||||
char *name = lp->cl_prq->CE_NAME;
|
||||
CELLPTR tcp;
|
||||
|
||||
name = _build_name( cp->CE_NAME, name, infcell->ce_per );
|
||||
tcp = Def_cell( name );
|
||||
tcp->ce_flag |= F_REMOVE;
|
||||
Add_prerequisite( infcell, tcp, FALSE, FALSE );
|
||||
|
||||
if( Verbose & V_INFER )
|
||||
printf( "%s: Inferred indirect prerequisite [%s]\n",
|
||||
Pname, name );
|
||||
FREE(name);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the previous cell as the prerequisite */
|
||||
if( prereq )
|
||||
(Add_prerequisite(infcell,prereq,FALSE,FALSE))->cl_flag |= F_TARGET;
|
||||
|
||||
pmatch = match;
|
||||
prereq = infcell;
|
||||
match = match->ic_parent;
|
||||
}
|
||||
|
||||
DB_PRINT("inf", ("Terminated due to a match"));
|
||||
break;
|
||||
}
|
||||
|
||||
all_done:
|
||||
_free_icells();
|
||||
|
||||
DB_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
static ICELLPTR
|
||||
_derive_prerequisites( ic, nnmp )/*
|
||||
===================================
|
||||
Take a cell and derive a set of prerequisites from the cell. Categorize
|
||||
them into those that MATCH (ie. those that we found in the file system),
|
||||
and those that do not match NOMATCH that we may possibly have a look at
|
||||
later. When we process the next level of the breadth-first search.
|
||||
|
||||
Once MATCH is non-empty we will stop inserting elements into NOMATCH
|
||||
since we know that either MATCH is successful and unique or it will
|
||||
issue an ambiguity error. We will never go on to look at elements
|
||||
in NOMATCH after wards. */
|
||||
ICELLPTR ic;
|
||||
ICELLPTR *nnmp;
|
||||
{
|
||||
ICELLPTR match = NIL(ICELL);
|
||||
DFALINKPTR pdfa;
|
||||
DFALINKPTR dfas;
|
||||
|
||||
DB_ENTER("_derive_prerequisites");
|
||||
|
||||
/* If none of the inference nodes match then forget about the inference.
|
||||
* The user did not tell us how to make such a target. We also stop the
|
||||
* Inference if the new set of DFA's is a proper subset of a previous
|
||||
* subset and it's PREP counts exceed the value of Prep.
|
||||
*/
|
||||
dfas = _dfa_subset( Match_dfa(ic->ic_name), &ic->ic_dfastack );
|
||||
|
||||
DB_EXECUTE("inf", _dump_dfa_stack(dfas, &ic->ic_dfastack); );
|
||||
|
||||
/* Ok, we have nothing here to work with so return an empty cell. */
|
||||
if( dfas == NIL(DFALINK) ) {
|
||||
DB_PRINT( "mem", ("%s:<- mem %ld",ic->ic_name, (long)coreleft()));
|
||||
DB_PRINT( "inf", ("<<< Exit, no dfas, cp = %04x", NIL(CELL)) );
|
||||
DB_RETURN( NIL(ICELL) );
|
||||
}
|
||||
|
||||
/* Save the dfas, we are going to use on the stack for this cell. */
|
||||
ic->ic_dfastack.df_set = dfas;
|
||||
|
||||
/* Run through the %-meta cells, build the prerequisite cells. For each
|
||||
* %-meta go through it's list of edges and try to use each in turn to
|
||||
* decuce a likely prerequisite. We perform a breadth-first search
|
||||
* matching the first path that results in a unique method for making the
|
||||
* target. */
|
||||
for( pdfa = dfas; pdfa != NIL(DFALINK); pdfa = pdfa->dl_next ) {
|
||||
LINK tl;
|
||||
LINKPTR edge;
|
||||
CELLPTR pmeta;
|
||||
|
||||
pmeta = pdfa->dl_meta;
|
||||
DB_PRINT( "inf", ("Using dfa: [%s]", pmeta->CE_NAME) );
|
||||
|
||||
/* If the %-meta is a singleton meta then deal with it differently from
|
||||
* the case when it is a bunch of %-meta's found on the original entries
|
||||
* prerequisite list. */
|
||||
if( pmeta->ce_flag & F_MULTI )
|
||||
edge = pmeta->ce_prq;
|
||||
else {
|
||||
tl.cl_prq = pmeta;
|
||||
tl.cl_next = NIL(LINK);
|
||||
edge = &tl;
|
||||
}
|
||||
|
||||
/* Now run through the list of prerequisite edge's for the %-meta. */
|
||||
for( ; edge != NIL(LINK); edge = edge->cl_next ) {
|
||||
HASHPTR thp; /* temporary hash table pointer */
|
||||
HASH iprqh; /* hash cell for new prerequisite */
|
||||
CELL iprq; /* inferred prerequisite to look for */
|
||||
CELLPTR idirroot; /* Inferred prerequisite root */
|
||||
CELLPTR nidirroot; /* Inferred prerequisite root */
|
||||
STRINGPTR ircp; /* Inferred prerequisites recipe */
|
||||
char *idir; /* directory to CD to. */
|
||||
int ipush = 0; /* flag for push on inferred prereq */
|
||||
char *name = NIL(char); /* prerequisite name */
|
||||
CELLPTR meta = edge->cl_prq;
|
||||
int dmax_fix;
|
||||
int trans;
|
||||
int noinf;
|
||||
int exists;
|
||||
|
||||
if( meta->ce_prq ) name = meta->ce_prq->cl_prq->CE_NAME;
|
||||
|
||||
DB_PRINT( "inf", ("Trying edge from [%s] to [%s] for [%s]",
|
||||
meta->CE_NAME, name?name:"(nil)", ic->ic_name) );
|
||||
|
||||
/* Set the temp CELL used for building prerequisite candidates to
|
||||
* all zero so that we don't have to keep initializing all the
|
||||
* fields. */
|
||||
{
|
||||
register char *s = (char *) &iprq;
|
||||
register int n = sizeof(CELL);
|
||||
while( n ) { *s++ = '\0'; n--; }
|
||||
}
|
||||
|
||||
nidirroot = idirroot = ic->ic_setdirroot;
|
||||
iprq.ce_name = &iprqh;
|
||||
|
||||
if( name ) {
|
||||
/* Build the prerequisite name from the %-meta prerequisite given
|
||||
* for the %-meta rule. */
|
||||
iprqh.ht_name = _build_name( ic->ic_name, name, pdfa->dl_per );
|
||||
if((dmax_fix = (_count_dots(name)-_count_dots(meta->CE_NAME))) < 0)
|
||||
dmax_fix = 0;
|
||||
|
||||
if( !strcmp(ic->ic_name, iprqh.ht_name) ||
|
||||
(_count_dots(iprqh.ht_name) > ic->ic_dmax + dmax_fix) ) {
|
||||
FREE( iprqh.ht_name );
|
||||
continue;
|
||||
}
|
||||
|
||||
DB_PRINT( "inf", ("Checking prerequisite [%s]", iprqh.ht_name) );
|
||||
|
||||
/* See if the prerequisite CELL has been previously defined. If
|
||||
* it has, then make a copy of it into iprq, and use it to try
|
||||
* the inference. We make the copy so that we don't modify the
|
||||
* stat of the inferred cell if the inference fails.
|
||||
*/
|
||||
thp = Get_name( iprqh.ht_name, Defs, FALSE );
|
||||
if(thp != NIL(HASH)) {
|
||||
iprq = *thp->CP_OWNR;
|
||||
ircp = iprq.ce_recipe;
|
||||
}
|
||||
else
|
||||
ircp = NIL(STRING);
|
||||
}
|
||||
else
|
||||
iprqh.ht_name = NIL(char);
|
||||
|
||||
|
||||
/* If the %-meta has a .SETDIR set then we change to the new
|
||||
* directory prior to performing the stat of the new prerequisite.
|
||||
* If the change of directory fails then the rule is droped from
|
||||
* further consideration.
|
||||
*/
|
||||
if( iprq.ce_dir ) {
|
||||
if( ipush = Push_dir(iprq.ce_dir, iprqh.ht_name, TRUE) ) {
|
||||
nidirroot = thp->CP_OWNR;
|
||||
idir = Pwd;
|
||||
}
|
||||
else {
|
||||
if( iprqh.ht_name ) FREE( iprqh.ht_name );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
idir = NIL(char);
|
||||
|
||||
|
||||
/* Stat the inferred prerequisite.
|
||||
*/
|
||||
if( name ) {
|
||||
if( Verbose & V_INFER )
|
||||
printf( "%s: Trying prerequisite [%s] for [%s]\n", Pname,
|
||||
iprqh.ht_name, ic->ic_name );
|
||||
|
||||
if( !(iprq.ce_flag & F_STAT) ) Stat_target(&iprq, FALSE);
|
||||
}
|
||||
|
||||
|
||||
/* If the STAT succeeded or if the prerequisite has a recipe for
|
||||
* making it then it's a match and a candidate for getting infered.
|
||||
* Otherwise it is not a match, and we cannot yet tell if it is
|
||||
* going to be a successful path to follow, so we save it for
|
||||
* later consideration.
|
||||
*/
|
||||
noinf = ((Glob_attr)&A_NOINFER);
|
||||
if( meta->ce_prq )
|
||||
noinf |= ((meta->ce_prq->cl_prq->ce_attr)&A_NOINFER);
|
||||
trans = Transitive || !noinf;
|
||||
exists = (iprq.ce_time != (time_t)0L);
|
||||
|
||||
if( exists || (ircp != NIL(STRING)) || !name ) {
|
||||
match = _add_iset( match, ic, meta, pdfa, idirroot, ic->ic_dmax,
|
||||
trans, iprq.ce_name->ht_name, idir, exists );
|
||||
DB_PRINT("inf",("Added to MATCH %s",iprq.ce_name->ht_name));
|
||||
}
|
||||
else if( !noinf && match == NIL(ICELL) ) {
|
||||
*nnmp = _add_iset( *nnmp, ic, meta, pdfa, nidirroot, ic->ic_dmax,
|
||||
trans, iprq.ce_name->ht_name, idir, exists );
|
||||
DB_PRINT("inf",("Added to NOMATCH %s",iprq.ce_name->ht_name));
|
||||
}
|
||||
|
||||
/* If we pushed a directory for the inferred prerequisite then
|
||||
* pop it.
|
||||
*/
|
||||
if( ipush ) Pop_dir(FALSE);
|
||||
if( iprqh.ht_name ) FREE(iprqh.ht_name);
|
||||
}
|
||||
}
|
||||
|
||||
DB_RETURN(match);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
_build_name( tg, meta, per )
|
||||
char *tg;
|
||||
char *meta;
|
||||
char *per;
|
||||
{
|
||||
char *name;
|
||||
|
||||
name = Apply_edit( meta, "%", per, FALSE, FALSE );
|
||||
if( strchr(name, '$') ) {
|
||||
HASHPTR m_at;
|
||||
char *tmp;
|
||||
|
||||
m_at = Def_macro( "@", tg, M_MULTI );
|
||||
tmp = Expand( name );
|
||||
|
||||
if( m_at->ht_value != NIL(char) ) {
|
||||
FREE( m_at->ht_value );
|
||||
m_at->ht_value = NIL(char);
|
||||
}
|
||||
|
||||
if( name != meta ) FREE( name );
|
||||
name = tmp;
|
||||
}
|
||||
else if( name == meta )
|
||||
name = _strdup( name );
|
||||
|
||||
return(name);
|
||||
}
|
||||
|
||||
|
||||
static DFALINKPTR
|
||||
_dfa_subset( pdfa, stack )/*
|
||||
============================
|
||||
This is the valid DFA subset computation. Whenever a CELL has a Match_dfa
|
||||
subset computed this algorithm is run to see if any of the previously
|
||||
computed sets on the DFA stack are proper subsets of the new set. If they
|
||||
are, then any elements of the matching subset whose Prep counts exceed
|
||||
the allowed maximum given by Prep are removed from the computed DFA set,
|
||||
and hence from consideration, thereby cutting off the cycle in the
|
||||
inference graph. */
|
||||
DFALINKPTR pdfa;
|
||||
register DFASETPTR stack;
|
||||
{
|
||||
register DFALINKPTR element;
|
||||
DFALINKPTR nelement;
|
||||
|
||||
DB_ENTER( "_dfa_subset" );
|
||||
|
||||
for(; pdfa != NIL(DFALINK) && stack != NIL(DFASET); stack = stack->df_next) {
|
||||
int subset = TRUE;
|
||||
|
||||
for( element=stack->df_set; subset && element != NIL(DFALINK);
|
||||
element=element->dl_next ) {
|
||||
register DFALINKPTR subel;
|
||||
|
||||
for( subel = pdfa;
|
||||
subel != NIL(DFALINK) && (subel->dl_meta != element->dl_meta);
|
||||
subel = subel->dl_next );
|
||||
|
||||
if( subset = (subel != NIL(DFALINK)) ) element->dl_member = subel;
|
||||
}
|
||||
|
||||
if( subset )
|
||||
for( element=stack->df_set; element != NIL(DFALINK);
|
||||
element=element->dl_next ) {
|
||||
DFALINKPTR mem = element->dl_member;
|
||||
int npr = element->dl_prep + 1;
|
||||
|
||||
if( npr > _prep )
|
||||
mem->dl_delete++;
|
||||
else
|
||||
mem->dl_prep = npr;
|
||||
}
|
||||
}
|
||||
|
||||
for( element = pdfa; element != NIL(DFALINK); element = nelement ) {
|
||||
nelement = element->dl_next;
|
||||
|
||||
if( element->dl_delete ) {
|
||||
/* A member of the subset has a PREP count equal to PREP, so
|
||||
* it should not be considered further in the inference, hence
|
||||
* we remove it from the doubly linked set list */
|
||||
if( element == pdfa )
|
||||
pdfa = element->dl_next;
|
||||
else
|
||||
element->dl_prev->dl_next = element->dl_next;
|
||||
|
||||
if( element->dl_next != NIL(DFALINK) )
|
||||
element->dl_next->dl_prev = element->dl_prev;
|
||||
|
||||
DB_PRINT("inf", ("deleting dfa [%s]", element->dl_meta->CE_NAME));
|
||||
FREE( element->dl_per );
|
||||
FREE( element );
|
||||
}
|
||||
}
|
||||
|
||||
DB_RETURN( pdfa );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
_free_dfas( chain )/*
|
||||
=====================
|
||||
Free the list of DFA's constructed by Match_dfa, and linked together by
|
||||
LINK cells. FREE the % value as well, as long as it isn't NIL. */
|
||||
DFALINKPTR chain;
|
||||
{
|
||||
register DFALINKPTR tl;
|
||||
|
||||
DB_ENTER( "_free_dfas" );
|
||||
|
||||
for( tl=chain; tl != NIL(DFALINK); chain = tl ) {
|
||||
tl = tl->dl_next;
|
||||
|
||||
DB_PRINT( "inf", ("Freeing DFA [%s], %% = [%s]", chain->dl_meta->CE_NAME,
|
||||
chain->dl_per) );
|
||||
|
||||
if( chain->dl_per != NIL(char) ) FREE( chain->dl_per );
|
||||
FREE( chain );
|
||||
}
|
||||
|
||||
DB_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_count_dots( name )/*
|
||||
=====================*/
|
||||
char *name;
|
||||
{
|
||||
register char *p;
|
||||
register int i = 0;
|
||||
|
||||
for( p = name; *p; p++ ) if(*p == '.') i++;
|
||||
|
||||
return( i );
|
||||
}
|
||||
|
||||
|
||||
static ICELLPTR _icells = NIL(ICELL);
|
||||
#ifdef DBUG
|
||||
static int _icell_cost = 0;
|
||||
#endif
|
||||
|
||||
static ICELLPTR
|
||||
_add_iset( iset, parent, meta, dfa, setdirroot, dmax, noinf, name, dir, exists)
|
||||
ICELLPTR iset;
|
||||
ICELLPTR parent;
|
||||
CELLPTR meta;
|
||||
DFALINKPTR dfa;
|
||||
CELLPTR setdirroot;
|
||||
int dmax;
|
||||
int noinf;
|
||||
char *name;
|
||||
char *dir;
|
||||
int exists;
|
||||
{
|
||||
ICELLPTR icell;
|
||||
|
||||
DB_ENTER("_add_iset");
|
||||
TALLOC(icell, 1, ICELL);
|
||||
|
||||
DB_EXECUTE("inf", _icell_cost+=(sizeof(ICELL)+strlen(dir?dir:"")+strlen(name?name:"")+2););
|
||||
|
||||
icell->ic_meta = meta;
|
||||
icell->ic_dfa = dfa;
|
||||
icell->ic_setdirroot = setdirroot;
|
||||
|
||||
if( parent ) icell->ic_dfastack.df_next = &parent->ic_dfastack;
|
||||
|
||||
icell->ic_dmax = dmax;
|
||||
icell->ic_dir = _strdup(dir);
|
||||
icell->ic_name = _strdup(name);
|
||||
icell->ic_parent = parent;
|
||||
icell->ic_next = iset;
|
||||
icell->ic_flag = noinf;
|
||||
icell->ic_exists = exists;
|
||||
|
||||
icell->ic_link = _icells;
|
||||
_icells = icell;
|
||||
|
||||
DB_RETURN(icell);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_free_icells()
|
||||
{
|
||||
register ICELLPTR ic;
|
||||
|
||||
DB_ENTER("_free_icells");
|
||||
|
||||
for( ; _icells; _icells = ic ) {
|
||||
ic = _icells->ic_link;
|
||||
|
||||
_free_dfas(_icells->ic_dfastack.df_set);
|
||||
if( _icells->ic_dir ) FREE(_icells->ic_dir);
|
||||
if( _icells->ic_name) FREE(_icells->ic_name);
|
||||
FREE(_icells);
|
||||
}
|
||||
|
||||
DB_PRINT("inf",("Used %d memory for icells",_icell_cost));
|
||||
DB_EXECUTE("inf", _icell_cost=0; );
|
||||
|
||||
DB_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
static ICELLPTR
|
||||
_union_iset( iset, uset )
|
||||
ICELLPTR iset;
|
||||
ICELLPTR uset;
|
||||
{
|
||||
register ICELLPTR ic;
|
||||
|
||||
if( iset == NIL(ICELL) ) return(uset);
|
||||
|
||||
for( ic=iset; ic->ic_next != NIL(ICELL); ic=ic->ic_next );
|
||||
ic->ic_next = uset;
|
||||
|
||||
return(iset);
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
_dump_inf_chain( ip, flag, print )/*
|
||||
====================================*/
|
||||
ICELLPTR ip;
|
||||
int flag;
|
||||
int print;
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if( ip == NIL(ICELL) ) return(NIL(char));
|
||||
|
||||
tmp = _dump_inf_chain(ip->ic_parent, FALSE, FALSE);
|
||||
|
||||
if( ip->ic_meta ) {
|
||||
tmp = _strjoin(tmp, "(", -1, TRUE);
|
||||
tmp = _strjoin(tmp, ip->ic_meta->CE_NAME, -1, TRUE);
|
||||
|
||||
if( ip->ic_dir && !*ip->ic_dir ) {
|
||||
tmp = _strjoin(tmp, "[", -1, TRUE);
|
||||
if( strncmp(Makedir,ip->ic_dir, strlen(Makedir)) )
|
||||
tmp = _strjoin(tmp, ip->ic_dir, -1, TRUE);
|
||||
else
|
||||
tmp = _strjoin(tmp, ip->ic_dir+strlen(Makedir)+1, -1, TRUE);
|
||||
tmp = _strjoin(tmp, "]", -1, TRUE);
|
||||
}
|
||||
tmp = _strjoin(tmp, (ip->ic_name)?") -->":")", -1, TRUE);
|
||||
}
|
||||
|
||||
if( ip->ic_name ) tmp = _strapp( tmp, ip->ic_name );
|
||||
|
||||
if( flag && ip->ic_meta->ce_prq) {
|
||||
tmp = _strjoin(tmp, "(", -1, TRUE);
|
||||
tmp = _strjoin(tmp, ip->ic_meta->ce_prq->cl_prq->CE_NAME, -1, TRUE);
|
||||
tmp = _strjoin(tmp, ")", -1, TRUE);
|
||||
}
|
||||
|
||||
if( print ) {
|
||||
fprintf( stderr, "%s: %2d. %s\n", Pname, print, tmp );
|
||||
FREE(tmp);
|
||||
tmp = NIL(char);
|
||||
}
|
||||
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
|
||||
#ifdef DBUG
|
||||
_dump_dfa_stack(dfas, dfa_stack)
|
||||
DFALINKPTR dfas;
|
||||
DFASETPTR dfa_stack;
|
||||
{
|
||||
register DFALINKPTR pdfa;
|
||||
char *tmp = NIL(char);
|
||||
DFASETPTR ds;
|
||||
|
||||
for( pdfa = dfas; pdfa != NIL(DFALINK); pdfa = pdfa->dl_next )
|
||||
tmp = _strapp( tmp, pdfa->dl_meta->CE_NAME );
|
||||
|
||||
tmp = _strapp( tmp, ":: {" );
|
||||
for( ds = dfa_stack; ds != NIL(DFASET); ds = ds->df_next ) {
|
||||
tmp = _strapp( tmp, "[" );
|
||||
for( pdfa = ds->df_set; pdfa != NIL(DFALINK); pdfa = pdfa->dl_next )
|
||||
tmp = _strapp( tmp, pdfa->dl_meta->CE_NAME );
|
||||
tmp = _strapp( tmp, "]" );
|
||||
}
|
||||
tmp = _strapp( tmp, "}" );
|
||||
|
||||
printf( "DFA set and stack contents:\n%s\n", tmp );
|
||||
FREE(tmp);
|
||||
}
|
||||
|
||||
|
||||
_dump_iset( name, iset )
|
||||
char *name;
|
||||
ICELLPTR iset;
|
||||
{
|
||||
int cell = 0;
|
||||
|
||||
printf( "**** ISET for %s\n", name );
|
||||
for( ; iset != NIL(ICELL); iset = iset->ic_next ){
|
||||
printf( "cell %d\n", cell++ );
|
||||
if( iset->ic_meta )
|
||||
printf( "edge: %s --> %s\n", iset->ic_meta->CE_NAME,
|
||||
iset->ic_meta->ce_prq ?
|
||||
iset->ic_meta->ce_prq->cl_prq->CE_NAME :
|
||||
"(nil)" );
|
||||
else
|
||||
printf( "edge: (nil)\n" );
|
||||
|
||||
if( iset->ic_dfa )
|
||||
printf( "dfa: %s\n", iset->ic_dfa->dl_meta->CE_NAME );
|
||||
else
|
||||
printf( "dfa: (nil)\n" );
|
||||
|
||||
printf( "sdr: %04x\n", iset->ic_setdirroot );
|
||||
_dump_dfa_stack(iset->ic_dfastack.df_set, &iset->ic_dfastack);
|
||||
|
||||
printf( "dmax: %d\n", iset->ic_dmax );
|
||||
printf( "name: %s\n", iset->ic_name );
|
||||
printf( "dir: %s\n", iset->ic_dir?iset->ic_dir:"(nil)" );
|
||||
|
||||
printf( "parent: " );
|
||||
if( iset->ic_parent )
|
||||
if( iset->ic_parent->ic_meta )
|
||||
printf( "%s --> %s\n",
|
||||
iset->ic_parent->ic_meta->CE_NAME,
|
||||
iset->ic_parent->ic_meta->ce_prq ?
|
||||
iset->ic_parent->ic_meta->ce_prq->cl_prq->CE_NAME :
|
||||
"(nil)" );
|
||||
else
|
||||
printf( "(nil)\n" );
|
||||
else
|
||||
printf( "(nil)\n" );
|
||||
}
|
||||
printf( "==================================\n" );
|
||||
}
|
||||
#endif
|
56
dmake/itypes.h
Normal file
56
dmake/itypes.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/itypes.h,v 1.1 1992/01/24 03:29:40 dvadura Exp $
|
||||
-- SYNOPSIS -- type declarations for common types
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- portable type declarations.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: itypes.h,v $
|
||||
* Revision 1.1 1992/01/24 03:29:40 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ITYPES_h
|
||||
#define ITYPES_h
|
||||
|
||||
#if defined(M_I86) || defined(MC68000)
|
||||
typedef char int8; /* typedefs for right size ints */
|
||||
typedef int int16;
|
||||
typedef long int32;
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned int uint16;
|
||||
typedef unsigned long uint32;
|
||||
#else
|
||||
typedef char int8; /* typedefs for right size ints */
|
||||
typedef short int16;
|
||||
typedef long int32;
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned long uint32;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
58
dmake/mac/arlib.c
Normal file
58
dmake/mac/arlib.c
Normal file
@ -0,0 +1,58 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/mac/arlib.c,v 1.1 1992/01/24 03:29:41 dvadura Exp $
|
||||
-- SYNOPSIS -- Library access code.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- This implementation uses the library timestamp inplace of the
|
||||
-- library member timestamp.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: arlib.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:41 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
PUBLIC time_t
|
||||
seek_arch(char * /* name */, char *lib) {
|
||||
static int warned = FALSE;
|
||||
|
||||
if (!warned && !(Glob_attr&A_SILENT))
|
||||
warned = TRUE,
|
||||
Warning("Can't extract library member timestamp;\n\
|
||||
using library timestamp instead.");
|
||||
return (Do_stat(lib, NULL, NULL));
|
||||
}
|
||||
|
||||
PUBLIC int
|
||||
touch_arch(char * /* name */, char *lib) {
|
||||
static int warned = FALSE;
|
||||
|
||||
if (!warned && !(Glob_attr&A_SILENT))
|
||||
warned = TRUE,
|
||||
Warning("Can't update library member timestamp;\n\
|
||||
touching library instead.");
|
||||
return (Do_touch(lib, NULL, NULL));
|
||||
}
|
92
dmake/mac/bogus.c
Normal file
92
dmake/mac/bogus.c
Normal file
@ -0,0 +1,92 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/mac/bogus.c,v 1.1 1992/01/24 03:29:42 dvadura Exp $
|
||||
-- SYNOPSIS -- Write the shell of subroutines we can't or don't
|
||||
-- need to implement
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- dmake uses a couple of functions which I am either unable to figure out
|
||||
-- how to implement or which are not needed. The shells of these routines
|
||||
-- are in this file.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: bogus.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:42 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* tzset() is a Microsoft "extension" to ANSI C. It sets global
|
||||
* variables telling if we are in dayling savings time, the time
|
||||
* zone, and difference between the current time and GMT.
|
||||
* None of these globals are used by dmake, so this routine is
|
||||
* not needed
|
||||
*/
|
||||
PUBLIC void tzset () {}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Add an environmental variable that child processes can use.
|
||||
* Since MPW currently doesn't allow child processes, this isn't
|
||||
* needed.
|
||||
*/
|
||||
PUBLIC int putenv (char * /* pEnvString */) {return (0);}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Execute a child process. This may be able to be done with
|
||||
* the MPW system() call someday, but cannot be done currently.
|
||||
*/
|
||||
PUBLIC int runargv (CELLPTR /* target */, int /* ignore */, int /* group */,
|
||||
int /* last */, int /* shell */, char * /* pCmd */) {
|
||||
static int warned = FALSE;
|
||||
|
||||
if (!warned && !(Glob_attr & A_SILENT)) {
|
||||
warned = TRUE;
|
||||
Fatal ("Can't execute any targets: use '-n' option.");
|
||||
} /* if */
|
||||
|
||||
return (0);
|
||||
} /* int runargv () */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Wait for the child process to complete. Only needed to be implemented
|
||||
* if we could executing multiple processes at once.
|
||||
*/
|
||||
PUBLIC int Wait_for_child(int /* abort_flg */, int /* pid */) {return (1);}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Do any cleanup for any processes when we quit.
|
||||
*/
|
||||
PUBLIC void Clean_up_processes() {}
|
87
dmake/mac/config.h
Normal file
87
dmake/mac/config.h
Normal file
@ -0,0 +1,87 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/mac/config.h,v 1.1 1992/01/24 03:29:43 dvadura Exp $
|
||||
-- SYNOPSIS -- Configurarion include file for the Macintosh.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- There is one of these for each specific machine configuration.
|
||||
-- It can be used to further tweek the machine specific sources
|
||||
-- so that they compile.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: config.h,v $
|
||||
* Revision 1.1 1992/01/24 03:29:43 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
/* Definitions left out of StdArg.h */
|
||||
#define va_alist ...
|
||||
#define va_dcl
|
||||
|
||||
#define CONST const
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
/* signal extensions */
|
||||
#define SIGQUIT SIGTERM
|
||||
|
||||
|
||||
/* Mac doesn't have a stat function or structure so we have to add one in. */
|
||||
typedef long off_t;
|
||||
struct stat {
|
||||
unsigned short st_mode;
|
||||
off_t st_size;
|
||||
time_t st_mtime;
|
||||
time_t st_ctime;
|
||||
/* struct stat has lots of other fields, but we don't need them for dmake */
|
||||
}; /* struct stat */
|
||||
#define S_IFDIR 0040000 /* directory */
|
||||
#define S_IFREG 0100000 /* regular */
|
||||
#define S_IFMT (S_IFDIR | S_IFREG) /* Format */
|
||||
#define S_IREAD 0000400 /* read owner permission */
|
||||
#define S_IWRITE 0000200 /* write owner permission */
|
||||
#define S_IEXEC 0000100 /* execute owner permission */
|
||||
|
||||
|
||||
/* Global for environmental variables */
|
||||
extern char **environ;
|
||||
|
||||
|
||||
/* We really want main to be in the mac directory
|
||||
so that we get the envp argument */
|
||||
#define main(argc, argv) dmakemain(argc, argv)
|
||||
|
||||
/* Directory/file info. and directory moving */
|
||||
int stat (char *pPath, struct stat *pStat);
|
||||
char *getcwd (char *pPath, size_t pathSize);
|
||||
int chdir (char *pPath);
|
||||
int utime (char *pPath, time_t *pTimes);
|
||||
|
||||
/* Routines to handle conversion from Unix file names to Mac file names */
|
||||
char *Unix2MacFName(char *pUnixName);
|
||||
FILE *MacFOpen (char *pName, char *pMode);
|
||||
#define fopen(pFName, pMode) MacFOpen(pFName, pMode)
|
||||
|
||||
/* a small problem with pointer to voids on some unix machines needs this */
|
||||
#define PVOID void *
|
44
dmake/mac/config.mk
Normal file
44
dmake/mac/config.mk
Normal file
@ -0,0 +1,44 @@
|
||||
# This is an OS Mac specific configuration file
|
||||
# It assumes that OBJDIR, TARGET and DEBUG are previously defined.
|
||||
# It defines CFLAGS, LDARGS, CPPFLAGS, STARTUPFILE, LDOBJS
|
||||
# It augments SRC, OBJDIR, TARGET, CFLAGS, LDLIBS
|
||||
#
|
||||
|
||||
STARTUPFILE = :$(OS):startup.mk
|
||||
|
||||
CPPFLAGS = $(CFLAGS)
|
||||
LDOBJS = $(CSTARTUP) :$(OBJDIR):{$(<:f)}
|
||||
LDARGS = $(LDFLAGS) -o $@ $(LDOBJS) $(LDLIBS)
|
||||
|
||||
# Debug flags
|
||||
DB_CFLAGS = -sym on
|
||||
DB_LDFLAGS = -sym on
|
||||
DB_LDLIBS =
|
||||
|
||||
# NO Debug flags
|
||||
NDB_CFLAGS = -sym off
|
||||
NDB_LDFLAGS = -sym off
|
||||
NDB_LDLIBS =
|
||||
|
||||
# Local configuration modifications for CFLAGS.
|
||||
CFLAGS += -I :$(OS) -d _MPW -s $(<:b)
|
||||
LDFLAGS += -w -c 'MPS ' -t MPST
|
||||
|
||||
# Since we writing out what files we want to execute, we can't use .SETDIR
|
||||
# to specify the files to compile in the Mac directory.
|
||||
# Instead, we copy the files to the (top-level) current directory and compile
|
||||
# them there.
|
||||
%.c : ":$(OS):%.c"
|
||||
duplicate -y $< $@
|
||||
|
||||
# Common Mac source files.
|
||||
OS_SRC = arlib.c bogus.c dirbrk.c directry.c environ.c main.c rmprq.c \
|
||||
ruletab.c tempnam.c tomacfil.c
|
||||
.IF $(SHELL) != mwp
|
||||
.SETDIR=$(OS) : $(OS_SRC)
|
||||
.ENDIF
|
||||
SRC += $(OS_SRC)
|
||||
|
||||
# Set source dirs so that we can find files named in this
|
||||
# config file.
|
||||
.SOURCE.h : $(OS)
|
52
dmake/mac/dirbrk.c
Normal file
52
dmake/mac/dirbrk.c
Normal file
@ -0,0 +1,52 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/mac/dirbrk.c,v 1.1 1992/01/24 03:29:44 dvadura Exp $
|
||||
-- SYNOPSIS -- define the directory separator string.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- Define this string for any character that may appear in a path name
|
||||
-- and can be used as a directory separator.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: dirbrk.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:44 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
/* mac only uses ':' */
|
||||
char* DirBrkStr = ":";
|
||||
|
||||
/*
|
||||
** Return TRUE if the name is the full specification of a path name to a file
|
||||
** starting at the root of the file system, otherwise return FALSE
|
||||
*/
|
||||
PUBLIC int
|
||||
If_root_path(name)
|
||||
char *name;
|
||||
{
|
||||
name = Unix2MacFName (name);
|
||||
return( (strchr(name, ':') != NIL(char)) &&
|
||||
(name[0] != ':') );
|
||||
}
|
270
dmake/mac/directry.c
Normal file
270
dmake/mac/directry.c
Normal file
@ -0,0 +1,270 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/mac/directry.c,v 1.1 1992/01/24 03:29:45 dvadura Exp $
|
||||
-- SYNOPSIS -- Fake directory and file functions for the Mac
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- This file contains implementations for some ANSI standard routines dmake
|
||||
-- uses which are not otherwise available for the mac.
|
||||
--
|
||||
-- Assume we are using at least 128K ROMS.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: directry.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:45 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Errors.h>
|
||||
#include <Files.h>
|
||||
#include <OSUtils.h>
|
||||
#include <StdLib.h>
|
||||
#include <Strings.h>
|
||||
#include <SysEqu.h>
|
||||
#include "extern.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Implementation of stat function for dmake on the mac.
|
||||
*
|
||||
* Many fields aren't filled in, and the times are seconds from 1/1//1904,
|
||||
* but it should be enough for dmake (I think we only need st_mtime and
|
||||
* st_mode's S_IFDIR set correctly).
|
||||
*/
|
||||
PUBLIC int stat(pPath, pStat)
|
||||
char *pPath;
|
||||
struct stat *pStat;
|
||||
{
|
||||
CInfoPBRec infoPB;
|
||||
OSErr err;
|
||||
int retVal;
|
||||
|
||||
pPath = Unix2MacFName (pPath);
|
||||
|
||||
infoPB.hFileInfo.ioCompletion = NULL;
|
||||
infoPB.hFileInfo.ioNamePtr = c2pstr (pPath);
|
||||
infoPB.hFileInfo.ioVRefNum = 0;
|
||||
infoPB.hFileInfo.ioFDirIndex = 0;
|
||||
infoPB.hFileInfo.ioDirID = 0;
|
||||
err = PBGetCatInfo(&infoPB, FALSE);
|
||||
p2cstr ((StringPtr) pPath);
|
||||
|
||||
if (err == noErr) {
|
||||
pStat->st_mtime = (time_t) infoPB.hFileInfo.ioFlMdDat;
|
||||
pStat->st_ctime = (time_t) infoPB.hFileInfo.ioFlCrDat;
|
||||
pStat->st_mode = S_IREAD | S_IEXEC;
|
||||
|
||||
/* If it is a directory ... */
|
||||
if (infoPB.hFileInfo.ioFlAttrib & 0x10) {
|
||||
pStat->st_size = infoPB.dirInfo.ioDrNmFls;
|
||||
pStat->st_mode |= S_IFDIR;
|
||||
} else {
|
||||
pStat->st_size = infoPB.hFileInfo.ioFlLgLen;
|
||||
pStat->st_mode |= S_IFREG;
|
||||
} /* if ... else */
|
||||
|
||||
/* If it is writeable */
|
||||
if ((infoPB.hFileInfo.ioFlAttrib & 0x1) == 0) {
|
||||
pStat->st_mode |= S_IWRITE;
|
||||
} /* if */
|
||||
|
||||
retVal = 0;
|
||||
|
||||
} else {
|
||||
retVal = -1;
|
||||
} /* if ... else */
|
||||
|
||||
return (retVal);
|
||||
} /* PUBLIC int stat () */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Return the current working directory, or NULL if there is an error.
|
||||
*/
|
||||
PUBLIC char *getcwd (char *pPath, size_t pathSize) {
|
||||
DirInfo dirInfo;
|
||||
OSErr err;
|
||||
Str255 dirName;
|
||||
char *pBeginName;
|
||||
char *pC;
|
||||
size_t len;
|
||||
size_t spaceForColon;
|
||||
|
||||
pPath = Unix2MacFName (pPath);
|
||||
|
||||
/* Set up the info for the PBGetCatInfo() calls */
|
||||
dirInfo.ioCompletion = NULL;
|
||||
dirInfo.ioNamePtr = dirName;
|
||||
dirInfo.ioVRefNum = 0;
|
||||
dirInfo.ioFDirIndex = -1;
|
||||
dirInfo.ioDrDirID = 0;
|
||||
pBeginName = pPath + pathSize - 1;
|
||||
spaceForColon = 0; /* Make sure we don't have an end colon on the name */
|
||||
|
||||
/*
|
||||
* Keep going up the directory path until the end is reached or an error
|
||||
* occurs. Ideally, we would check for errors at every level and stop
|
||||
* when we received an fnfErr (File Not Found), but it appears that there
|
||||
* are some problems with network volumes. (During testing, I received
|
||||
* a paramErr (No Default Volume) beyond the top level.) Thus, to keep it
|
||||
* simple, I assume any error past the first directory indicates we have
|
||||
* seen all directories.
|
||||
*/
|
||||
while (TRUE) {
|
||||
err = PBGetCatInfo ((CInfoPBPtr) &dirInfo, FALSE);
|
||||
len = ((size_t)(unsigned char) dirName[0]);
|
||||
if ((err == noErr) && (len < pBeginName - pPath)) {
|
||||
p2cstr (dirName);
|
||||
pBeginName -= len + spaceForColon;
|
||||
strcpy (pBeginName, dirName);
|
||||
/* Note that strcpy() adds the '\0' at the end of
|
||||
the first directory for us */
|
||||
if (spaceForColon == 1) {
|
||||
pBeginName[len] = ':';
|
||||
} else {
|
||||
/* The end of the string shouldn't have a ':' */
|
||||
spaceForColon = 1;
|
||||
} /* if */
|
||||
|
||||
/* Set up for the next call to PBGetCatInfo() with
|
||||
the parent's directory ID */
|
||||
dirInfo.ioDrDirID = dirInfo.ioDrParID;
|
||||
|
||||
} else if (spaceForColon == 1) {
|
||||
/* We got past the top-level directory */
|
||||
break;
|
||||
|
||||
} else {
|
||||
/* We either have an error when looking at the first directory
|
||||
or have run out of room. */
|
||||
return (NULL);
|
||||
} /* if ... elses */
|
||||
} /* while */
|
||||
|
||||
/* Now copy the directory string to the beginning of the path string.
|
||||
(It's possible the directory already starts at the beginning of the
|
||||
string, but this is unlikely and doesn't hurt anything if it does,
|
||||
so we don't bother to check for it.) */
|
||||
pC = pPath;
|
||||
while ((*(pC++) = *(pBeginName++)) != '\0')
|
||||
;
|
||||
|
||||
return (pPath);
|
||||
} /* PUBLIC char *getcwd () */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Change the directory to a new default directory.
|
||||
*
|
||||
* Return 0 if successful, or -1 if there is an error.
|
||||
*/
|
||||
PUBLIC int chdir (char *pPath) {
|
||||
WDPBRec WDPB;
|
||||
VolumeParam vParam;
|
||||
OSErr err;
|
||||
int result;
|
||||
char *pC;
|
||||
char c;
|
||||
|
||||
pPath = Unix2MacFName (pPath);
|
||||
|
||||
/* Set up the directory */
|
||||
c2pstr (pPath);
|
||||
WDPB.ioCompletion = NULL;
|
||||
WDPB.ioNamePtr = pPath;
|
||||
WDPB.ioVRefNum = 0;
|
||||
WDPB.ioWDProcID = 0;
|
||||
WDPB.ioWDDirID = 0;
|
||||
err = PBOpenWD (&WDPB, FALSE);
|
||||
/* Restore path to a C-type string in case the caller wants
|
||||
to use it after this call. */
|
||||
p2cstr (pPath);
|
||||
if (err != noErr) {
|
||||
return (-1);
|
||||
} /* if */
|
||||
|
||||
/* Set up the volume if necessary */
|
||||
if (*pPath != ':') {
|
||||
for (pC = pPath + 1; (*pC != ':') && (*pC != '\0'); ++pC)
|
||||
;
|
||||
c = *pC;
|
||||
*pC = '\0';
|
||||
vParam.ioCompletion = NULL;
|
||||
vParam.ioNamePtr = c2pstr (pPath);
|
||||
vParam.ioVRefNum = WDPB.ioVRefNum;
|
||||
err = PBSetVol ((ParmBlkPtr) &vParam, FALSE);
|
||||
p2cstr (pPath);
|
||||
*pC = c;
|
||||
result = ((err == noErr) ? 0 : -1);
|
||||
|
||||
} else {
|
||||
result = 0;
|
||||
} /* if ... else */
|
||||
|
||||
return (result);
|
||||
} /* PUBLIC int chdir () */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Change the modification time for the file to the current time.
|
||||
*
|
||||
* The normal version of utime can set the modification time to any
|
||||
* time, this function aborts the function if this is tried.
|
||||
*
|
||||
* We return 0 if the modification time was updated and -1 if there
|
||||
* was an error.
|
||||
*/
|
||||
PUBLIC int utime (char *pPath, time_t *pTimes) {
|
||||
CInfoPBRec infoPB;
|
||||
OSErr err;
|
||||
|
||||
pPath = Unix2MacFName (pPath);
|
||||
|
||||
if (pTimes != NULL) {
|
||||
Fatal ("SUBROUTINE SHORTCOMING: utime cannot take a utimbuf struct");
|
||||
} /* if */
|
||||
|
||||
/* Get the old info */
|
||||
infoPB.hFileInfo.ioCompletion = NULL;
|
||||
infoPB.hFileInfo.ioNamePtr = c2pstr (pPath);
|
||||
infoPB.hFileInfo.ioVRefNum = 0;
|
||||
infoPB.hFileInfo.ioFDirIndex = 0;
|
||||
infoPB.hFileInfo.ioDirID = 0;
|
||||
err = PBGetCatInfo (&infoPB, FALSE);
|
||||
if (err != noErr) {
|
||||
p2cstr ((StringPtr) pPath);
|
||||
return (-1);
|
||||
} /* if */
|
||||
|
||||
/* Change the modification time and set the new info */
|
||||
GetDateTime (&(infoPB.hFileInfo.ioFlMdDat));
|
||||
infoPB.hFileInfo.ioDirID = 0;
|
||||
err = PBSetCatInfo (&infoPB, FALSE);
|
||||
p2cstr ((StringPtr) pPath);
|
||||
return ((err == noErr) ? 0 : -1);
|
||||
} /* PUBLIC int utime () */
|
54
dmake/mac/dompwmak
Normal file
54
dmake/mac/dompwmak
Normal file
@ -0,0 +1,54 @@
|
||||
newfolder objects
|
||||
c -I. -I :mac -d _MPW -s infer -sym off -o :objects:infer.c.o infer.c
|
||||
c -I. -I :mac -d _MPW -s make -sym off -o :objects:make.c.o make.c
|
||||
c -I. -I :mac -d _MPW -s stat -sym off -o :objects:stat.c.o stat.c
|
||||
c -I. -I :mac -d _MPW -s expand -sym off -o :objects:expand.c.o expand.c
|
||||
c -I. -I :mac -d _MPW -s dmstring -sym off -o :objects:dmstring.c.o dmstring.c
|
||||
c -I. -I :mac -d _MPW -s hash -sym off -o :objects:hash.c.o hash.c
|
||||
c -I. -I :mac -d _MPW -s dag -sym off -o :objects:dag.c.o dag.c
|
||||
c -I. -I :mac -d _MPW -s dmake -sym off -o :objects:dmake.c.o dmake.c
|
||||
c -I. -I :mac -d _MPW -s path -sym off -o :objects:path.c.o path.c
|
||||
c -I. -I :mac -d _MPW -s imacs -sym off -o :objects:imacs.c.o imacs.c
|
||||
c -I. -I :mac -d _MPW -s sysintf -sym off -o :objects:sysintf.c.o sysintf.c
|
||||
c -I. -I :mac -d _MPW -s parse -sym off -o :objects:parse.c.o parse.c
|
||||
c -I. -I :mac -d _MPW -s getinp -sym off -o :objects:getinp.c.o getinp.c
|
||||
c -I. -I :mac -d _MPW -s quit -sym off -o :objects:quit.c.o quit.c
|
||||
c -I. -I :mac -d _MPW -s state -sym off -o :objects:state.c.o state.c
|
||||
c -I. -I :mac -d _MPW -s basename -sym off -o :objects:basename.c.o basename.c
|
||||
c -I. -I :mac -d _MPW -s dmdump -sym off -o :objects:dmdump.c.o dmdump.c
|
||||
c -I. -I :mac -d _MPW -s macparse -sym off -o :objects:macparse.c.o macparse.c
|
||||
c -I. -I :mac -d _MPW -s rulparse -sym off -o :objects:rulparse.c.o rulparse.c
|
||||
c -I. -I :mac -d _MPW -s percent -sym off -o :objects:percent.c.o percent.c
|
||||
c -I. -I :mac -d _MPW -s function -sym off -o :objects:function.c.o function.c
|
||||
duplicate -y :mac:arlib.c arlib.c
|
||||
c -I. -I :mac -d _MPW -s arlib -sym off -o :objects:arlib.c.o arlib.c
|
||||
delete arlib.c
|
||||
duplicate -y :mac:bogus.c bogus.c
|
||||
c -I. -I :mac -d _MPW -s bogus -sym off -o :objects:bogus.c.o bogus.c
|
||||
delete bogus.c
|
||||
duplicate -y :mac:dirbrk.c dirbrk.c
|
||||
c -I. -I :mac -d _MPW -s dirbrk -sym off -o :objects:dirbrk.c.o dirbrk.c
|
||||
delete dirbrk.c
|
||||
duplicate -y :mac:directry.c directry.c
|
||||
c -I. -I :mac -d _MPW -s directry -sym off -o :objects:directry.c.o directry.c
|
||||
delete directry.c
|
||||
duplicate -y :mac:environ.c environ.c
|
||||
c -I. -I :mac -d _MPW -s environ -sym off -o :objects:environ.c.o environ.c
|
||||
delete environ.c
|
||||
duplicate -y :mac:main.c main.c
|
||||
c -I. -I :mac -d _MPW -s main -sym off -o :objects:main.c.o main.c
|
||||
delete main.c
|
||||
duplicate -y :mac:rmprq.c rmprq.c
|
||||
c -I. -I :mac -d _MPW -s rmprq -sym off -o :objects:rmprq.c.o rmprq.c
|
||||
delete rmprq.c
|
||||
duplicate -y :mac:ruletab.c ruletab.c
|
||||
c -I. -I :mac -d _MPW -s ruletab -sym off -o :objects:ruletab.c.o ruletab.c
|
||||
delete ruletab.c
|
||||
duplicate -y :mac:tempnam.c tempnam.c
|
||||
c -I. -I :mac -d _MPW -s tempnam -sym off -o :objects:tempnam.c.o tempnam.c
|
||||
delete tempnam.c
|
||||
duplicate -y :mac:tomacfil.c tomacfil.c
|
||||
c -I. -I :mac -d _MPW -s tomacfil -sym off -o :objects:tomacfil.c.o tomacfil.c
|
||||
delete tomacfil.c
|
||||
link -w -c 'MPS ' -t MPST -sym off -o dmake :objects:infer.c.o :objects:make.c.o :objects:stat.c.o :objects:expand.c.o :objects:dmstring.c.o :objects:hash.c.o :objects:dag.c.o :objects:dmake.c.o :objects:path.c.o :objects:imacs.c.o :objects:sysintf.c.o :objects:parse.c.o :objects:getinp.c.o :objects:quit.c.o :objects:state.c.o :objects:basename.c.o :objects:dmdump.c.o :objects:macparse.c.o :objects:rulparse.c.o :objects:percent.c.o :objects:function.c.o :objects:arlib.c.o :objects:bogus.c.o :objects:dirbrk.c.o :objects:directry.c.o :objects:environ.c.o :objects:main.c.o :objects:rmprq.c.o :objects:ruletab.c.o :objects:tempnam.c.o :objects:tomacfil.c.o "Micah:MPW:Libraries:CLibraries:CSANELib.o" "Micah:MPW:Libraries:CLibraries:Math.o" "Micah:MPW:Libraries:CLibraries:StdCLib.o" "Micah:MPW:Libraries:Libraries:Runtime.o" "Micah:MPW:Libraries:Libraries:Interface.o" "Micah:MPW:Libraries:Libraries:Toollibs.o"
|
||||
duplicate :mac:startup.mk startup.mk
|
236
dmake/mac/environ.c
Normal file
236
dmake/mac/environ.c
Normal file
@ -0,0 +1,236 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/mac/environ.c,v 1.1 1992/01/24 03:29:46 dvadura Exp $
|
||||
-- SYNOPSIS -- Set up and free for environ
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- This file contains routines that will fill in and dispose of the
|
||||
-- list of environmental variables in the environ global variable.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: environ.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:46 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
/* The char used to replace the equal signs in environmental variable names. */
|
||||
const char kEqualReplace = '_';
|
||||
|
||||
/* Maximum size of a "name=value" environmental string, including the ending '\0'.
|
||||
Larger environmental variables will be clipped before dmake sees them.
|
||||
(Caution: When I tested the program, the Mac or dmake trashed memory
|
||||
when environmental variables of >4K were read in. I looked around a bit
|
||||
and couldn't find out the exact cause, so I simply made this variable.
|
||||
The memory trashing may be related to the value for MAXLINELENGTH.) */
|
||||
const int kMaxEnvLen = 1024;
|
||||
|
||||
|
||||
/* The list of environmental variables in the form "name=value".
|
||||
(Once make_env() has been called.) */
|
||||
char **environ = NULL;
|
||||
|
||||
/* Characters replaced during make_env() */
|
||||
struct ReplaceChar {
|
||||
char *fpPos;
|
||||
char fC;
|
||||
struct ReplaceChar *fpNext;
|
||||
}; /* struct ReplaceChar */
|
||||
struct ReplaceChar *gpReplaceList = NULL;
|
||||
|
||||
|
||||
void AddReplace (char *pReplacePos);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Set up the environmental variables in a format used by
|
||||
* the environ global variable.
|
||||
*
|
||||
* environ has already been set to main's envp argument when
|
||||
* this suboroutine is called. We assume that envp is a copy
|
||||
* MPW makes for this process' use alone, so we can modify it
|
||||
* below.
|
||||
*/
|
||||
PUBLIC void make_env () {
|
||||
char **ppCurEnv;
|
||||
char *pCurPos;
|
||||
#if 0
|
||||
char **ppMacEnv;
|
||||
char *pMacPos;
|
||||
|
||||
if (!gMECalled) {
|
||||
gMECalled = TRUE;
|
||||
|
||||
environ = MALLOC (1, char *);
|
||||
*environ = NULL;
|
||||
#endif
|
||||
#if 0
|
||||
{
|
||||
int numenv;
|
||||
int len;
|
||||
int firstnil;
|
||||
|
||||
numenv = 1;
|
||||
ppMacEnv = environ;
|
||||
while (*(ppMacEnv++) != NULL) {
|
||||
++numenv;
|
||||
} /* while */
|
||||
|
||||
ppMacEnv = environ;
|
||||
if ((environ = MALLOC (numenv, char *)) == NULL) {
|
||||
No_ram ();
|
||||
} /* if */
|
||||
|
||||
numenv = 80;
|
||||
for (ppCurEnv = environ; (numenv-- > 0) && (*ppMacEnv != NULL); ++ppCurEnv, ++ppMacEnv) {
|
||||
pMacPos = *ppMacEnv;
|
||||
len = strlen (pMacPos) + 1;
|
||||
len += strlen (pMacPos + len) + 1;
|
||||
#define MAXLEN 4098
|
||||
if (len > MAXLEN) len = MAXLEN;
|
||||
if ((*ppCurEnv = MALLOC (len, char)) == NULL) {
|
||||
No_ram ();
|
||||
} /* if */
|
||||
|
||||
firstnil = TRUE;
|
||||
for (pCurPos = *ppCurEnv; ((pCurPos - *ppCurEnv) < MAXLEN - 1); ++pCurPos, ++pMacPos) {
|
||||
if (*pMacPos == '=') {
|
||||
*pCurPos = gEqualReplace;
|
||||
|
||||
} else if (*pMacPos == '\0') {
|
||||
if (firstnil) {
|
||||
*pCurPos = '=';
|
||||
firstnil = FALSE;
|
||||
} else {
|
||||
*pCurPos = *pMacPos;
|
||||
break;
|
||||
} /* if ... else */
|
||||
|
||||
} else {
|
||||
*pCurPos = *pMacPos;
|
||||
} /* if ... elses */
|
||||
} /* for */
|
||||
firstnil = FALSE;
|
||||
} /* for */
|
||||
*ppCurEnv = NULL;
|
||||
}
|
||||
#endif
|
||||
{
|
||||
int firstnil;
|
||||
|
||||
/* Get rid of any equal signs in any environmental name, and put
|
||||
equal signs between the names and their values */
|
||||
for (ppCurEnv = environ; *ppCurEnv != NULL; ++ppCurEnv) {
|
||||
|
||||
firstnil = TRUE;
|
||||
for (pCurPos = *ppCurEnv;
|
||||
((pCurPos - *ppCurEnv < kMaxEnvLen - 1) &&
|
||||
((*pCurPos != '\0') || !firstnil));
|
||||
++pCurPos) {
|
||||
if (*pCurPos == '=') {
|
||||
AddReplace (pCurPos);
|
||||
*pCurPos = kEqualReplace;
|
||||
|
||||
} else if (*pCurPos == '\0') {
|
||||
AddReplace (pCurPos);
|
||||
*pCurPos = '=';
|
||||
firstnil = FALSE;
|
||||
} /* if ... else if */
|
||||
} /* for */
|
||||
|
||||
/* If the environtmental variable was too large ... */
|
||||
if (*pCurPos != '\0') {
|
||||
AddReplace (pCurPos);
|
||||
*pCurPos = '\0';
|
||||
if (firstnil) {
|
||||
AddReplace (--pCurPos);
|
||||
*pCurPos = '=';
|
||||
} /* if */
|
||||
} /* if */
|
||||
} /* for */
|
||||
}
|
||||
#if 0
|
||||
} /* if */
|
||||
#endif
|
||||
} /* PUBLIC void make_env () */
|
||||
|
||||
|
||||
/*
|
||||
* The character at pReplacePos is about to be replaced. Remember the
|
||||
* old value so we can restore it when we're done.
|
||||
*/
|
||||
void AddReplace (char *pReplacePos) {
|
||||
struct ReplaceChar *pReplaceChar;
|
||||
|
||||
if ((pReplaceChar = MALLOC (1, struct ReplaceChar)) == NULL) {
|
||||
No_ram ();
|
||||
} /* if */
|
||||
pReplaceChar->fpPos = pReplacePos;
|
||||
pReplaceChar->fC = *pReplacePos;
|
||||
pReplaceChar->fpNext = gpReplaceList;
|
||||
gpReplaceList = pReplaceChar;
|
||||
} /* void AddReplace () */
|
||||
|
||||
|
||||
/*
|
||||
* Restore the old environmental variables to the way they looked before
|
||||
* the make_env() call, on the unlikely chance that something else will look
|
||||
* at our copy of the environmental variables during the program execution.
|
||||
*
|
||||
*/
|
||||
PUBLIC void free_env () {
|
||||
struct ReplaceChar *pReplaceChar;
|
||||
|
||||
while (gpReplaceList != NULL) {
|
||||
pReplaceChar = gpReplaceList;
|
||||
gpReplaceList = pReplaceChar->fpNext;
|
||||
|
||||
*(pReplaceChar->fpPos) = pReplaceChar->fC;
|
||||
|
||||
FREE (pReplaceChar);
|
||||
} /* while */
|
||||
|
||||
#if 0
|
||||
char **ppCurEnv;
|
||||
char *pCurPos;
|
||||
|
||||
if (!gFECalled) {
|
||||
gFECalled = TRUE;
|
||||
|
||||
//FREE (environ);
|
||||
environ = NULL;
|
||||
#endif
|
||||
#if 0
|
||||
/* Restore the environment list to what it was before we
|
||||
read it in. */
|
||||
for (ppCurEnv = environ; *ppCurEnv != NULL; ++ppCurEnv) {
|
||||
for (pCurPos = *ppCurEnv; *pCurPos != '='; ++pCurPos)
|
||||
;
|
||||
*pCurPos = '\0';
|
||||
} /* for */
|
||||
} /* if */
|
||||
#endif
|
||||
} /* PUBLIC void free_env () */
|
128
dmake/mac/eold.c
Normal file
128
dmake/mac/eold.c
Normal file
@ -0,0 +1,128 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/mac/eold.c,v 1.1 1992/01/24 03:29:47 dvadura Exp $
|
||||
-- SYNOPSIS -- Set up and free for environ
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- This file contains routines that will fill in and dispose of the
|
||||
-- list of environmental variables in the environ global variable.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: eold.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:47 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
|
||||
/*
|
||||
* Keep track of any environmental variables that have '='s in their
|
||||
* name.
|
||||
*/
|
||||
struct EqualPos {
|
||||
char *fpPos;
|
||||
struct equalsign *fpNext;
|
||||
} /* struct EqualPos */
|
||||
|
||||
struct EqualPos *gpEqualList;
|
||||
|
||||
/*
|
||||
* The character used to replae the equal signs.
|
||||
*/
|
||||
const char gEqualReplace = '_';
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Set up the environmental variables in a format used by
|
||||
* the environ global variable.
|
||||
*
|
||||
* environ has already been set to main's envp argument when
|
||||
* this suboroutine is called.
|
||||
*/
|
||||
void main_env () {
|
||||
char **ppCurEnv;
|
||||
char *pCurPos;
|
||||
struct equalpos *pNewEqual;
|
||||
|
||||
gpEqualList = NULL;
|
||||
|
||||
for (ppCurEnv = environ; *ppCurEnv != NULL; ++ppCurEnv) {
|
||||
for (pCurPos = *ppCurEnv; *pCurPos != '\0'; ++pCurPos) {
|
||||
if (*pCurPos == '=') {
|
||||
if ((pNewEqual =
|
||||
(struct EqualPos *) malloc (sizeof (struct EqualPos))) ==
|
||||
NULL) {
|
||||
fputs ("Out of Memory", stderr);
|
||||
exit (EXIT_FAILURE);
|
||||
} /* if */
|
||||
pNewEqual->fpPos = pCurPos;
|
||||
pNewEqual->fpNext = gpEqualList;
|
||||
gpEqualList = pNewEqual;
|
||||
|
||||
*pCurPos = gEqualReplace;
|
||||
} /* if */
|
||||
} /* for */
|
||||
|
||||
*pCurPos = '=';
|
||||
} /* for */
|
||||
} /* void main_env () */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Reset the environmental variables so they look like they did
|
||||
* before the main_env() call.
|
||||
*
|
||||
* environ has already been set to main's envp argument when
|
||||
* this suboroutine is called.
|
||||
*/
|
||||
void main_env () {
|
||||
char **ppCurEnv;
|
||||
char *pCurPos;
|
||||
struct equalpos *pNewEqual;
|
||||
|
||||
gpEqualList = NULL;
|
||||
|
||||
for (ppCurEnv = environ; *ppCurEnv != NULL; ++ppCurEnv) {
|
||||
for (pCurPos = *ppCurEnv; *pCurPos != '\0'; ++pCurPos) {
|
||||
if (*pCurPos == '=') {
|
||||
if ((pNewEqual =
|
||||
(struct EqualPos *) malloc (sizeof (struct EqualPos))) ==
|
||||
NULL) {
|
||||
fputs ("Out of Memory", stderr);
|
||||
exit (EXIT_FAILURE);
|
||||
} /* if */
|
||||
pNewEqual->fpPos = pCurPos;
|
||||
pNewEqual->fpNext = gpEqualList;
|
||||
gpEqualList = pNewEqual;
|
||||
|
||||
*pCurPos = gEqualReplace;
|
||||
} /* if */
|
||||
} /* for */
|
||||
|
||||
*pCurPos = '=';
|
||||
} /* for */
|
||||
} /* void main_env () */
|
52
dmake/mac/main.c
Normal file
52
dmake/mac/main.c
Normal file
@ -0,0 +1,52 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/mac/main.c,v 1.1 1992/01/24 03:29:48 dvadura Exp $
|
||||
-- SYNOPSIS -- The real main function
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- In order to get the third argument to main(), which is a list of
|
||||
-- environmental variables, we have #defined main to dmakemain,
|
||||
-- and put the real main here.
|
||||
--
|
||||
-- The environmental variables are placed in the environ global variable
|
||||
-- and set up for processing by dmake in make_env().
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: main.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:48 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Put envp in environ and call dmake's main().
|
||||
*/
|
||||
#undef main
|
||||
void main (int argc, char *argv[], char *envp[]) {
|
||||
environ = envp;
|
||||
dmakemain (argc, argv);
|
||||
} /* void main () */
|
43
dmake/mac/make.sh
Normal file
43
dmake/mac/make.sh
Normal file
@ -0,0 +1,43 @@
|
||||
newfolder objects
|
||||
c -I. -I :mac -d _MPW -s infer -sym off -o :objects:infer.c.o infer.c
|
||||
c -I. -I :mac -d _MPW -s make -sym off -o :objects:make.c.o make.c
|
||||
c -I. -I :mac -d _MPW -s stat -sym off -o :objects:stat.c.o stat.c
|
||||
c -I. -I :mac -d _MPW -s expand -sym off -o :objects:expand.c.o expand.c
|
||||
c -I. -I :mac -d _MPW -s dmstring -sym off -o :objects:dmstring.c.o dmstring.c
|
||||
c -I. -I :mac -d _MPW -s hash -sym off -o :objects:hash.c.o hash.c
|
||||
c -I. -I :mac -d _MPW -s dag -sym off -o :objects:dag.c.o dag.c
|
||||
c -I. -I :mac -d _MPW -s dmake -sym off -o :objects:dmake.c.o dmake.c
|
||||
c -I. -I :mac -d _MPW -s path -sym off -o :objects:path.c.o path.c
|
||||
c -I. -I :mac -d _MPW -s imacs -sym off -o :objects:imacs.c.o imacs.c
|
||||
c -I. -I :mac -d _MPW -s sysintf -sym off -o :objects:sysintf.c.o sysintf.c
|
||||
c -I. -I :mac -d _MPW -s parse -sym off -o :objects:parse.c.o parse.c
|
||||
c -I. -I :mac -d _MPW -s getinp -sym off -o :objects:getinp.c.o getinp.c
|
||||
c -I. -I :mac -d _MPW -s quit -sym off -o :objects:quit.c.o quit.c
|
||||
c -I. -I :mac -d _MPW -s state -sym off -o :objects:state.c.o state.c
|
||||
c -I. -I :mac -d _MPW -s basename -sym off -o :objects:basename.c.o basename.c
|
||||
c -I. -I :mac -d _MPW -s dmdump -sym off -o :objects:dmdump.c.o dmdump.c
|
||||
c -I. -I :mac -d _MPW -s macparse -sym off -o :objects:macparse.c.o macparse.c
|
||||
c -I. -I :mac -d _MPW -s rulparse -sym off -o :objects:rulparse.c.o rulparse.c
|
||||
c -I. -I :mac -d _MPW -s percent -sym off -o :objects:percent.c.o percent.c
|
||||
c -I. -I :mac -d _MPW -s function -sym off -o :objects:function.c.o function.c
|
||||
c -I. -I :mac -d _MPW -s arlib -sym off -o :objects:arlib.c.o :mac:arlib.c
|
||||
c -I. -I :mac -d _MPW -s bogus -sym off -o :objects:bogus.c.o :mac:bogus.c
|
||||
c -I. -I :mac -d _MPW -s dirbrk -sym off -o :objects:dirbrk.c.o :mac:dirbrk.c
|
||||
c -I. -I :mac -d _MPW -s directry -sym off -o :objects:directry.c.o :mac:directry.c
|
||||
c -I. -I :mac -d _MPW -s environ -sym off -o :objects:environ.c.o :mac:environ.c
|
||||
c -I. -I :mac -d _MPW -s main -sym off -o :objects:main.c.o :mac:main.c
|
||||
c -I. -I :mac -d _MPW -s rmprq -sym off -o :objects:rmprq.c.o :mac:rmprq.c
|
||||
c -I. -I :mac -d _MPW -s ruletab -sym off -o :objects:ruletab.c.o :mac:ruletab.c
|
||||
c -I. -I :mac -d _MPW -s tempnam -sym off -o :objects:tempnam.c.o :mac:tempnam.c
|
||||
c -I. -I :mac -d _MPW -s tomacfil -sym off -o :objects:tomacfil.c.o :mac:tomacfil.c
|
||||
link -w -c 'MPS ' -t MPST -sym off -o dmake :objects:infer.c.o \
|
||||
:objects:make.c.o :objects:stat.c.o :objects:expand.c.o :objects:dmstring.c.o \
|
||||
:objects:hash.c.o :objects:dag.c.o :objects:dmake.c.o :objects:path.c.o \
|
||||
:objects:imacs.c.o :objects:sysintf.c.o :objects:parse.c.o :objects:getinp.c.o \
|
||||
:objects:quit.c.o :objects:state.c.o :objects:basename.c.o :objects:dmdump.c.o \
|
||||
:objects:macparse.c.o :objects:rulparse.c.o :objects:percent.c.o \
|
||||
:objects:function.c.o :objects:arlib.c.o :objects:bogus.c.o :objects:dirbrk.c.o \
|
||||
:objects:directry.c.o :objects:environ.c.o :objects:main.c.o :objects:rmprq.c.o \
|
||||
:objects:ruletab.c.o :objects:tempnam.c.o :objects:tomacfil.c.o "CSANELib.o" \
|
||||
"Math.o" "StdCLib.o" "Runtime.o" "Interface.o" "Toollibs.o"
|
||||
duplicate :mac:startup.mk startup.mk
|
152
dmake/mac/public.h
Normal file
152
dmake/mac/public.h
Normal file
@ -0,0 +1,152 @@
|
||||
/* RCS -- $Header$
|
||||
-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT
|
||||
--
|
||||
-- SYNOPSIS -- Local functions exported to be visible by others.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- This file is generated by 'genpub'. Function declarations
|
||||
-- that appear in this file are extracted by 'genpub' from
|
||||
-- source files. Any function in the source file whose definition
|
||||
-- appears like:
|
||||
--
|
||||
-- PUBLIC return_type
|
||||
-- function( arg_list );
|
||||
-- type_expr1 arg1;
|
||||
-- ...
|
||||
--
|
||||
-- has its definition extracted and a line of the form:
|
||||
--
|
||||
-- return_type function ANSI((type_expr1,type_expr2,...));
|
||||
--
|
||||
-- entered into the output file.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log$
|
||||
*/
|
||||
|
||||
#ifndef _DMAKE_PUBLIC_h
|
||||
#define _DMAKE_PUBLIC_h
|
||||
|
||||
void Infer_recipe ANSI((CELLPTR, CELLPTR));
|
||||
int Make_targets ANSI(());
|
||||
int Exec_commands ANSI((CELLPTR));
|
||||
void Print_cmnd ANSI((char *, int, int));
|
||||
void Pop_dir ANSI((int));
|
||||
void Append_line ANSI((char *, int, FILE *, char *, int, int));
|
||||
void Stat_target ANSI((CELLPTR, int));
|
||||
char * Expand ANSI((char *));
|
||||
char * Apply_edit ANSI((char *, char *, char *, int, int));
|
||||
void Map_esc ANSI((char *));
|
||||
char* Apply_modifiers ANSI((int, char *));
|
||||
char* Tokenize ANSI((char *, char *));
|
||||
char * _strjoin ANSI((char *, char *, int, int));
|
||||
char * _stradd ANSI((char *, char *, int));
|
||||
char * _strapp ANSI((char *, char *));
|
||||
char * _strdup ANSI((char *));
|
||||
char * _strdup2 ANSI((char *));
|
||||
char * _strpbrk ANSI((char *, char *));
|
||||
char * _strspn ANSI((char *, char *));
|
||||
char * _strstr ANSI((char *, char *));
|
||||
char * _substr ANSI((char *, char *));
|
||||
uint16 Hash ANSI((char *, uint32 *));
|
||||
HASHPTR Get_name ANSI((char *, HASHPTR *, int));
|
||||
HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *));
|
||||
HASHPTR Def_macro ANSI((char *, char *, int));
|
||||
CELLPTR Def_cell ANSI((char *));
|
||||
LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int));
|
||||
void Clear_prerequisites ANSI((CELLPTR));
|
||||
int Test_circle ANSI((CELLPTR, int));
|
||||
STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int));
|
||||
t_attr Rcp_attribute ANSI((char *));
|
||||
void main ANSI((int, char **));
|
||||
FILE * Openfile ANSI((char *, int, int));
|
||||
FILE * Closefile ANSI(());
|
||||
FILE * Search_file ANSI((char *, char **));
|
||||
char * Filename ANSI(());
|
||||
int Nestlevel ANSI(());
|
||||
void No_ram ANSI(());
|
||||
int Usage ANSI((int));
|
||||
int Version ANSI(());
|
||||
char * Get_suffix ANSI((char *));
|
||||
char * Build_path ANSI((char *, char *));
|
||||
void Make_rules ANSI(());
|
||||
void Create_macro_vars ANSI(());
|
||||
time_t Do_stat ANSI((char *, char *, char **));
|
||||
int Do_touch ANSI((char *, char *, char **));
|
||||
void Void_lib_cache ANSI((char *, char *));
|
||||
time_t Do_time ANSI(());
|
||||
int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int));
|
||||
char ** Pack_argv ANSI((int, int, char *));
|
||||
char * Read_env_string ANSI((char *));
|
||||
int Write_env_string ANSI((char *, char *));
|
||||
void ReadEnvironment ANSI(());
|
||||
void Catch_signals ANSI((void (*)()));
|
||||
void Clear_signals ANSI(());
|
||||
void Prolog ANSI((int, char* []));
|
||||
void Epilog ANSI((int));
|
||||
char * Get_current_dir ANSI(());
|
||||
int Set_dir ANSI((char*));
|
||||
char Get_switch_char ANSI(());
|
||||
FILE* Get_temp ANSI((char **, char *, int));
|
||||
FILE * Start_temp ANSI((char *, CELLPTR, char **));
|
||||
void Open_temp_error ANSI((char *, char *));
|
||||
void Link_temp ANSI((CELLPTR, FILE *, char *));
|
||||
void Close_temp ANSI((CELLPTR, FILE *));
|
||||
void Unlink_temp_files ANSI((CELLPTR));
|
||||
void Handle_result ANSI((int, int, int, CELLPTR));
|
||||
void Update_time_stamp ANSI((CELLPTR));
|
||||
int Remove_file ANSI((char *));
|
||||
void Parse ANSI((FILE *));
|
||||
int Get_line ANSI((char *, FILE *));
|
||||
char * Do_comment ANSI((char *, char **, int));
|
||||
char * Get_token ANSI((TKSTRPTR, char *, int));
|
||||
void Quit ANSI(());
|
||||
void Read_state ANSI(());
|
||||
void Write_state ANSI(());
|
||||
int Check_state ANSI((CELLPTR, STRINGPTR *, int));
|
||||
char* basename ANSI((char *));
|
||||
void Dump ANSI(());
|
||||
void Dump_recipe ANSI((STRINGPTR));
|
||||
int Parse_macro ANSI((char *, int));
|
||||
int Macro_op ANSI((char *));
|
||||
int Parse_rule_def ANSI((int *));
|
||||
int Rule_op ANSI((char *));
|
||||
void Add_recipe_to_list ANSI((char *, int, int));
|
||||
void Bind_rules_to_targets ANSI((int));
|
||||
int Set_group_attributes ANSI((char *));
|
||||
DFALINKPTR Match_dfa ANSI((char *));
|
||||
void Check_circle_dfa ANSI(());
|
||||
void Add_nfa ANSI((char *));
|
||||
char * Exec_function ANSI((char *));
|
||||
time_t seek_arch ANSI(());
|
||||
void tzset () {} PUBLIC int putenv ANSI((PUBLIC int Wait_for_child(int /* abort_flg */, int /* pid */) {return (1)));
|
||||
int If_root_path ANSI((char *));
|
||||
int stat(pPath, pStat) pPath = Unix2MacFName ANSI(());
|
||||
void make_env () { if ANSI((environ = MALLOC (1, char *), *environ = NULL));
|
||||
void free_env () { while ANSI((//FREE (environ), environ = NULL));
|
||||
void Remove_prq ANSI((CELLPTR));
|
||||
char *tempnam (char * /* pDir */, char * pPrefix) { pName = tmpnam ANSI(());
|
||||
char *Unix2MacFName(char *pUnixName) { if ANSI(());
|
||||
|
||||
#endif
|
47
dmake/mac/rmprq.c
Normal file
47
dmake/mac/rmprq.c
Normal file
@ -0,0 +1,47 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/mac/rmprq.c,v 1.1 1992/01/24 03:29:48 dvadura Exp $
|
||||
-- SYNOPSIS -- remove prerequisites code.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- This code is different for The Mac and for UNIX and parallel make
|
||||
-- architectures since the parallel case requires the rm's to be
|
||||
-- run in parallel, whereas The Mac guarantees to run them sequentially.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: rmprq.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:48 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
PUBLIC void
|
||||
Remove_prq( tcp )
|
||||
CELLPTR tcp;
|
||||
{
|
||||
tcp->ce_flag &= ~(F_MADE|F_VISITED);
|
||||
tcp->ce_time = 0L;
|
||||
|
||||
Make( tcp, NIL(LINK), NIL(CELL) );
|
||||
}
|
52
dmake/mac/ruletab.c
Normal file
52
dmake/mac/ruletab.c
Normal file
@ -0,0 +1,52 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/mac/ruletab.c,v 1.1 1992/01/24 03:29:49 dvadura Exp $
|
||||
-- SYNOPSIS -- Default initial configuration of dmake.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- Define here the initial set of rules that are defined before
|
||||
-- dmake performs any processing.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: ruletab.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:49 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
/* These are control macros for dmake that MUST be defined at some point
|
||||
* if they are NOT dmake will not work! These are default definitions. They
|
||||
* may be overridden inside the .STARTUP makefile, they are here
|
||||
* strictly so that dmake can parse the STARTUP makefile */
|
||||
|
||||
static char *_rules[] = {
|
||||
"MAXLINELENGTH := 4094",
|
||||
"MAXPROCESSLIMIT := 1",
|
||||
"MAXPROCESS := 1",
|
||||
".IMPORT .IGNORE: MPW DMSTARTUPDIR",
|
||||
".MAKEFILES : makefile.mk makefile",
|
||||
".SOURCE : .NULL",
|
||||
#include "startup.h"
|
||||
0 };
|
||||
|
||||
char **Rule_tab = _rules; /* for sundry reasons in Get_environment() */
|
||||
|
7
dmake/mac/startup.h
Normal file
7
dmake/mac/startup.h
Normal file
@ -0,0 +1,7 @@
|
||||
/* This file contains the default value of the DMMAKESTARTUP variable.
|
||||
* You must set the quoted string below to the default path to the startup
|
||||
* variable, so that it gets compiled in. LEAVE DMSTARTUPDIR in
|
||||
* the path. This allows the user to customize his environment for dmake
|
||||
* by setting up a new DMSTARTUPDIR environment variable. */
|
||||
|
||||
"MAKESTARTUP := $(MPW)tools:$(DMSTARTUPDIR)startup.mk",
|
126
dmake/mac/startup.mk
Normal file
126
dmake/mac/startup.mk
Normal file
@ -0,0 +1,126 @@
|
||||
# MPW Mac startup file. Customize to suit your needs.
|
||||
# Assumes MPW C. Change as req'd.
|
||||
# See the documentation for a description of internally defined macros.
|
||||
#
|
||||
# Disable warnings for macros redefined here that were given
|
||||
# on the command line.
|
||||
__.SILENT := $(.SILENT)
|
||||
.SILENT := yes
|
||||
|
||||
# Configuration parameters for DMAKE startup.mk file
|
||||
# Set these to NON-NULL if you wish to turn the parameter on.
|
||||
_HAVE_RCS := yes # yes => RCS is installed.
|
||||
_HAVE_SCCS := # yes => SCCS is installed.
|
||||
|
||||
# Applicable suffix definitions
|
||||
A := .lib # Libraries
|
||||
C := .c # C
|
||||
E := # Executables
|
||||
F := .f # Fortran
|
||||
O := .c.o # Object files: Assume they are created from C files
|
||||
P := .p # Pascal
|
||||
S := .a # Assembler sources
|
||||
V := v # RCS suffix
|
||||
|
||||
# See if these are defined
|
||||
TMPDIR := $(MPW)/tmp
|
||||
.IMPORT .IGNORE : TMPDIR
|
||||
.IMPORT .IGNORE : CLibraries Libraries
|
||||
|
||||
# Set arguments for the SHELL. Since we can't execute sub-processes,
|
||||
# these variables are not important, except for some makefiles that check
|
||||
# for some values to determine the platform.
|
||||
SHELL := mpw
|
||||
SHELLFLAGS :=
|
||||
GROUPFLAGS :=
|
||||
SHELLMETAS :=
|
||||
GROUPSUFFIX :=
|
||||
DIVFILE = $(TMPFILE)
|
||||
|
||||
# Standard C-language command names and flags
|
||||
CC := c # C-compiler and flags
|
||||
CFLAGS +=
|
||||
|
||||
AS := asm # Assembler and flags
|
||||
ASFLAGS +=
|
||||
|
||||
LD = link # Loader and flags
|
||||
LDFLAGS +=
|
||||
LDLIBS = "$(CLibraries)CSANELib.o" "$(CLibraries)Math.o" \
|
||||
"$(CLibraries)StdCLib.o" "$(Libraries)Runtime.o" \
|
||||
"$(Libraries)Interface.o" "$(Libraries)Toollibs.o"
|
||||
|
||||
# Definition of $(MAKE) macro for recursive makes.
|
||||
MAKE = $(MAKECMD) $(MFLAGS)
|
||||
|
||||
# Language and Parser generation Tools and their flags
|
||||
YACC := yacc # standard yacc
|
||||
YFLAGS +=
|
||||
YTAB := ytab # yacc output files name stem.
|
||||
|
||||
LEX := lex # standard lex
|
||||
LFLAGS +=
|
||||
LEXYY := lex_yy # lex output file
|
||||
|
||||
# Other Compilers, Tools and their flags
|
||||
PC := any_pc # pascal compiler
|
||||
RC := anyf77 # ratfor compiler
|
||||
FC := anyf77 # fortran compiler
|
||||
|
||||
CO := co # check out for RCS
|
||||
COFLAGS += -q
|
||||
|
||||
RM := delete # remove a file command
|
||||
RMFLAGS +=
|
||||
|
||||
# Implicit generation rules for making inferences.
|
||||
# We don't provide .yr or .ye rules here. They're obsolete.
|
||||
# Rules for making *$O
|
||||
%$C.o : %$C ; $(CC) $(CFLAGS) -c $<
|
||||
%$P.o : %$P ; $(PC) $(PFLAGS) -c $<
|
||||
%$S.o : %$S ; $(AS) $(ASFLAGS) $(<:s,/,\);
|
||||
%$F.o : %$F ; $(FC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $<
|
||||
|
||||
# Executables rules should go here. However, on the Mac, there is not
|
||||
# executable suffix (such as ".exe") and thus we end up with rules like
|
||||
# "% : %.c.o", which cause circular-dependency errors. Thus, it's easier
|
||||
# just to avoid specifiying any default rule for executables.
|
||||
|
||||
# lex and yacc rules
|
||||
%.c : %.y ; $(YACC) $(YFLAGS) $<; mv $(YTAB).c $@
|
||||
%.c : %.l ; $(LEX) $(LFLAGS) $<; mv $(LEXYY).c $@
|
||||
|
||||
# RCS support
|
||||
.IF $(_HAVE_RCS)
|
||||
% : $$(@:d)RCS$$(DIRSEPSTR)$$(@:f)$V;- $(CO) $(COFLAGS) $@
|
||||
.NOINFER : $$(@:d)RCS$$(DIRSEPSTR)$$(@:f)$V
|
||||
.END
|
||||
|
||||
# SCCS support
|
||||
.IF $(_HAVE_SCCS)
|
||||
% : s.% ; get $@
|
||||
.NOINFER : s.%
|
||||
.END
|
||||
|
||||
# DMAKE uses this recipe to remove intermediate targets
|
||||
.REMOVE :; $(RM) $<
|
||||
|
||||
# AUGMAKE extensions for SYSV compatibility
|
||||
@B = $(@:b)
|
||||
@D = $(@:d)
|
||||
@F = $(@:f)
|
||||
"*B" = $(*:b)
|
||||
"*D" = $(*:d)
|
||||
"*F" = $(*:f)
|
||||
<B = $(<:b)
|
||||
<D = $(<:d)
|
||||
<F = $(<:f)
|
||||
?B = $(?:b)
|
||||
?F = $(?:f)
|
||||
?D = $(?:d)
|
||||
|
||||
# Turn warnings back to previous setting.
|
||||
.SILENT := $(__.SILENT)
|
||||
|
||||
# Local init file if any, gets parsed before user makefile
|
||||
.INCLUDE .IGNORE: "_startup.mk"
|
23
dmake/mac/sysintf.h
Normal file
23
dmake/mac/sysintf.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
** assorted bits of system interface, for common routines inside dmake.
|
||||
** System specific code can be found in the config.h files for each
|
||||
** of the system specifications.
|
||||
*/
|
||||
#define STAT stat
|
||||
#define VOID_LCACHE(l,m)
|
||||
#define Hook_std_writes(A)
|
||||
#define GETPID 1
|
||||
|
||||
/*
|
||||
** standard C items
|
||||
*/
|
||||
|
||||
/*
|
||||
** Mac interface standard items
|
||||
*/
|
||||
#define getswitchar() '-'
|
||||
|
||||
/*
|
||||
** make parameters
|
||||
*/
|
||||
#define MAX_PATH_LEN 1024
|
72
dmake/mac/tempnam.c
Normal file
72
dmake/mac/tempnam.c
Normal file
@ -0,0 +1,72 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/mac/tempnam.c,v 1.1 1992/01/24 03:29:52 dvadura Exp $
|
||||
-- SYNOPSIS -- Fake tempnam function for the mac
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- Get a temporary file name.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: tempnam.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:52 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "extern.h"
|
||||
#include <StdIO.h>
|
||||
#include <String.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Try to open a temporary file in the given directory (if non-NULL)
|
||||
* with the given prefix (if non-NULL).
|
||||
*
|
||||
* We ignore the directory argument.
|
||||
*/
|
||||
PUBLIC char *tempnam (char * /* pDir */, char * pPrefix) {
|
||||
char *pName;
|
||||
char *pFullName;
|
||||
|
||||
pName = tmpnam ((char *) NULL);
|
||||
|
||||
/* Assume that if the name returned by tmpnam is not being used,
|
||||
the name with the prefix is also not being used. */
|
||||
pFullName = MALLOC (((pPrefix != NULL) ? strlen (pPrefix) : 0) +
|
||||
strlen (pName) + 1, char);
|
||||
|
||||
/* Copy in the name if we successfully allocated space for it. */
|
||||
if (pFullName != NULL) {
|
||||
if (pPrefix != NULL) {
|
||||
strcpy (pFullName, pPrefix);
|
||||
} else {
|
||||
*pFullName = '\0';
|
||||
} /* if ... else */
|
||||
|
||||
strcat (pFullName, pName);
|
||||
} /* if */
|
||||
|
||||
return (pFullName);
|
||||
} /* PUBLIC char *tempnam () */
|
114
dmake/mac/tomacfil.c
Normal file
114
dmake/mac/tomacfil.c
Normal file
@ -0,0 +1,114 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/mac/tomacfil.c,v 1.1 1992/01/24 03:29:53 dvadura Exp $
|
||||
-- SYNOPSIS -- Routines to change unix file names to mac file names
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- Dmake sometimes assumes that files have '/' as a directory parameter in some makefiles.
|
||||
-- This works, even on DOS, but not on the Mac. In fact, on the Mac, you can't even do a
|
||||
-- a simple switch of ':' for '/' because all other the Mac has decided to reverse the use
|
||||
-- of a first-character directory delimiter to mean a relative path rather than absolute path.
|
||||
-- (i.e., ':test:b' means directory test is relative to the current directory, rather than
|
||||
-- a top-level directory. Thus, this file attempts to do the directory conversion behind
|
||||
-- the back of the rest of the program.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: tomacfil.c,v $
|
||||
* Revision 1.1 1992/01/24 03:29:53 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
int IsUnixFName (char *pFileName);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Convert a file that may be in unix format to mac format.
|
||||
*
|
||||
* The returned name is either the untouched pUnixName, or a static buffer.
|
||||
*/
|
||||
PUBLIC char *Unix2MacFName(char *pUnixName) {
|
||||
static char MacName[256];
|
||||
char *pCurMac;
|
||||
|
||||
if (IsUnixFName (pUnixName)) {
|
||||
if (strlen (pUnixName) + (*pUnixName == '/' ? -1 : 1) >= sizeof (MacName)) {
|
||||
Fatal ("File name '%s' is too long and will cause a buffer overflow", pUnixName);
|
||||
} /* if */
|
||||
|
||||
/* Set up relative or absolute path */
|
||||
pCurMac = MacName;
|
||||
if (*pUnixName == '/') {
|
||||
++pUnixName;
|
||||
} else {
|
||||
*(pCurMac++) = ':';
|
||||
} /* if ... else */
|
||||
|
||||
/* Convert the rest of the name */
|
||||
while (*pUnixName != '\0') {
|
||||
if (*pUnixName == '/') {
|
||||
*(pCurMac++) = ':';
|
||||
pUnixName++;
|
||||
|
||||
} else {
|
||||
*(pCurMac++) = *(pUnixName++);
|
||||
} /* if ... else */
|
||||
} /* while */
|
||||
|
||||
*pCurMac = '\0';
|
||||
return (MacName);
|
||||
|
||||
} else {
|
||||
return (pUnixName);
|
||||
} /* if ... else */
|
||||
} /* PUBLIC char *Unix2MacFName() */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Is this file name in UNIX format?
|
||||
* (We assume it is if there are any slashes in its name.)
|
||||
*/
|
||||
int IsUnixFName (char *pFileName) {
|
||||
|
||||
for ( ; *pFileName != '\0'; ++pFileName) {
|
||||
if (*pFileName == '/') {
|
||||
return (TRUE);
|
||||
} /* if */
|
||||
} /* while */
|
||||
|
||||
return (FALSE);
|
||||
} /* int IsUnixFName () */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Call the real fopen() from this override of the function
|
||||
* that the rest of the program uses.
|
||||
*/
|
||||
#undef fopen
|
||||
PUBLIC FILE *MacFOpen (char *pFName, char *pMode) {
|
||||
return (fopen (Unix2MacFName (pFName), pMode));
|
||||
} /* PUBLIC FILE *MacFOpen () */
|
167
dmake/macparse.c
Normal file
167
dmake/macparse.c
Normal file
@ -0,0 +1,167 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/RCS/macparse.c,v 1.1 1992/01/24 03:27:52 dvadura Exp $
|
||||
-- SYNOPSIS -- parse a macro definition
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- This file contains the code that parses a macro definition
|
||||
-- stored in a buffer. If the string in buffer is not a valid
|
||||
-- macro definition the routie Parse_macro returns 0, otherwise it
|
||||
-- returns 1 to indicate success.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: macparse.c,v $
|
||||
* Revision 1.1 1992/01/24 03:27:52 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
PUBLIC int
|
||||
Parse_macro( buffer, flag )/*
|
||||
=============================
|
||||
Parse the string in buffer and define it as a macro if it is a valid macro.
|
||||
Note especially the string .SETDIR= since it is an attribute, but looks a
|
||||
lot like a macro definition. This would not be a problem if make used
|
||||
white space as token separators, since this is not the case we must do
|
||||
something about it. */
|
||||
char *buffer;
|
||||
int flag;
|
||||
{
|
||||
register char *tok1; /* temporary place to keep a token */
|
||||
register char *tok2; /* temporary place to keep a token */
|
||||
char *result; /* temporary pointer for strings */
|
||||
TKSTR input; /* place to scan the buffer from */
|
||||
HASHPTR hv; /* pointer to hash table value */
|
||||
int operator; /* what macro operator do we have */
|
||||
|
||||
DB_ENTER( "Parse_macro" );
|
||||
|
||||
SET_TOKEN( &input, buffer );
|
||||
tok1 = Get_token( &input, "=+:*", 0 );
|
||||
|
||||
if( Macro_op( tok1 ) ) {
|
||||
Error( "No macro name" );
|
||||
CLEAR_TOKEN( &input );
|
||||
DB_RETURN( 1 );
|
||||
}
|
||||
|
||||
tok1 = _strdup( tok1 );
|
||||
tok2 = Get_token( &input, "=+:*", 2 );
|
||||
if( !(operator = Macro_op(tok2)) ||
|
||||
(!strcmp(tok1, ".SETDIR") &&
|
||||
((operator != M_OP_CL) || (operator != M_OP_PLCL) ||
|
||||
(operator != M_OP_DFCL))) ) {
|
||||
CLEAR_TOKEN( &input );
|
||||
FREE( tok1 );
|
||||
DB_RETURN( 0 );
|
||||
}
|
||||
|
||||
tok2 = Expand(tok1); FREE(tok1); tok1 = tok2;
|
||||
tok2 = Get_token( &input, NIL( char ), FALSE );
|
||||
|
||||
switch( operator ) {
|
||||
case M_OP_PLCL:
|
||||
tok2 = Expand( tok2 );
|
||||
/* Fall thru */
|
||||
|
||||
case M_OP_PL:
|
||||
/* Add to an existing macro, if it is not defined, though, then
|
||||
* just define a new macro */
|
||||
|
||||
if( (hv = GET_MACRO(tok1)) == NIL(HASH) || hv->ht_value == NIL(char) )
|
||||
Def_macro( tok1, tok2, flag );
|
||||
else {
|
||||
result = _stradd( hv->ht_value, tok2, FALSE );
|
||||
Def_macro( tok1, result, flag );
|
||||
FREE( result );
|
||||
}
|
||||
if( operator == M_OP_PLCL ) FREE(tok2);
|
||||
break;
|
||||
|
||||
case M_OP_DF:
|
||||
if( (hv = GET_MACRO(tok1)) != NIL(HASH) )
|
||||
break;
|
||||
/* else FALLTHRU */
|
||||
|
||||
case M_OP_EQ:
|
||||
Def_macro( tok1, tok2, flag );
|
||||
break;
|
||||
|
||||
case M_OP_DFCL:
|
||||
if( (hv = GET_MACRO(tok1)) != NIL(HASH) )
|
||||
break;
|
||||
/* else FALLTHRU */
|
||||
|
||||
case M_OP_CL:
|
||||
/* If the macro we are assigning from is a single control
|
||||
* macro with nothing else, then we propagate the M_MULTI
|
||||
* flag to the macro we are assigning the value to so that
|
||||
* the same macro can be used to do this over and over. */
|
||||
If_multi = 0;
|
||||
tok2 = Expand( tok2 );
|
||||
Def_macro( tok1, tok2, M_EXPANDED | flag | If_multi );
|
||||
FREE( tok2 );
|
||||
break;
|
||||
}
|
||||
|
||||
FREE( tok1 );
|
||||
|
||||
DB_RETURN( 1 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
PUBLIC int
|
||||
Macro_op( op )/*
|
||||
================
|
||||
Check the passed in op string and map it to one of the macro operators */
|
||||
char *op;
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
DB_ENTER( "macro_op" );
|
||||
|
||||
switch( *op ) {
|
||||
case '=': ret = M_OP_EQ; break;
|
||||
case ':': ret = M_OP_CL; op++; break;
|
||||
|
||||
case '+':
|
||||
ret = M_OP_PL; op++;
|
||||
if( *op == ':' ) { ret = M_OP_PLCL; op++; }
|
||||
break;
|
||||
|
||||
case '*':
|
||||
ret = M_OP_DF; op++;
|
||||
if( *op == ':' ) { ret = M_OP_DFCL; op++; }
|
||||
break;
|
||||
}
|
||||
|
||||
if( *op++ != '=' )
|
||||
ret = 0;
|
||||
else if( *op != '\0' )
|
||||
ret = 0;
|
||||
|
||||
DB_RETURN( ret );
|
||||
}
|
||||
|
165
dmake/make.bat
Normal file
165
dmake/make.bat
Normal file
@ -0,0 +1,165 @@
|
||||
echo off
|
||||
cls
|
||||
rem *** This is the make batchfile that is used under MSDOS to make the
|
||||
rem *** first version of dmake. It isn't pretty but it does work, assuming
|
||||
rem *** the compilers have been correctly setup. See the warning below
|
||||
rem *** concerning tlink, if you are making the Turbo C version.
|
||||
rem
|
||||
|
||||
if %0%1 == %0 goto error
|
||||
if %1 == tcc goto mktcc
|
||||
if %1 == tccswp goto mktccswp
|
||||
if %1 == bcc goto mkbcc
|
||||
if %1 == bccswp goto mkbccswp
|
||||
if %1 == msc40 goto mkmsc40
|
||||
if %1 == msc40swp goto mkmsc40swp
|
||||
if %1 == msc50 goto mkmsc50
|
||||
if %1 == msc50swp goto mkmsc50swp
|
||||
if %1 == msc51 goto mkmsc51
|
||||
if %1 == msc51swp goto mkmsc51swp
|
||||
if %1 == msc60 goto mkmsc60
|
||||
if %1 == msc60swp goto mkmsc60swp
|
||||
if %1 == ztc goto mkztc
|
||||
if %1 == ztcswp goto mkztcswp
|
||||
|
||||
rem label the possible DOS variations for dmake here.
|
||||
:error
|
||||
echo MSDOS: You must specify 'make target' where target is one of:
|
||||
echo -------------
|
||||
echo tcc - Turbo C 2.0 compile.
|
||||
echo tccswp - Turbo C 2.0 compile of swapping dmake.
|
||||
echo bcc - Borland C++ 2.0,3.0 compile.
|
||||
echo bccswp - Borland C++ 2.0,3.0 compile of swapping dmake.
|
||||
echo msc40 - Microsoft C 4.0 compile.
|
||||
echo msc50 - Microsoft C 5.0 compile.
|
||||
echo msc51 - Microsoft C 5.1 compile.
|
||||
echo msc60 - Microsoft C 6.0 compile.
|
||||
echo msc40swp - Microsoft C 4.0, MASM 5.1 compile of swapping dmake.
|
||||
echo msc50swp - Microsoft C 5.0, MASM 5.1 compile of swapping dmake.
|
||||
echo msc51swp - Microsoft C 5.1, MASM 5.1 compile of swapping dmake.
|
||||
echo msc60swp - Microsoft C 6.0, MASM 5.1 compile of swapping dmake.
|
||||
echo ztc - Zortech C++ 2.1 compile.
|
||||
echo ztcswp - Zortech C++ 2.1 compile of swapping dmake.
|
||||
goto end
|
||||
|
||||
rem This is the script that makes dmake using Microsoft C 4.0
|
||||
:mkmsc40
|
||||
msdos\mscdos\mk40.bat
|
||||
goto end
|
||||
|
||||
:mkmsc40swp
|
||||
msdos\mscdos\mk40swp.bat
|
||||
goto end
|
||||
|
||||
rem This is the script that makes dmake using Microsoft C 5.0
|
||||
:mkmsc50
|
||||
msdos\mscdos\mk50.bat
|
||||
goto end
|
||||
|
||||
:mkmsc50swp
|
||||
msdos\mscdos\mk50swp.bat
|
||||
goto end
|
||||
|
||||
rem This is the script that makes dmake using Microsoft C 5.1
|
||||
:mkmsc51
|
||||
msdos\mscdos\mk51.bat
|
||||
goto end
|
||||
|
||||
:mkmsc51swp
|
||||
msdos\mscdos\mk51swp.bat
|
||||
goto end
|
||||
|
||||
rem This is the script that makes dmake using Microsoft C 6.0
|
||||
:mkmsc60
|
||||
msdos\mscdos\mk60.bat
|
||||
goto end
|
||||
|
||||
:mkmsc60swp
|
||||
msdos\mscdos\mk60swp.bat
|
||||
goto end
|
||||
|
||||
rem This is the script that makes dmake using Zortech C++ 2.1
|
||||
:mkztc
|
||||
msdos\ztcdos\mk.bat
|
||||
goto end
|
||||
|
||||
:mkztcswp
|
||||
msdos\ztcdos\mkswp.bat
|
||||
goto end
|
||||
|
||||
rem This is the script that makes dmake using Turbo C 2.0 or higher.
|
||||
:mktcc
|
||||
cls
|
||||
echo WARNING:
|
||||
echo The default response files:
|
||||
echo msdos\tccdos\obj.rsp
|
||||
echo msdos\tccdos\lib.rsp
|
||||
echo contain absolute paths to TURBO-C runtime startup objects, and to
|
||||
echo the standard libraries. You should check that these files contain
|
||||
echo the correct path names for your installation of Turbo-C before
|
||||
echo proceeding further. Also check that the mkdir command at the start
|
||||
echo of the response file and the copy command at the end of the response
|
||||
echo file will work on your system.
|
||||
echo --
|
||||
echo Continue if ok, or abort and edit the response files.
|
||||
pause
|
||||
msdos\tccdos\mk.bat
|
||||
goto end
|
||||
|
||||
:mktccswp
|
||||
cls
|
||||
echo WARNING:
|
||||
echo The default response files:
|
||||
echo msdos\tccdos\objswp.rsp
|
||||
echo msdos\tccdos\libswp.rsp
|
||||
echo contain absolute paths to TURBO-C runtime startup objects, and to
|
||||
echo the standard libraries. You should check that these files contain
|
||||
echo the correct path names for your installation of Turbo-C before
|
||||
echo proceeding further. Also check that the mkdir command at the start
|
||||
echo of the response file and the copy command at the end of the response
|
||||
echo file will work on your system.
|
||||
echo --
|
||||
echo Continue if ok, or abort and edit the response files.
|
||||
pause
|
||||
msdos\tccdos\mkswp.bat
|
||||
goto end
|
||||
|
||||
rem This is the script that makes dmake using Turbo C++ 2.0.
|
||||
:mkbcc
|
||||
cls
|
||||
echo WARNING:
|
||||
echo The default response files:
|
||||
echo msdos\bccdos\obj.rsp
|
||||
echo msdos\bccdos\lib.rsp
|
||||
echo contain absolute paths to Borland C++ runtime startup objects, and to
|
||||
echo the standard libraries. You should check that these files contain
|
||||
echo the correct path names for your installation of Borland C++ before
|
||||
echo proceeding further. Also check that the mkdir command at the start
|
||||
echo of the response file and the copy command at the end of the response
|
||||
echo file will work on your system.
|
||||
echo --
|
||||
echo Continue if ok, or abort and edit the response files.
|
||||
pause
|
||||
msdos\bccdos\mk.bat
|
||||
goto end
|
||||
|
||||
:mkbccswp
|
||||
cls
|
||||
echo WARNING:
|
||||
echo The default response files:
|
||||
echo msdos\bccdos\objswp.rsp
|
||||
echo msdos\bccdos\libswp.rsp
|
||||
echo contain absolute paths to Borland C++ runtime startup objects, and to
|
||||
echo the standard libraries. You should check that these files contain
|
||||
echo the correct path names for your installation of Borland C++ before
|
||||
echo proceeding further. Also check that the mkdir command at the start
|
||||
echo of the response file and the copy command at the end of the response
|
||||
echo file will work on your system.
|
||||
echo --
|
||||
echo Continue if ok, or abort and edit the response files.
|
||||
pause
|
||||
msdos\bccdos\mkswp.bat
|
||||
goto end
|
||||
|
||||
rem All done!
|
||||
:end
|
1028
dmake/make.c
Normal file
1028
dmake/make.c
Normal file
File diff suppressed because it is too large
Load Diff
53
dmake/make.cmd
Normal file
53
dmake/make.cmd
Normal file
@ -0,0 +1,53 @@
|
||||
echo off
|
||||
cls
|
||||
rem *** This is the make command file that is used under OS/2 to make the
|
||||
rem *** first version of dmake. It isn't pretty but it does work, assuming
|
||||
rem *** the compilers have been correctly setup.
|
||||
rem
|
||||
echo Running make.cmd script to make a %1 copy of dmake.
|
||||
|
||||
if %0%1 == %0 goto error
|
||||
if %1 == msc40 goto mkmsc40
|
||||
if %1 == msc50 goto mkmsc50
|
||||
if %1 == msc51 goto mkmsc51
|
||||
if %1 == msc60 goto mkmsc60
|
||||
if %1 == ibm goto mkibm
|
||||
|
||||
rem label the possible DOS variations for dmake here.
|
||||
:error
|
||||
echo OS/2 INDEX: You must specify one of:
|
||||
echo ------------------
|
||||
echo msc40 - Microsoft C 4.0 compile.
|
||||
echo msc50 - Microsoft C 5.0 compile.
|
||||
echo msc51 - Microsoft C 5.1 compile.
|
||||
echo msc60 - Microsoft C 6.0 compile.
|
||||
3cho ibm - IBM C 2.0 compile.
|
||||
goto end
|
||||
|
||||
rem This is the script that makes dmake using Microsoft C 4.0
|
||||
:mkmsc40
|
||||
os2\mscdos\mk40.cmd
|
||||
goto end
|
||||
|
||||
rem This is the script that makes dmake using Microsoft C 5.0
|
||||
:mkmsc50
|
||||
os2\mscdos\mk50.cmd
|
||||
goto end
|
||||
|
||||
rem This is the script that makes dmake using Microsoft C 5.1
|
||||
:mkmsc51
|
||||
os2\mscdos\mk51.cmd
|
||||
goto end
|
||||
|
||||
rem This is the script that makes dmake using Microsoft C 6.0
|
||||
:mkmsc60
|
||||
os2\mscdos\mk60.cmd
|
||||
goto end
|
||||
|
||||
rem This is the script that makes dmake using Microsoft C 6.0
|
||||
:ibm
|
||||
os2\ibm\mkc2.cmd
|
||||
goto end
|
||||
|
||||
rem All done!
|
||||
:end
|
73
dmake/makefile
Normal file
73
dmake/makefile
Normal file
@ -0,0 +1,73 @@
|
||||
# Default makefile for the various versions of dmake that we
|
||||
# have available. This is a bootstrap version and uses /bin/sh to
|
||||
# execute a script which compiles dmake.
|
||||
#
|
||||
# Note the DOS commands actually invoke command.com to run the .bat file
|
||||
# to make the script.
|
||||
|
||||
all :
|
||||
@-echo ""; clear; exit 0
|
||||
@echo "INDEX: You must specify 'make target' where target is one of:"
|
||||
@echo "-------------"
|
||||
@echo " make bsd43 - Generic BSD 4.3 System"
|
||||
@echo " make bsd43uw - Generic BSD 4.3 at U of Waterloo"
|
||||
@echo " make bsd43vf - Generic BSD 4.3 that needs vfprintf"
|
||||
@echo " make sysvr4 - Generic SysV R4 UNIX System"
|
||||
@echo " make sysvr3 - Generic SysV R3 UNIX System"
|
||||
@echo " make sysvr3pwd - Generic SysV R3 UNIX System, our PWD, (Any HP System)"
|
||||
@echo " make sysvr1 - Generic SysV R1 UNIX System"
|
||||
@echo " make dynix - Sequent DYNIX System"
|
||||
@echo " make ultrix - Ultrix 3.0 System"
|
||||
@echo " make mips - Any MIPS System"
|
||||
@echo " make coherent - Any Coherent System"
|
||||
@echo " make 386ix - 386/ix (SysV R3) System"
|
||||
@echo " make xenix - 386 Xenix System"
|
||||
@echo " make xenixpwd - 386 Xenix System, our PWD"
|
||||
@echo " make aix - IBM RS6000/AIX System"
|
||||
@echo " make os2msc40 - OS/2 using MSC 4.0 compiler"
|
||||
@echo " make os2msc50 - OS/2 using MSC 5.0 compiler"
|
||||
@echo " make os2msc51 - OS/2 using MSC 5.1 compiler"
|
||||
@echo " make os2msc60 - OS/2 using MSC 6.0 compiler"
|
||||
@echo " make os2ibm - OS/2 using IBM C 2.0 compiler"
|
||||
@echo " make tos - Atari-ST TOS using GCC as compiler"
|
||||
@echo " make tcc - DOS with Turbo C 2.0"
|
||||
@echo " make bcc - DOS with Borland C++ 3.0"
|
||||
@echo " make tccswp - swapping DOS version with Turbo C 2.0"
|
||||
@echo " make bccswp - swapping DOS version with Borland C++ 3.0"
|
||||
@echo " make msc40 - DOS with MSC 4.0"
|
||||
@echo " make msc50 - DOS with MSC 5.0"
|
||||
@echo " make msc51 - DOS with MSC 5.1"
|
||||
@echo " make msc60 - DOS with MSC 6.0"
|
||||
@echo " make msc40swp - swapping DOS version with MSC 4.0"
|
||||
@echo " make msc50swp - swapping DOS version with MSC 5.0"
|
||||
@echo " make msc51swp - swapping DOS version with MSC 5.1"
|
||||
@echo " make msc60swp - swapping DOS version with MSC 6.0"
|
||||
@echo " make ztc - DOS with Zortech C++ 2.1"
|
||||
@echo " make ztcswp - swapping DOS version with Zortech C++ 2.1"
|
||||
@echo " make mpwmac - Macintosh under MPW"
|
||||
|
||||
ultrix aix: sysvr3;
|
||||
|
||||
sysvr1 sysvr3 sysvr4 bsd43 386ix :; /bin/sh -x < unix/$@/make.sh
|
||||
|
||||
bsd43uw :; /bin/sh -x < unix/bsd43/uw/make.sh
|
||||
bsd43vf dynix mips :; /bin/sh -x < unix/bsd43/vf/make.sh
|
||||
coherent :; /bin/sh -x < unix/coherent/make.sh
|
||||
xenix :; /bin/sh -x < unix/xenix/make.sh
|
||||
xenixpwd :; /bin/sh -x < unix/xenix/pwd/make.sh
|
||||
sysvr3pwd :; /bin/sh -x < unix/sysvr3/pwd/make.sh
|
||||
tos :; sh -x tos/make.sh
|
||||
mpwmac :; :mac:make.sh
|
||||
|
||||
# Various OS/2 targets.
|
||||
OS2_VER = os2msc40 os2msc50 os2msc51 os2msc60 os2ibm
|
||||
$(OS2_VER) :; make.cmd $(@:s/os2//)
|
||||
|
||||
# DOS with some form of make and sh
|
||||
# Note if you do not have a 'make and/or sh' program under MSDOS then
|
||||
# typing 'make' in the dmake distribution directory will invoke the make.bat
|
||||
# batch file which will issue the appropriate instructions.
|
||||
DOS_VER = tcc msc40 msc50 msc51 msc60 \
|
||||
tccswp msc40swp msc50swp msc51swp msc60swp \
|
||||
bcc bccswp ztc ztcswp
|
||||
$(DOS_VER) :; make.bat $@
|
342
dmake/makefile.mk
Normal file
342
dmake/makefile.mk
Normal file
@ -0,0 +1,342 @@
|
||||
# //// Makefile for DMAKE. \\\\
|
||||
# The target system is characterized by the following macros imported from
|
||||
# the environment.
|
||||
#
|
||||
# OS - gives the class of operating system
|
||||
# OSRELEASE - optionally gives the particular release of the OS above.
|
||||
# OSENVIRONMENT - optionally gives the environment under which the above
|
||||
# OS is in use.
|
||||
#
|
||||
# For valid values for the above macros consult the readme/* files or type
|
||||
# 'make' by itself to get a summary of what is available.
|
||||
|
||||
# First target in the makefile, do this so that targets declared in the
|
||||
# included files are never marked as being the first *default* target.
|
||||
first : all ;
|
||||
|
||||
#Enable keeping of state for future compiles
|
||||
.KEEP_STATE := _state.mk
|
||||
|
||||
# Pull in the configuration macros, from the environment. OS is required,
|
||||
# OSRELEASE, and OSENVIRONMENT are optional.
|
||||
.IF $(OS) == $(NULL)
|
||||
.IMPORT : OS
|
||||
.END
|
||||
.IMPORT .IGNORE : OSRELEASE OSENVIRONMENT TMPDIR
|
||||
|
||||
# Define $(PUBLIC)
|
||||
_osenv := $(OSENVIRONMENT)$(DIRSEPSTR)
|
||||
_osre := $(OSRELEASE)$(DIRSEPSTR)$(!null,$(OSENVIRONMENT) $(_osenv))
|
||||
ENVDIR = $(OS)$(DIRSEPSTR)$(!null,$(OSRELEASE) $(_osre))
|
||||
PUBLIC = $(ENVDIR)public.h
|
||||
STARTUP := startup.mk
|
||||
|
||||
# Define the source files
|
||||
SRC =\
|
||||
infer.c make.c stat.c expand.c dmstring.c hash.c dag.c dmake.c\
|
||||
path.c imacs.c sysintf.c parse.c getinp.c quit.c state.c\
|
||||
basename.c dmdump.c macparse.c rulparse.c percent.c function.c
|
||||
|
||||
# Common Include files.
|
||||
HDR = dmake.h extern.h struct.h vextern.h patchlvl.h version.h
|
||||
|
||||
# Define the TARGET we are making, and where the OBJECT files go.
|
||||
OBJDIR := objects
|
||||
TARGET = dmake$E
|
||||
CFLAGS += -I.
|
||||
|
||||
# Meta rule for making .o's from .c's (give our own so we can move object
|
||||
# to objects directory in a portable, compiler independent way)
|
||||
# Define it before the .INCLUDE so that different OS combinations can redefine
|
||||
# it.
|
||||
%$O : %.c
|
||||
.IF $(SHELL) == mpw
|
||||
%$(CC) $(CFLAGS) -o :$(OBJDIR:s,/,:,):$@ $<
|
||||
.ELSE
|
||||
%$(CC) -c $(CFLAGS) $<
|
||||
.IF $(SHELL) != $(COMSPEC)
|
||||
mv $(@:f) $(OBJDIR)
|
||||
.ELSE
|
||||
+copy $(@:f) $(OBJDIR)
|
||||
+del $(@:f)
|
||||
.ENDIF
|
||||
.ENDIF
|
||||
|
||||
# Pull in the proper configuration files, based on the value of OS.
|
||||
.INCLUDE : $(OS)/config.mk
|
||||
.INCLUDE : dbug/dbug.mk
|
||||
|
||||
# Set the .SOURCE targets so that we look for things in the right place.
|
||||
.SOURCE.c :^ .NULL
|
||||
.SOURCE.h :^ .NULL
|
||||
.SOURCE$O :^ $(OBJDIR)
|
||||
.PRECIOUS : $(HDR)
|
||||
|
||||
# Must come after the above INCLUDE so that it gets ALL objects.
|
||||
OBJECTS := {$(ASRC:b) $(SRC:b)}$O
|
||||
|
||||
# The main target, make sure the objects directory exists first.
|
||||
# LDARGS is defined in config.mk file of each OS/OSRELEASE combination.
|
||||
all : $(TARGET) $(STARTUP);
|
||||
$(TARGET) : $(OBJDIR)
|
||||
$(TARGET) : $(OBJECTS);$(LD) $(LDARGS)
|
||||
.IF $(SHELL) == mpw
|
||||
$(STARTUP) : $(ENVDIR)$(STARTUP); duplicate :$(<:s,/,:,) $@
|
||||
.ELSE
|
||||
$(STARTUP) : $(ENVDIR)$(STARTUP); $(eq,$(SHELL),$(COMSPEC) +copy cp) $< $@
|
||||
.ENDIF
|
||||
|
||||
# how to make public.h
|
||||
public .PHONY : $(PUBLIC);
|
||||
$(PUBLIC) .SHELL .NOSTATE: $(SRC)
|
||||
genpub -n DMAKE $< >$@
|
||||
rcsclean $@ > /dev/null
|
||||
|
||||
# Other obvious targets...
|
||||
.IF $(SHELL) == mpw
|
||||
$(OBJDIR):;-newfolder $@
|
||||
.ELSE
|
||||
$(OBJDIR):;-$(eq,$(SHELL),$(COMSPEC) +md mkdir) $@
|
||||
.ENDIF
|
||||
|
||||
# remaining dependencies should be automatically generated
|
||||
sysintf$O : $(OS)/sysintf.h
|
||||
ruletab$O : $(OS)/startup.h #khc 01NOV90 - dependency was missing
|
||||
$(OBJECTS) : $(HDR)
|
||||
|
||||
clean:;+- $(RM) -rf dmake$E dbdmake$E objects* $(STARTUP) _*state*.mk
|
||||
|
||||
# Rules for making the manual pages.
|
||||
man .SETDIR=man : dmake.nc dmake.uue ;
|
||||
dmake.nc : dmake.p ; scriptfix < $< > $@
|
||||
dmake.p : dmake.tf; typeset -man -Tdumb $< > $@
|
||||
dmake.uue : dmake.p
|
||||
compress -b 12 dmake.p
|
||||
mv dmake.p.Z dmake.Z
|
||||
uuencode dmake.Z dmake.Z >dmake.uue
|
||||
/bin/rm -f dmake.Z
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Make the various archives for shipping the thing around.
|
||||
#
|
||||
archives : zoo tar shar;
|
||||
|
||||
zoo .PHONY : dmake.zoo ;
|
||||
shar .PHONY : dmake.shar;
|
||||
tar .PHONY : dmake.tar;
|
||||
|
||||
dmake.zoo : dir-copy
|
||||
[
|
||||
find dmake -type f -print | zoo aI $@
|
||||
$(RM) -rf src-list dmake
|
||||
]
|
||||
|
||||
dmake.shar : dir-copy
|
||||
[
|
||||
find dmake -type f -print >src-list
|
||||
xshar -vc -o$@ -L40 `cat src-list`
|
||||
$(RM) -rf src-list dmake
|
||||
]
|
||||
|
||||
dmake.tar : dir-copy
|
||||
[
|
||||
tar cf $@ dmake
|
||||
$(RM) -rf src-list dmake
|
||||
]
|
||||
|
||||
dir-copy .PHONY : src-list
|
||||
[
|
||||
echo 'tmp.tar .SILENT :$$(ALLSRC) ;tar -cf tmp.tar $$(ALLSRC)' >> $<
|
||||
$(MAKECMD) -f $< tmp.tar
|
||||
mkdir dmake
|
||||
cd dmake
|
||||
tar xf ../tmp.tar; chmod -R u+rw .
|
||||
cd ..
|
||||
/bin/rm -f tmp.tar
|
||||
]
|
||||
|
||||
src-list : clean man
|
||||
echo 'ALLSRC = \' >$@
|
||||
find . -type f -print |\
|
||||
sed -e 's/RCS\///' -e 's/,v//' -e 's/$$/\\/' -e 's/^\.\// /'|\
|
||||
sort -u |\
|
||||
grep -v tst | grep -v $@ | grep -v LICENSE |\
|
||||
grep -v '\.zoo' | grep -v '\.tar'| grep -v '\.shar' >> $@
|
||||
echo ' LICENSE' >> $@
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# This section can be used to make the necessary script files so that dmake
|
||||
# can be bootstrapped.
|
||||
#
|
||||
# dmake scripts -- makes all the script files at once.
|
||||
#
|
||||
SH_n = $(@:s/swp-/-/:s,-,/,:s/scripts/${SCRIPTFILE}/)
|
||||
MS_n = MAKESTARTUP=$(@:s/swp-/-/:s,-,/,:s/scripts/startup.mk/)
|
||||
SH = $(SH_n:s/c40d/cd/:s/c50d/cd/:s/c51d/cd/:s/c60d/cd/:s/ibmc2/ibm/)
|
||||
MS = $(MS_n:s/c40d/cd/:s/c50d/cd/:s/c51d/cd/:s/c60d/cd/:s/ibmc2/ibm/)
|
||||
FIX-SH = $(SH:s,fix/,,)
|
||||
|
||||
scripts: unix-scripts atari-tos-scripts msdos-scripts os2-scripts\
|
||||
apple-mac-scripts
|
||||
|
||||
# To add a new environment for UNIX, simply create the appropriate entry
|
||||
# in the style below for the macro which contains the OS, OSRELEASE and
|
||||
# OSENVIRONMENT flags. Then add the entry as a recipe line for the target
|
||||
# unix-scripts.
|
||||
#
|
||||
unix-bsd43-scripts-flags = OS=unix OSRELEASE=bsd43 OSENVIRONMENT=
|
||||
unix-bsd43-uw-scripts-flags= OS=unix OSRELEASE=bsd43 OSENVIRONMENT=uw
|
||||
unix-bsd43-vf-scripts-flags= OS=unix OSRELEASE=bsd43 OSENVIRONMENT=vf
|
||||
unix-sysvr4-scripts-flags = OS=unix OSRELEASE=sysvr4 OSENVIRONMENT=
|
||||
unix-sysvr3-scripts-flags = OS=unix OSRELEASE=sysvr3 OSENVIRONMENT=
|
||||
unix-sysvr3-pwd-scripts-flags = OS=unix OSRELEASE=sysvr3 OSENVIRONMENT=pwd
|
||||
unix-xenix-scripts-flags = OS=unix OSRELEASE=xenix OSENVIRONMENT=
|
||||
unix-xenix-pwd-scripts-flags = OS=unix OSRELEASE=xenix OSENVIRONMENT=pwd
|
||||
unix-sysvr1-scripts-flags = OS=unix OSRELEASE=sysvr1 OSENVIRONMENT=
|
||||
unix-386ix-scripts-flags = OS=unix OSRELEASE=386ix OSENVIRONMENT=
|
||||
unix-coherent-scripts-flags= OS=unix OSRELEASE=coherent OSENVIRONMENT=
|
||||
unix-gno-scripts-flags = OS=unix OSRELEASE=gno OSENVIRONMENT=
|
||||
tos--scripts-flags = OS=tos OSRELEASE= OSENVIRONMENT=
|
||||
mac--scripts-flags = OS=mac OSRELEASE= OSENVIRONMENT=
|
||||
|
||||
unix-scripts .SWAP : clean
|
||||
$(MAKE) SCRIPTFILE=make.sh unix-bsd43-scripts
|
||||
$(MAKE) SCRIPTFILE=make.sh unix-bsd43-uw-scripts
|
||||
$(MAKE) SCRIPTFILE=make.sh unix-bsd43-vf-scripts
|
||||
$(MAKE) SCRIPTFILE=make.sh unix-sysvr4-scripts
|
||||
$(MAKE) SCRIPTFILE=make.sh unix-sysvr3-scripts
|
||||
$(MAKE) SCRIPTFILE=make.sh unix-sysvr3-pwd-scripts
|
||||
$(MAKE) SCRIPTFILE=make.sh unix-xenix-scripts
|
||||
$(MAKE) SCRIPTFILE=make.sh unix-xenix-pwd-scripts
|
||||
$(MAKE) SCRIPTFILE=make.sh unix-sysvr1-scripts
|
||||
$(MAKE) SCRIPTFILE=make.sh unix-386ix-scripts
|
||||
$(MAKE) SCRIPTFILE=make.sh unix-coherent-scripts
|
||||
$(MAKE) SCRIPTFILE=make.sh unix-gno-scripts
|
||||
|
||||
unix-%-scripts .SWAP :
|
||||
$(MAKECMD) -s $($@-flags) .KEEP_STATE:= public
|
||||
$(MAKECMD) -ns .KEEP_STATE:= $(MS) $($@-flags) >/tmp/dmscr
|
||||
dfold </tmp/dmscr >$(SH)
|
||||
|
||||
tos-%-scripts .SWAP :
|
||||
$(MAKECMD) -s $($@-flags) .KEEP_STATE:= public
|
||||
$(MAKECMD) -ns .KEEP_STATE:= $(MS) $($@-flags) >/tmp/dmscr
|
||||
dfold </tmp/dmscr >$(SH)
|
||||
|
||||
atari-tos-scripts .SWAP : clean
|
||||
$(MAKE) SCRIPTFILE=make.sh tos--scripts
|
||||
|
||||
apple-mac-scripts .SWAP : clean
|
||||
$(MAKE) SCRIPTFILE=make.sh mac--scripts
|
||||
|
||||
mac-%-scripts .SWAP :
|
||||
$(MAKECMD) -s $($@-flags) .KEEP_STATE:= public
|
||||
$(MAKECMD) -ns .KEEP_STATE:= $(MS) $($@-flags) >$(SH)
|
||||
sed 's/ mac\/\(.*\)$$/ :mac:\1/' <$(SH) | dfold >/tmp/dmscr
|
||||
/bin/mv /tmp/dmscr $(SH)
|
||||
|
||||
# We make the standard dos scripts here, but we have to go and fix up the
|
||||
# mkXX.bat file since it contains names of temporary files for the response
|
||||
# files required by the linker. We need to also construct the response file
|
||||
# contents. These two functions are performed by the fix-msdos-%-scripts
|
||||
# meta-target.
|
||||
#
|
||||
# To add a new DOS environment just do what is described for adding a new
|
||||
# unix environment, and then make certain that the fix-msdos-%-scripts target
|
||||
# performs the correct function for the new environment.
|
||||
msdos-cf = OS=msdos OSENVIRONMENT=
|
||||
msdos-tccdos-scripts-flags = $(msdos-cf) OSRELEASE=tccdos SWAP=n
|
||||
msdos-tccdosswp-scripts-flags = $(msdos-cf) OSRELEASE=tccdos
|
||||
msdos-bccdos-scripts-flags = $(msdos-cf) OSRELEASE=bccdos SWAP=n
|
||||
msdos-bccdosswp-scripts-flags = $(msdos-cf) OSRELEASE=bccdos
|
||||
msdos-msc40dos-scripts-flags= $(msdos-cf) OSRELEASE=mscdos SWAP=n MSC_VER=4.0
|
||||
msdos-msc40dosswp-scripts-flags = $(msdos-cf) OSRELEASE=mscdos MSC_VER=4.0
|
||||
msdos-msc50dos-scripts-flags= $(msdos-cf) OSRELEASE=mscdos SWAP=n MSC_VER=5.0
|
||||
msdos-msc50dosswp-scripts-flags = $(msdos-cf) OSRELEASE=mscdos MSC_VER=5.0
|
||||
msdos-msc51dos-scripts-flags= $(msdos-cf) OSRELEASE=mscdos SWAP=n MSC_VER=5.1
|
||||
msdos-msc51dosswp-scripts-flags = $(msdos-cf) OSRELEASE=mscdos MSC_VER=5.1
|
||||
msdos-msc60dos-scripts-flags= $(msdos-cf) OSRELEASE=mscdos SWAP=n MSC_VER=6.0
|
||||
msdos-msc60dosswp-scripts-flags = $(msdos-cf) OSRELEASE=mscdos MSC_VER=6.0
|
||||
msdos-ztcdos-scripts-flags= $(msdos-cf) OSRELEASE=ztcdos SWAP=n
|
||||
msdos-ztcdosswp-scripts-flags= $(msdos-cf) OSRELEASE=ztcdos
|
||||
|
||||
msdos-scripts: clean\
|
||||
msdos-tcc-scripts msdos-bcc-scripts\
|
||||
msdos-msc-scripts msdos-ztc-scripts;
|
||||
|
||||
msdos-tcc-scripts .SWAP :
|
||||
$(MAKE) SCRIPTFILE=mk.bat msdos-tccdos-scripts
|
||||
$(MAKE) SCRIPTFILE=mkswp.bat msdos-tccdosswp-scripts
|
||||
|
||||
msdos-bcc-scripts .SWAP :
|
||||
$(MAKE) SCRIPTFILE=mk.bat msdos-bccdos-scripts
|
||||
$(MAKE) SCRIPTFILE=mkswp.bat msdos-bccdosswp-scripts
|
||||
|
||||
msdos-msc-scripts .SWAP :! 40 50 51 60
|
||||
$(MAKE) SCRIPTFILE=mk$?.bat msdos-msc$?dos-scripts
|
||||
$(MAKE) SCRIPTFILE=mk$?swp.bat msdos-msc$?dosswp-scripts
|
||||
|
||||
msdos-ztc-scripts .SWAP :
|
||||
$(MAKE) SCRIPTFILE=mk.bat msdos-ztcdos-scripts
|
||||
$(MAKE) SCRIPTFILE=mkswp.bat msdos-ztcdosswp-scripts
|
||||
|
||||
msdos-%-scripts .SWAP .SILENT:
|
||||
$(MAKE) -s $($@-flags) .KEEP_STATE:= public
|
||||
$(MAKE) -ns SHELL=command.com COMSPEC=command.com .KEEP_STATE:= $(MS) $($@-flags) >$(SH)
|
||||
$(MAKE) -s $(MAKEMACROS) $(MS) $($@-flags) fix-msdos-$*-scripts
|
||||
|
||||
|
||||
# We make the standard OS/2 scripts here, but we have to go and fix up the
|
||||
# mkXX.cmd file since it contains names of temporary files for the response
|
||||
# files required by the linker. We need to also construct the response file
|
||||
# contents. These two functions are performed by the fix-msdos-%-scripts
|
||||
# meta-target.
|
||||
#
|
||||
# To add a new OS/2 environment just do what is described for adding a new
|
||||
# unix environment, and then make certain that the fix-msdos-%-scripts target
|
||||
# performs the correct function for the new environment.
|
||||
os2-cf = OS=os2 OSENVIRONMENT=
|
||||
os2-msc40dos-scripts-flags= $(os2-cf) OSRELEASE=mscdos SWAP=n MSC_VER=4.0
|
||||
os2-msc50dos-scripts-flags= $(os2-cf) OSRELEASE=mscdos SWAP=n MSC_VER=5.0
|
||||
os2-msc51dos-scripts-flags= $(os2-cf) OSRELEASE=mscdos SWAP=n MSC_VER=5.1
|
||||
os2-msc60dos-scripts-flags= $(os2-cf) OSRELEASE=mscdos SWAP=n MSC_VER=6.0
|
||||
os2-ibmc2-scripts-flags= $(os2-cf) OSRELEASE=ibm SWAP=n MSC_VER=5.1
|
||||
|
||||
os2-scripts: clean os2-msc-scripts os2-ibm-scripts;
|
||||
|
||||
os2-msc-scripts .SWAP :! 40 50 51 60
|
||||
$(MAKE) SCRIPTFILE=mk$?.cmd os2-msc$?dos-scripts
|
||||
|
||||
os2-ibm-scripts .SWAP :! c2
|
||||
$(MAKE) SCRIPTFILE=mk$?.cmd os2-ibm$?-scripts
|
||||
|
||||
os2-%-scripts .SWAP :
|
||||
$(MAKE) -s $($@-flags) .KEEP_STATE:= public
|
||||
$(MAKE) -ns SHELL=cmd.exe COMSPEC=cmd.exe .KEEP_STATE:= $(MS) $($@-flags) >$(SH)
|
||||
$(MAKE) -s $(MAKEMACROS) $(MS) $($@-flags) fix-os2-$*-scripts
|
||||
|
||||
# Signify NULL targets for the various MSC compiler versions.
|
||||
c2 40 50 51 60:;
|
||||
|
||||
# Go over the created script file and make sure all the '/' that are in
|
||||
# filenames are '\', and make sure the final link command line looks
|
||||
# reasonable.
|
||||
MAPOBJ = obj$(SWAP:s/y/swp/:s/n//).rsp
|
||||
MAPLIB = lib$(SWAP:s/y/swp/:s/n//).rsp
|
||||
OBJRSP = $(SH:s,fix/,,:s,${SCRIPTFILE},${MAPOBJ},)
|
||||
LIBRSP = $(SH:s,fix/,,:s,${SCRIPTFILE},${MAPLIB},)
|
||||
DOSOBJ = $(CSTARTUP) $(OBJDIR)/{$(OBJECTS)}
|
||||
fix-%-scripts:
|
||||
tail -r $(FIX-SH) >tmp-sh-r
|
||||
tail +3 tmp-sh-r | sed -e 's,/,\\,g' >tmp-out
|
||||
tail -r tmp-out >$(FIX-SH)
|
||||
head -2 tmp-sh-r |\
|
||||
sed -e 's,\\usr\\tmp\\mkA[a-zA-Z]*[0-9]*,$(OBJRSP),'\
|
||||
-e 's,\\usr\\tmp\\mkB[a-zA-Z]*[0-9]*,$(LIBRSP),' |\
|
||||
sed -e 's,$(OS)/,$(OS)\\,g'\
|
||||
-e 's,$(OS)/$(OSRELEASE)/,$(OS)\\$(OSRELEASE)\\,g'\
|
||||
-e 's,$(OS)\\$(OSRELEASE)/,$(OS)\\$(OSRELEASE)\\,g'\
|
||||
-e 's,$(OS)/$(OSRELEASE)\\,$(OS)\\$(OSRELEASE)\\,g' >>$(FIX-SH)
|
||||
rm -f tmp-sh-r tmp-out
|
||||
mv <+$(DOSOBJ:s,/,\\,:t"+\n")\n+> $(OBJRSP)
|
||||
mv <+$(LDLIBS:s,/,\\,:t"+\n")\n+> $(LIBRSP)
|
9
dmake/man/README
Normal file
9
dmake/man/README
Normal file
@ -0,0 +1,9 @@
|
||||
To unpack the DMAKE manual page please issue the following sequence of
|
||||
commands:
|
||||
|
||||
uudecode dmake.uue
|
||||
uncompress dmake.Z
|
||||
mv dmake dmake.p
|
||||
|
||||
NOTE: You only need to do this if you cannot typeset the manual page
|
||||
yourself.
|
3200
dmake/man/dmake.nc
Normal file
3200
dmake/man/dmake.nc
Normal file
File diff suppressed because it is too large
Load Diff
2732
dmake/man/dmake.tf
Normal file
2732
dmake/man/dmake.tf
Normal file
File diff suppressed because it is too large
Load Diff
1248
dmake/man/dmake.uue
Normal file
1248
dmake/man/dmake.uue
Normal file
File diff suppressed because it is too large
Load Diff
67
dmake/msdos/_chdir.c
Normal file
67
dmake/msdos/_chdir.c
Normal file
@ -0,0 +1,67 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/msdos/_chdir.c,v 1.1 1992/01/24 03:27:24 dvadura Exp $
|
||||
-- SYNOPSIS -- Change directory.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- Under DOS change the current drive as well as the current directory.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: _chdir.c,v $
|
||||
* Revision 1.1 1992/01/24 03:27:24 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include <dos.h>
|
||||
#include "extern.h"
|
||||
|
||||
PUBLIC int
|
||||
_chdir(path)
|
||||
char *path;
|
||||
{
|
||||
int res;
|
||||
|
||||
res = chdir(path);
|
||||
|
||||
#if defined(OS2)
|
||||
if (res != -1 && path[1] == ':') {
|
||||
unsigned new_drive;
|
||||
unsigned max_drives;
|
||||
|
||||
/* for OS2 we must change drive without using intdos() */
|
||||
new_drive = (*path & ~0x20) - 'A' + 1;
|
||||
_dos_setdrive(new_drive, &max_drives);
|
||||
}
|
||||
#else
|
||||
if (res != -1 && path[1] == ':') {
|
||||
union REGS reg;
|
||||
|
||||
/* we must change the logged drive, since the chdir worked. */
|
||||
reg.h.ah = 0x0E;
|
||||
reg.h.dl = (*path & ~0x20) - 'A';
|
||||
intdos(®, ®);
|
||||
}
|
||||
#endif /* OS2 */
|
||||
return (res);
|
||||
}
|
||||
|
65
dmake/msdos/arlib.c
Normal file
65
dmake/msdos/arlib.c
Normal file
@ -0,0 +1,65 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/msdos/arlib.c,v 1.1 1992/01/24 03:27:23 dvadura Exp $
|
||||
-- SYNOPSIS -- Library access code.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- This implementation uses the library timestamp inplace of the
|
||||
-- library member timestamp.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: arlib.c,v $
|
||||
* Revision 1.1 1992/01/24 03:27:23 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
PUBLIC time_t
|
||||
seek_arch(name, lib)
|
||||
char* name;
|
||||
char* lib;
|
||||
{
|
||||
static int warned = FALSE;
|
||||
|
||||
if (!warned && !(Glob_attr&A_SILENT))
|
||||
warned = TRUE,
|
||||
Warning("Can't extract library member timestamp;\n\
|
||||
using library timestamp instead.");
|
||||
return (Do_stat(lib, NULL, NULL));
|
||||
}
|
||||
|
||||
PUBLIC int
|
||||
touch_arch(name, lib)
|
||||
char* name;
|
||||
char* lib;
|
||||
{
|
||||
static int warned = FALSE;
|
||||
|
||||
if (!warned && !(Glob_attr&A_SILENT))
|
||||
warned = TRUE,
|
||||
Warning("Can't update library member timestamp;\n\
|
||||
touching library instead.");
|
||||
return (Do_touch(lib, NULL, NULL));
|
||||
}
|
||||
|
54
dmake/msdos/bccdos/config.h
Normal file
54
dmake/msdos/bccdos/config.h
Normal file
@ -0,0 +1,54 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/msdos/bccdos/config.h,v 1.1 1992/01/24 03:27:46 dvadura Exp $
|
||||
-- SYNOPSIS -- Configurarion include file.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- There is one of these for each specific machine configuration.
|
||||
-- It can be used to further tweek the machine specific sources
|
||||
-- so that they compile.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: config.h,v $
|
||||
* Revision 1.1 1992/01/24 03:27:46 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
/* define this for configurations that don't have the coreleft function
|
||||
* so that the code compiles. To my knowledge coreleft exists only on
|
||||
* Turbo C, but it is needed here since the function is used in many debug
|
||||
* macros. */
|
||||
/*#define coreleft() 0L*/
|
||||
extern unsigned int coreleft();
|
||||
|
||||
#define SIGQUIT SIGTERM /* turbo C doesn't understand SIGQUIT */
|
||||
|
||||
/* Turbo-C understands const declarations. */
|
||||
#define CONST const
|
||||
|
||||
#ifndef MSDOS
|
||||
# define MSDOS 1
|
||||
#endif
|
||||
|
||||
/* a small problem with pointer to voids on some unix machines needs this */
|
||||
#define PVOID void *
|
50
dmake/msdos/bccdos/config.mk
Normal file
50
dmake/msdos/bccdos/config.mk
Normal file
@ -0,0 +1,50 @@
|
||||
# This is the Turbo C++ 2.0 DOS configuration file for DMAKE
|
||||
# It simply modifies the values of SRC, and checks to see if
|
||||
# OSENVIRONMENT is defined. If so it includes the appropriate
|
||||
# config.mk file.
|
||||
#
|
||||
# It also sets the values of .SOURCE.c and .SOURCE.h to include the local
|
||||
# directory.
|
||||
#
|
||||
osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE)
|
||||
|
||||
# Definition of macros for library, and C startup code.
|
||||
LDLIBS = d:/cc/bcc/lib/c$(MODEL)
|
||||
CSTARTUP = d:/cc/bcc/lib/c0$(MODEL).obj
|
||||
|
||||
# The following sources are required for TURBO C++ 2.0
|
||||
OSR_SRC = tempnam.c utime.c
|
||||
.SETDIR=$(osrdir) : $(OSR_SRC)
|
||||
|
||||
SRC += $(OSR_SRC)
|
||||
.SOURCE.h : $(osrdir)
|
||||
|
||||
# Local configuration modifications for CFLAGS. Make sure your turboc.cfg
|
||||
# file contains a -D__STDC__=1 and -DM_I86=1, if not then uncomment the line
|
||||
# below!
|
||||
#CFLAGS += -DM_I86=1 -D__STDC__=1
|
||||
|
||||
# You can get a smaller executable still, buy adding a -1 to the list of
|
||||
# flags below, but then you can't run this on an 8086/88 cpu.
|
||||
#CFLAGS += -1
|
||||
CFLAGS += -I$(osrdir) -d -O -N- -w-nod $(C_$(MODEL))
|
||||
ASFLAGS += -t -mx $(S_$(MODEL))
|
||||
|
||||
# Debugging information for Turbo-C
|
||||
DB_CFLAGS += -v
|
||||
DB_LDFLAGS += /v
|
||||
|
||||
# See if we modify anything in the lower levels.
|
||||
.IF $(OSENVIRONMENT) != $(NULL)
|
||||
.INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk
|
||||
.END
|
||||
|
||||
C_s =
|
||||
C_m = -mm
|
||||
C_c = -mc
|
||||
C_l = -ml
|
||||
|
||||
S_s = -dmsmall
|
||||
S_m = -dmmedium
|
||||
S_c = -dmcompact
|
||||
S_l = -dmlarge
|
1
dmake/msdos/bccdos/lib.rsp
Normal file
1
dmake/msdos/bccdos/lib.rsp
Normal file
@ -0,0 +1 @@
|
||||
d:\cc\bcc\lib\cl
|
1
dmake/msdos/bccdos/libswp.rsp
Normal file
1
dmake/msdos/bccdos/libswp.rsp
Normal file
@ -0,0 +1 @@
|
||||
d:\cc\bcc\lib\cl
|
96
dmake/msdos/bccdos/mk.bat
Normal file
96
dmake/msdos/bccdos/mk.bat
Normal file
@ -0,0 +1,96 @@
|
||||
md objects
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml infer.c
|
||||
copy infer.obj objects
|
||||
del infer.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml make.c
|
||||
copy make.obj objects
|
||||
del make.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml stat.c
|
||||
copy stat.obj objects
|
||||
del stat.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml expand.c
|
||||
copy expand.obj objects
|
||||
del expand.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml dmstring.c
|
||||
copy dmstring.obj objects
|
||||
del dmstring.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml hash.c
|
||||
copy hash.obj objects
|
||||
del hash.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml dag.c
|
||||
copy dag.obj objects
|
||||
del dag.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml dmake.c
|
||||
copy dmake.obj objects
|
||||
del dmake.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml path.c
|
||||
copy path.obj objects
|
||||
del path.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml imacs.c
|
||||
copy imacs.obj objects
|
||||
del imacs.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml sysintf.c
|
||||
copy sysintf.obj objects
|
||||
del sysintf.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml parse.c
|
||||
copy parse.obj objects
|
||||
del parse.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml getinp.c
|
||||
copy getinp.obj objects
|
||||
del getinp.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml quit.c
|
||||
copy quit.obj objects
|
||||
del quit.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml state.c
|
||||
copy state.obj objects
|
||||
del state.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml basename.c
|
||||
copy basename.obj objects
|
||||
del basename.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml dmdump.c
|
||||
copy dmdump.obj objects
|
||||
del dmdump.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml macparse.c
|
||||
copy macparse.obj objects
|
||||
del macparse.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml rulparse.c
|
||||
copy rulparse.obj objects
|
||||
del rulparse.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml percent.c
|
||||
copy percent.obj objects
|
||||
del percent.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml function.c
|
||||
copy function.obj objects
|
||||
del function.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\ruletab.c
|
||||
copy ruletab.obj objects
|
||||
del ruletab.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\dirbrk.c
|
||||
copy dirbrk.obj objects
|
||||
del dirbrk.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\runargv.c
|
||||
copy runargv.obj objects
|
||||
del runargv.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\arlib.c
|
||||
copy arlib.obj objects
|
||||
del arlib.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\_chdir.c
|
||||
copy _chdir.obj objects
|
||||
del _chdir.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\switchar.c
|
||||
copy switchar.obj objects
|
||||
del switchar.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\rmprq.c
|
||||
copy rmprq.obj objects
|
||||
del rmprq.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\tee.c
|
||||
copy tee.obj objects
|
||||
del tee.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\bccdos\tempnam.c
|
||||
copy tempnam.obj objects
|
||||
del tempnam.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\bccdos\utime.c
|
||||
copy utime.obj objects
|
||||
del utime.obj
|
||||
copy msdos\bccdos\startup.mk startup.mk
|
||||
tlink @msdos\bccdos\obj.rsp,dmake.exe,NUL.MAP,@msdos\bccdos\lib.rsp
|
101
dmake/msdos/bccdos/mkswp.bat
Normal file
101
dmake/msdos/bccdos/mkswp.bat
Normal file
@ -0,0 +1,101 @@
|
||||
md objects
|
||||
tasm -t -mx -dmlarge msdos\exec.asm;
|
||||
mv exec.obj objects
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml infer.c
|
||||
copy infer.obj objects
|
||||
del infer.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml make.c
|
||||
copy make.obj objects
|
||||
del make.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml stat.c
|
||||
copy stat.obj objects
|
||||
del stat.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml expand.c
|
||||
copy expand.obj objects
|
||||
del expand.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml dmstring.c
|
||||
copy dmstring.obj objects
|
||||
del dmstring.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml hash.c
|
||||
copy hash.obj objects
|
||||
del hash.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml dag.c
|
||||
copy dag.obj objects
|
||||
del dag.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml dmake.c
|
||||
copy dmake.obj objects
|
||||
del dmake.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml path.c
|
||||
copy path.obj objects
|
||||
del path.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml imacs.c
|
||||
copy imacs.obj objects
|
||||
del imacs.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml sysintf.c
|
||||
copy sysintf.obj objects
|
||||
del sysintf.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml parse.c
|
||||
copy parse.obj objects
|
||||
del parse.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml getinp.c
|
||||
copy getinp.obj objects
|
||||
del getinp.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml quit.c
|
||||
copy quit.obj objects
|
||||
del quit.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml state.c
|
||||
copy state.obj objects
|
||||
del state.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml basename.c
|
||||
copy basename.obj objects
|
||||
del basename.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml dmdump.c
|
||||
copy dmdump.obj objects
|
||||
del dmdump.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml macparse.c
|
||||
copy macparse.obj objects
|
||||
del macparse.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml rulparse.c
|
||||
copy rulparse.obj objects
|
||||
del rulparse.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml percent.c
|
||||
copy percent.obj objects
|
||||
del percent.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml function.c
|
||||
copy function.obj objects
|
||||
del function.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\ruletab.c
|
||||
copy ruletab.obj objects
|
||||
del ruletab.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\dirbrk.c
|
||||
copy dirbrk.obj objects
|
||||
del dirbrk.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\runargv.c
|
||||
copy runargv.obj objects
|
||||
del runargv.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\arlib.c
|
||||
copy arlib.obj objects
|
||||
del arlib.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\_chdir.c
|
||||
copy _chdir.obj objects
|
||||
del _chdir.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\switchar.c
|
||||
copy switchar.obj objects
|
||||
del switchar.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\rmprq.c
|
||||
copy rmprq.obj objects
|
||||
del rmprq.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\find.c
|
||||
copy find.obj objects
|
||||
del find.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\spawn.c
|
||||
copy spawn.obj objects
|
||||
del spawn.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\bccdos\tempnam.c
|
||||
copy tempnam.obj objects
|
||||
del tempnam.obj
|
||||
bcc -c -I. -Imsdos -Imsdos\bccdos -d -O -N- -w-nod -ml msdos\bccdos\utime.c
|
||||
copy utime.obj objects
|
||||
del utime.obj
|
||||
copy msdos\bccdos\startup.mk startup.mk
|
||||
tlink @msdos\bccdos\objswp.rsp,dmake.exe,NUL.MAP,@msdos\bccdos\libswp.rsp
|
32
dmake/msdos/bccdos/obj.rsp
Normal file
32
dmake/msdos/bccdos/obj.rsp
Normal file
@ -0,0 +1,32 @@
|
||||
d:\cc\bcc\lib\c0l.obj+
|
||||
objects\infer.obj+
|
||||
objects\make.obj+
|
||||
objects\stat.obj+
|
||||
objects\expand.obj+
|
||||
objects\dmstring.obj+
|
||||
objects\hash.obj+
|
||||
objects\dag.obj+
|
||||
objects\dmake.obj+
|
||||
objects\path.obj+
|
||||
objects\imacs.obj+
|
||||
objects\sysintf.obj+
|
||||
objects\parse.obj+
|
||||
objects\getinp.obj+
|
||||
objects\quit.obj+
|
||||
objects\state.obj+
|
||||
objects\basename.obj+
|
||||
objects\dmdump.obj+
|
||||
objects\macparse.obj+
|
||||
objects\rulparse.obj+
|
||||
objects\percent.obj+
|
||||
objects\function.obj+
|
||||
objects\ruletab.obj+
|
||||
objects\dirbrk.obj+
|
||||
objects\runargv.obj+
|
||||
objects\arlib.obj+
|
||||
objects\_chdir.obj+
|
||||
objects\switchar.obj+
|
||||
objects\rmprq.obj+
|
||||
objects\tee.obj+
|
||||
objects\tempnam.obj+
|
||||
objects\utime.obj
|
34
dmake/msdos/bccdos/objswp.rsp
Normal file
34
dmake/msdos/bccdos/objswp.rsp
Normal file
@ -0,0 +1,34 @@
|
||||
d:\cc\bcc\lib\c0l.obj+
|
||||
objects\exec.obj+
|
||||
objects\infer.obj+
|
||||
objects\make.obj+
|
||||
objects\stat.obj+
|
||||
objects\expand.obj+
|
||||
objects\dmstring.obj+
|
||||
objects\hash.obj+
|
||||
objects\dag.obj+
|
||||
objects\dmake.obj+
|
||||
objects\path.obj+
|
||||
objects\imacs.obj+
|
||||
objects\sysintf.obj+
|
||||
objects\parse.obj+
|
||||
objects\getinp.obj+
|
||||
objects\quit.obj+
|
||||
objects\state.obj+
|
||||
objects\basename.obj+
|
||||
objects\dmdump.obj+
|
||||
objects\macparse.obj+
|
||||
objects\rulparse.obj+
|
||||
objects\percent.obj+
|
||||
objects\function.obj+
|
||||
objects\ruletab.obj+
|
||||
objects\dirbrk.obj+
|
||||
objects\runargv.obj+
|
||||
objects\arlib.obj+
|
||||
objects\_chdir.obj+
|
||||
objects\switchar.obj+
|
||||
objects\rmprq.obj+
|
||||
objects\find.obj+
|
||||
objects\spawn.obj+
|
||||
objects\tempnam.obj+
|
||||
objects\utime.obj
|
152
dmake/msdos/bccdos/public.h
Normal file
152
dmake/msdos/bccdos/public.h
Normal file
@ -0,0 +1,152 @@
|
||||
/* RCS -- $Header$
|
||||
-- WARNING -- This file is AUTOMATICALLY GENERATED DO NOT EDIT IT
|
||||
--
|
||||
-- SYNOPSIS -- Local functions exported to be visible by others.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- This file is generated by 'genpub'. Function declarations
|
||||
-- that appear in this file are extracted by 'genpub' from
|
||||
-- source files. Any function in the source file whose definition
|
||||
-- appears like:
|
||||
--
|
||||
-- PUBLIC return_type
|
||||
-- function( arg_list );
|
||||
-- type_expr1 arg1;
|
||||
-- ...
|
||||
--
|
||||
-- has its definition extracted and a line of the form:
|
||||
--
|
||||
-- return_type function ANSI((type_expr1,type_expr2,...));
|
||||
--
|
||||
-- entered into the output file.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log$
|
||||
*/
|
||||
|
||||
#ifndef _DMAKE_PUBLIC_h
|
||||
#define _DMAKE_PUBLIC_h
|
||||
|
||||
void Infer_recipe ANSI((CELLPTR, CELLPTR));
|
||||
int Make_targets ANSI(());
|
||||
int Exec_commands ANSI((CELLPTR));
|
||||
void Print_cmnd ANSI((char *, int, int));
|
||||
void Pop_dir ANSI((int));
|
||||
void Append_line ANSI((char *, int, FILE *, char *, int, int));
|
||||
void Stat_target ANSI((CELLPTR, int));
|
||||
char * Expand ANSI((char *));
|
||||
char * Apply_edit ANSI((char *, char *, char *, int, int));
|
||||
void Map_esc ANSI((char *));
|
||||
char* Apply_modifiers ANSI((int, char *));
|
||||
char* Tokenize ANSI((char *, char *));
|
||||
char * _strjoin ANSI((char *, char *, int, int));
|
||||
char * _stradd ANSI((char *, char *, int));
|
||||
char * _strapp ANSI((char *, char *));
|
||||
char * _strdup ANSI((char *));
|
||||
char * _strdup2 ANSI((char *));
|
||||
char * _strpbrk ANSI((char *, char *));
|
||||
char * _strspn ANSI((char *, char *));
|
||||
char * _strstr ANSI((char *, char *));
|
||||
char * _substr ANSI((char *, char *));
|
||||
uint16 Hash ANSI((char *, uint32 *));
|
||||
HASHPTR Get_name ANSI((char *, HASHPTR *, int));
|
||||
HASHPTR Search_table ANSI((HASHPTR *, char *, uint16 *, uint32 *));
|
||||
HASHPTR Def_macro ANSI((char *, char *, int));
|
||||
CELLPTR Def_cell ANSI((char *));
|
||||
LINKPTR Add_prerequisite ANSI((CELLPTR, CELLPTR, int, int));
|
||||
void Clear_prerequisites ANSI((CELLPTR));
|
||||
int Test_circle ANSI((CELLPTR, int));
|
||||
STRINGPTR Def_recipe ANSI((char *, STRINGPTR, int, int));
|
||||
t_attr Rcp_attribute ANSI((char *));
|
||||
void main ANSI((int, char **));
|
||||
FILE * Openfile ANSI((char *, int, int));
|
||||
FILE * Closefile ANSI(());
|
||||
FILE * Search_file ANSI((char *, char **));
|
||||
char * Filename ANSI(());
|
||||
int Nestlevel ANSI(());
|
||||
void No_ram ANSI(());
|
||||
int Usage ANSI((int));
|
||||
int Version ANSI(());
|
||||
char * Get_suffix ANSI((char *));
|
||||
char * Build_path ANSI((char *, char *));
|
||||
void Make_rules ANSI(());
|
||||
void Create_macro_vars ANSI(());
|
||||
time_t Do_stat ANSI((char *, char *, char **));
|
||||
int Do_touch ANSI((char *, char *, char **));
|
||||
void Void_lib_cache ANSI((char *, char *));
|
||||
time_t Do_time ANSI(());
|
||||
int Do_cmnd ANSI((char *, int, int, CELLPTR, int, int, int));
|
||||
char ** Pack_argv ANSI((int, int, char *));
|
||||
char * Read_env_string ANSI((char *));
|
||||
int Write_env_string ANSI((char *, char *));
|
||||
void ReadEnvironment ANSI(());
|
||||
void Catch_signals ANSI((void (*)()));
|
||||
void Clear_signals ANSI(());
|
||||
void Prolog ANSI((int, char* []));
|
||||
void Epilog ANSI((int));
|
||||
char * Get_current_dir ANSI(());
|
||||
int Set_dir ANSI((char*));
|
||||
char Get_switch_char ANSI(());
|
||||
FILE* Get_temp ANSI((char **, char *, int));
|
||||
FILE * Start_temp ANSI((char *, CELLPTR, char **));
|
||||
void Open_temp_error ANSI((char *, char *));
|
||||
void Link_temp ANSI((CELLPTR, FILE *, char *));
|
||||
void Close_temp ANSI((CELLPTR, FILE *));
|
||||
void Unlink_temp_files ANSI((CELLPTR));
|
||||
void Handle_result ANSI((int, int, int, CELLPTR));
|
||||
void Update_time_stamp ANSI((CELLPTR));
|
||||
int Remove_file ANSI((char *));
|
||||
void Parse ANSI((FILE *));
|
||||
int Get_line ANSI((char *, FILE *));
|
||||
char * Do_comment ANSI((char *, char **, int));
|
||||
char * Get_token ANSI((TKSTRPTR, char *, int));
|
||||
void Quit ANSI(());
|
||||
void Read_state ANSI(());
|
||||
void Write_state ANSI(());
|
||||
int Check_state ANSI((CELLPTR, STRINGPTR *, int));
|
||||
char* basename ANSI((char *));
|
||||
void Dump ANSI(());
|
||||
void Dump_recipe ANSI((STRINGPTR));
|
||||
int Parse_macro ANSI((char *, int));
|
||||
int Macro_op ANSI((char *));
|
||||
int Parse_rule_def ANSI((int *));
|
||||
int Rule_op ANSI((char *));
|
||||
void Add_recipe_to_list ANSI((char *, int, int));
|
||||
void Bind_rules_to_targets ANSI((int));
|
||||
int Set_group_attributes ANSI((char *));
|
||||
DFALINKPTR Match_dfa ANSI((char *));
|
||||
void Check_circle_dfa ANSI(());
|
||||
void Add_nfa ANSI((char *));
|
||||
char * Exec_function ANSI((char *));
|
||||
int If_root_path ANSI((char *));
|
||||
int runargv ANSI((CELLPTR, int, int, int, int, char *));
|
||||
void Clean_up_processes ANSI(());
|
||||
int Wait_for_child ANSI((int, int));
|
||||
time_t seek_arch ANSI((char*, char*));
|
||||
int touch_arch ANSI((char*, char*));
|
||||
int _chdir ANSI((char *));
|
||||
void Remove_prq ANSI((CELLPTR));
|
||||
void Hook_std_writes ANSI((char *));
|
||||
|
||||
#endif
|
154
dmake/msdos/bccdos/startup.mk
Normal file
154
dmake/msdos/bccdos/startup.mk
Normal file
@ -0,0 +1,154 @@
|
||||
# MSDOS DMAKE startup file. Customize to suit your needs.
|
||||
# Assumes MKS toolkit for the tool commands, and Turbo-C. Change as req'd.
|
||||
# See the documentation for a description of internally defined macros.
|
||||
#
|
||||
# Disable warnings for macros redefined here that were given
|
||||
# on the command line.
|
||||
__.SILENT := $(.SILENT)
|
||||
.SILENT := yes
|
||||
|
||||
# Configuration parameters for DMAKE startup.mk file
|
||||
# Set these to NON-NULL if you wish to turn the parameter on.
|
||||
_HAVE_RCS := yes # yes => RCS is installed.
|
||||
_HAVE_SCCS := # yes => SCCS is installed.
|
||||
|
||||
# Applicable suffix definitions
|
||||
A := .lib # Libraries
|
||||
E := .exe # Executables
|
||||
F := .for # Fortran
|
||||
O := .obj # Objects
|
||||
P := .pas # Pascal
|
||||
S := .asm # Assembler sources
|
||||
V := # RCS suffix
|
||||
|
||||
# See if these are defined
|
||||
TMPDIR := $(ROOTDIR)/tmp
|
||||
.IMPORT .IGNORE : TMPDIR SHELL COMSPEC
|
||||
|
||||
# Recipe execution configurations
|
||||
# First set SHELL, If it is not defined, use COMSPEC, otherwise
|
||||
# it is assumed to be MKS Korn SHELL.
|
||||
.IF $(SHELL) == $(NULL)
|
||||
.IF $(COMSPEC) == $(NULL)
|
||||
SHELL := $(ROOTDIR)/bin/sh$E
|
||||
.ELSE
|
||||
SHELL := $(COMSPEC)
|
||||
.END
|
||||
.END
|
||||
GROUPSHELL := $(SHELL)
|
||||
|
||||
# Now set remaining arguments depending on which SHELL we
|
||||
# are going to use. COMSPEC (assumed to be command.com) or
|
||||
# MKS Korn Shell.
|
||||
.IF $(SHELL)==$(COMSPEC)
|
||||
SHELLFLAGS := $(SWITCHAR)c
|
||||
GROUPFLAGS := $(SHELLFLAGS)
|
||||
SHELLMETAS := *"?<>
|
||||
GROUPSUFFIX := .bat
|
||||
DIRSEPSTR := \\
|
||||
DIVFILE = $(TMPFILE:s,/,\)
|
||||
.ELSE
|
||||
SHELLFLAGS := -c
|
||||
GROUPFLAGS :=
|
||||
SHELLMETAS := *"?<>|()&][$$\#`'
|
||||
GROUPSUFFIX := .ksh
|
||||
.MKSARGS := yes
|
||||
DIVFILE = $(TMPFILE:s,/,${DIVSEP_shell_${USESHELL}})
|
||||
DIVSEP_shell_yes := \\\
|
||||
DIVSEP_shell_no := \\
|
||||
.END
|
||||
|
||||
# Standard C-language command names and flags
|
||||
CC := bcc # C-compiler and flags
|
||||
CFLAGS +=
|
||||
|
||||
AS := tasm # Assembler and flags
|
||||
ASFLAGS +=
|
||||
|
||||
LD = tlink # Loader and flags
|
||||
LDFLAGS +=
|
||||
LDLIBS =
|
||||
|
||||
# Definition of $(MAKE) macro for recursive makes.
|
||||
MAKE = $(MAKECMD) $(MFLAGS)
|
||||
|
||||
# Language and Parser generation Tools and their flags
|
||||
YACC := yacc # standard yacc
|
||||
YFLAGS +=
|
||||
YTAB := ytab # yacc output files name stem.
|
||||
|
||||
LEX := lex # standard lex
|
||||
LFLAGS +=
|
||||
LEXYY := lex_yy # lex output file
|
||||
|
||||
# Other Compilers, Tools and their flags
|
||||
PC := tpc # pascal compiler
|
||||
RC := anyf77 # ratfor compiler
|
||||
FC := anyf77 # fortran compiler
|
||||
|
||||
CO := co # check out for RCS
|
||||
COFLAGS += -q
|
||||
|
||||
AR := ar # archiver
|
||||
ARFLAGS+= ruv
|
||||
|
||||
RM := rm # remove a file command
|
||||
RMFLAGS +=
|
||||
|
||||
# Implicit generation rules for making inferences.
|
||||
# We don't provide .yr or .ye rules here. They're obsolete.
|
||||
# Rules for making *$O
|
||||
%$O .SWAP: %.c ; $(CC) $(CFLAGS) -c $<
|
||||
%$O .SWAP: %$P ; $(PC) $(PFLAGS) -c $<
|
||||
%$O .SWAP: %$S ; $(AS) $(ASFLAGS) $(<:s,/,\);
|
||||
%$O : %.cl ; class -c $<
|
||||
%$O .SWAP: %.e %.r %.F %$F ; $(FC) $(RFLAGS) $(EFLAGS) $(FFLAGS) -c $<
|
||||
|
||||
# Executables
|
||||
%$E .SWAP: %$O ; $(CC) $(LDFLAGS) -e$@ $<
|
||||
|
||||
# lex and yacc rules
|
||||
%.c .SWAP: %.y ; $(YACC) $(YFLAGS) $<; mv $(YTAB).c $@
|
||||
%.c .SWAP: %.l ; $(LEX) $(LFLAGS) $<; mv $(LEXYY).c $@
|
||||
|
||||
# RCS support
|
||||
.IF $(_HAVE_RCS)
|
||||
% : $$(@:d)RCS/$$(@:f)$V;- $(CO) $(COFLAGS) $@
|
||||
.NOINFER : $$(@:d)RCS/$$(@:f)$V
|
||||
.END
|
||||
|
||||
# SCCS support
|
||||
.IF $(_HAVE_SCCS)
|
||||
% : s.% ; get $<
|
||||
.NOINFER : s.%
|
||||
.END
|
||||
|
||||
# Recipe to make archive files.
|
||||
%$A .SWAP:
|
||||
[
|
||||
$(AR) $(ARFLAGS) $@ $?
|
||||
$(RM) $(RMFLAGS) $?
|
||||
]
|
||||
|
||||
# DMAKE uses this recipe to remove intermediate targets
|
||||
.REMOVE :; $(RM) -f $<
|
||||
|
||||
# AUGMAKE extensions for SYSV compatibility
|
||||
@B = $(@:b)
|
||||
@D = $(@:d)
|
||||
@F = $(@:f)
|
||||
"*B" = $(*:b)
|
||||
"*D" = $(*:d)
|
||||
"*F" = $(*:f)
|
||||
<B = $(<:b)
|
||||
<D = $(<:d)
|
||||
<F = $(<:f)
|
||||
?B = $(?:b)
|
||||
?F = $(?:f)
|
||||
?D = $(?:d)
|
||||
|
||||
# Turn warnings back to previous setting.
|
||||
.SILENT := $(__.SILENT)
|
||||
|
||||
# Local init file if any, gets parsed before user makefile
|
||||
.INCLUDE .IGNORE: "_startup.mk"
|
82
dmake/msdos/bccdos/tempnam.c
Normal file
82
dmake/msdos/bccdos/tempnam.c
Normal file
@ -0,0 +1,82 @@
|
||||
/*LINTLIBRARY*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <dos.h>
|
||||
|
||||
#if defined(max)
|
||||
# undef max
|
||||
#endif
|
||||
#define max(A,B) (((A)<(B))?(B):(A))
|
||||
|
||||
extern char *mktemp();
|
||||
extern int access();
|
||||
int _access();
|
||||
|
||||
/* Turbo C stdio.h doesn't define P_tmpdir, so let's do it here */
|
||||
/* Under DOS leave the default tmpdir pointing here! */
|
||||
#ifndef P_tmpdir
|
||||
static char *P_tmpdir = "";
|
||||
#endif
|
||||
|
||||
char *
|
||||
tempnam(dir, prefix)
|
||||
char *dir; /* use this directory please (if non-NULL) */
|
||||
char *prefix; /* use this (if non-NULL) as filename prefix */
|
||||
{
|
||||
static int count = 0;
|
||||
register char *p, *q, *tmpdir;
|
||||
int tl=0, dl=0, pl;
|
||||
char buf[30];
|
||||
|
||||
pl = strlen(P_tmpdir);
|
||||
|
||||
if( (tmpdir = getenv("TMPDIR")) != NULL ) tl = strlen(tmpdir);
|
||||
if( dir != NULL ) dl = strlen(dir);
|
||||
|
||||
if( (p = malloc((unsigned)(max(max(dl,tl),pl)+13))) == NULL )
|
||||
return(NULL);
|
||||
|
||||
*p = '\0';
|
||||
|
||||
if( (tl == 0) || (_access( strcpy(p, tmpdir), 0) != 0) )
|
||||
if( (dl == 0) || (_access( strcpy(p, dir), 0) != 0) )
|
||||
if( _access( strcpy(p, P_tmpdir), 0) != 0 )
|
||||
if( !prefix )
|
||||
prefix = "tp";
|
||||
|
||||
if(prefix)
|
||||
{
|
||||
*(p+strlen(p)+2) = '\0';
|
||||
(void)strncat(p, prefix, 2);
|
||||
}
|
||||
|
||||
sprintf( buf, "%08x", _psp );
|
||||
buf[6]='\0';
|
||||
(void)strcat(p, buf );
|
||||
sprintf( buf, "%04d", count++ );
|
||||
q=p+strlen(p)-6;
|
||||
*q++ = buf[0]; *q++ = buf[1];
|
||||
*q++ = buf[2]; *q++ = buf[3];
|
||||
|
||||
if( (q = strrchr(p,'.')) != NULL ) *q = '\0';
|
||||
|
||||
return(p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
_access( name, flag )
|
||||
char *name;
|
||||
int flag;
|
||||
{
|
||||
char *p;
|
||||
int r;
|
||||
|
||||
if( name == NULL || !*name ) return(1); /* NULL dir means current dir */
|
||||
r = access( name, flag );
|
||||
p = name+strlen(name)-1;
|
||||
if(*p != '/' && *p != '\\') strcat( p, "/" );
|
||||
|
||||
return( r );
|
||||
}
|
42
dmake/msdos/bccdos/utime.c
Normal file
42
dmake/msdos/bccdos/utime.c
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
** change access and modify times of file
|
||||
*/
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
|
||||
int
|
||||
utime(name, timep)/*
|
||||
====================
|
||||
Broken for turbo C it only sets the file time to the current time by
|
||||
touching a character in the file */
|
||||
char* name;
|
||||
time_t timep[2];
|
||||
{
|
||||
struct stat buf;
|
||||
int fil;
|
||||
char data;
|
||||
|
||||
if (stat(name, &buf) != 0)
|
||||
return (-1);
|
||||
if (buf.st_size != 0) {
|
||||
if ((fil = open(name, O_RDWR, S_IWRITE)) < 0)
|
||||
return (-1);
|
||||
if (read(fil, &data, 1) < 1) {
|
||||
close(fil);
|
||||
return (-1);
|
||||
}
|
||||
lseek(fil, 0L, 0);
|
||||
if (write(fil, &data, 1) < 1) {
|
||||
close(fil);
|
||||
return (-1);
|
||||
}
|
||||
close(fil);
|
||||
return (0);
|
||||
} else if ((fil = creat(name, S_IWRITE)) < 0) {
|
||||
return (-1);
|
||||
} else {
|
||||
close(fil);
|
||||
return (0);
|
||||
}
|
||||
}
|
68
dmake/msdos/config.mk
Normal file
68
dmake/msdos/config.mk
Normal file
@ -0,0 +1,68 @@
|
||||
# This is an OS specific configuration file
|
||||
# It assumes that OBJDIR, TARGET and DEBUG are previously defined.
|
||||
# It defines CFLAGS, LDARGS, CPPFLAGS, STARTUPFILE, LDOBJS
|
||||
# It augments SRC, OBJDIR, TARGET, CFLAGS, LDLIBS
|
||||
#
|
||||
|
||||
# Memory model to compile for
|
||||
# set to s - small, m - medium, c - compact, l - large
|
||||
# Need large model now, dmake has grown up :-)
|
||||
MODEL = l
|
||||
|
||||
STARTUPFILE = $(OS)/startup.mk
|
||||
|
||||
CPPFLAGS = $(CFLAGS)
|
||||
LDOBJS = $(CSTARTUP) $(OBJDIR)/{$(<:f)}
|
||||
LDARGS = $(LDHEAD) @$(LDTMPOBJ),$(TARGET),NUL.MAP$(LDTAIL)
|
||||
LDTAIL = $(_libs)$(LDFLAGS:s/ //)
|
||||
_libs = $(!null,$(LDLIBS) ,@$(LDTMPLIB))
|
||||
LDTMPOBJ = $(mktmp,,$(DIVFILE) $(LDOBJS:s,/,\\,:t"+\n")\n)
|
||||
LDTMPLIB = $(mktmp,,$(DIVFILE) $(LDLIBS:s,/,\\,:t"+\n")\n)
|
||||
|
||||
# Debug flags
|
||||
DB_CFLAGS = -DDBUG
|
||||
DB_LDFLAGS =
|
||||
DB_LDLIBS =
|
||||
|
||||
# NO Debug flags
|
||||
NDB_CFLAGS =
|
||||
NDB_LDFLAGS =
|
||||
NDB_LDLIBS =
|
||||
|
||||
# Local configuration modifications for CFLAGS.
|
||||
CFLAGS += -I$(OS)
|
||||
|
||||
# Common MSDOS source files.
|
||||
# Define SWAP to anything but 'y' for the swap code to be excluded on making.
|
||||
# Swapping for DOS versions is enabled by default.
|
||||
# Note: swapping is handled specially for ZTC in msdos/ztcdos/config.mk.
|
||||
SWAP *= y
|
||||
.IF $(OSRELEASE) != ztcdos
|
||||
.IF $(SWAP) == y
|
||||
SWP_SRC = find.c spawn.c
|
||||
ASRC += exec.asm
|
||||
.ELSE
|
||||
SWP_SRC = tee.c
|
||||
.END
|
||||
.ELSE
|
||||
SWP_SRC = tee.c
|
||||
.END
|
||||
|
||||
OS_SRC += ruletab.c dirbrk.c runargv.c arlib.c _chdir.c switchar.c rmprq.c\
|
||||
$(SWP_SRC)
|
||||
SRC += $(OS_SRC)
|
||||
.SETDIR=$(OS) : $(ASRC) $(OS_SRC)
|
||||
|
||||
# Provide our own %$O : %$S rule.
|
||||
%$O : %$S
|
||||
$(AS) $(ASFLAGS) $(<:s,/,\,);
|
||||
mv $(@:f) $(OBJDIR)
|
||||
|
||||
# Set source dirs so that we can find files named in this
|
||||
# config file.
|
||||
.SOURCE.h : $(OS)
|
||||
|
||||
# See if we modify anything in the lower levels.
|
||||
.IF $(OSRELEASE) != $(NULL)
|
||||
.INCLUDE : $(OS)$(DIRSEPSTR)$(OSRELEASE)$(DIRSEPSTR)config.mk
|
||||
.END
|
51
dmake/msdos/dirbrk.c
Normal file
51
dmake/msdos/dirbrk.c
Normal file
@ -0,0 +1,51 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/msdos/dirbrk.c,v 1.1 1992/01/24 03:27:29 dvadura Exp $
|
||||
-- SYNOPSIS -- define the directory separator string.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- Define this string for any character that may appear in a path name
|
||||
-- and can be used as a directory separator.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: dirbrk.c,v $
|
||||
* Revision 1.1 1992/01/24 03:27:29 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#include "extern.h"
|
||||
|
||||
/* dos uses /, \, and : */
|
||||
char* DirBrkStr = "/\\:";
|
||||
|
||||
/*
|
||||
** Return TRUE if the name is the full specification of a path name to a file
|
||||
** starting at the root of the file system, otherwise return FALSE
|
||||
*/
|
||||
PUBLIC int
|
||||
If_root_path(name)
|
||||
char *name;
|
||||
{
|
||||
return( (strchr(DirBrkStr, *name) != NIL(char)) ||
|
||||
(isalpha(*name) && name[1] == ':') );
|
||||
}
|
42
dmake/msdos/dirlib.h
Normal file
42
dmake/msdos/dirlib.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* DIRLIB.H by M. J. Weinstein Released to public domain 1-Jan-89 */
|
||||
|
||||
#ifndef _DIRLIB_h_
|
||||
#define _DIRLIB_h_
|
||||
|
||||
#include <stdio.h>
|
||||
#include "stdmacs.h"
|
||||
|
||||
#define MAXNAMLEN 15
|
||||
|
||||
struct direct {
|
||||
long d_ino;
|
||||
unsigned short d_reclen;
|
||||
unsigned short d_namlen;
|
||||
char d_name[MAXNAMLEN+1];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char fcb[21];
|
||||
char attr;
|
||||
short time;
|
||||
short date;
|
||||
long size;
|
||||
char name[13];
|
||||
} DTA;
|
||||
|
||||
typedef struct {
|
||||
DTA dd_dta; /* disk transfer area for this dir. */
|
||||
short dd_stat; /* status return from last lookup */
|
||||
char dd_name[1]; /* full name of file -- struct is extended */
|
||||
} DIR;
|
||||
|
||||
extern DIR *opendir ANSI((char *));
|
||||
extern struct direct *readdir ANSI((DIR *));
|
||||
extern long telldir ANSI((DIR *));
|
||||
extern void seekdir ANSI((DIR *, long));
|
||||
extern void closedir ANSI((DIR *));
|
||||
extern DTA *findfirst ANSI((char *, DTA *));
|
||||
extern DTA *findnext ANSI((DTA *));
|
||||
|
||||
#define rewinddir(dirp) seekdir(dirp,0L)
|
||||
#endif
|
1234
dmake/msdos/exec.asm
Normal file
1234
dmake/msdos/exec.asm
Normal file
File diff suppressed because it is too large
Load Diff
19
dmake/msdos/exec.h
Normal file
19
dmake/msdos/exec.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef _EXEC_h_
|
||||
#define _EXEC_h_
|
||||
|
||||
#ifndef ANSI
|
||||
#if defined(__STDC__) || defined(__TURBOC__)
|
||||
#define ANSI(x) x
|
||||
#else
|
||||
#define ANSI(x) ()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern int exec ANSI((int, char far *, char far *, unsigned int, char far *));
|
||||
|
||||
#ifndef MK_FP
|
||||
#define MK_FP(seg,ofs) \
|
||||
((void far *) (((unsigned long)(seg) << 16) | (unsigned)(ofs)))
|
||||
#endif
|
||||
|
||||
#endif
|
63
dmake/msdos/exec.uue
Normal file
63
dmake/msdos/exec.uue
Normal file
@ -0,0 +1,63 @@
|
||||
begin 600 exec.obj
|
||||
M@! #DU31$]37&5X96,N87-M;(@@ '%1U<F)O($%S<V5M8FQE<B @5F5R
|
||||
M<VEO;B S+C";B!8 0.FRO888#DU31$]37&5X96,N87-M*(@# $#I3)8" !H
|
||||
MB , 0*&4EA "45814-?5$585 1#3T1%:9@' $@:" (# ?&6# %7T1!5$$$
|
||||
M1$%40<*8!P!( @ $!0$-E@@ !D1'4D]54(N:! &_P);C D !E]E<G)N;P#@
|
||||
MD!, 0(,7TEN=&5R<G5P=&5D 69 < !%5]D;U]U;FAO;VM?<W1D7W=R
|
||||
M:71E<P,( &>0# 05?97AE8^$& '.0&@ 1-?9&]?:&]O:U]S=&1?=W)I
|
||||
M=&5SN < FH@$ $"B 9&@!@ !F ,&B#@ !7 $E $ 0 $ RJ(. &(
|
||||
M 4$ 0 ! 0""H@X <D! 0 ! $ ! (&@" !S $ BJ#' '4
|
||||
M 65X96,Z($9A:6QU<F4@<F5A9&EN9R!H96%D97(@8FQO8VL-"B1E>&5C.B!&
|
||||
M86EL=7)E(')E861I;F<@<V5G;65N="!D871A#0HD97AE8SH@1F%I;'5R92!O
|
||||
M;B!R97-I>F4-"B1E>&5C.B!&86EL=7)E('1O(&9R964@82!B;&]C:PT*)&5X
|
||||
M96,Z(%!R;V=R86T@<W=A<"!F86EL=7)E#0HD97AE8SH@365M;W)Y(&)L;V-K
|
||||
M<R!D;VXG="!M871C: T*)+>B#@ !EP(! $ 0 $ LJ H &8 G(&=0:7
|
||||
M!G,&=@:]!@,$!P0+! 0$" 0J! 8$"@1@! 4$"012! J<20#$ %0!Q )4 <0$
|
||||
M5 '$!E0!Q A4 <0*5 '$#%0!Q Y4 <005 '$$E0!Q!14 <065 '$&%0!Q!I4
|
||||
M <0<5 '$'E0!Q"!4 <0B5 $GH P <H"7 $ %P! #-G D S !4 <P$5 $5
|
||||
MH,T# =8" "<@/Q =0J#^P%T"X/[ G0&G2[_+LP!4%%24U155E<>!HOL+HL^
|
||||
MT &T49PN_Q[, 2X['HP =&R.PR;%'C0 BW8,B@ N.@;3 75CB@$N.@;2 71*
|
||||
MN SG"[_'LP!B_(KTK@!,YPN_Q[, 2Z+'HP M%"<+O\>S &+WXY> HM6#K1
|
||||
MG"[_'LP!C,.T4)PN_Q[, 8O6N $SG"[_'LP!ZQ".7@*+5@Z+W[1 G"[_'LP!
|
||||
M!Q]?7EV#Q );6EE8G2[_+LP!@\0&6%M96EY?71\'58OLAT8�$ AT8&7;@%
|
||||
M ,_X+O\&D@ N@SZ8 !T ?G/NM0!ZQR0NOD!ZQ:0NAX"ZQ"0NC@"ZPJ0NG4"
|
||||
MZP20NE@"4HL>C@#_E[ "C,B.V%JT"<TAN/],S2'1Z7,!I/.EP\/#P\/#P\/#
|
||||
MNH$!N0< BQ[* ;0_S2%S NNF/0< = <+P'0"ZYOYPQXNCAZ! 2Z+%H,!+HL.
|
||||
MA0$NBQ[* ;0_S2$?<P+K@3L&A0%T ^EX_\.+'LH!,\F+T;@ 0LTAPXL>R@&T
|
||||
M/LTANH@!M$'-(<.+'I8 N %8S2&+'HX _Y>V HX&C "+'H0 M$K-(7,#Z4__
|
||||
MBQZ. /^7I )R**"' 3P =.\\ 743BQZ% ;1(S2%R!CL&@0%TV^DA_XL>C@#_
|
||||
MEZH"Z\Z+'HX _Y>P L.X %C-(:.6 (L^C ",RRO?B\=(CL FBS8# (DVA "X
|
||||
MYP71Z-'HT>C1Z /8*_,#^XD>A@")/H@ L #H'0%R,:&, $B.P+LD!NC+ '(C
|
||||
MH8P 2([ NQT&Z+T <P/IJ_Z.!HP BQZ& +1*S2%S ^F4_L.+'HX _Y>P C/
|
||||
MHXX ^<.#/HX '0(Z(, <@/H<_^#/I( '5FH8H "\!T"%".P+1)S2%8H8H
|
||||
MH\0"C,G'!L8"VP")#L@"NIH CL&[Q (>B2;4 HP6T@+'!M8" #_!I@ N !+
|
||||
MS2$NCA;2 BZ+)M0"'W,&H]8"ZQ.0M$W-(8#\ 74$_P:2 #+DHY @SZ. !T
|
||||
M ^B?_L<&F ,/'!HX #HE@##)HLV P",QT<FH0$ +CL&C !U)BX[/HH
|
||||
M=!DN.SZ, '025U93_]-;7E]R#R:@ \6G0& _Z.Q^O'^,..Q[1)S2'#L %7
|
||||
M5C/2BQZ. /^7F )>7W(Z@_X =#6+SH'Y_P]^ [G_#U'1X='AT>'1X5=6B_$S
|
||||
MTK "BQZ. %/_EY@"6_^7G@)>7UIR!@/Z*_+KQL/#P\/#P\.@B $*P'07NH@!
|
||||
M,\FT/,TA<@RCR@''!HX ! #K I#YPXD^@0&)%H,!(YR1 <065 '$)U0!Q"]4
|
||||
M <0T5 '$1U0!Q%!4 <1;5 '$:%0!Q&U4 <1U5 '$A50!Q(]4 <2:5 '$K%0!
|
||||
MQ+Y4 <3A5 '$YE0!Q.Y4 <3T5 '$^E0!Q0!4 <4&5 '%#%0!Q1%4 <455 '%
|
||||
M-E0!Q3U4 <585 '%750!Q6)4 <5G5 '%=%0!Q7Y4 <6,5 '%DU0!Q9Q4 <6E
|
||||
M5 '%J50!Q:U4 <6Q5 '%OE0!Q<)4 <7'5 '%TU0!Q=U4 <865 '&/%0!QDI4
|
||||
M <7F5 '%ZE0!Q?!4 <7T5 '%_50!Q@%4 <835 '&*%0!QBQ4 <8V5 '&1%0!
|
||||
MQE94 <9:5 '&:%0!QFQ4 <9Q5 '&=U0!QH94 <:,5 '&FU0!QIY4 <:D5 '&
|
||||
MIE0!QJI4 <:M5 '&LE0!QK=4 <:[5 '&OU0!QL54 <;/5 '&U%0!QMI4 <;J
|
||||
M5 '&[U0!QO-4 <;]5 ''!%0!QQM4 <<B5 ''*50!QU94 <=:5 ''@U0!QXA4
|
||||
M <>-5 ''HE0!QZE4 <>T5 ''N%0!Q\-4 <?'5 $%H'\! 9\&B3:% :*' ;J!
|
||||
M ;D' (L>R@&T0,TA<@8]!P!T ?G#'BZ.'H$!+HL6@P$NBPZ% 2Z+'LH!M$#-
|
||||
M(1]R!SL&A0%T ?G#58OL5E<>#@?\BT8&)J.. (M&$":CB@"_F@#%=@BY00#H
|
||||
M]_R_VP#%=@RY@0#HZ_R_B '%=A*Y00#HW_R,T":C@ FB2:" (S(CMB.T+R
|
||||
M ,<&D@ ,<&D +@C-<TA+HD>O (NC :^ KJS [@C)<TAN"0US2$NB1[
|
||||
M BZ,!L("NI8#N"0ES2&T4<TA+HD>C #HU?TNQ1:\ K@C)<TA+L46P *X)"7-
|
||||
M(2ZA@ ".T"Z+)H( '[@ ([ +J&2 ":C "X ".P"ZAU@(FHP +J&0 %]>
|
||||
M7<M5B^Q7BWX&+HD^T &T4<TA+HD>C ".PR;$'C0 )HI' 2ZBTP$FB@$NHM(!
|
||||
MN"$US2$NB1[, 2Z,!LX!'HS(CMBZV *X(27-(1]?7<L>+L46S &,V O"= FX
|
||||
M(26<+O\>S $?RPJ<O0#$ E0!Q 54 <0(5 '$#U0!Q")4 <0G5 '$+%0!Q#%4
|
||||
M <0\5 '$4%0!Q%=4 <1:5 '$9E0!Q')4 <2!5 '$AE0!Q(]4 <235 '$F50!
|
||||
MQ*54 <2J5 '$K50!Q+Q4 <3!5 '$Q%0!Q-)4 <3:5 '$Y%0!Q.U4 <3T5 '(
|
||||
M^!0! L3^5 '% A0! LD%%@$!Q0M4 <4/%@$!Q1-4 <4C5 '%+%0!Q3M4 <5"
|
||||
E5 '%3%0!Q5%4 <595 '%:%0!Q7=4 ?6@!@ " %B* @ =%0!
|
||||
|
||||
end
|
130
dmake/msdos/find.c
Normal file
130
dmake/msdos/find.c
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
Directory Access Library
|
||||
|
||||
FIND.C taken from DIRLIB.C by M. J. Weinstein
|
||||
Released to public domain 1-Jan-89
|
||||
|
||||
The author may be contacted at:
|
||||
matt@cs.ucla.edu -or- POB 84524, L.A., CA 90073
|
||||
|
||||
Modified by dvadura@watdragon.edu to work with dmake.
|
||||
(nuked the DOS version 2 code, since dmake needs version
|
||||
3.0 or greater to function).
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* revision history:
|
||||
*
|
||||
* VER MM/DD/YY COMMENTS
|
||||
* ---- -------- --------
|
||||
* 0.99 02/24/86 Beta release to INTERNET
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <alloc.h>
|
||||
#include <dos.h>
|
||||
#include "dirlib.h"
|
||||
|
||||
#ifndef MK_FP
|
||||
#define MK_FP(seg,ofs) ((void far *) \
|
||||
(((unsigned long)(seg) << 16) | (unsigned)(ofs)))
|
||||
#endif
|
||||
#ifndef FP_SEG
|
||||
#define FP_SEG(fp) ((unsigned)((unsigned long)(fp) >> 16))
|
||||
#endif
|
||||
#ifndef FP_OFF
|
||||
#define FP_OFF(fp) ((unsigned)(fp))
|
||||
#endif
|
||||
|
||||
int _err;
|
||||
static DTA far *_getsetdta ANSI((DTA far *));
|
||||
|
||||
/*
|
||||
* get/set dta address
|
||||
*/
|
||||
|
||||
static DTA far *
|
||||
_getsetdta(newdta)
|
||||
DTA far *newdta;
|
||||
{
|
||||
DTA far *olddta;
|
||||
union REGS r;
|
||||
struct SREGS s;
|
||||
|
||||
/* get old dta */
|
||||
r.h.ah = 0x2f;
|
||||
intdos(&r, &r);
|
||||
segread(&s);
|
||||
olddta = (DTA far *) MK_FP(s.es, r.x.bx);
|
||||
|
||||
/* conditionally set new dta */
|
||||
if (newdta) {
|
||||
r.h.ah = 0x1a;
|
||||
s.ds = FP_SEG(newdta);
|
||||
r.x.dx = FP_OFF(newdta);
|
||||
intdosx(&r, &r, &s);
|
||||
}
|
||||
|
||||
return olddta;
|
||||
}
|
||||
|
||||
/*
|
||||
* dos findfirst
|
||||
*/
|
||||
|
||||
DTA *
|
||||
findfirst(name, dta)
|
||||
char *name;
|
||||
DTA *dta;
|
||||
{
|
||||
union REGS r;
|
||||
struct SREGS s;
|
||||
DTA far *dtasave;
|
||||
char far *nmp = (char far *)name;
|
||||
|
||||
dtasave = _getsetdta((DTA far *)dta);
|
||||
|
||||
/* do directory lookup */
|
||||
segread(&s);
|
||||
r.h.ah = 0x4e;
|
||||
r.x.cx = 0x10;
|
||||
r.x.dx = FP_OFF(nmp);
|
||||
s.ds = FP_SEG(nmp);
|
||||
intdosx(&r, &r, &s);
|
||||
/* restore dta */
|
||||
_getsetdta(dtasave);
|
||||
_err = r.x.ax;
|
||||
if (r.x.cflag)
|
||||
return (DTA *) 0;
|
||||
|
||||
return dta;
|
||||
}
|
||||
|
||||
/*
|
||||
* dos findnext
|
||||
*/
|
||||
|
||||
DTA *
|
||||
findnext(dta)
|
||||
DTA *dta;
|
||||
{
|
||||
union REGS r;
|
||||
DTA far *dtasave;
|
||||
|
||||
dtasave = _getsetdta((DTA far *)dta);
|
||||
|
||||
/* do directory lookup */
|
||||
r.h.ah = 0x4f;
|
||||
intdos(&r, &r);
|
||||
/* restore old dta */
|
||||
_getsetdta(dtasave);
|
||||
_err = r.x.ax;
|
||||
if (r.x.cflag)
|
||||
return (DTA *) 0;
|
||||
|
||||
return dta;
|
||||
}
|
83
dmake/msdos/mscdos/config.h
Normal file
83
dmake/msdos/mscdos/config.h
Normal file
@ -0,0 +1,83 @@
|
||||
/* RCS -- $Header: /u2/dvadura/src/generic/dmake/src/msdos/mscdos/config.h,v 1.1 1992/01/24 03:27:25 dvadura Exp $
|
||||
-- SYNOPSIS -- Configurarion include file.
|
||||
--
|
||||
-- DESCRIPTION
|
||||
-- There is one of these for each specific machine configuration.
|
||||
-- It can be used to further tweek the machine specific sources
|
||||
-- so that they compile.
|
||||
--
|
||||
-- AUTHOR
|
||||
-- Dennis Vadura, dvadura@watdragon.uwaterloo.ca
|
||||
-- CS DEPT, University of Waterloo, Waterloo, Ont., Canada
|
||||
--
|
||||
-- COPYRIGHT
|
||||
-- Copyright (c) 1990 by Dennis Vadura. All rights reserved.
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or
|
||||
-- modify it under the terms of the GNU General Public License
|
||||
-- (version 1), as published by the Free Software Foundation, and
|
||||
-- found in the file 'LICENSE' included with this distribution.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warrant of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program; if not, write to the Free Software
|
||||
-- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
--
|
||||
-- LOG
|
||||
-- $Log: config.h,v $
|
||||
* Revision 1.1 1992/01/24 03:27:25 dvadura
|
||||
* dmake Version 3.8, Initial revision
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
# if _MSC_VER < 500
|
||||
Force a compile-time blowup.
|
||||
Do not define define _MSC_VER for MSC compilers ealier than 5.0.
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* define this for configurations that don't have the coreleft function
|
||||
* so that the code compiles. To my knowledge coreleft exists only on
|
||||
* Turbo C, but it is needed here since the function is used in many debug
|
||||
* macros. */
|
||||
#define coreleft() 0L
|
||||
|
||||
/* MSC Version 4.0 doesn't understand SIGTERM, later versions do. */
|
||||
#ifndef SIGTERM
|
||||
# define SIGTERM SIGINT
|
||||
#endif
|
||||
|
||||
/* Fixes unimplemented line buffering for MSC 5.x and 6.0.
|
||||
* MSC _IOLBF is the same as _IOFBF
|
||||
*/
|
||||
#if defined(MSDOS) && defined (_MSC_VER)
|
||||
# undef _IOLBF
|
||||
# define _IOLBF _IONBF
|
||||
#endif
|
||||
|
||||
/* in alloc.h: size_t is redefined
|
||||
* defined in stdio.h which is included by alloc.h
|
||||
*/
|
||||
#if defined(MSDOS) && defined (_MSC_VER)
|
||||
# define _TYPES_
|
||||
#endif
|
||||
|
||||
/* in sysintf.c: SIGQUIT is used, this is not defined in MSC */
|
||||
#ifndef SIGQUIT
|
||||
# define SIGQUIT SIGTERM
|
||||
#endif
|
||||
|
||||
/* MSC doesn't seem to care about CONST */
|
||||
#define CONST
|
||||
|
||||
#ifndef MSDOS
|
||||
# define MSDOS 1
|
||||
#endif
|
||||
|
||||
/* a small problem with pointer to voids on some unix machines needs this */
|
||||
#define PVOID void *
|
93
dmake/msdos/mscdos/config.mk
Normal file
93
dmake/msdos/mscdos/config.mk
Normal file
@ -0,0 +1,93 @@
|
||||
# This is the MSC 4.0 and higher DOS configuration file for DMAKE
|
||||
# It simply modifies the values of SRC, and checks to see if
|
||||
# OSENVIRONMENT is defined. If so it includes the appropriate
|
||||
# config.mk file.
|
||||
#
|
||||
# It also sets the values of .SOURCE.c and .SOURCE.h to include the local
|
||||
# directory.
|
||||
#
|
||||
osrdir := $(OS)$(DIRSEPSTR)$(OSRELEASE)
|
||||
|
||||
TMPDIR :=
|
||||
.EXPORT : TMPDIR
|
||||
|
||||
# Definition of macros for library, and C startup code.
|
||||
|
||||
# The following sources are required for MSC
|
||||
OSR_SRC = tempnam.c
|
||||
.SETDIR=$(osrdir) : $(OSR_SRC)
|
||||
|
||||
SRC += $(OSR_SRC)
|
||||
.SOURCE.h : $(osrdir)
|
||||
|
||||
SET_STACK = /stack:4096
|
||||
NDB_LDFLAGS += $(SET_STACK)
|
||||
|
||||
# Local configuration modifications for CFLAGS
|
||||
# If you have a 286 or better, you can uncomment the following line.
|
||||
#HAVE_286 = y
|
||||
|
||||
.IF $(HAVE_286)
|
||||
CFLAGS += -G2
|
||||
ASFLAGS += -Dhave286
|
||||
.END
|
||||
|
||||
ASFLAGS += -t -mx $(S_$(MODEL))
|
||||
|
||||
# Microsoft C doesn't need tail but needs head
|
||||
LDTAIL = ;
|
||||
LDHEAD = $(LDFLAGS)
|
||||
|
||||
# Debugging libraries
|
||||
DB_LDFLAGS += /co /li /map $(SET_STACK)
|
||||
DB_LDLIBS +=
|
||||
|
||||
# NO Debug MSC flags:
|
||||
# Set the environment variable MSC_VER to be one of 4.0, 5.0, 5.1, or 6.0
|
||||
# to get these by default when you make dmake using 'dmake'.
|
||||
#
|
||||
# Setting MSC_VER to one of the above sets the variable _MSC_VER appropriately
|
||||
# and sets the flags appropriately.
|
||||
|
||||
.IMPORT .IGNORE : MSC_VER
|
||||
MSC_VER *= 6.0 # If unset, assume 6.0 by default.
|
||||
|
||||
.IF $(MSC_VER) == 4.0
|
||||
CFLAGS += -I$(osrdir) $(C_$(MODEL):s/A/m/)
|
||||
CFLAGS += -DM_I86=1 # 5.0+ define this automatically
|
||||
# CFLAGS += -D__STDC__=1 # 5.0, 5.1, but not 6.0 do this automatically
|
||||
NDB_CFLAGS +=
|
||||
DB_CFLAGS += -Zi
|
||||
.ELSE
|
||||
DB_CFLAGS += -Zi
|
||||
CFLAGS += -I$(osrdir) $(C_$(MODEL))
|
||||
.IF $(MSC_VER) != 6.0
|
||||
# For 5.0 and 5.1, we define _MSC_VER=500 or 510
|
||||
CFLAGS += -D_MSC_VER=$(MSC_VER:s,.,,)0
|
||||
NDB_CFLAGS += -Oscl -Gs
|
||||
.ELSE
|
||||
# Microsoft C 6.0 auto defines _MSC_VER=600, but not __STDC__
|
||||
CFLAGS += -D__STDC__=1 # incredibly not auto done by 6.0
|
||||
NDB_CFLAGS += -Osecgl -Gs
|
||||
|
||||
# Redefine rule for making our objects, we don't need mv
|
||||
%$O : %.c ;% $(CC) -c $(CFLAGS) -Fo$@ $<
|
||||
.END
|
||||
NDB_LDFLAGS += /exe /packc /batch
|
||||
NDB_LDLIBS +=
|
||||
.END
|
||||
|
||||
# See if we modify anything in the lower levels.
|
||||
.IF $(OSENVIRONMENT) != $(NULL)
|
||||
.INCLUDE .IGNORE : $(osrdir)$(DIRSEPSTR)$(OSENVIRONMENT)$(DIRSEPSTR)config.mk
|
||||
.END
|
||||
|
||||
C_s =
|
||||
C_m = -AM
|
||||
C_c = -AC
|
||||
C_l = -AL
|
||||
|
||||
S_s = -Dmsmall
|
||||
S_m = -Dmmedium
|
||||
S_c = -Dmcompact
|
||||
S_l = -Dmlarge
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user