                                        PJ User's Manual

                                           Revision A
                                        February 23, 1994

                                  Copyright (C) 1994 MICROTOOLSIntroduction

PJ is a simple source file manager for use on moderate size software
projects (20 - 5,000 source files) utilizing a shared project library with 1-
20 programmers.  

PJ is intended to solve the following problems:

    Avoid costly collisions between programmers modifying the same
        file.

    Eliminate programmer maintenance when extracting and adding files
        from and to a library.

    Prevent loss of work by maintaining multiple versions of the same
        file in a library.  Older versions of the same file can be retrieved.


What PJ provides:

    þ   Library check out control - only one programmer can have a
           source file out for modification at a time.
    þ   Automatic updating of Make and Library command files -
           when the programmer puts a new module into the library, the
           Make and Library command files can be automatically updated
    þ   Automatic insertion/removal with the programmers Make
           file(s) - when the programmer removes a source file from a
           library, the programmers local Make file is updated to allow
           the programmer to modify the file and reference it in their
           local directory.  When the file is put back in the library, the
           local Make file is updated to remove the file.  Additional files
           can be deleted from the local directory.
    þ   Automatic "BAK" versions of up to 1000 files per library - PJ
        allows you to keep up to 1000 "bak" versions of library files per
        library.

    
Description of the Development Environment

PJ was developed for a medium scale two programmer software project
developing four similar embedded systems (approximately 40,000 lines
of code in 1000 modules).  Borland C++ was used for the development
cycle.  A Novell network server was used as the source library. 
However PJ is flexible enough to allow utilization in many other
environments (Including MicroSoft C/C++).  Each programmer had
their own working directory with a baseline Make file.  Within the
programmer's working directory, one of the four systems could be built
at a time.  Additional working directories could be used if simultaneous
development of the four systems was required.

Several different directories housed the source library files.  The
programmer did not need to know which library he was removing the
file from (this assumes that no two files are named the same for a given
system).  

Associated with each library directory, is a Make file and a Library
command file (You can configure these differently).  When a new file is
added by a programmer to the library, the Make file and library
command file is updated.

This manual is written assuming you understand the concepts of source
file librarians and make utilities.  The examples given utilize Borland
C++ 3.1 MAKE and TLIB formats.

Registration Benefits

If you register PJ for $25, in addition to a "no nag" version, a printed
manual, unlimited technical support, and free upgrade policy, we will
also provide the source code (in Borland C++ version 3.1 format) for
the source file manager (source code for the automatic backup will not
be provided).  This will allow you to modify PJ to meet any unforseen
requirements.

Using PJ

Removing Files from the library

From the programmer's working directory, a file can be removed from
the library with the following command:

        pj - FILENAME

        where FILENAME specifies the name of the file(s) to remove
           from the program library.  This specification may include
           wildcards and need not specify the extension.  PJ will search
           all of the library directories specified in PJ.CFG for a match
           of the filename (with the configured extension).  The file will
           be marked read only in the library.

If the file has already been extracted, the following message will be
displayed:

    Unable to extract FILENAME.EXT - File already extracted

If the file cannot be found in the library, the following message will be
displayed:

    Unable to find file FILENAME

To remove a file without modifying the files specified in the PJ.CFG
(for example to remove an .H file), the user should specify the file
extension (and that file extension should not be in the PJ.CFG).  PJ will
search all of the libraries specified in PJ.DIR and attempt to find the file
specified.  When this file is returned to the library, the corresponding
files (for example the Make file) will not be modified.

Inserting Files into the library

From the programmer's working directory, a file can be added to the
library with the following command:

        pj + FILENAME

        where FILENAME specifies the name of the file(s) to add to the
           program library.  This specification may include wildcards and
           need not specify the extension.  PJ will search all of the
           library directories for a match of the filename and add it to
           one or more of the defined libraries.  If FILENAME is not
           specified, all files extracted by the programmer will be
           returned to their respective libraries.

If the file has not been extracted, the following message will be
displayed:

    Unable to add FILENAME - File not in EXT_LIST.DIR; Use full
        path for new files

If a new file is being added to the library, the user should specify the
full filename (including path and extension).  This will place the new file
in the library specified by the path and modify the files specified in
PJ.CFG.

Restarting a file in your Local Directory

Sometimes (although we hope, not very often), you remove a file from a
library, make a fix, test the fix and find that you don't want to put the
modified file back in the library.  The * command, allows you to take
the file specified in the library and overwrite your changes in your local
directory.  This can be a dangerous operator if not used properly.  

Library BAK files

PJ provides a powerful tool for maintaining up to 1000 old versions of
files in a given library through inclusion of MICROTOOLS ComeBack
program (See the ComeBack user manual in the Appendix of this
document - COMEBACK.MAN).  ComeBack can be configured to
maintain the last 1000 files that were deleted and overwritten for a given
Drive.  If you configure your source library as a drive (using the
network mapping function or DOS SUBST), each library can be
configured to protect your source files.  Using ComeBack's configuration
program, (CBCONFIG), you can specify what drives you desire to
include and what files you desire to have protected (For example,
ComeBack can be configured to only protect .CPP, .H, .MAK and .BLD
files).

An older version of a file can easily be retrieved using the COMEBACK
program.

Configuring PJ

Configuring PJ requires the programmer to set up the following files:
(NOTE: All configuration file lines are limited to 200 characters each)

    PJ.DIR            This file defines the library files and the associated
                      extensions used in the project.  For example, let's
                      assume that you have four libraries on your H:
                      drive entitled: COMMON, ENGINE, MAIN and
                      RATES.  In the first three libraries, .CPP files are
                      kept.  In the RATES directory, .RAT, .RT1, .RT2,
                      .RM1 and .RM2 files are kept.  The PJ.DIR file
                      would look like:

                                    h:\common\*.cpp
                                    h:\engine\*.cpp
                                    h:\MAIN\*.cpp
                                    h:\rates\*.rat
                                    h:\rates\*.rt1
                                    h:\rates\*.rt2
                                    h:\rates\*.rm1
                                    h:\rates\*.rm2

                       This file is limited to 200 entries

    PJ.CFG             This file tells PJ what to do with a file when it is
                       extracted from and returned to the library. 
                       Multiple lines can be used to define each operation. 
                       For example, one file may need to be modified in
                       several places in different ways during an extract. 
                       Thus two entries would be required.  For example,
                       in our configuration, when a file is extracted from
                       a library, we want it to be inserted in the local
                       directory's make file.  We need to tell PJ what file
                       to modify (in our case, the make file), and where
                       in the make file to insert the file.  We need to tell
                       PJ how to insert the file into the make file (a Prefix
                       and a Suffix to the line).  Each item is delimited by
                       a comma.  If a comma is desired on the command
                       line, it should be prefaced with a double quote ("). 

                       When a file is extracted or returned by PJ, the
                       following line is added to specified file:

                       PREFIXFileExtractedSUFFIX

                       Thus the PJ.CFG file consists of a definition of the
                       extract (-) or replace (+) operator:

OPERATOR,FILENAME,PREFIX,SUFFIX,AFTER HERE
STRING,.EXT,.EXT,...etc

                       where:
                              OPERATOR is the definition operator
                                    (either a + or a -)
                                    -  operators are used to extract files
                                       from a library and specify how to
                                       modify files in your local directory
                                       for both - and + operators.
                                    +  operators are used to put files back
                                       into the library and to specify how
                                       to modify files in the library's
                                       directory when the + operator is
                                       used to add a new file.
                              FILENAME is the name of the file to
                                    modify (in our case - the make file). 
                                    For the + operator, if only an
                                    extension is used (.MAK for
                                    example), the filename of the library
                                    directory will be used for the
                                    filename.  For example, if the
                                    programmer is inserting a new file
                                    into the COMMON directory, the
                                    COMMON.MAK file will be updated.
                              PREFIX is the comma delimited string to go
                                    on the line being added to
                                    FILENAME before the file being
                                    extracted       is added to the line
                              SUFFIX is the comma delimited string to go
                                    on the line being added to
                                    FILENAME after the file being
                                    extracted       is added to the line
                              AFTER HERE STRING is the comma
                                    delimited string to tell PJ where to
                                    insert the line being added to
                                    FILENAME.  PJ searches
                                    FILENAME for the AFTER HERE
                                    STRING, and inserts the line after this
                                    line.  If not specified, PJ inserts the
                                    file at the beginning of FILENAME.
                              EXT is the extension of the files that can be
                                    automatically extracted/returned
                                    without specifying the extension as
                                    well as the files that will be inserted
                                    into the FILENAME.  Files with
                                    extensions not part of this list will
                                    result in the file being
                                    extracted/returned but FILENAME
                                    will not be updated.  For example, .C
                                    and .CPP files will be included in this
                                    list, because these are source files to
                                    be included in the local make. 
                                    However, .H files will not be included
                                    as these files can be removed from the
                                    library but the make file need not be
                                    modified.  Up to twenty extensions
                                    can be configured on each line.
               
                      For example, with our Borland C++ compiler, our
                      first extract line in PJ.CFG looks as follows:
                      
        -,makefile,,.OBJ \,$(MARK_1)
                  
                      If multiple entries are required, a second extract
                      definition line can be defined.  Our second line
                      looks as follows:

        -,makefile,, +,$(MARK_2)

                      The $ character is used in the Borland make file to
                      indicate a macro (which in our case is not defined). 
                      Those lines are inserted in the makefile.  The
                      following represents a sample makefile:

####################### BORLAND C++ MAKEFILE
#######################
lsw = /v /c  /m /s
csw = 
cppmodel = -ml

DRIVE = H

.cpp.obj:
        bcc $(csw) -zEtest_seg $(cppmodel) {$< }

.rm2.obj:
        bcc $(csw) $(cppmodel) -zEmenu_seg {$< }

.rm1.obj:
        bcc $(csw) $(cppmodel) -zEmenu_seg {$< }

.rat.obj:
        bcc $(csw) $(cppmodel) -zErat_seg {$< }

.rt1.obj:
        bcc $(csw) $(cppmodel) -zErat_seg {$< }

.rt2.obj:
        bcc $(csw) $(cppmodel) -zErat_seg {$< }

.precious: MAIN.exe

MAIN.exe: makefile \
$(DRIVE):\MAIN\MAIN.lib \
$(MARK_1) \
TASKINIT.obj 
           tlink $(lsw)  @&&!
c0l +
$(MARK_2) +
TASKINIT +
, MAIN, MAIN, $(DRIVE):\MAIN\MAIN + $(DRIVE):\MAIN\COMMON
$(DRIVE):\MAIN\rates +
$(DRIVE):\MAIN\engine 
!
#End##################### BORLAND C++ MAKEFILE
#######################

                       The return operator works in a similar fashion. 
                       Files can be modified in the directory from which
                       the module came using the same syntax. This
                       operation only occurs when a new file is being
                       inserted into the library (i.e. when the programmer
                       specifies the path).  In our environment, the return
                       operator specification in PJ.CFG modifies a make
                       file used to compile the library modules as well as
                       a library command file to insert the files into the
                       library.  Files that are listed for modification that
                       do not exist in the directory will not be created nor
                       will an error be generated.  This allows the
                       programmer to have multiple make files for a given
                       library.

                       In our environment, each library has a .MAK
                       associated with it and a .BLD associated with it. 
                       The .MAK is used to compile the modules.  The
                       .BLD is used to insert the .OBJs into the library. 
                       The PJ.CFG definition in this case would appear as
                       follows:

                       +,.MAK,,.OBJ \,$(MARK_1),.CPP,.C,.ASM
                       +,.BLD,+ ,.OBJ &,,.CPP,.C,.ASM

                       The following defines a simple TLIB .BLD file:

                               +ACCESS   &
                               +DO_EVENT &
                               +DSP_OBJ  &
                               +DSPERROR &
                               +DSPFUNCS &
                               +PASSWORD &
                               +Q_EVENT  &         
                               +SOFT_KEY &
                               +STATE_EN &
                               +

                       In addition to the extract (-) and return (+)
                       operators, there is one additional operator (*).  The
                       * operator in  the PJ.CFG file defines what file
                       extensions should be deleted when a file is removed
                       from the local library (with the + operator).  For
                       example, when a .CPP file is returned to the
                       library, .OBJ, .BAK, and .ERR files should be
                       deleted.   Up to twenty extensions can be defined
                       with the * operator.   This would be specified in
                       PJ.CFG as follows:

                             *,.OBJ
                             *,.BAK
                             *,.ERR

                      In summary, for a Borland C++ development
                      environment, we would have the following PJ.CFG:

                      -,makefile,,.obj \,$(MARK_1),.cpp,.asm,.c
                      -,makefile,, + ,$(MARK_2),.cpp,.asm,.c
                      +,.mak,,.obj \,$(MARK),.cpp,.asm,.c,.cas
                      +,.bld, + , &,,.cpp,.asm,.c,.cas
                      *,.obj
                      *,.err

                      Line 1  When you extract a file, modify the file
                              MAKEFILE every time a .CPP, .ASM, or
                              a .C file is extracted.  After the first
                              occurrence of $(MARK_1) in MAKEFILE,
                              on the next line, insert the file name being
                              extracted with no prefix and with a:
                                    .obj \
                              suffix.  

                      Line 2  When you extract a file, modify the file
                              MAKEFILE every time a .CPP, .ASM, or
                              a .C file is extracted.  After the first
                              occurrence of $(MARK_2) in MAKEFILE,
                              on the next line, insert the file name being
                              extracted with no prefix and with a:
                                    +
                              suffix.

                      Line 3  When you place a new file (with a .cpp,
                              .asm,.c,.cas extension) back in the library
                              (by specifying the path and extension),
                              modify the library_name.mak file as
                              follows:  After the first occurrence of
                              $(MARK_1) in library_name.mak file, on
                              the next line, insert the file name being
                              extracted with no prefix and with a:
                                    .obj \
                              suffix.  

                      Line 4  When you place a new file (with a .cpp,
                              .asm,.c,.cas extension) back in the library
                              (by specifying the path and extension),
                              modify the library_name.bld file as follows: 
                              At the beginning of the file,  insert the file
                              name being extracted with a + prefix  and
                              with an & suffix.  

                      Line 5  When a replace operator is used with
                              FILENAME, delete the FILENAME.OBJ
                              file in the local directory.

                      Line 6  When a replace operator is used with
                              FILENAME, delete the FILENAME.ERR
                              file in the local directory.
