[net.sources] msdos make

grayson@uiucuxc.CSO.UIUC.EDU (01/18/86)

This file is part 1 of 2.


Here is the current version of MAKE for MSDOS, due to popular demand.
This version reads an init file for default rules, and handles several
cases better than the old version.


The next improvement that needs to be made is to speed up floppy disk
times by not looking so often for dates on files...

        uucp:   grayson@uiucuxc.UUCP
    old uucp:	{ihnp4,pur-ee}!uiucdcs!uiucuxc!grayson
    internet:   grayson@uiucuxc.cso.uiuc.edu
       telex:	5101011969 UI TELCOM URUD --> Dan Grayson, Altgeld Hall.
     us mail:	Dan Grayson, Math Dept, Univ of Ill, Urbana 61801
       phone:	217-367-6384 home   217-333-6209 office
-----Cut Here-----Cut Here-----Cut Here-----Cut Here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	make.c
#	make.doc
#	mstring.h
#	path.c
#	touch.c
echo shar: extracting make.c
sed 's/^X//' << 'SHAR_EOF' > make.c
X/*
X * make.c
X *
X *      An imitation of the Unix MAKE facility
X *
X *      Copyright (C) 1984 by Larry Campbell, 73 Concord St., Maynard, Mass.
X *      Rewritten w/modifications by Mike Hickey, University of DC
X *
X *      This software may be freely copied and disseminated for noncommercial 
X *      purposes, if and only if this entire copyright statement and notice 
X *      is included intact.  This software, and the information contained 
X *      herein, may not be used for commercial purposes without my prior 
X *      written permission.
X *
X *      This program runs a new shell (COMMAND.COM) for each command specified 
X *      in the makefile.  This, I recommend that you put a copy of the shell in
X *      ramdisk (if you have one).  Assuming your ramdisk is called, say, drive
X *      F:, you would:
X *      
X *
X *              COPY A:\COMMAND.COM F:
X *              SET COMSPEC=F:\COMMAND.COM
X *
X */
X
X/* Certain portions of this software are Copyright (C) 1985 by Dan Grayson,
X   2409 S. Vine St, Urbana, IL 61801, namely all those lines which differ
X   between versions 2.10 and 2.11.  Qualitative descriptions of these 
X   changes are described in the edit history below.
X        Provided this copyright notice is not changed, and VERS211 below
X   is not changed, and VERS211 is still prints when 'usage()' runs, these
X   portions may be freely copied and used for any purpose, with one exception,
X   namely:  those persons or corporations who claim a copyright on this
X   program or a part of it may not use these portions for any commercial
X   purpose whatsoever.  In particular, they may not collect royalties on
X   any version of this program which includes these portions. */
X
X/*
X * Edit history:
X *
X *  2.14      Allowed a default file MAKE.INI that is always read.
X              Now it makes the prerequisites in left right order.
X              Fixed various bugs involving default rules.
X              Improved the behavior with names that don't correspond to
X              existing files.  -dan grayson
X                         
X *  2.13      Allowed the use of multiple default rules for a given
X *            default target, enforced the requirement of a single
X *            instance of a given explicit target:
X *                    *.obj : *.asm
X *                            asm $*;
X *                    *.obj : *.c
X *                            cc $* -ia
X *            is legal, but:
X *                    foo.obj: bar.asm
X *                            asm bar,foo;
X *                    foo.obj: bar.c
X *                            cc bar -ia -ofoo
X *            is not (and not terribly useful or interesting).
X                Peter da Silva (the mad Australian)
X                        UUCP: ...!shell!neuro1!{hyd-ptd,baylor,datafac}!peter
X *  2.12      Made it compilable by Lattice C version 2.14. Use '-dLATTICE'
X *            on the command line for this. Default is Microsoft C.
X *  2.11        Fixed breakout_symbols, which tried to return a pointer to
X                        a local variable!
X                Made symbol substitution occur in all lines, not just shell
X                        command lines.
X                Fixed breakout_symbols, which blew up when a symbol was 
X                        undefined.
X                Allowed blank lines, which are ignored now.
X                Change command line length to 1000.
X                Fixed it so MAKE, when no targets are specified on the command
X                        line, will simply make the first target in the makefile.
X                Remove the command line symbol definition option.
X                Changed the line continuation character to \ (it was - )
X                Now symbol definition lines do NOT begin with $.
X                Fixed numerous bugs dealing with character arrays and their
X                        lengths.
X                Now a shell command line which begins with @ is not echoed.
X                A shell command line beginning with + is executed through
X                        command.com ; this makes io redirection and pipes
X                        available, but the exit code of the program cannot
X                        be checked due to a misfeature of command.com.
X                A shell command line beginning with - may return a nonzero
X                        exit code without halting 'make'.
X                Fixed it so a target:prerequisite line followed by no how-to
X                        lines is interpreted not as an error, and not as 
X                        sharing the how-to lines following the next
X                        target:prerequisite line, but is considered fulfilled
X                        by no action other than making all the 
X                        prerequisites.
X                Fixed the bug which meant the return code from the commmand
X                        was never dicovered.  This resulted from using 
X                        "system", which uses "command.com", which hides the
X                        return code of the program it runs.  Resident 
X                        commands can still be used, nevertheless.
X                Error messages now include the line number of the makefile,
X                        if relevant.
X                Made the return code of the command print out if nonzero.
X                Now the copyright notice only prints when the usage appears.
X                Convert to Microsoft vers 3.00, large memory model.
X                                - dan grayson
X *  2.10        Fix bug in abort routine, update copyright notice
X *  2.09        Set up for command line parsing of macros
X *  2.08        Remove edit 2.05; keep debug a compile-time option
X *  2.07        Finish macro parsing
X *  2.06        Add initial code for macro handling
X *  2.05        Add -d (debug) switch
X *  2.04        Add error message handling (doserror).
X *  2.03        Add -i (ignore errors) switch.
X *  2.02        Add -s (silent run) switch.
X *  2.01        Convert to Lattice 2.14.  Clean up code for faster execution.
X *  1.11        Make default makefilename be MAKEFILE.
X *  1.10        Add -n (trace) switch.
X *  1.09        Allow multiple targets before colon.
X *  1.08        Cleanup and speedup of makefile parsing.
X *  1.07        Add continuation lines (hyphen as last char of line)
X *  1.06        Don't need to make dummy FCBs, zero seems to work OK.
X *  1.05        Fix bug finding COMSPEC when it's not first env variable
X *  1.04        Wordier usage text, including copyright notice.
X *              Remove printf's (except when DEBUG on) to shrink EXE
X *  1.03        Don't uppercase shell command and fix datetime bug
X *  1.02        Random cleanup
X *  1.01        The beginning
X */
X
X#define VERSION "MAKE ver. 2.10 Copyright (C) 1984 by Larry Campbell, Maynard Mass."
X#define VERS211 "MAKE ver. 2.14 Portions copyright (C) 1985 by Dan Grayson, Urbana IL."
X
X#ifdef LATTICE
X#define assert(a)
X#define perror error
X#include <dos.h>
X#include <stdio.h>
X#include <ctype.h>
Xextern char *strchr();
X
X#else
X
X#include <assert.h>
X#include <process.h>
X#include <dos.h>
X#include <stdio.h>
X#include <malloc.h>
X#include <ctype.h>
X#include <string.h>
X
X#endif
X
X#include "make.h"
X#include "mstring.h"
X
X#define MAKEINI "make.ini"
X
Xchar *dos_commands[] = {
X      "dir", "type", "rem", "pause", "date", "time",
X      "ren", "rename", "ver", "vol", "break", "verify",
X      "mkdir", "md", "exit", "ctty", "echo", "if", "cls",
X      "chdir", "cd", "rmdir", "rd", "copy", "del", "erase",
X                         NULL };
X
X#define PREREQ_MAGIC 123
X#define FILE_MAGIC 543
X#define SHELL_MAGIC 678
X#define TARG_MAGIC 987
X#define SYMBOL_MAGIC 653
X#define MAXLIN 1000
X#define SYMLEN 1000
X#define MAXTARGETS 100
X
X
X#ifndef TRUE
X#define TRUE 1
X#define FALSE 0
X#endif
X
X#define EQUAL 0
X
X#define EOS '\0'                /* End Of String */
X
X#define LINESIZE 1000            /* max length of input line */
X#define MAXCOMMON 8             /* max no. of targets with common prereqs */
X
X#define NEGINF 0x8000           /* smallest int */
X#define LONGNEGINF 0x80000000L  /* smallest long int */
X#define LONGPOSINF 0x7fffffffL  /* largest long int */
X
X#define tfree(x) if (x) free(x),x=NULL
X
X#ifdef LATTICE
Xextern char _dos;
X#else
Xextern unsigned char _osmajor;           /* in MS ver 3, gives version of OS to left of point */
Xextern int _doserrno;
X#endif
X
Xchar  *talloc(), *strperm();
X
Xextern int linenumber;   /* defined in mstring.c */
Xlong getdatetime ();
X
X    static int dontworry=0;
X
Xunion REGS inregs, outregs;
X
Xstruct {
X    char reserved[21];
X    char attr;
X    unsigned time, date, size_l, size_h;
X    char pname[13];
X} 
Xfind_buf;
X
X/*
X * MAKE parses the make file and constructs a somewhat tangled
X * directed graph describing dependencies.  There is a list of
X * TargNode structures, each of which points to a list of
X * prereq_node structures.  These both point to FileNode structures,
X * which contain information about files such as date-time of write
X * and the filename.  To keep things simple, MAKE insures that only
X * one FileNode exists for any given file.
X */
X
Xtypedef struct FileNode {
X    #ifndef NDEBUG
X    int magic;
X    #endif
X    char *fname;
X    struct FileNode *chain;
X    }    *fileptr;
Xfileptr  FileNodeList, NewFileNode ();
X
Xtypedef struct TargNode {
X    #ifndef NDEBUG
X    int magic;
X    #endif
X    struct TargNode *next;
X    fileptr file;
X    struct prereq_node *PreqList;
X    struct shell_node *shell_list;
X    }    *targptr;
Xtargptr first_targ, target_list, new_target (), lookup_target ();
X
Xtypedef struct prereq_node {
X    #ifndef NDEBUG
X    int magic;
X    #endif
X    struct prereq_node *next;
X    fileptr file;
X    } *preqptr;
Xpreqptr NewPreqNode ();
X
Xtypedef struct shell_node {
X    #ifndef NDEBUG
X    int magic;
X    #endif
X    struct shell_node *next;
X    char *command;
X    unsigned quiet : 1, ignore : 1, useshell : 1;
X    } *shellptr;
X
Xtypedef struct symbol_node {
X    #ifndef NDEBUG
X    int magic;
X    #endif
X    char *token, *value;
X    struct symbol_node *next;
X    }    *symbptr;
Xsymbptr SymbolList;
X
Xstatic char *makefilename;
Xstatic int status, tracing, quietly, ignore_errors;
X
Xusage ()
X{
X    puts (VERS211);
X    puts (VERSION);
X    puts ("This program may be copied freely for noncommercial purposes.  It may");
X    puts ("not be copied for commercial use without the author's written permission.\n");
X    puts ("This  program is an imitation of the MAKE program supplied with Unix.");
X    puts ("Usage: make [target ...] [options ...]");
X    puts ("Options:");
X    puts ("        -f filename specify makefile, default is MAKEFILE");
X    puts ("        -i          ignore errors while processing");
X    puts ("        -n          trace and print, but don't execute commands");
X    puts ("        -s          suppress MAKE echoing commands");
X    exit (21);
X}
X
Xmain (argc, argv)
Xint argc;
Xchar **argv;
X{
X    int
X        argi,
X        targi,
X        linlen;
X
X    char  *targname[MAXTARGETS];
X
X    if (
X        #ifdef LATTICE
X          _dos
X        #else
X          _osmajor
X        #endif
X                 < 2) error ("Must have DOS 2.XX or higher");
X    makefilename = "MAKEFILE";
X    tracing = quietly = ignore_errors = FALSE;
X    target_list = 0;
X    SymbolList = 0;
X    FileNodeList = 0;
X    targi = 0;
X    for (argi = 1; argi < argc; argi++) {
X        if (argv[argi][0] == '-')               /* switch */
X            switch (argv[argi][1]) {            /* switch character */
X            case 'f':
X                if (argi < (argc - 1))      makefilename = argv[++argi];
X                else                        usage ();
X                break;
X            case 'i':                ignore_errors = TRUE;             break;
X            case 'n':                tracing = TRUE;                   break;
X            case 's':                quietly = TRUE;                   break;
X            default:                 usage ();
X            }
X        else {                          /* target name */
X            if (targi == MAXTARGETS)    error ("Too many target files");
X            targname[targi] = strperm (argv[argi]);
X            targi++;
X        }
X    }
X    if (tracing && quietly) quietly = 0;
X
X    { FILE *fd, *fopenp(char *,char *);
X       if (fd = fopenp(MAKEINI,      "r")) parse(fd);
X       first_targ = NULL;
X       if (fd = fopen (makefilename, "r")) parse(fd); else /* no makefile, okay */ ;
X    }
X
X    if (targi)
X            /* make the targets specified on the command line */
X            for (argi = 0; argi < targi; argi++) make (targname[argi]);
X    else if (first_targ) make(first_targ->file->fname);
X    else error ("No targets specified");
X    return 0;
X}
X
Xparse (fd)
XFILE *fd;
X{
X    int targi=0,   i;
X    char  c,  *sp,  *dp;  int wlen;
X    mstring input=NULL;
X    targptr targ[MAXTARGETS];
X
X    while (1) {
X        tfree(input);
X        input = mfgets(fd);
X        if (input==NULL) break;
X        #if DEBUG
X            printf ("Makefile Input: \"%s\"\n", input);
X            #endif
X        sp = input;
X        passpace(&sp);
X        if (*sp==0 || *sp=='#') continue;
X           /* ignore comment lines and blank lines */
X
X        if (isspace(*input)) {   /* if leading space, then this is a shell line */
X                if (targi == 0) error ("Target line must come before shell lines");
X                sp = input; passpace(&sp);
X                for (i = 0; i < targi; i++)  NewShellLine (targ[i], sp);
X                continue;
X        }
X
X        {               /* substitute for symbols - this will be done later
X                           for shell lines, to take special symbols like $*
X                           into account, which can only be known at run time
X                           */
X              breakout_symbols(&input);
X        }
X
X        {       /*** check for the form 'name = value'   ***/
X                char *endword;
X                sp=input;
X                password(&sp);    endword = sp;
X                passpace(&sp);
X                if (*sp == '=') {
X                    targi=0;
X                    sp++;
X                    *endword = EOS;
X                    SetSymbol (input, sp) ;
X                    continue;
X                }
X        }                               /* end of macro parsing */
X
X
X        /**** now we know this is a 'targets : prerequisite' line ***/
X
X
X        for ( targi=0, wlen=1, dp = sp = input; 1 ; wlen++, sp++)        /*** collect the targets ***/
X            if (    *sp == ':'
X                #ifdef MSDOS
X                 && (wlen!=2 || isspace(sp[1]))   /* allow filenames like C:FOO.BAR, so the drive can be specified */
X                #endif
X                 ||  isspace (*sp)) { /* space or colon ends target name */
X                if (targi == MAXTARGETS) error ("Too many targets in one line");
X                c = *sp;  *sp = EOS; targ[targi] = new_target (dp); *sp = c;
X                if (first_targ == NULL  &&  *dp != '*') first_targ = targ[targi];
X                targi++;
X                passpace(&sp);
X                if (*sp == ':') break;
X                dp = sp;
X                wlen = 0;
X            }
X            else if (*sp == EOS) error ("no separating ':' ");
X
X        sp++;   /* pass over the ':' */
X        if (targi == 0) error ("No target file before ':' ");
X        while(1) {              /*** collect the prerequisites ***/
X            passpace(&sp);
X            if (*sp == EOS) break;            /* end of line */
X            dp = sp;                    /* beginning of prereq word */
X            passnonsp(&sp);
X            c = *sp;
X            *sp = EOS ;                /* end of prereq word */
X            for (i = 0; i < targi; i++) LinkPreq (targ[i], NewFileNode(dp) );
X            *sp = c;
X        }
X    }   /* end while */
X    tfree(input);
X    fclose (fd);
X    linenumber = 0;
X}
X
X/*
X * new_target
X *
X *      We think we have a new target;  this routine scans the
X *      target list and if we've already seen this name returns
X *      the node we already built.  Otherwise, a new node is
X *      allocated and linked.
X */
X
X        targptr
Xnew_target (name)
X    char *name; {
X    targptr targ ;
X
X    #if DEBUG
X      printf ("new_target (\"%s\")\n", name);
X      #endif
X    if (name[0] != '*') { /* look for name already on target list, unless it's a default rule */
X        targptr p = target_list;
X        while (p) {
X                assert (p->magic == TARG_MAGIC);
X                if (EQUAL == strcmp(name,p->file->fname)) return p;
X                p = p->next;
X                }
X        }
X    
X    /* add new target to top of list */
X    targ = (targptr) talloc (sizeof (struct TargNode));
X    #ifndef NDEBUG
X       targ->magic = TARG_MAGIC;
X       #endif
X    targ->file = NewFileNode (name);
X    targ->next = target_list;
X    targ->shell_list = NULL;
X    targ->PreqList = NULL;
X    target_list = targ;
X    return targ;
X}
X
XSetSymbol (name, value)
Xchar *name, *value;
X{
X    symbptr sym;
X    for (sym = SymbolList; sym; sym = sym->next)
X         if (0==strcmp(sym->token,name)) {
X                free(sym->value);
X                sym->value = strperm(value) ;
X                return;
X                }
X    sym = (symbptr) talloc (sizeof (struct symbol_node));
X    #ifndef NDEBUG
X        sym->magic = SYMBOL_MAGIC;
X        #endif
X    sym->token = strperm (name);
X    sym->value = strperm (value);
X    sym->next = SymbolList;
X    SymbolList = sym;
X}
X
X/*
X * NewShellLine
X *
X *      Add a shell command to the list of commands needed to update
X *      a target file
X */
X
XNewShellLine (targ, line)
Xtargptr targ;
Xchar *line;
X{
X    shellptr snode, new;
X
X    #if DEBUG
X         printf ("NewShellLine (%x, \"%s\")\n", targ, line);
X         #endif
X    new = (shellptr) talloc (sizeof (struct shell_node));
X    new->next = 0;
X    #ifndef NDEBUG
X        new->magic = SHELL_MAGIC;
X        #endif
X    new->useshell = new->ignore = 0;
X    new -> quiet = quietly ;
X    for ( ; 1 ; line++, passpace(&line) )
X       if      (line[0] == '@')  new->quiet = 1;
X       else if (line[0] == '+')  new->useshell = 1;
X       else if (line[0] == '-')  new->ignore = 1;
X       else break;
X    new->command = strperm (line);
X    snode = targ->shell_list;
X    if (snode) {
X        assert (snode->magic == SHELL_MAGIC);
X        while (snode->next) {
X                snode = snode->next;
X                assert (snode->magic == SHELL_MAGIC);
X                }
X        snode->next = new;
X    }
X    else
X        targ->shell_list = new;
X}
X
X/*
X * LinkPreq
X *
X *      Link a new prerequisite file onto prereq list for a target.
X */
X
XLinkPreq (targ, fnode)
X   targptr targ;  fileptr fnode; {
X   preqptr p,np=NewPreqNode(fnode);
X
X    #if DEBUG
X        printf ("LinkPreq (\"%s\")\n", fnode->fname );
X        #endif
X
X   /* we attach the prerequisite to the end of the list so prerequisites
X      are made in left to right order */
X
X   p = targ->PreqList;
X   if (p) {
X        assert (p->magic == PREREQ_MAGIC);
X        while (p->next) {p=p->next; assert (p->magic == PREREQ_MAGIC);}
X        p->next=np;
X        }
X   else {
X        targ->PreqList = np;
X        }
X    }
X
X/*
X * NewPreqNode
X *
X *      Allocate and return a new prerequisite node
X */
X
X        preqptr 
XNewPreqNode (fnode)
X        fileptr fnode;
X{
X    preqptr new;
X
X    #if DEBUG
X        printf ("NewPreqNode (struct FileNode *%x, \"%s\")\n",fnode,fnode->fname);
X        #endif
X    new = (preqptr) talloc (sizeof (struct prereq_node));
X    new->next = NULL;
X    #ifndef NDEBUG
X        new->magic = PREREQ_MAGIC;
X        #endif
X    new->file = fnode;
X    return new;
X}
X
X/*
X * NewFileNode
X *
X *      Return FileNode pointer for a file;  returns pointer to
X *      existing FileNode if this file already seen, else allocates
X *      and inits a new node
X */
X
X        fileptr
XNewFileNode (name)
X        char *name;
X{
X    fileptr fnode;
X
X    #if DEBUG
X        printf ("NewFileNode (\"%s\")\n", name);
X        #endif
X    for ( fnode = FileNodeList; fnode; fnode = fnode->chain) {
X        assert (fnode->magic == FILE_MAGIC);
X        if (strcmp (name, fnode->fname) == 0) {
X    #if DEBUG
X        printf ("NewFileNode returning existing node\n");
X        #endif
X            return fnode;
X        }
X        
X    }
X    fnode = (fileptr) talloc (sizeof (struct FileNode));
X    fnode->fname = strperm (name);
X    fnode->chain = 0;
X    #ifndef NDEBUG
X        fnode->magic = FILE_MAGIC;
X        #endif
X    fnode -> chain = FileNodeList;
X    FileNodeList = fnode;
X    return fnode;
X}
X
X/*
X * 
Xgetdatetime
X *
X *      Return date-time of a file squished into a long so compares
X *      are easy
X */
X
X        long 
Xgetdatetime (name,deflt)
X        char *name;      long deflt;
X{
X    long datetime;
X    int dma_off;
X
X    #ifdef DEBUG
X        printf("getdatetime(%s)\n",name);
X        #endif
X
X    inregs.x.ax = 0x2F00;            /* get current DMA address */
X    intdos (&inregs, &outregs);   /*  .. */
X    dma_off = outregs.x.bx;           /* and save for later restoration */
X    inregs.x.dx = (int) & find_buf;  /* set DMA to GNJFN block */
X    inregs.x.ax = 0x1A00;
X    intdos (&inregs, &outregs);
X
X    inregs.x.dx = (int) name;       /* pathname */
X    inregs.x.cx = 0;                 /* attributes */
X    inregs.x.ax = 0x4E00;            /* GTJFN */
X    outregs.x.cflag = 0;
X    status = intdos (&inregs, &outregs);
X    if (
X         #ifndef LATTICE
X           outregs.x.cflag ||
X         #endif
X           (status & 1)
X                         ) {
X    #if DEBUG
X        printf ("File \"%s\" does not exist\n", name);
X        #endif
X    return deflt;
X    }
X
X    inregs.x.dx = dma_off;
X    inregs.x.ax = 0x1A00;
X    intdos (&inregs, &outregs);
X
X    /* the ^LONGNEGINF in the next line is an artifice so we can get by without
X       unsigned longs - future comparisons of datetimes will work AS THOUGH
X       we were using unsigned longs, as we switch here all the negative
X       numbers with the positive ones.  */
X    datetime = ((((long) find_buf.date) << 16) | find_buf.time) ^ LONGNEGINF;
X
X    #if DEBUG
X      printf ("file=%s date=%04x time=%04x datetime=%08lx\n",
X        find_buf.pname, find_buf.date,find_buf.time,datetime);
X        #endif
X
X    return datetime;
X}
X
X/*
X * make(name)
X *
X *      This routine actually does the work.  It scans the list of
X *      targets parsed from the makefile, and checks the target's
X *      prerequisites date/time values against the target's.  If
X *      the prerequisite is itself a target (present in target_list),
X *      we call make recursively to check it.  Then, if any of our
X *      prerequisites are newer than we are, we execute all our shell
X *      commands.  If there are no prerequisites specified at all, then
X *      also execute all our shell commands.
X */
X
X        int
Xmake (targname)         /* use fnode instead of fname here */
X    char *targname;
X{          
X    targptr targ;
X    preqptr prereq;
X    long NewestPreq=LONGNEGINF+1, targtime=LONGNEGINF; /* the +1 will arrange it so the commands will execute if there are no prerequisites and the target file does not exist */
X
X    #if DEBUG
X        printf ("Making %s\n", targname);
X        #endif
X
X    if ((targ = lookup_target (targname)) == NULL)
X       return TryDefault( targname , 0);
X    prereq = targ->PreqList; 
X    if (prereq)
X        {
X        for ( ; prereq; prereq = prereq->next) {
X            long date;
X            assert (prereq->magic == PREREQ_MAGIC);
X            make (prereq->file->fname);             /* recursively make */
X            date =  getdatetime(prereq->file->fname,LONGPOSINF);
X            if (date > NewestPreq) NewestPreq = date;
X            }
X        }
X    targtime = getdatetime(targ->file->fname, LONGNEGINF);
X    #if DEBUG
X        printf ("Target \"%s\" datetime is %08lx, newest prereq is %08lx\n", targ->file->fname, targtime, NewestPreq);
X        #endif
X    if (targ->shell_list)
X        if (targtime < NewestPreq) build(targ);
X        else ;
X    else {   /* no shell lines specified, so there might be some implicit prerequisites */
X         int i;
X         dontworry ++;
X         i = TryDefault( targname , targtime < NewestPreq );
X         dontworry --;
X         return i;
X         }
X    return 1;
X}
X
X
XTryDefault(targname, outofdate)
X        char *targname;
X        int outofdate; /* non zero if the target is out of date with respect to some other prerequisites */
X        {
X        targptr targ;
X        char * ext = strchr (targname, '.');
X        dontworry ++;
X        if (ext != NULL)
X            for (targ = target_list ; targ ; targ = targ -> next )
X                if (targ->file->fname[0] == '*' &&
X                    0 == strcmp ( ext , targ->file->fname+1 ) ) {
X                        char *root = msubstr( targname , 0 , ext-targname );
X                        char *cname;
X                        int worked;
X                        long cnamedate;
X                        cname = mstrcat( root ,targ->PreqList->file->fname+1 );
X                        worked = make ( cname ) ;
X                        SetSymbol ( "*" , root ) ;  /* should really have a way of freeing this space later... */
X                        if (worked && !outofdate) cnamedate = getdatetime(cname,LONGNEGINF);
X                        free(cname);
X                        free(root);
X                        if (!worked) continue; /*** was: goto ret0; ***/
X                        if (outofdate || cnamedate > getdatetime(targname,LONGNEGINF)) build (targ) ;
X                        goto ret1;
X                        }
X
X        if (getdatetime(targname,LONGNEGINF) > LONGNEGINF) goto ret1;
X
X        ret0:                   /* unsuccessful return */
X            if (--dontworry) return 0;
X            else {
X                error(mstrcat("Don't know how to make ",targname));
X                }
X
X        ret1:                   /* successful return */
X            dontworry--;
X            return 1;
X        }
X
X
X
X
X/*
X * build
X *
X *      Invoke shell commands to build a target file
X */
X
Xbuild (targ)
X    targptr targ;
X    {
X    shellptr snode;
X    char *cmd;
X    int  runsts = 0;
X
X    #if DEBUG
X        printf ("Building \"%s : %s...\"\n", targ->file->fname, targ->PreqList->file->fname);
X        #endif
X    for ( snode = targ->shell_list; snode; snode = snode->next, free(cmd) ) {
X        char *p, **q, *cmdstart, *cmdname, *cmdtail, sys=FALSE;
X
X        assert (snode->magic == SHELL_MAGIC);
X        cmd = strperm(snode->command);
X        breakout_symbols(&cmd);           /* notice that this may introduce a space at the beginning of the command line */
X        cmdstart = cmd; passpace(&cmdstart);
X
X        if (!snode->quiet)  fputs (cmdstart, stdout);
X        if (tracing) {
X               puts ("");   /* EXEC does newline, so must be faked */
X               continue;
X               }
X
X        /* separate the name of the command */
X        p = cmdstart ; passnonsp(&p);
X        if (*p)  *p = EOS, cmdname = strperm(cmdstart), *p = ' ';
X        else               cmdname = strperm(cmdstart);
X
X        cmdtail = p;  passpace(&cmdtail);
X
X        /* find whether it is a dos command */
X        strlwr(cmdname);          /* lower  case for comparison */
X        for (q=dos_commands ; *q ; q++) if (0==strcmp(*q,cmdname)) break;
X
X        if (*q || snode->useshell)        /* must we use command.com ? */
X
X        #ifndef LATTICE
X                if (0==strcmp(cmdname,"chdir") || 0==strcmp(cmdname,"cd"))
X                        if (*cmdtail) {   /* chdir with arg */
X                            char *q=cmdtail;
X                            passnonsp(&q);  *q = EOS;
X                            runsts = chdir(cmdtail), sys=FALSE;
X                            }
X                        else {                      /* chdir without arg */
X                            char name[200];
X                            if (getcwd(name,200)) {
X                                if (!snode->quiet) putchar('\n');
X                                fputs(name,stdout);
X                                runsts = 0;
X                                }
X                            else error("path name too long");
X                             }
X                else
X        #endif
X                        {                           /* resident command */
X                        if (strlen(cmdstart) > 128) error("shell command line too long");
X                        #if DEBUG
X                           printf("\nsystem -- %s --",cmdstart);
X                           #endif
X
X                        #ifdef LATTICE
X                        runsts = forklp(cmdname,cmdname,"",cmdtail,NULL) ?
X                                         -1         /* error */    :
X                                         wait()   /* get status */ ;
X                        #else
X                        runsts = system(cmdstart), sys = TRUE;
X                        #endif
X
X                        }
X        else    {                                   /* transient command */
X                if (!snode->quiet) putchar ('\n');
X                #if DEBUG
X                  printf ("spawnvp -- %s --\n",cmdstart);
X                  #endif
X                runsts = mspawn(cmdstart), sys = FALSE;
X                /* can't use 'system()' here, because command.com does not
X                   return the exit code of the program */
X                }
X        putchar('\n');      /* some programs do not end with return */
X        if (runsts == -1)
X           perror(
X                sys ? "command.com not found" : "can't run program"
X                ),
X           exit(23);
X        if (runsts > 0 && !snode->ignore && !ignore_errors) {
X              fputs( " --- return code ", stderr);
X              fputint(runsts,stderr);
X              fputs(" ---\7",stderr);
X              exit(runsts);
X              }
X
X    free(cmdname);
X    free(cmd);
X                     
X    }
X}
X
X        targptr 
Xlookup_target (name)
Xchar *name;
X{
X    targptr targ;
X    for ( targ = target_list; targ ; targ = targ->next)
X        if (strcmp (name, targ->file->fname) == 0) break;
X    return targ;
X}
X
Xbreakout_symbols (cmdlinptr)
Xchar **cmdlinptr; {
X    char *cmdlin = *cmdlinptr, *cmd = talloc(LINESIZE+100);
X    symbptr sym;
X    char   symcmp[SYMLEN];
X    int i, paren, cmdptr;
X
X    #if DEBUG
X        printf("breakout_symbols (\"%s\")\n", cmdlin);
X        #endif
X    /* this routine doesn't check for overflow of the line ! */
X
X    strcpy ( cmd, "");
X    cmdptr = 0;
X    while (1) {
X        while (*cmdlin != '$' && *cmdlin != EOS) {
X                if (cmdptr >= LINESIZE) error ("Line too long after symbol substitution");
X                cmd[cmdptr++] = *cmdlin++;
X                }
X        if (cmdptr >= LINESIZE) error ("Line too long after symbol substitution");
X        cmd[cmdptr] = EOS;
X        if (0==*cmdlin) break;            /* end of line */
X        cmdlin++;               /* pass the $ */
X        /* now we know we are looking at a symbol */
X        if (*cmdlin == '(') paren = 1, cmdlin++; else paren=0;
X        for (i = 0; i < SYMLEN-1 && (*cmdlin == '*' || isalnum (*cmdlin)); )
X            symcmp[i++] = *cmdlin++;
X        symcmp[i] = EOS;
X        if (paren)
X           if (*cmdlin == ')') cmdlin++;
X           else puts ("No closing paren on shell line macro");
X        for ( sym = SymbolList; 1 ; sym = sym->next) {
X            if (sym==NULL)  error (mstrcat("Undefined symbol ", symcmp) );
X            assert (sym->magic == SYMBOL_MAGIC);
X            if (strcmp (sym->token, symcmp) == 0) break;
X        }
X        strcpy ( cmd + cmdptr , sym->value );
X        cmdptr = strlen ( cmd ) ;
X    }
X
X    free(*cmdlinptr);
X    *cmdlinptr = strperm(cmd);
X
X    #if DEBUG                    
X        printf ("breakout_symbols returning (\"%s\")\n", cmd);
X        #endif
X
X    free(cmd);
X
X}
X
X#ifdef LATTICE
X
Xstrlwr(p)
X        char *p;{
X        for ( ; *p ; p++) *p = tolower(*p);
X        }
X
X#endif
SHAR_EOF
echo 'Orignal Sum -> 61474    31'
echo -n 'Current Sum -> '
sum make.c
echo shar: extracting make.doc
sed 's/^X//' << 'SHAR_EOF' > make.doc
XThe majority of the text of this file was written by:  
X
X                Jeffrey Spidle
X                Systems Analyst
X                Office of Continuing Education
X                Iowa State University
X                Ames,   IA 50011
X
XSince there is a similarity in operation between his program and this one,  I
Xsaw no reason to "re-invent the wheel".
X
X        This a utility called 'MAKE' and is a much simplified version of the 
XMAKE utility on UNIX (a trademark or something of AT&T).  This program was ori-
Xginally written by Larry Campbell of DEC using the CI-C86 compiler.  I have re-
Xwritten it using the Lattice C compiler Ver. 2.14 running under MS/PC-DOS 2.1x. 
XAdded features include macro capability, command line parsing of macros, silent
Xoperation (-s option), ignore/obey errors (-i option), faster operation, and 
Xthe ability to run any DOS-level command.       --      March 31,  1985
X
X                                Mike Hickey
X                                Systems Programmer
X                                Computer Center
X                                University of DC
X                                Washington, DC
X
X
X/* modifications made June, 1985 by Dan Grayson, 2409 S. Vine St. , Urbana, 
X        IL 61801 */
X
X
X
X        'MAKE' takes a file of dependencies (a  'makefile') and decides what
Xcommands have to be executed to bring the  files up to  date.  These commands 
Xare either executed directly from 'MAKE' or written to the standard output with-
Xout executing them.
X
X'MAKEFILE' format:
X
X        -       The first makefile read is MAKE.INI, which can be located
X                anywhere along the PATH.
X
X        -       The default name of the makefile is MAKEFILE on the default
X                disk.  An alternate makefile can be specified using the '-f' 
X                option on the command  line.
X
X        -       Any line starting with a "#" is considered to be a
X                comment line and is ignored by MAKE.  So is a line which is
X                completely blank.
X
X        -       A line in a 'makefile' that starts with a tab or space is a 
X                'howto' line and consists of a command name followed by arg-
X                uments.  When
X                commands are executed, the PATH environment variable is used to
X                find the command, in the same manner as DOS does. 
X                'Howto' lines apply to the most recently preceding 'dependency'
X                line.  It is an error for a 'howto' line  to precede the first 
X                'dependency' line.  Howto lines may have any combination of the
X                following characters to the left of the command:
X
X                        @               will not echo the command line
X
X                        -               MAKE will ignore the exit code of the
X                                        command, i.e. the ERRORLEVEL of MSDOS.
X                                        Without this, make terminates when a
X                                        nonzero exit code is returned.
X
X                        +               MAKE will use command.com to execute
X                                        the command - you must use this if the
X                                        command is non resident and you use
X                                        io redirection with < or > or | .
X
X        -       A line of the form
X
X                FOOBAR = THIS AND THAT AND MORE OF THOSE
X
X                is a symbol definition line.  Later in the makefile, any line
X                containing $FOOBAR or $(FOOBAR) will have that bit replaced by
X                ' THIS AND THAT AND MORE OF THOSE'.
X
X        -       Any other non-blank line is a 'dependency' line.  Dependency
X                lines consist of a filenames, then ':', then the filenames on
X                which the previous ones depend.  If one of the files (call this
X                one the target) to the
X                left of the ':' needs to be made, first all the files to right
X                will be made.  Then if any of the dates on the right is more
X                recent than the target, the howto lines (if any) following this
X                dependency line will be executed.  If there weren't any howto
X                lines, then we try to make the target according to any
X                existing wildcard dependency lines - see the next item.
X         
X        -       Special allowance is made on MSDOS for the colons which are
X                needed to specify files on other drives, so for example:
X                        c:foo.bar : a:fee.ber
X                ought to work as intended.
X
X        -       There is a special sort of dependency line which allows for
X                wildcards in the file names.  It looks like this (along with
X                an example howto line) :
X
X                *.obj : *.c
X                        msc $*.c ;
X
X                This says that whenever a file of the form *.obj needs to be
X                made, say it's called foo.obj, then provided foo.c can
X                be made, we will make foo.obj by means of the command
X
X                        msc foo.c ;
X
X                which on my system, is the way I run the C compiler.
X
X
X                        Operation
XSyntax:
X        make [filename]  [-f makefilename] [-i] [-n] [-s]
X
X        -i      means continue even if an error is encountered while executing 
X                a command.
X
X        -n      means don't execute the commands, just write the ones that
X                should be executed to the standard output.  This is useful
X                for creating batch files, for  example.
X
X        -f      specifies that the following argument is the name of a makefile
X                to be used instead of the default (MAKEFILE).
X
X        -s      suppress MAKE echoing commands.  Only text echoed from an
X                invoked program will appear on the screen.
X
X        First, MAKE reads all of the makefiles.  It then proceeds through all of
Xthe filename arguments,  'making' each one in turn, unless there are none, in
Xwhich case it makes the first item in the makefile.  A file is remade if it is 
Xout of date with respect to the files it depends on or is non-existent.  Depen-
Xdencies are processed in a 'tree' fashion,  so that the lowest-order files are 
Xremade first.
X
X        
X
X
Xremarks:
X
X    1    MAKE REQUIRES DOS 2.0 OR HIGHER
X
X    2    With a moderate size makefile, the programs executed by MAKE will
X         notice that available RAM has decreased by about 40K.
X
SHAR_EOF
echo 'Orignal Sum -> 57564     7'
echo -n 'Current Sum -> '
sum make.doc
echo shar: extracting mstring.h
sed 's/^X//' << 'SHAR_EOF' > mstring.h
X/* mstring.h */
X
Xtypedef char * mstring;
X
X#ifdef LINT_ARGS
Xchar lastchar(char *);
Xchar *endptr(char *);
Xchar *mfgets(struct _iobuf *);
Xchar *msubstr(char *,int ,int );
Xchar *mstrcat(char *,char *);
Xchar *strperm(char *);
Xint passpace(char * *);
Xint passnonsp(char * *);
Xint password(char * *);
X            int fputint(int, struct _iobuf *);
Xvoid error(char *);
Xchar *talloc(int );
Xchar *token(char *);
Xint numtokens(char *);
Xchar * *tokenize(char *);
Xvoid freev(char * *);
X#else
Xchar lastchar();
Xchar *endptr();
Xchar *mfgets();
Xchar *msubstr();
Xchar *mstrcat();
Xchar *strperm();
Xint passpace();
Xint passnonsp();
Xint password();
Xint fputint();
Xvoid error();
Xchar *talloc();
Xchar *token();
Xint numtokens();
Xchar * *tokenize();
Xvoid freev();
X#endif
SHAR_EOF
echo 'Orignal Sum -> 34056     1'
echo -n 'Current Sum -> '
sum mstring.h
echo shar: extracting path.c
sed 's/^X//' << 'SHAR_EOF' > path.c
X
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X#include "mstring.h"
X
X        FILE *
Xfopenp(name,attr)
X        char *name, *attr; {
X        char *path;
X        FILE *file = fopen(name,attr);
X        if (file==NULL
X         && strchr(name,'\\')==NULL 
X         && strchr(name,':' )==NULL 
X         && (path = getenv("PATH"))) {
X                char *sname;
X                char *p = strtok(path = strperm(path),";");
X                sname = mstrcat("\\",name);
X                while (p) {
X                        char * filename = mstrcat(p,lastchar(p)=='\\' ? name : sname);
X                        file = fopen(filename,attr) ;
X                        free(filename);
X                        if (file) break;
X                        p = strtok(NULL,";") ;
X                        }
X                free(path);
X                free(sname);
X                }
X        return file;
X        }
X
SHAR_EOF
echo 'Orignal Sum -> 03204     1'
echo -n 'Current Sum -> '
sum path.c
echo shar: extracting touch.c
sed 's/^X//' << 'SHAR_EOF' > touch.c
X#include <fcntl.h>
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <io.h>
X#define ERROR -1
X
Xusage(){
X        puts("usage :    touch file ...");
X        exit (1);
X        }
X
Xmain(argc,argv)
X        char **argv;{
X        int f,i;
X        char ch[1];
X        if (argc == 1) usage();
X        for (i=1; i<argc; i++) {
X            if (ERROR != (f = open(argv[i], O_CREAT | O_EXCL, S_IWRITE | S_IREAD))) {
X                 /* we've created it */
X                 if (ERROR != close(f)) continue;
X                 puts("Can't close file"), exit(3);
X                 }
X            if (ERROR != (f = open(argv[i], O_RDWR | O_BINARY)))
X                 /* we've opened it */
X                 if (1 == read(f,ch,1)) {
X                      /* we've read one character */
X                      lseek(f,0L,0);    /* rewind */
X                      if (1 == write(f,ch,1)) { close(f); continue; }
X                      puts("Can't write to file."), exit(5);
X                      }
X                 else {
X                      /* we know the file has length 0 */
X                      close(f);
X                      if (ERROR != (f = open(argv[i], O_TRUNC, S_IWRITE | S_IREAD))) { close(f); continue; }
X                      puts("Can't truncate file"), exit(7);
X                      }
X            else puts("Can't open file"), exit(4);
X            }
X        exit(0);
X        }
X
X_setenvp(){}  /* don't use envp arg */
X
X_nullcheck(){}  /* don't check for null pointer assignments */
SHAR_EOF
echo 'Orignal Sum -> 41598     2'
echo -n 'Current Sum -> '
sum touch.c
exit 0

grayson@uiucuxc.CSO.UIUC.EDU (01/18/86)

This file is part 2 of 2.


Here is the current version of MAKE for MSDOS, due to popular demand.
This version reads an init file for default rules, and handles several
cases better than the old version.


        uucp:   grayson@uiucuxc.UUCP
    old uucp:	{ihnp4,pur-ee}!uiucdcs!uiucuxc!grayson
    internet:   grayson@uiucuxc.cso.uiuc.edu
       telex:	5101011969 UI TELCOM URUD --> Dan Grayson, Altgeld Hall.
     us mail:	Dan Grayson, Math Dept, Univ of Ill, Urbana 61801
       phone:	217-367-6384 home   217-333-6209 office
-----Cut Here-----Cut Here-----Cut Here-----Cut Here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	make.exe.uuencoded
#	make.h
#	make.ini
#	makefile.
#	mstring.c
echo shar: extracting make.exe.uuencoded
sed 's/^X//' << 'SHAR_EOF' > make.exe.uuencoded
Xbegin 644 make.exe
XM35I( "0 !P @ $<$1P2+! ! CBDY&0  '@    $ ) B6 SH9  ".'P  X!\ 
XM $ K  "*"I8#C@J6 P                                          
XM                                                            
XM                                                            
XM                                                            
XM                                                            
XM                                                            
XM                                                            
XM                                                            
XM                                                            
XM                                                            
XM                         %6+[#/ Z& 6N,T 4.B2&X/$ K@3 5#HB!N#
XMQ *X5@%0Z'X;@\0"N)P!4.AT&X/$ KCG 5#H:AN#Q *X+0)0Z& ;@\0"N%0"
XM4.A6&X/$ KA= E#H3!N#Q *XEP)0Z$(;@\0"N,H"4.@X&X/$ K@* U#H+AN#
XMQ *X%0!0Z$D:B^5=PU6+[+C0 .C>%5: /M@) G,*N'8#4.A%$8/$ L<&.@N3
XM S/ HT +HSP+HSX+HV -HYP/HYX/B88R_\>&-O\! .F? (N>-O_1XXMV!HL8
XM@#\M=5N+GC;_T>.+&(I' 9@]9@!T%#UI '0M/6X =# ]<P!T,^@*_^MFBT8$
XM2#N&-O]^\?^&-O^+GC;_T>.+=@:+ *,Z"^M(QP9 "P$ ZT#'!CX+ 0#K.,<&
XM/ L! .LP@[XR_V1U"KB< U#HHA"#Q *+GC;_T>.+=@;_,.B##X/$ HNV,O_1
XMYHF"./__AC+__X8V_XM&!#F&-O]] ^E5_X,^/@L = V#/CP+ '0&QP8\"P  
XMN+(#4+BT U#HDA*#Q 2)AC#_"\!T!U#H>0"#Q +'!EX-  "XO0-0_S8Z"^AE
XM$X/$!(F&,/\+P'0'4.A6 (/$ H.^,O\ =";'AC;_  "+AC+_.88V_WTUB[8V
XM_]'F_[(X_^@N!H/$ O^&-O_KX(,^7@T = Z+'EX-BU\"_S?H$@;K![B_ U#H
XMTP^#Q (SP%Z+Y5W#58OLN-@ Z$H45L>&+O\  ,>&*O\  (.^*O\ =!#_MBK_
XMZ-\4@\0"QX8J_P  _W8$Z!,-@\0"B88J_PO =0/I2 *)AC#_C88P_U#HK@Z#
XMQ *+GC#_@#\ =+V /R-TN(N>*O^*!YB+V/:'QP@(=%&#OB[_ '4*N-0#4.A-
XM#X/$ HN&*O^)AC#_C88P_U#H; Z#Q +'AC+_  "+AB[_.88R_WP#Z7'__[8P
XM_XNV,O_1YO^R-O_H_P*#Q 3_AC+_Z]F-ABK_4.BV"H/$ HN&*O^)AC#_C88P
XM_U#HHPZ#Q *+AC#_B88H_XV&,/]0Z X.@\0"BYXP_X _/74BQX8N_P  _X8P
XM_XN>*/_&!P#_MC#__[8J_^@9 H/$!.G[_L>&+O\  +@! (F&+/^+ABK_B88P
XM_XF&-/^+GC#_@#\Z=12#OBS_ G4@BD<!F(O8]H?'" AU$XN>,/^*!YB+V/:'
XMQP@(=0/IJP"#OB[_9'4*N/T#4.A7#H/$ HN>,/^*!XA&_L8' /^V-/_H+ &#
XMQ *+MB[_T>:)@C;_BYXP_XI&_H@'@SY>#0!U%HN>-/^ /RIT#8NV+O_1YHN"
XM-O^C7@W_AB[_C88P_U#H- V#Q *+GC#_@#\Z=2S_AC#_@[XN_P!U"K@M!%#H
XMY V#Q *-AC#_4.@+#8/$ HN>,/^ /P!U,>D7_HN&,/^)AC3_QX8L_P  ZQ.+
XMGC#_@#\ =0JX&@10Z*H-@\0"_X8L__^&,/_I!_^+AC#_B88T_XV&,/]0Z/H,
XM@\0"BYXP_XH'B$;^Q@< QX8R_P  ZQ__MC3_Z(\"@\0"4(NV,O_1YO^R-O_H
XM#0*#Q 3_AC+_BX8N_SF&,O]\UXN>,/^*1OZ(!^E?_X.^*O\ =!#_MBK_Z&P2
XM@\0"QX8J_P  _W8$Z)T9@\0"QP9D!0  7HOE7<-5B^RX! #HEA&+7@2 /RIT
XM*Z%@#>L?BU[\BU\"_S?_=@3HC!>#Q 0+P'4%BT;\ZT:+7OR+!XE&_ O ==JX
XM" !0Z",-@\0"B4;^_W8$Z.<!@\0"BU[^B4<"BU[^H6 -B0>+7O['1P8  (M>
XM_L='!   BT;^HV -B^5=PU6+[+@" .@<$:&<#^LU_W8$BU[^_S?H'1>#Q 0+
XMP'4=BU[^_W<"Z*P1@\0"_W8&Z%L+@\0"BU[^B4<"ZT:+7OZ+1P2)1OX+P'7$
XMN 8 4.B;#(/$ HE&_O]V!.@P"X/$ HM>_HD'_W8&Z"(+@\0"BU[^B4<"BU[^
XMH9P/B4<$BT;^HYP/B^5=PU6+[+@$ .B5$%:X!@!0Z%0,@\0"B4;^B]C'!P  
XMBU[^B_.!9 3]_X%G!/O_BU[^B_.+1 0E_O^+#CP+@>$!  O!B4<$BUX&@#] 
XM=0F+7OZ 3P0!ZR"+7@: /RMU"8M>_H!/! 3K#XM>!H _+746BU[^@$\$ O]&
XM!HU&!E#HQPJ#Q +KP/]V!NA\"H/$ HM>_HE' HM>!(M'!HE&_ O =!;K!8L'
XMB4;\BU[\@S\ =?.+1OZ)!^L)BUX$BT;^B4<&7HOE7<-5B^RX! #HT0__=@;H
XM-@"#Q *)1OZ+7@2+1P2)1OP+P'06ZP6+!XE&_(M>_(,_ '7SBT;^B0?K"8M>
XM!(M&_HE'!(OE7<-5B^RX @#HC ^X! !0Z$P+@\0"B4;^B]C'!P  BU[^BT8$
XMB4<"BT;^B^5=PU6+[+@" .A@#Z&>#^L=BU[^_S?_=@3H816#Q 0+P'4%BT;^
XMZS^+7OZ+1P*)1OX+P'7<N 0 4.CW"H/$ HE&_O]V!.B,"8/$ HM>_HD'BU[^
XMQT<"  "+7OZAG@^)1P*+1OZCG@^+Y5W#58OLN 8 Z/@.QP:.#P ON% +4+B.
XM#U#H71.#Q 2A4@N)1OZX8@^CE _'!HX/ !JX4 M0N(X/4.@]$X/$!(M&!*.4
XM#\<&D@\  ,<&C@\ 3L<&7 L  +A0"U"XC@]0Z!<3@\0$HS@+@SY<"P!U"/<&
XM. L! '0(BT8&BU8(ZRR+1OZCE _'!HX/ !JX4 M0N(X/4.CC$H/$!(L6>@\K
XMP*%X#X#V@(E&^HE6_(OE7<-5B^RX$@#H2P['1O8! ,=&^ " QT;Z  #'1OP 
XM@/]V!.@E!8/$ HE&_@O =0\SP%#_=@3HX0"#Q 3IUP"+7OZ+1P2)1O0+P'18
XMZU"+7O2+7P+_-^BJ_X/$ KC__[K_?U)0BU[TBU\"_S?HY_Z#Q :)1O")5O*+
XM1O:+5O@Y5O)\$W\%.4;P=@R+1O"+5O*)1O:)5OB+7O2+!XE&](-^] !UJC/ 
XMN@" 4E"+7OZ+7P+_-^B@_H/$!HE&^HE6_(M>_H-_!@!T((M&]HM6^#E6_'\0
XM? 4Y1OIS"?]V_NB* 8/$ K@! .LN_P9T XM&]HM6^#E6_'\,? 4Y1OIS!;@!
XM .L",\!0_W8$Z X @\0$B4;N_PYT XOE7<-5B^RX#@#H- VX+@!0_W8$Z!,3
XM@\0$B4;\_P9T PO =0/IYP"A8 V)1OX+P'4#Z=H B]B+7P*+'X _*G0#Z<, 
XMB]B+7P*+!T!0_W;\Z/\2@\0$"\!T ^FJ (M&_"M&!% SP%#_=@3HMP:#Q :)
XM1OJ+7OZ+7P2+7P*+!T!0_W;ZZ-H&@\0$B4;R4.A=_H/$ HE&^/]V^KA(!%#H
XM?/N#Q 2#?O@ =!R#?@8 =18SP+H @%)0_W;RZ(3]@\0&B4;TB5;V_W;RZ"8-
XM@\0"_W;ZZ!T-@\0"@W[X '0J@WX& '4<,\"Z (!24/]V!.A0_8/$!CM6]G]1
XM? 4[1O1S2O]V_NA/ .L_BU[^BP?I'/\SP+H @%)0_W8$Z"3]@\0&@?H @'P&
XM?R(+P'<>_PYT W0$,\#K&_]V!+A*!%#H(0:#Q 10Z'$'@\0"_PYT [@! (OE
XM7<-5B^RXW #HY O'1OP  (M>!(M'!HE&^NFZ L9&\ "+7OK_=P+H+@:#Q *)
XM1OZ-1OY0Z.,"@\0"BT;^B4;RC4;R4.A1!H/$ HM>^O='! $ =0VX(@90_W;R
XMZ.\+@\0$@SX^"P!T"KAB!%#HNA#I40*+1O*)1OB-1OA0Z%4&@\0"BU[X@#\ 
XM=!?&!P#_=O+HQ06#Q *)1NZ+7OC&!R#K#/]V\NBQ!8/$ HE&[HM&^(E&](U&
XM]%#HW@6#Q +_=N[H  N#Q +'1O8^ XM>]H,_ '0/_W;N_S?H)A&#Q 0+P'5@
XMBU[V@S\ =0V+7OKW1P0$ '4#Z>, N&,$4/]V[N@ $8/$! O =!2X:010_W;N
XMZ.\0@\0$"\!T ^F4 (M>]( _ '0DB\.)1NR-1NQ0Z*0%@\0"BU[LQ@< _W;T
XMZ(T0Z=$ @T;V NN#N,@ 4(V&)/]0Z-<2@\0$"\!T28M>^O='! $ =2G_#B0&
XM@SXD!@!\$+ *BQXB!O\&(@:(!RKDZPZX(@90N H 4.@X"8/$!+@B!E"-AB3_
XM4.BS"H/$!,=&_   ZWFX; 10Z+L%@\0"ZVW_=O+H6@^#Q (]@ !V"KA_!%#H
XMH06#Q +_=O+H%A&#Q *)1OS&1O !ZT.+7OKW1P0! '4I_PXD!H,^) 8 ?!"P
XM"HL>(@;_!B(&B <JY.L.N"(&4+@* %#HN0B#Q 3_=O+H7@>#Q *)1OS&1O  
XM_PXD!H,^) 8 ?!"P"HL>(@;_!B(&B <JY.L.N"(&4+@* %#H@ B#Q 2#?OS_
XM=1^ ?O  = 6XFP3K [BQ!%#HYPN#Q *X%P!0Z.8-@\0"@W[\ 'Y#BU[Z]T<$
XM @!U.8,^0 L =3*X*@90N,,$4.C "8/$!+@J!E#_=OSHI 2#Q 2X*@90N-4$
XM4.BE"8/$!/]V_.B=#8/$ O]V[NCF"8/$ O]V_NC="8/$ HM>^HL'B4;Z_W;^
XMZ,P)@\0"@W[Z '0#Z3W]B^5=PU6+[+@" .@#":%@#>L:BU[^BU\"_S?_=@3H
XM 0^#Q 0+P'0,BU[^BP>)1OX+P'7?BT;^B^5=PU6+[+CT ^C-"%:+7@2+!XE&
XM^+A,!%#HA 2#Q *)1OZXVP10_W;^Z,$(@\0$QT;\  #K*8 _ '0L@7[\Z -\
XM"KC<!%#H!@2#Q *+7OC_1OB*!XM>_/]&_(MV_H@ BU[X@#\D=<^!?OSH WP*
XMN 0%4.C: X/$ HM>_(MV_L8  (M>^( _ '4#Z=< _T;XBU[X@#\H=0O'A@[\
XM 0#_1OCK!L>&#OP  ,>&#/P  (M>^( _*G0,B@>8B]CVA\<(!W0<BU[X_T;X
XMB@>+M@S\_X8,_(B"$/R!O@S\YP-\T(NV#/S&@A#\ (.^#OP =!>+7OB /REU
XM!?]&^.L*N"P%4.@0#8/$ J&<#XE&^@O =1:-AA#\4+A1!5#HW0&#Q 10Z"T#
XM@\0"C880_%"+7OK_-^BX#8/$! O =2*+7OK_=P*+1OP#1OY0Z*0'@\0$_W;^
XMZ*<,@\0"B4;\Z03_BU[ZBT<$ZZ6+7@3_-^@>"(/$ O]V_NC- 8/$ HM>!(D'
XM_W;^Z <(@\0"7HOE7<-5B^RX @#H1@?&1OX ZPC_1@2*!XA&_HM>!( _ '7P
XMBD;^F(OE7<-5B^PSP.@@!^L#_T8$BUX$@#\ =?6+PXOE7<-5B^RX! #H! >+
XM7@3V1P80= /I@0"X4 ")1OY0Z+4"@\0"B4;\B]C&!P#_=OSH_0N#Q (%4  [
XM1OYV*X-&_E#_=O[_=OSH@ N#Q 2)1OP+P'44N&8%4.CM"X/$ K@! %#H" N#
XMQ +_=@2X4 !0_W;\Z'+_@\0"4.@K#8/$!@O =1F+7OR /P!T!(O#ZU__=OSH
XM*@>#Q (SP.M2_W;\Z![_@\0"/ IU@_\&9 7_=OSH-/^#Q *+V,9'_P#_=OSH
XM;0N#Q ) 4/]V_.C]"H/$!(E&_ O =12X?@50Z&H+@\0"N $ 4.B%"H/$ HM&
XM_(OE7<-5B^RX @#H% 96BT8(0%#HT@&#Q *)1O[_=@B+1@8#1@10_W;^Z"P&
XM@\0&BUX(BW;^Q@  BT;^7HOE7<-5B^RX @#HV 56_W8&Z/$*@\0"_W8$B_#H
XMY@J#Q (#QD!0Z(,!@\0"B4;^_W8$4.C#!8/$!/]V!O]V_NA("X/$!(M&_EZ+
XMY5W#58OLN ( Z(\%_W8$Z*D*@\0"0%#H2 &#Q *)1OZ#?@0 =0JXE@50Z.0 
XM@\0"_W8$_W;^Z'8%@\0$BT;^B^5=PU6+[#/ Z% %@WX$ '0(BUX$@S\ =1&X
XMK050Z+$ @\0"ZP6+7@3_!XM>!(L?B@>8B]CVA\<("'7JB^5=PU6+[#/ Z!0%
XM@WX$ '0(BUX$@S\ =2*XP@50Z'4 @\0"ZQ:+7@2+'XH'F(O8]H?'" AU#XM>
XM!/\'BUX$BQ^ /P!UX(OE7<-5B^PSP.C.!.L%BUX$_P>+7@2+'XH'F(O8]H?'
XM" =UZHOE7<-5B^RX% #HJ02X"@!0C4;L4/]V!.CO!8/$!O]V!HU&[%#HZP2+
XMY5W#58OL,\#H@@2#/F0% '0JN"H&4+C8!5#HS02#Q 2X*@90_S9D!>BP_X/$
XM!+@J!E"XX050Z+$$@\0$N"H&4/]V!.BD!(/$!+@! %#HFPB+Y5W#58OLN ( 
XMZ# $_W8$Z.@$@\0"B4;^"\!U"KCE!5#HC_^#Q *+1OZ+Y5W#58OLN ( Z 8$
XM@WX$ '4.H?0%B48$"\!U!#/ ZW>-1@10Z)/^@\0"BUX$@#\ =0<SP*/T!>M>
XMBUX$@#\B=2G_1@2+1@2)1OZ+7OZ /P!T*( _(G0C@#]<=0F ?P$B=0/_1O[_
XM1O[KX(M&!(E&_HU&_E#H?_Z#Q *+7OZ /P!T#,8' (M&_D"C] 7K!L<&] 4 
XM (M&!(OE7<-5B^RX @#H;@/'1OX  /]V!.C+_8/$ HE&!%#H2O^#Q (+P'00
XM_T;^,\!0Z#K_@\0""\!U\/]V!.CL X/$ HM&_HOE7<-5B^RX!@#H*0-6_W8$
XMZ*O_@\0"B4;ZT>! 0%#HV_Z#Q *)1O['1OP! /]V!.AK_8/$ HE&!%#HZOZ#
XMQ *+7OZ)!^L=,\!0Z-K^@\0"4.A*_8/$ HM>_/]&_-'CBW;^B0"+1OHY1OQ\
XMVXO8T>.+=O['    _W8$Z&D#@\0"BT;^7HOE7<-5B^RX @#HI0*+1@2)1O[K
XM#(-&_@+_-^A$ X/$ HM>_H,_ '7L_W8$Z#,#B^5=PU6+[+@$ .AV O]V!.@^
XM_X/$ HE&_E"+V/\W,\!0Z,X#@\0&B4;\_W;^Z*7_@\0"BT;\B^5=PU6+[+@*
XM .A  O]V!O]V!.CD (/$!(E&_ O = /IO "X7 !0_W8$Z D(@\0$"\!T ^FH
XM +@Z %#_=@3H]0>#Q 0+P'0#Z90 N/8%4.C_ H/$ HE&_@O =0/I@ "X^P50
XM_W;^Z$S\@\0"B4;^4.@?"(/$!(E&^O]V!+C]!5#HZ?N#Q 2)1OB#?OH =#[_
XM=OKH:?J#Q (\7'4%BT8$ZP.+1OA0_W;ZZ,'[@\0$B4;V_W8&4.A" (/$!(E&
XM_/]V]N@Y H/$ H-^_ !T%_]V_N@J H/$ O]V^.@A H/$ HM&_.L2N/\%4#/ 
XM4.BD!X/$!(E&^NN3B^5=PU6+[(/L E;H*0R+\ OV= ]6_W8&_W8$Z' 3@\0&
XMZP(SP%Z+Y5W#58OL@^P$5U:+=@:*1 :8J8, = ;V1 9 = :X___IV@#V1 8!
XM= : 3 8@Z^Z 3 8"@&0&[S/ B40"B_B)?O[V1 8(=0^*1 >8B]C1X_:'N@8!
XM=#"+/"M\! O_?A)7_W0$BD0'F%#HR ^#Q :)1OZ+1 1 B03'1 +_ 8M<!(I&
XM!(@'ZVKV1 8$=4Z!_B(&=2V*1 >84.BP"X/$ @O =37'!M8) R3'1 1>"XI$
XM!YB+V-'CQH>Z!@''!%\+Z[BX  )0Z"@!@\0"B40$"\!T!H!,!@CKFX!,!@2_
XM 0!7C48$4(I$!YA0Z$D/@\0&B4;^.7[^= /I,?^*1@0JY%Y?B^5=PU6+[%:+
XM=@2+UK5!L5JT88K<*MV*! K = \ZQ7((.L%W! +#B 1&Z^N+PEY=PUF+W"O8
XM<@H['@(&<@2+X__AZ2,$58OL5U8>!XM^!HOW,\"Y___RKD'WV8M^!(O7\Z2+
XMPEY?7<-5B^Q75AX'BWX$BW8&B]^+3@CC#*P*P'0#JN+X,L#SJHO#7E]=PU6+
XM[(/L!E=6_W8$Z+4$@\0"B_C_=@;HM0^#Q *+\/]V!E>X 0!0_W8$Z*,2@\0(
XMB4;\_W8&5N@7$(/$!#E^_'4)BUX$BD'_F.L#N/__7E^+Y5W#58OLBUX$@$_^
XM 8OE7<-5B^Q65[L$!H,_ '4I'@>X!0#H,PEU!3/ F>LD0"3^HP0&HP8&EL<$
XM 0"#Q@3'1/[^_XDV"@:+3@2,V([ Z-T'7UZ+Y5W#58OL@^P$5U:+-MX)"_9T
XM.(-^! !T,O]V!.@ !(/$ HOXZR"+'( Y/7465_]V!%/H! J#Q 8+P'4'BQR-
XM00'K"H/& H,\ '7;,\!>7XOE7<-5B^Q75K,!BTX(BT8$,]*#^0IU 9F+?@;I
XM.PM5B^RXU@#HB/Y75HO]@^]2_S;>"?]V"/]V!O]V!.A\#X/$"(E&_D!U*H,^
XMT@D"=2.+7@: /UQT&X _ '0&@'\!.G00N X&4.A+_X/$ HOP"_9U!HM&_NF'
XM +A_ %!6C88L_U#H8OZ#Q :+\,9&JP"X$P905NA?!(/$!(OP"_9TTU97Z"#^
XM@\0$5^@E X/$ HO8@'G_7'0+N!4&4%?HEP.#Q 3_=@97Z(T#@\0$_S;>"?]V
XM"%?_=@3HX@Z#Q B)1OY =9"#/M() G6)N!<&4#/ 4.@"!(/$!(OP"_9UH^ES
XM_UY?B^5=PU6+[(/L E=6BW8$OP( "_9T(H \ '0=5NBP @/G4%97Z(L,@\0&
XMB\=0N H(4%?H?0R#Q :A: @Y!M()?1.#/M() 'P,BQ[2"='CBX<>".L#N T(
XMB_!6Z'("@\0"4%97Z$P,@\0&N $ 4+@;"%!7Z#T,@\0&7E^+Y5W#OY$#BS8"
XM "OW@?X $'(#O@ 0^H[7@<2>#_MS ^E) 8'D_O\VB29R"#:))G (B\:Q!-/@
XM2#:C;@BT,,TA-J/8"3P"<RH>,\!0#A^ZBQFT"<TART1/4R R+C @;W(@;&%T
XM97(@<F5Q=6ER960-"B0#]XDV @",PRO>]]NT2LTA-HP>T F+-BP 'A:X #7-
XM(3:)'FH(-HP&; @.'[@ );JZ&LTA-HL.+@OC(C;%!C +C-HSVS;_'BP+<P/I
XMS  VQ08T"XS:NP, -O\>+ L''_R_. NYH \KSS/ \ZH6%@<?Z+H0NP0 N !$
XMS2%R"O;"@'0%@(_V"4!+>>SH PKH+ F[. N!^S@+<PA3_Q=;0T/K\KD& "OA
XMOMH)B_P6!_.DZ#\(,^WH)>90Z&8 #0I3=&%C:R!O=F5R9FQO=PT*#0I$:79I
XM9&4@97)R;W(-"@T*1FQO871I;F<@<&]I;G0@;F]T(&QO861E9 T*L1*Z8AHR
XM[0X?NP( M$#-(18?N/\ 4.@%";$0NG0:Z^6Q';J$&NO>58OL@S[6"0!T!/\6
XMU@G_=@3HXPB+Y5W#58OL5U:+?@2+!8M= HM-!(M5!HMU"(M]"LTA5XM^!HD%
XMB5T"B4T$B54&B74(CT4*<@0S]NL(Z$L'O@$ BP6)=0Q>7UW#58OL@^P&5U:+
XM=@3_=@96Z/$/@\0$"\!T"(!D_OZ+QNL^@$S^ 8M\_H'G_O__=@;HT?N#Q *)
XM1OX+P'0C.7X&<P.+?@:+1OZ)1OKK"8M>^O]&^JR(!XO'3PO =?"+1OY>7XOE
XM7<-5B^Q7'@>+?@0SP+G___*NB\% 0/?87UW#58OL@^P(5U:^(@;_=@3HUO^#
XMQ *+^%;HV J#Q *)1OY65[@! %#_=@3HQPV#Q B)1OI6_W;^Z#L+@\0$.7[Z
XM=2+_3 *#? ( ? RP"HL<_P2(!RKDZQ!6N H 4.@\^8/$!.L#N/__7E^+Y5W#
XM58OL5U8>!XM^!(O7,\"Y___RKD^+]XM^!HO?N?__\JY!]]F+_HOS\Z2+PEY?
XM7<.T.>L&M#KK K0[58OLBU8$S2'I_055B^Q7BWX$'@>+WS/ N?__\JY!]]F*
XM1@:+^_*N3S@%= (S_XO'7UW#58OL5U:+=@2+?@8>!XO?,\"Y___RKD'WV8O[
XM\Z:*1/\SR3I%_W(%= 5!ZP+WT8O!7E]=PU6+[%=6'@>+=@;HEPF #P&+=@0+
XM]G4$BS;$"#/ K K ="WHI@DZQ'7T3HO.,\"LBO#HEPDZQ'3V"O9U"4X[\74(
XM,\#K"L9$_P")-L0(B\%>7UW#58OL@^P$5U:+=@B+?@2#?@8 =2KK$E;H<P.#
XMQ *)1OY =0DY?@1U#C/ ZRJ*1OZ(!4<\"G4(Q@4 BT8$ZQC_3@9T\_], H-\
XM @!\RHL<_P2*!RKDZ\=>7XOE7<-5B^RXW #H _E6N!0*4.C_^8/$ HE&^,=&
XM^AP*BT8$B4;\QT;^  #_-MX)C4;X4/]V^#/ 4.C?"8/$"(OP0'4'@S[2"0)T
XM!8O&Z:L N!\*4.B]^8/$ HF&)/\+P'3IN'\ 4/^V)/^-AB;_4.C5^(/$!HF&
XM)/_&1J4 C4:HB4;XN#L 4/^V)/_HQ_Z#Q 2)AB3_"\!TLK@D"E"X, I0_[8D
XM_XU&J%#H>/B#Q 10Z +^@\0$4.C[_8/$!/\VW@F-1OA0_W;X,\!0Z$T)@\0(
XMB_! = /I<O^#/M() G0#Z6C_N#L 4#/ 4.AH_H/$!(F&)/\+P'6AN/__7HOE
XM7<-5B^R#[ )75HMV!+___XI$!IBI@P!T*/9$!D!U(E;H:@.#Q *+^%;HMP:#
XMQ **1 >84.B #(/$ @O ?0.____&1 8 B\=>7XOE7<-5B^R#[$)75HMV!HM^
XM! O_=1Y6Z&WX@\0"B_@+_W4.QP;2"0P QP;@"0@ ZUJ)?@0SP%"-1KY0Z&$'
XM@\0$C4:^4.BA_(/$ @4# #O&?!#'!M()(@#'!N ) 0 SP.LI,\!04+@9 %#H
XM) "#Q 8$08@%1\8%.D?&!5Q'C4:^4%?H6/>#Q 2+1@1>7XOE7<-5B^R*9@2+
XM5@:*1@C-(5W#Z<L @_GN<_A!@.'^BW<"_*V+_J@!=$)(.\%S%8O0 _"MJ %T
XM- /"!0( B_>)1/[KYHO^= P#^8E,_BO!2(D%ZP4#^?Y,_HO&C-J!^I$#= 4F
XMC!XV"HE_ L,FQ@8Z"@(]_O]T)8O^ _"MJ %T\HO^2#O!<[V+T /PK:@!=.(#
XMP@4" (OWB43^Z^:+1P@+P'0$CMCK$R;^#CH*=!",V#V1 W0%)HX>,@J+-^N]
XMBW<&,\#H60 [QG0-) % 0)CH30!T#?Y-_N@+ '0%EDY.ZYHSP)G#48M%_J@!
XM= ,KR$E!0;K_?R8[%C@*=@31ZG7UB\$#QG(5 \)R#??2(\(KQN@, '4(]]+1
XMZG7E,\!9PU)1Z!T =!A7B_Z+\ /RQT3^_O^)=P:+UBO72HE5_EA96L-34#/2
XM'E)24+@! % &'^@E#H/$"(/Z_Q]:6W0""]+#58OL5HMV!(I$!IBI@P!T!O9$
XM!D!T!KC__^F: /9$!@)T!H!,!B#K[H!,!@'V1 8,=2F*1 >8B]C1X_:'N@8!
XM=1JX  )0Z%'V@\0"B40$"\!T!+ (ZP*P! A$!H-\! !U#(I$!YC1X 6[!HE$
XM!(M$!(D$]D0&!'0%N $ ZP.X  )0_W0$BD0'F%#HQ0J#Q :)1 (+P'\5"\!T
XM!+ @ZP*P$ A$!L=$ @  Z6O__TP"BQS_!(H'*N1>B^5=PU6+[(/L E:^&@:*
XM1 :8J8, =14SP(E$ HA$!HE$!(D$QD0'_XO&ZPV+QH/&"#L&X@9UUS/ 7HOE
XM7<-5B^R+7@2#^Q1]$8/[ 'P,]H?V"4!T!;@! .L",\!=PU6+[%=6'@>+3@CC
XM+XO9BWX$B_<SP+G___*N0??9.\MV HO+B_Z+=@;SIHI$_S/).D7_=P5T!4'K
XM O?1B\%>7UW#58OL@^P$5U:+=@0S_U;HL J#Q **1 8D SP"=3SV1 8(=0^*
XM1 >8B]C1X_:'N@8!=">+!"M$!(E&_ O ?AM0_W0$BD0'F%#H/@.#Q 8[1OQT
XM!X!,!B"___^+1 2)!,=$ @  B\=>7XOE7<-R"#/ B^5=PW,&Z T N/__B^5=
XMPS+DZ $ PZ+@"0KD=2. /M@) W(-/")S#3P@<@6P!>L'D#P3=@*P$[L\"M>8
XMH]()PXK$Z_=5B^R#[ A75HLVW@GK%[@, %"X4 I0_S3H\?Z#Q 8+P'0(@\8"
XM@SP =>2#/ !T.8L\@\<,QT;^  "*!4>8B4;ZZQR*!9@]_P!U!#+ ZP**!8M>
XM_O]&_HB']@G_3OI'@W[Z '7>QP0  %Y?B^5=PU=6BTX*BT8$BU8&BWX(5QX'
XM_),*P'03@_D*=0X+TGD*L"VJ]]N#T@#WVHOWDC/2"\!T O?QD_?QDH?3!# \
XM.78"!">JB\(+PW7BB 5/K(8%B$3_3SOW<O587E]=PX\&7@J.'M ),\F+P8OI
XMB_E)BS8L  OV= B.QO*N1:YU^D670"3^B_W1Y0/%%A_HUO*+SXO\ _V+[!8'
XMCMXS]DGC#8E^ $5%K*H*P'7ZXO.)3@ 6'XDFW@G_)EX*58OLNS@+@?LX"W,(
XM4_\76T-#Z_+H_@8*Y'0*@'X$ '4$QD8$_A[%%FH(N  ES2$?BPXN"^,'NP( 
XM_QXL"XM&!+1,S2%5B^R#[ 175KX:!C/_ZQ>*1 :8J8, = M6Z,;]@\0"0'0!
XM1X/&"#DVX@9SXXO'7E^+Y5W#CP9@"HX>T D6![Z  *R8,](F@#[8"0-R95".
XM!BP ,\"+R/?1B_CRKB8X!77Y@\<#B\CWT8OW)HH%1T$ZX'04/")T"#P)= 0\
XM('7K6!8'OH$ ZRM/*_X+_W3QB\]"6XO# \$% P E_O\KX(O\'@8?%@?SI+ @
XMJHO+'[Z! .L.B\@$!"3^*^"+_+A#(*OSI(O!JHOT%A]0B]R+_JRJ"L!T/3PB
XM=1]6_P;:":P*P'0N/")U!X!]_UQU!$^JZ^U'QD7_ .O5Z#< =-!.5D;_!MH)
XMK*H*P'0(Z"4 =?7KX:J+]$M+._-S"*V'!XE$_NORB]P+TG4"_P>))MP)_R9@
XM"CP)= (\(,-5B^Q6BW8$BD0&F*F# '0=]D0&"'07_W0$Z,/Q@\0"@&0&]S/ 
XMB02)1 2)1 )>B^5=PU6+[(M>!/:']@D@= ZX D(SR8O1S2%S ^G0_/:']@F 
XM=0/I@0"+3@B+5@8>!S/ _%=6B_"+^N-EN I \JYU,E&+SRO*2>,0S2&< _"=
XM<P2T">M)"\!T+T:Y @"Z8@JT0,TA<P2T">LT"\!T&EF+U^O%48O/*\K-(9P#
XM\)US!+0)ZQH+P'46]H?V"4!T"XM>!H _&G4#^.L$^;@('%ER HO&7E_I1?R+
XM3@B+5@:T0,TA<P2T">OMX^L+P'7G]H?V"4!T"HO:@#\:=0/XZ];YN @<Z]!5
XMB^R+WHM6!HMV!+1'S2&+\UW#OV0*B]^Y$  SP/.JK K =!6+^+$#T^\#^[(!
XMBLB X0?2X@@5Z^;#48OXL0/3[P/[L@&*R(#A!]+B63/ A!5T 4##58OL5HMV
XM!('^(@9U//9$!@QU-HI$!YB+V-'C]H>Z!@%U)\=$!%X+BD0'F(O8T>/&A[H&
XM <<&U@D#),=$ @ "BT0$B02X 0#K-('^.@9U+/9$!@QU)HI$!YB+V-'C]H>Z
XM!@%U%[@  E#H*/"#Q *)1 0+P'0&@$P&".NY,\!>B^5=PU6+[%:+=@:#?@0 
XM=$R!_B(&=26*1 >84.A2^H/$ @O =!96Z*CZ@\0"BD0'F(O8T>/&A[H& .L:
XM@?XZ!G4;5NB,^H/$ O]T!.BX[X/$ H!D!O<SP(D$B40$7HOE7<-5B^RXB@#H
XM[.Y75HMV!H-^! )U$/]V"O]V"%;H+ F#Q ;I @&#/M8) '0$_Q;6"3/ 4(V&
XM>/]0,\!0C4;X4(U&_E#_=@K_=@CH\@2#Q Y =0:X___ISP"X7 !05NCC X/$
XM!(OX"_]U HO^N"X 4%?H;/2#Q 0+P'08_W;XC89X_U!6_W8$Z'L+@\0(B4;Z
XMZ8D 5NB \X/$ @4% %#H%.^#Q *+^ O_=0O_=O[H]^Z#Q +KGKAT"E!65^A-
XM[H/$!%#HU_.#Q 3'!M()  #_=OB-AGC_4%?_=@3H* N#Q B)1OJ#/M() '0K
XMN'D*4+@N %!7Z$X#@\0$4.@.[H/$!/]V^(V&>/]05_]V!.CV"H/$"(E&^E?H
XMCNZ#Q +_=O[HA>Z#Q *+1OI>7XOE7<-5B^R#[ 975HMV"(M>!HH'F#UA '1"
XM/7( = @]=P!T,>F& ,=&_@$ _T8&BUX&@#\K=0> 3OX(_T8&BT;^)0< /0$ 
XM=!H] @!T-#T$ '0TZQ#'1OX" .O0QT;^! #KR3/_]T;^" !T"('/ @"!Y_[_
XMBUX&@#]T=1"!SP! ZQ:_ 0/KWK\) >O9BUX&@#]B=02!SP" N*0!4%?_=@3H
XM*@:#Q :)1OH+P'T$,\#K0O=&_@@ = ;&1 : ZQ'W1OX& '0&QD0& NL$QD0&
XM <<&U@D#)#+ BU[ZT>.(A[H&F(E$ C/ B02)1 2*1OJ(1 >+QEY?B^5=PU6+
XM[(/L!E=6BW8$BWX*BT8&]V8(B4;ZB4;\"\!T._9%!@QU/HI%!YB+V-'C]H>Z
XM!@%U+_]- H-] @!\#(H$BQW_!8@'*N3K"U>*!)A0Z%?K@\0$]D4&('0%,\#I
XMV@!&_T[\]D4&"'42BD4'F(O8T>/VA[H& 74#Z:, @W[\ '4#Z8D BT;\.44"
XM<AQ05O\UZ (*@\0&BT;\*44"BT;\ 07'1OP  .O3@WT" '0A_W4"5O\UZ-X)
XM@\0&BT4" 06+10(I1OP#=0+'10(  .NL_TT"@WT" 'P,B@2+'?\%B <JY.L+
XM5XH$F%#HO.J#Q 3V108@=1A&_T[\Z7__5XH$F%#HI.J#Q 3V108@= V+1OHK
XM1OPKTO=V!NL?1O]._(-^_ !TZ?]- H-] @!\SXH$BQW_!8@'*N3KSEY?B^5=
XMPU6+[%8S]KDU #+D_*PRX.+[@/15_@XU '4&B"8T .L1"N1T#;HV +L" +D9
XM +1 S2$RP*(U %Z+Y5W#58OLBUX$M#[-(7(*QH?V"0#&A^() .DH]U6+[%97
XM'OP>!XM.!D& X?Z+?@0SVXS8/9$#=0.[! :+5P)/3XOWK5!7)/Z)!0/P._)U
XM 4*MJ %T!_\% 05(Z^W1ZG,#B7\".PUT+G(?/?[_=2Q'1S/ Z,WT.\9U(>B,
XM]'0<EUY:@.(!"!3KLXL%B0U!00/Y*\% B06+1@3K S/ F5]9@.$!" T?7UZ+
XMY5W#58OL5QX'BWX$,\"Y___RKD'WV4^*1@;]\JY'. 5T!#/ ZP*+Q_Q?7<-5
XMB^R+7@3VA^() 70%,\#I9O:+3@B+5@:T/\TA<P2T">L*]H?V"8!T ^@# .E)
XM]E97_(ORB_J+R.,;M VL.L1T%SP:=0?&A^() >L%B 5'XNN+QRO"7U[#@_D!
XM= > / IT[>OH]H?V"4!T&;@ 1,TA]\(@ '4*C19^"K0_S2%RU; *ZR_&!GX*
XM (T6?@JT/\TA<L(+P'0:@WX( 70@N?__B]&X 4+-(;D! ( ^?@H*= >P#8M6
XM!NN4BU8&ZY* /GX*"G79Z[I5B^R+7@2 9P;/7<-5B^R#[ Y75H-^!@!U!J'>
XM"8E&!HMV!L=&]   ZQ"#Q@+_=/[HL>Z#Q )  4;T@SP =>N+1O1 B4;VQT;\
XM$P"+7OR O_8) '4)_T[\@W[\_W_M@W[\ 'P3N( *4.AY[H/$ @-&_ 4#  %&
XM]H-^$ !T$8M>!/\WZ%_N@\0"!0,  4;VBT;V!0\ 4.CJZ8/$ HE&^(M>"(D'
XM"\!U(8-^# !T"?]V#.C!Z8/$ L<&T@D, ,<&X D( +C__^DR 8M&^ 4/ "3P
XMB_B+7@J)/XMV!NL9,\!0_S17Z//H@\0$4.C![H/$!$"+^(/& H,\ '7B@W[\
XM 'Q*,\!0N(T*4%?HS>B#Q 10Z)ON@\0$B_B*1OS^P(@%1\=&]   BU[T@+_V
XM"0!T!HJ']@GK K#_B 5'_T;TBT;\_T[\"\!UWL8% $?&!0"#?A  = ^#QP.+
XM7@3_-U?H>>B#Q 3'1O0  (M^#D>+7@2#/P!T>8-_ @!T!\8%($?_1O2+=@2#
XMQ@*#/ !T8?\TZ%3M@\0"B4;Z T;T/7T ?BS'!M()!P#'!N )"@"+7@C_-^C"
XMZ(/$ H-^# !U ^D$__]V#.BPZ(/$ NGX_HM&^D !1O0SP%#_-%?H_N>#Q 10
XMZ,SM@\0$B_C&!2!'ZY?&!0V+7@Z*1O2(!XM&]EY?B^5=PU6+[%97!H-^" !U
XM.+]R"(M6!HM&!$AU!^A3 '(GZTB+-L((2'01._=T#8M$ HE&#%;H.@!><S"#
XMQ@2!_L((<P0+TG4&N/__F>L=B]J#PP_1V[$#T^NT2,TA<NF2B02)5 *)-L((
XM,\ '7UZ+Y5W#BTX,B_<Y3 )T#(/&!('^P@AU\OGK/XO: QQR.8O3CL$[]W4&
XM.1YN"',F@\,/T=O1Z]'KT>L[]W4) ]FAT DKV([ M$K-(7(-._=U!(D6;@B2
XMAP2+T<-5B^PR_X@^Q@J+1@8R[:D( '0"M2"(+L4*)0, /0, =06!=@8! +J:
XM"K0:S2&Y)P"+5@2T3LTA<P/IFP"+1@:+R"4 !3T !74'N 41^>F>\L8&QPH!
XMD:D  G0+BU8$N !#S2'IH "I P!T5ZD @'52]@8%"X!U2[ ""@;&"HM6!+0]
XMS2%RQY.X $3-(?;"@'4MN?__B]&X D+-(??9NIH*M#_-(0O =!: /IH*&G4/
XM]]F+T;@"0LTA,\FT0,TAM#[-(8I&!B0#"@;&"HM6!+0]S2%R.^GK!/=&!@ !
XM=0:X @#I:/_&!L<* /]V".@C!5F)3@@R[?8&Q@K_=0?W1@8" '4#@.'^BU8$
XMM#S-(7,#Z=SQ]@;&"O]U!_=&!@( =3*3M#[-(8I&!B0#"@;&"HM6!+0]S2%R
XMV/8&QPH!=13W1@@! '0-@,D!DXM6!+@!0\TAD^EM!%6+[+BD .BBY5=6,__'
XM1O0! #D^U@ET!/\6U@FX7 !0_W8$Z-+Z@\0$B_ +]G4#BW8$N"X 4%;H6NN#
XMQ 0+P'09N " 4/]V!.A@_H/$!(E&YD!U>+C__^E/ O]V!.AKZH/$ @4% %#H
XM_^6#Q *+^ O_=.&XR I0_W8$5^A!Y8/$!%#HR^J#Q 2X (!05^@;_H/$!(E&
XMYD!U,+C-"E"X+@!05^A3^H/$!%#H$^6#Q 2X (!05^CT_8/$!(E&YD!U"5?H
XME^6#Q +KBXE^!(OU@>ZB +@8 %!6_W;FZ$3Z@\0&0'4C"_]T!U?H<.6#Q +_
XM=N;H7/F#Q +'!M()" #'!N )"P#I3O^X @!0*\!04/]VYNC( H/$"(E&^HE6
XM_ O2?0@SP(E&_(E&^O=&^@\ =!F+1OJ+5ORQ!.B? P4! (/2 (E&^HE6_.L*
XML 10C4;Z4.B2 _]VYNCW^(/$ H \374&@'P!6G01@#Q:= /IN " ? %-= /I
XMKP#_3O2*1 68L0C3X"K BDP$*NT#P8E&[L=&\   N"  F5)0C4;N4.@; HI$
XM"9BQ"-/@*L"*3 @J[0/!*](I1NX95O"*1 .8L0C3X"+%BDP" \$M  +WV(E&
XMWK$$TV[>BT;>*4;N&5;PBD0/F+$(T^ BQ8I,#@/!B4;@BD01F+$(T^ BQ8I,
XM$ /!B4;RBD05F+$(T^ BQ8I,% /!B4;HBD07F+$(T^ BQ8I,%@/!B4;^N $ 
XM4(V&7O]05XU&Y%"-1OA0_W8(_W8&Z+'Y@\0.B4;B0'40"_]T!U?H".2#Q *+
XM1N+K3O]V^O]VZ/]V_O]V\O]VX/]V[O]VXO]VY(V&7O]0_W8$Z$WH@\0"0%#_
XM=@3_=O3H=@*#Q!B)1NH+_W0'5^C!XX/$ O]V^.BXXX/$ HM&ZEY?B^5=PP  
XM          !5B^Q65XS8BUX*L033ZP/#H](*BT8(H]0*C![6"AX'BS;4"D:_
XMX JX 2G-(;@!*;_P"LTA508>+HP6<#,NB29N,[O2"H-^! !T!K $,\GK C+ 
XM^+\N (LU+HDV<C.+=0(NB39T,RZ,'G8S4+0+S2%8QP8*"@$ BU8&M$O-(2Z.
XM%G S+HLF;C,?QP8*"@  ORX +HX>=C,NBS9T,XEU BZ+-G(SB34'75]><@2T
XM3<TAZ2[N58OL5U8>!XM^!(MV!HO7BTX(._YV%(O& \$[^',, _$#^4Y/_?.D
XM_.LAB\<+QM'H<PJ+QS/&T>ARZZ1)B]G1Z?.ET>MS!8H$)H@%B\)>7UW#58OL
XMBUX$_W8(_W8&_W<"_S?H102+7@2)!XE7 EW"!@!5B^R+7@3W1@@ @'1+@WX*
XM '0:,\F+T;@!0LTA<E#W1@H" '4. T8&$U8(>2NX 0#YZSN)%@ +HP(+B]&X
XM D+-(0-&!A-6"'D/BPX "XL6 @NX $+-(>O5BU8&BTX(BD8*M$+-(7('QH?B
XM"0#K [K__^E)[56+[,8&Q0H _W8&Z%\ 68E.!HM6!#+MM#S-(7)-B]B+5@2X
XM $/-(??! 0!U!#+)ZP*Q$/=&!@! =0[W1@8 @'4*]@8%"X!U X#)@ H.Q0J 
XMR0&X $3-(8O#]L* = . R4"(C_8)QH?B"0#IW.Q5B^RAU GWT(M>!"/#@>, 
XMP*B =0. RP&)7@1=PS+MXP;1^M'8XOK#58OLBUX$BP>+5P*+3@;HY/^+7@2)
XM!XE7 EW"! !5B^PSTKD3 +MR"(/#!(M' @O =!..P%.[__^T2LTA ]-"6X/#
XM!.+FC@;0";O__[1*S2$#VH ^V D"=Q1T#+H&"[0)S2&X 0#K.('K@ )R+X-^
XM! !T"+C4."U]..L)N'TX+0LX!0@ !:   T8(BU8.@\(/ \*Q!-/HT^H[V'<'
XMN @ ^>D1["O82X-^! !T"(M.&D%RZNL#BTX0@\$1<N #RG+<.]ERV(-^! !T
XM%8'Y !!WS":+'@( C,(KVCO9<P*+V5!3N1, NW((@\,$BT<""\!T"X[ M$G-
XM(8/#!.+N6XX&T FT2LTA6W*8M$C-(7*24$@FHP( 0([ '@X?,_^#?@0 = BY
XMU#B^?3CK!KE].+X+."O.\Z0?B]>#?@0 =1"+1A*KBT84JXM&%JN+1ABKBW8&
XMBTX(\Z2+WXMV#(M.#O.DC@;0"1Y2!A^Z@ "T&LTA6A^,P 40 (-^! !T! -&
XM&D! )J,L +^  (MV"HH,04'SI+]< )&Y( #SJK]< (MV"D:X 2G-(3S_= (R
XMP(K(OVP N $IS2$\_W0",L"+\XK9BOA8HR@+BTX.@WX$ (OK=$<FBSXL (S#
XM*_M1L033YXO?@^L0)L<'  $FC$<")L='!(S8)L='!H[ )L='"(O%BNNQNR:)
XM3PJU^(K/)HE/#%DFQT<._R_K,+\0 ;L  2:)%X/""";'1P2,V";'1P:.P";'
XM1PB+Q2;'1PJ[ ";'1PP!^";'1P[_+_R#/@X* '044%(>CAX."HL6# JP([0E
XMS2$?6EC_+B8+CMCSI(/'#X'G\/^+WXO'L033Z(S! \$FB0<FB4<"OP !)HE%
XM K@#2XS9@<:0 /J.T8OF^\TANP !)HLW)HM_ JT#Q_J.T*V+X/N<!K@$ 5"M
XM \<FB4<"BP0FB0>,P;@A-<TA!H[!4XS"C-F.VH[!M$G+CMCSI(S !1  NP !
XM)HD')HE' K@#2XS9@<:0 /J.T8OF^\TAC, FBQXL "O82[$$T^/ZCM"+X_LS
XMP%"<!H/#!%.,P;@A-<TA!H[!4XS"C-F.VH[!M$G+58OL5HM&"HM.!/?AB]B+
XM1@B+\/?A ]J6]V8& ]B+TXO&7EW""                               
XM          !#($QI8G)A<GD@+2 H0RE#;W!Y<FEG:'0@36EC<F]S;V9T($-O
XM<G @,3DX-0 !3G5L;"!P;VEN=&5R(&%S<VEG;FUE;G0-"@!D:7( ='EP90!R
XM96T <&%U<V4 9&%T90!T:6UE ')E;@!R96YA;64 =F5R '9O; !B<F5A:P!V
XM97)I9GD ;6MD:7( ;60 97AI= !C='1Y &5C:&\ :68 8VQS &-H9&ER &-D
XM ')M9&ER ')D &-O<'D 9&5L &5R87-E $U!2T4@=F5R+B R+C$T(%!O<G1I
XM;VYS(&-O<'ER:6=H=" H0RD@,3DX-2!B>2!$86X@1W)A>7-O;BP@57)B86YA
XM($E,+@!-04M%('9E<BX@,BXQ,"!#;W!Y<FEG:'0@*$,I(#$Y.#0@8GD@3&%R
XM<GD@0V%M<&)E;&PL($UA>6YA<F0@36%S<RX 5&AI<R!P<F]G<F%M(&UA>2!B
XM92!C;W!I960@9G)E96QY(&9O<B!N;VYC;VUM97)C:6%L('!U<G!O<V5S+B @
XM270@;6%Y &YO="!B92!C;W!I960@9F]R(&-O;6UE<F-I86P@=7-E('=I=&AO
XM=70@=&AE(&%U=&AO<B=S('=R:71T96X@<&5R;6ES<VEO;BX* %1H:7,@('!R
XM;V=R86T@:7,@86X@:6UI=&%T:6]N(&]F('1H92!-04M%('!R;V=R86T@<W5P
XM<&QI960@=VET:"!5;FEX+@!5<V%G93H@;6%K92!;=&%R9V5T("XN+ET@6V]P
XM=&EO;G,@+BXN70!/<'1I;VYS.@ @(" @(" @("UF(&9I;&5N86UE('-P96-I
XM9GD@;6%K969I;&4L(&1E9F%U;'0@:7,@34%+149)3$4 (" @(" @(" M:2 @
XM(" @(" @("!I9VYO<F4@97)R;W)S('=H:6QE('!R;V-E<W-I;F< (" @(" @
XM(" M;B @(" @(" @("!T<F%C92!A;F0@<')I;G0L(&)U="!D;VXG="!E>&5C
XM=71E(&-O;6UA;F1S " @(" @(" @+7,@(" @(" @(" @<W5P<')E<W,@34%+
XM12!E8VAO:6YG(&-O;6UA;F1S  !0 %0 60!= &, : !M '$ > !\ (  A@"-
XM ), E@"; *  I0"H *P L@"U +L O@## ,<      $UU<W0@:&%V92!$3U,@
XM,BY86"!O<B!H:6=H97( 34%+149)3$4 5&]O(&UA;GD@=&%R9V5T(&9I;&5S
XM '( ;6%K92YI;FD <@!.;R!T87)G971S('-P96-I9FEE9 !487)G970@;&EN
XM92!M=7-T(&-O;64@8F5F;W)E('-H96QL(&QI;F5S %1O;R!M86YY('1A<F=E
XM=',@:6X@;VYE(&QI;F4 ;F\@<V5P87)A=&EN9R G.B<@ $YO('1A<F=E="!F
XM:6QE(&)E9F]R92 G.B<@ "H 1&]N)W0@:VYO=R!H;W<@=&\@;6%K92   &-H
XM9&ER &-D '!A=&@@;F%M92!T;V\@;&]N9P!S:&5L;"!C;VUM86YD(&QI;F4@
XM=&]O(&QO;F< 8V]M;6%N9"YC;VT@;F]T(&9O=6YD &-A;B=T(')U;B!P<F]G
XM<F%M " M+2T@<F5T=7)N(&-O9&4@ " M+2T'  !,:6YE('1O;R!L;VYG(&%F
XM=&5R('-Y;6)O;"!S=6)S=&ET=71I;VX 3&EN92!T;V\@;&]N9R!A9G1E<B!S
XM>6UB;VP@<W5B<W1I='5T:6]N $YO(&-L;W-I;F<@<&%R96X@;VX@<VAE;&P@
XM;&EN92!M86-R;P!5;F1E9FEN960@<WEM8F]L(     !N;R!M;W)E(&UE;6]R
XM>2 H;69G971S*0!N;R!M;W)E(&UE;6]R>2 H;69G971S*0!S=')P97)M("T@
XM3E5,3"!P;VEN=&5R $Y53$P@87)G('1O('!A<W-P86-E $Y53$P@87)G('1O
XM('!A<W-N;VYS< !A="!L:6YE(  @.B  ;F\@;6]R92!M96UO<GD   !0051(
XM #L 7  [   V$             !0051( #L 7  [  !B#0  8@T!        
XM  (!        !@(       "$ P        ($                        
XM                                                            
XM                                                            
XM                 0                                          
XM         +(&17)R;W(@,   3F\@<W5C:"!F:6QE(&]R(&1I<F5C=&]R>0  
XM    07)G(&QI<W0@=&]O(&QO;F< 17AE8R!F;W)M870@97)R;W( 0F%D(&9I
XM;&4@;G5M8F5R    3F]T(&5N;W5G:"!C;W)E %!E<FUI<W-I;VX@9&5N:65D
XM     $9I;&4@97AI<W1S $-R;W-S+61E=FEC92!L:6YK     $EN=F%L:60@
XM87)G=6UE;G0  %1O;R!M86YY(&]P96X@9FEL97,     3F\@<W!A8V4@;&5F
XM="!O;B!D979I8V4      $UA=&@@87)G=6UE;G0 4F5S=6QT('1O;R!L87)G
XM90  4F5S;W5R8V4@9&5A9&QO8VL@=V]U;&0@;V-C=7( .B  56YK;F]W;B!E
XM<G)O<@ *  #D!NP&[08'!P@'"0<*!PL''0<O!S\'0 =!!U$'8P=D!V4'9@=R
XM!X0'A0>&!X<'F >9!ZT'K@>O![ 'R ?)!\H'RP?,!]H'ZP?L!R4         
XM     )$#                                                    
XM                                                 '((    (" @
XM(" @(" @*"@H*"@@(" @(" @(" @(" @(" @("!($! 0$! 0$! 0$! 0$! 0
XMA(2$A(2$A(2$A! 0$! 0$!"!@8&!@8$! 0$! 0$! 0$! 0$! 0$! 0$! 1 0
XM$! 0$(*"@H*"@@(" @(" @(" @(" @(" @(" @("$! 0$"              
XM                                                            
XM                                                            
XM                                                            
XM                                        @8&! 0$             
XM                    0T]-4U!%0P O8P!0051( &-O;6UA;F0N8V]M %P 
XM         "     6 @(8#0D,# P'"/___Q(-$@+_.T-?1DE,15])3D9/    
XM    #0H                     +F-O;0 N97AE    .T-?1DE,15])3D9/
XM #M#7T9)3$5?24Y&3P                                          
XM                    +F-O;0 N97AE         ) *E@.@"I8#        
XM                                          !%>&5C(&YO="!A=F%I
XE;&%B;&4@;VX@1$]3(#$N> T*)                        &YO
X 
Xend
SHAR_EOF
echo 'Orignal Sum -> 09851    25'
echo -n 'Current Sum -> '
sum make.exe.uuencoded
echo shar: extracting make.h
sed 's/^X//' << 'SHAR_EOF' > make.h
X
X#ifdef LINT_ARGS
Xint usage(void );
Xint main(int ,char * *);
Xint parse(struct _iobuf *);
Xstruct TargNode *new_target(char *);
Xint SetSymbol(char *,char *);
Xint NewShellLine(struct TargNode *,char *);
Xint LinkPreq(struct TargNode *,struct FileNode *);
Xstruct prereq_node *NewPreqNode(struct FileNode *);
Xstruct FileNode *NewFileNode(char *);
Xlong getdatetime(char *,long );
Xint make(char *);
Xint TryDefault(char *, int);
Xint build(struct TargNode *);
Xstruct TargNode *lookup_target(char *);
Xint breakout_symbols(char * *);
X#else
Xint usage();
Xint main();
Xint parse();
Xstruct TargNode *new_target();
Xint SetSymbol();
Xint NewShellLine();
Xint LinkPreq();
Xstruct prereq_node *NewPreqNode();
Xstruct FileNode *NewFileNode();
Xlong getdatetime();
Xint make();
Xint TryDefault();
Xint build();
Xstruct TargNode *lookup_target();
Xint breakout_symbols();
X#endif
SHAR_EOF
echo 'Orignal Sum -> 32975     1'
echo -n 'Current Sum -> '
sum make.h
echo shar: extracting make.ini
sed 's/^X//' << 'SHAR_EOF' > make.ini
X
X  ### this is the default makefile , MAKE.INI
X
X
XBIN      =g:\bin
XLIB      =g:\msc
XLINKFLAGS=/STACK:4000/NOI
XCFLAGS   =
XCC       =msc /DLINT_ARGS
X
X
X*.o : *.c
X        $CC /Fo$*.o $CFLAGS $*.c;
X*.exe : *.o
X        link $*.o $LINKFLAGS;
X
SHAR_EOF
echo 'Orignal Sum -> 18981     1'
echo -n 'Current Sum -> '
sum make.ini
echo shar: extracting makefile.
sed 's/^X//' << 'SHAR_EOF' > makefile.
X        ### this is the makefile for make.exe itself
X
XOBJS=make.o mstring.o path.o
XARCS=make.doc make.exe make.c make.h makefile mstring.c mstring.h path.c make.ini touch.c
XCFLAGS=/DNDEBUG
X
Xexe : make.exe touch.exe
Xall : install
Xinstall : $BIN\make.exe $BIN\touch.exe $BIN\make.ini
Xarc : make.arc
Xclean : install
X        del *.o
X        del make.arc
Xchkdsk :
X        # use this to see how much memory remains when make is resident
X        chkdsk
X
X     ###      lines below this one are not for the user                 ###
X
Xmstring.o : mstring.h
Xmake.o : make.h mstring.h
X$BIN\make.ini : make.ini
X        copy make.ini $BIN
X$BIN\make.exe : make.exe
X        copy make.exe $BIN
X$BIN\touch.exe : touch.exe
X        copy touch.exe $BIN
Xmake.arc : $ARCS
X        del make.arc
X        arc u make $ARCS
Xmake.exe : $OBJS
X        # the CPARMAXALLOC option gives spawned programs more space !!
X        # with it and the msc v 3.00 compiler, MAKE uses only 42K
X        link $OBJS /CPARMAXALLOC:1 /STACK:0x4000;
Xtouch.exe : touch.o
X        link touch.o $LIB\ssetargv;
X
X
SHAR_EOF
echo 'Orignal Sum -> 49576     2'
echo -n 'Current Sum -> '
sum makefile.
echo shar: extracting mstring.c
sed 's/^X//' << 'SHAR_EOF' > mstring.c
X/* mstring.c */
X
X/* The purpose of this file is to provide subroutines for handling
X   strings whose space is allocated with malloc - in this way we remove
X   all limitations on length of strings */
X
X#include "mstring.h"
X#include <ctype.h>
X#include <malloc.h>
X#include <string.h>
X#include <stdlib.h>
X#include <process.h>
X#include <stdio.h>
X
X#define DLEN 80
X
Xint linenumber = 0;
X
X        char
Xlastchar(p)
X        char *p;{
X        char c=0;
X        while (*p) c = *p++;
X        return c;
X        }
X
X        char *
Xendptr(p)
X        char *p;{
X        while (*p) p++;
X        return p;
X        }
X
X        mstring
Xmfgets (stream)
X        FILE *stream;{
X        mstring p; int plen;
X        if (feof(stream)) return NULL;
X        p = talloc(plen = DLEN);
X        p[0] = '\0';
X        while (1) {
X                if (strlen(p) + DLEN > plen) {
X                        p = realloc(p, plen += DLEN);
X                        if (p==NULL) puts("no more memory (mfgets)"), exit(1);
X                        }
X                if (NULL == fgets(endptr(p),DLEN,stream))
X                        if (*p) return p;
X                        else {
X                                free(p);
X                                return NULL;
X                                }
X                if (lastchar(p) != '\n') continue;
X                linenumber++;
X                endptr(p)[-1] = 0;
X#if 0
X                /* this next bit allows \ at end of line to force continuation */
X                if (lastchar(p) == '\\') {
X                        endptr(p)[-1] = 0;
X                        continue;
X                        }
X#endif
X                break;
X                }
X        p = realloc (p,strlen(p)+1) ;
X        if (p==NULL) puts("no more memory (mfgets)"), exit(1);
X        return p;
X        }
X
X        mstring
Xmsubstr(p,i,l)  /* creates a string from p[i],p[i+1],...,p[i+l-1] */
X        mstring p;{
X        mstring q;
X        q = talloc(l+1);
X        strncpy(q,p+i,l);
X        q[l] = '\0';
X        return q;
X        }
X
X        mstring
Xmstrcat(p,q)
X        mstring p,q;{
X        mstring r = talloc (strlen(p) + strlen(q) + 1);
X        strcpy(r,p);
X        strcat(r,q);
X        return r;
X        }
X
X        mstring
Xstrperm(s)
X        char *s;{       /* allocate space for s, return new pointer */
X        char *t = talloc(strlen(s)+1);
X        if (s==NULL) error ("strperm - NULL pointer");
X        strcpy(t,s);
X        return t;
X        }
X
Xpasspace(p)
X        char **p;{
X        if (p==NULL  ||  *p==NULL) error("NULL arg to passpace");
X        while (isspace (**p)) (*p)++;
X        }
X
Xpassnonsp(p)
X        char **p;{
X        if (p==NULL  ||  *p==NULL) error("NULL arg to passnonsp");
X        while (**p && !isspace(**p)) (*p)++;
X        }
X
Xpassword(p)
X        char **p;{
X        while (isalnum(**p)) (*p)++;
X        }
X
Xfputint(i,file)
X        int i; FILE *file;{
X        char b[20];
X        itoa(i,b,10);   /* we're trying to avoid using printf here */
X        fputs(b,file);
X        };
X
X        void
Xerror (errmsg)
X    char *errmsg;{
X    /* unfortunately, this assumes only one file is being used */
X    if (linenumber) {
X         fputs("at line ",stderr);
X         fputint(linenumber,stderr);
X         fputs(" : ",stderr);
X         }
X    fputs(errmsg,stderr);
X    exit (1);
X    }
X
X        mstring
Xtalloc(i)
X        int i;{
X        char *p;
X        char *malloc();
X        p = malloc(i);
X        if (p==NULL) error ("no more memory");
X        return p;
X        }
X
X        char *
Xtoken(s)
X        char *s;{
X        char *t;
X        static char *old=NULL;
X        if (s == NULL  &&  (s = old) == NULL) return NULL;
X        passpace(&s);
X        if (!*s) return old = NULL;
X
X        if (*s == '"')
X             for (t=++s; *t ; t++) {
X                  if (t[0] == '"') break;
X                  else if (t[0]=='\\' && t[1]=='"') t++;
X                  }
X        else t = s, passnonsp(&t);
X
X        if (*t) *t = '\0', old = t+1;
X        else               old = NULL;
X        return s;
X        }
X
X
Xnumtokens(s)
X        char *s;{
X        int n=0;
X        s = strperm(s);
X        if (token(s)) {
X                n++;
X                while (token(NULL)) n++;
X                }
X        free(s);
X        return n;
X        }
X
X        mstring*
Xtokenize(s)
X        char *s; {
X        int argc    = numtokens(s);
X        char **argv = (char **) talloc ( (argc+1) * sizeof(char *) ) ;
X        int i = 1 ;
X        s = strperm(s);
X                       argv[0]    =         token(s) ;
X        while (i<argc) argv[i++]  = strperm(token(NULL));
X                       argv[argc] = NULL ;
X        free(s);
X        return argv;
X        }
X
X        void
Xfreev(v)
X        char **v;{
X        char **w=v;
X        while (*w) free(*w++);
X        free((char *)v);
X        }
X
X        int
Xmspawn(cmd) char * cmd; {
X        char **argv = tokenize(cmd);
X        int runsts = spawnvp (P_WAIT, argv[0], argv);
X        freev(argv);
X        return runsts;
X        }
X
SHAR_EOF
echo 'Orignal Sum -> 51753     5'
echo -n 'Current Sum -> '
sum mstring.c
exit 0