1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<!-- $Id: jmk.html,v 1.3 2001/12/06 14:48:39 ramsdell Exp $ -->
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="John D. Ramsdell">
<META NAME="GENERATOR" CONTENT="GNU Emacs 19">
<style type="text/css">
h1 { text-align: center }
body { background: white; color: black }
</style>
<TITLE>jmk-Make in Java</TITLE>
</HEAD>
<!--
/*
* Copyright 1997 by John D. Ramsdell
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-->
<BODY>
<p><a name="top"></a>
<h1>jmk - Make in Java</h1>
<blockquote>
<p>Maintain a group files in a consistent state
</blockquote>
<h2>SYNOPSIS</h2>
<blockquote>
<p><b><tt>jmk</tt></b> [ <a href="#options">options</a> ] [ target ]*
<br>
<b><tt>java -jar jmk.jar</tt></b> [ <a href="#options">options</a> ] [ target ]*
</blockquote>
<h2>DESCRIPTION</h2>
<blockquote>
<p>
[<a href="#rules">Rules</a>]
[<a href="#file names">File Names</a>]
[<a href="#assignments">Assignments</a>]
[<a href="#functions">Functions</a>]
[<a href="#commands">Commands</a>]
[<a href="#rule patterns">Rule Patterns</a>]
[<a href="#special targets">Special Targets</a>]
[<a href="#file inclusion">File Inclusion</a>]
[<a href="#conditionals">Conditionals</a>]
[<a href="#expressions">Expressions</a>]
[<a href="#example">Example</a>]
[<a href="#grammar">Grammar</a>]
<p><tt>jmk</tt> is an application which is used to ensure that a set
of files is in a consistent state. If <tt>jmk</tt> detects an
inconsistency, it executes commands that correct the
inconsistency. The rules used to detect and correct inconsistencies
are given in a makefile.
<p><tt>jmk</tt> is designed to support the task of writing platform
independent makefiles. File names and path lists are written in a
canonical form, and translated by <tt>jmk</tt> into native form.
<p>The rules given in a <tt>jmk</tt> makefile can invoke programs as
separate processes. To produce a machine independent makefile, a
makefile should only invoke programs that use the same command line
argument syntax across platforms. Examples of such programs include
Sun's Java compiler (<tt>javac</tt>) and their Java Archive Tool
(<tt>jar</tt>).
</blockquote>
<H3><a name="rules">Rules</a></H3>
<blockquote>
<p>A makefile contains a sequence of statements that are used to build a
database of rules. The elements of a makefile rule are targets,
prerequisites, and commands. Typically, targets and prerequisites are
names of files. A makefile rule is a nonempty list of targets
terminated by a colon, a list of prerequisites terminated by a
semicolon, and optionally, a sequence of commands delimited by curly
braces. A rule that keeps file <TT>A.class</TT> consistent with
<TT>A.java</TT> follows.
<blockquote>
<pre>
"A.class": "A.java"; {
exec "javac" "-g" "A.java";
}
</pre>
</blockquote>
<p>This rule runs the Java compiler when <TT>A.class</TT> is older than
<TT>A.java</TT> or nonexistent.
<p>A makefile rule without commands adds prerequisites to the end of a
target's list of prerequisites. For each target, only one makefile
rule can contain commands.
<P>Internally, there is one rule for each target. The interpretation
of a makefile rule depends on whether its target exists. When the
target does not exist, each prerequisite is checked for consistency in
textual order, and then the rule's commands are executed
sequentially. The rule fails if an error is detected while running a
command or if the rule has no prerequisites and no commands. A target
with no rule implied by the makefile behaves as if it is the target of
a rule with no prerequisites and no commands.
<P>When the target exists, the rule's commands are executed only if
the target is in an inconsistent state. Each prerequisite is checked
for consistency in textual order. The target's state is consistent if
the consistency check of the prerequisites found they were all
consistent, each prerequisite exists, and no prerequisite is younger
than the target. When the target is in an inconsistent state, the
rule's commands are executed sequentially. The rule fails if an error
is detected while running a command.
<p>Errors generated by commands are ignored when a command is preceded
by the '-' character.
</blockquote>
<H3><a name="file names">File Names</a></H3>
<blockquote>
<p>File names are given by strings, which are sequences of characters
delimited by double quotes. The backslash and double quote character
may be included in a string by preceding each character with a
backslash.
<p>The slash character separates the directory and file components in
a file name. When running commands and testing for the existence of
files, the slash character is replaced by the character appropriate
for the host, which is the first character of the system property
<code>file.separator</code>.
<p>The semicolon character separates file names in a path list.
When running commands and testing for the existence of
files, the semicolon character is replaced by the character appropriate
for the host, which is the first character of the system property
<code>path.separator</code>.
<p>To enhance portability, file names should contain only the
alphanumeric, the period, the underscore, and the separator
characters described above. <tt>jmk</tt> treats the asterisk and the
percent sign characters specially in some contexts, so these should be
avoided in file names.
</blockquote>
<H3><a name="assignments">Assignments</a></H3>
<blockquote>
<p>There are two types of values used to specify rules: lists of strings
and functions. An assignment associates a value with a variable.
An assignment is a identifier and an equal sign, followed by a
semicolon terminated expression sequence that denotes a value.
<blockquote>
<pre>
javac = "javac" "-g";
</pre>
</blockquote>
<p>After the assignment, a reference to the variable is replaced by its
value. A reference to an unassigned variable produces the empty list.
In the following example, <tt>javac</tt> is replaced by two strings.
<blockquote>
<pre>
exec javac "A.java";
</pre>
</blockquote>
<p>Assignments occur while reading the makefile and before any rules are
interpreted.
<p>In common usage, variables are assigned lists of strings and the
elements of the right-hand-side of an assignment are string
constants, variable references, and calls of predefined functions. A
complete description of <a href="#expressions">expressions</a> occurs
later in this document.
</blockquote>
<H3><a name="functions">Functions</a></H3>
<blockquote>
<p>A list of strings can be transformed by a function. A function call is
delimited by parenthesis. The first element of the call is an
expression, which is usually the variable of a predefined function.
The parameters to the call are comma separated expression sequences.
A description of each predefined function follows.
<dl>
<dt><tt>(subst</tt> <em>pattern</em>, <em>replacement</em>,
<em>list</em><tt>)</tt>
<dd>
The function <tt>subst</tt> produces a list of the same
length as <em>list</em>. Each string in the list is the result of
replacing every non-overlapping occurrence of <em>pattern</em> by
<em>replacement</em> in the corresponding element of <em>list</em>.
<p>For example,
<blockquote>
<pre>
(subst "a", "A", "java" "class")
</pre>
</blockquote>
produces the value <tt>"jAvA" "clAss"</tt>.
<p>
<dt><tt>(patsubst</tt> <em>pattern</em>, <em>replacement</em>,
<em>list</em><tt>)</tt>
<dd>
The function <tt>patsubst</tt> produces a list of the same
length as <em>list</em>. Each string in <em>list</em> that matches
<em>pattern</em> is replaced with <em>replacement</em>. The pattern
may contain a percent sign which acts as a wild card, matching any
number of any characters within a string. A pattern without the
percent sign behaves as if it starts with a percent sign.
<p>If <em>replacement</em> contains any number of percent signs, each
is replaced by the text that matched the percent sign in <em>pattern</em>.
A replacement without the percent sign behaves as if it starts with a
percent sign.
<p>For example,
<blockquote>
<pre>
(patsubst ".c", ".o", "a.c" "b.c")
</pre>
</blockquote>
produces the value <tt>"a.o" "b.o"</tt>.
<p>
<dt><tt>(cat</tt> <em>list</em><tt>)</tt>
<dd>
The <tt>cat</tt> function concatenates all the strings in
<em>list</em>. When there are no strings in <em>list</em>, it returns
a list with a single null string.
<p>For example,
<blockquote>
<pre>
(cat "a/b" ":" "c/d" ":" "e/f")
</pre>
</blockquote>
produces the value <tt>"a/b:c/d:e/f"</tt>.
<p>
<dt><a name="glob"></a><tt>(glob</tt> <em>list</em><tt>)</tt>
<dd>
The <tt>glob</tt> function expands file names that contain the wild
card character asterisk. Each string in <em>list</em> is translated
into a file name which uses the host's separators. All file
separators in the file name must precede every wild card. A file name
with wild cards is expanded into a list of file names from the given
directory that match the pattern. A file name is added to the output
after replacing the host's separator characters by the generic ones.
<p>For example, if the directory <tt>pkg</tt> contains two files,
<tt>"A.java"</tt> and <tt>"B.java"</tt>,
<blockquote>
<pre>
(glob "pkg/*.java")
</pre>
</blockquote>
produces the value <tt>"pkg/A.java" "pkg/B.java"</tt>.
<p>
<dt><tt>(dirs</tt> <em>list</em><tt>)</tt>
<dd>
The function <tt>dirs</tt> produces a list of all directories in the
files named in <em>list</em>.
<p>For example, if the directory <tt>a</tt> contains <tt>b</tt> and
<tt>c</tt>, and <tt>c</tt> contains directory <tt>d</tt>,
<blockquote>
<pre>
(dirs "a")
</pre>
</blockquote>
produces the value <tt>"a" "a/b" "a/c" "a/c/d"</tt>.
<p>
<dt><tt>(getprop</tt> <em>list</em><tt>)</tt>
<dd>
The function <tt>getprop</tt> uses each string in <em>list</em>
as a key into the system properties. If the system has a property
associated with the key, that string is added to the output after
replacing the host's separator characters with the generic ones.
<p>For example,
<blockquote>
<pre>
(getprop "user.dir")
</pre>
</blockquote>
produces the user's current directory using the generic separators.
<p>
<dt><tt>(join</tt> <em>prefixes</em>, <em>suffixes</em><tt>)</tt>
<dd>
The function <tt>join</tt> concatenates each string in
<em>prefixes</em> with every string in <em>suffixes</em>.
<p>For example,
<blockquote>
<pre>
(join "A" "B", ".java" ".class")
</pre>
</blockquote>
produces <tt>"A.java" "A.class" "B.java" "B.class"</tt>.
<p>
<dt><tt>(equal</tt> <em>list1</em>, <em>list2</em><tt>)</tt>
<dd>
The function <tt>equal</tt> returns a list containing the
string <tt>"true"</tt> if <em>list1</em> and <em>list2</em> are the
same, otherwise, it returns the empty list. This function is most
often used in the test of a <a href="#conditionals">conditional
statement</a> or a <a href="#conditional_expressions">conditional
expression</a>.
<p>For example,
<blockquote>
<pre>
(equal "A" "B", "A" "B")
</pre>
</blockquote>
produces <tt>"true"</tt>.
<p>
<dt><tt>(first</tt> <em>list</em><tt>)</tt>
<dd>The function <tt>first</tt> returns the first string in
<em>list</em> or the empty list if <em>list</em> is empty.
<p>For example,
<blockquote>
<pre>
(first "A" "B" "C")
</pre>
</blockquote>
produces <tt>"A"</tt>.
<p>
<dt><tt>(rest</tt> <em>list</em><tt>)</tt>
<dd>The function <tt>rest</tt> returns all but the first string in
<em>list</em> or the empty list if <em>list</em> is empty.
<p>For example,
<blockquote>
<pre>
(rest "A" "B" "C")
</pre>
</blockquote>
produces <tt>"B" "C"</tt>.
<p>
<dt><tt>(load </tt> <em>class</em><tt>)</tt>
<dd>The function <tt>load</tt>
dynamically loads a class that implements the
<tt>Function</tt> interface, and returns a new instance of the class.
<pre>
package edu.neu.ccs.jmk;
public interface Function
extends Value
{
String getName();
/**
* Invoke this function.
* @param args parameters to the function
* @param list a string list
* @return result of invocation appended to the list
* (if list is non-null, result must be a string list)
* @exception Exception if invocation failed
*/
Value invoke(Value[] args, StringList list) throws Exception;
}
</pre>
<p>An example of a loadable function is in
<tt>edu.neu.ccs.jmk.ReverseFunction</tt>.
</dl>
</blockquote>
<H3><a name="commands">Commands</a></H3>
<blockquote>
<p>Commands are executed when a target is inconsistent. A command is an
operator followed by a semicolon terminated expression sequence. When
the command is executed, the operands of the command are produced by
evaluating the expression sequence, which must produce a list of
strings. The evaluation occurs in an environment in which the
following variables are bound.
<dl>
<dt><tt>@</tt>
<dd>
The <tt>@</tt> variable is bound to the target of the
current rule.
<dt><tt><</tt>
<dd>
The <tt><</tt> variable is bound to the first
prerequisite of the rule if there is one, otherwise, it is bound to
the null list.
<dt><tt>?</tt>
<dd>
The <tt>?</tt> variable is bound to the list of
prerequisites that are out of date with respect to current target.
<dt><tt>%</tt>
<dd>
In rules that receive their commands from a rule pattern,
the <tt>%</tt> variable is bound to the characters in the
target that match the wild card in the rule pattern's target.
Otherwise, the <tt>%</tt> variable is bound to
the null list.
<dd>
</dl>
<p>The generic separators in each operand are replaced by the host's
separators before they are given to the operator.
<P>The operator determines the method invoked on the operands used to
implement a command.
<dl>
<dt><tt>exec</tt>
<dd>
The <tt>exec</tt>
operator executes a command in a separate process using a Java runtime
exec method.
<dt><tt>delete</tt>
<dd>
The <tt>delete</tt> file operator deletes the named files.
<dt><tt>delall</tt>
<dd>
The <tt>delall</tt> file operator deletes the named files.
If the file names a directory, it recusively deletes its contents.
<dt><tt>mkdir</tt>
<dd>
The <tt>mkdir</tt> file operator creates the named directories.
<dt><tt>mkdirs</tt>
<dd>
The <tt>mkdirs</tt> file operator creates the named directories,
including any necessary parent directories.
<dt><tt>copy</tt>
<dd>
The <tt>copy</tt> file operator copies a file.
<dt><tt>rename</tt>
<dd>
The <tt>rename</tt> file operator renames a file.
<dt><tt>create</tt>
<dd>
The <tt>create</tt> operator creates a file given by its first operand
and than writes any remaining operands into the file as separate lines
of text.
<dt><tt>note</tt>
<dd>
The <tt>note</tt> operator does nothing. It is used to print notes
during a make run.
<dt><tt>forname</tt>
<dd>
The <tt>forname</tt> operator dynamically loads and executes a Java
object provided with the makefile. The first operand must name a
class that implements the Operator interface given below.
<pre>
package edu.neu.ccs.jmk;
public interface Operator
{
String getName();
/**
* Execute the operation specified by the operator.
* @param args parameters to the operation
* @param out place to write messages
* @exception CommandFailedException if operation failed
*/
void exec(String[] args, java.io.PrintWriter out)
throws CommandFailedException;
}
</pre>
<p>An example of a dynamically loadable operator is in
<tt>edu.neu.ccs.jmk.ReverseOperator</tt>.
<p>The class that starts <tt>jmk</tt> is edu.neu.ccs.jmk.Make.
It implements the Operator interface
allowing the invocation of <tt>jmk</tt> from commands in a makefile.
<pre>
make = "edu.neu.ccs.jmk.Make";
"all":;
{
forname make "-d" "-f" "edu/neu/ccs/jmk/tester.jmk";
}
</pre>
</dl>
<p>The five file operators expand a file name with asterisks into a list
of file names from the given directory that match the pattern. The
restrictions on the pattern are the same as the ones for the <a
href="#glob"><tt>glob</tt></a> function. The expansion occurs when
the command executes.
<p>If the operator of a command is preceded by the '-' character,
errors that occur as the command executes are ignored.
</blockquote>
<H3><a name="rule patterns">Rule Patterns</a></H3>
<blockquote>
<p>A target with no commands explicitly given in the makefile may infer
commands from rule patterns. Syntactically, a rule pattern is the
same as a rule except that the target contains one occurrence of the
wild card character, the percent sign. Prerequisites may also contain
a wild card character. A rule pattern for Java classes follows.
<blockquote>
<pre>
"%.class": "%.java"; {
exec "javac" "-g" <;
}
</pre>
</blockquote>
<p>The list of rule patterns are searched in reverse textual order after
a makefile has been read. A rule pattern is applicable to a target if
the pattern's target is equal to the target after a matching string is
substituted for the wild card character. The match is substituted for
the wild card characters in the pattern's prerequisites and the
prerequisites are added to the front of the target's list of
prerequisites. The match is also the value of the percent sign
variable in commands inferred by the pattern.
</blockquote>
<H3><a name="special targets">Special Targets</a></H3>
<blockquote>
<p>A makefile rule with the target <tt>".PHONY"</tt> declares that its
prerequisites are not the names of files. When one of the
prerequisites appears as a target, the interpretation of its
associated rule always assumes the target does not exist.
</blockquote>
<H3><a name="file inclusion">File Inclusion</a></H3>
<blockquote>
<p>The <tt>include</tt> statement tells <tt>jmk</tt> to suspend reading
the current makefile and read one or more other makefiles before
continuing. The statement is a line in the makefile that looks like
this:
<blockquote>
<p><tt>include</tt> List ;
</blockquote>
<p>where List evaluates to a list of strings, each is used as a file name.
</blockquote>
<H3><a name="conditionals">Conditionals</a></H3>
<blockquote>
<p>A conditional statement causes part of a makefile to be obeyed or ignored
depending on the value of a list of strings. An empty list counts as
false, and a nonempty list of strings counts as true. The syntax is the
traditional if-then-else-end syntax, where the else part is optional:
<blockquote>
<p><tt>if</tt> List <tt>then</tt> Statements <tt>end</tt>
</blockquote>
<p>or
<blockquote>
<p><tt>if</tt> List <tt>then</tt> Statements
<tt>else</tt> Statements <tt>end</tt>
</blockquote>
<p>For example,
<blockquote>
<pre>
if (equal "Solaris", (getprop "os.name")) then
include "sun.jmk";
end
</pre>
</blockquote>
<p>includes the file <tt>"sun.jmk"</tt> when running on a Solaris machine.
</blockquote>
<H3><a name="expressions">Expressions</a></H3>
<blockquote>
<p>An expression evaluates to a value or fails to terminate. A value is
either a list of strings or a function.
<p>There are three types of expressions. An expression is either an
item, a list, or a block. A list is a sequence of zero or more items.
If a list contains no items, it evaluates to the empty list of
strings. If the list contains one item, the value of the list is the
value of the item. Otherwise, each item in the list must produce a
list of strings, all of which are concatenated to produce the value of the
list.
<p><a href="#block">Blocks</a> are described later, and
the various categories of items are described next. In what
follows, Item stands for an expression that is an item, List for a
list, and Identifier stands for a Java Identifier or one of the four
characters <tt>@</tt>, <tt><</tt>, <tt>?</tt>, or <tt>%</tt>. The
pattern Thing... indicates zero or more Things, and Thing,,, indicates
one or more Things separated by commas.
<h4>String Constant</h4>
<p>Syntax: <tt>"</tt> Characters... <tt>"</tt>
<p>A string constant evaluates to a list of strings of length one.
<h4>Variable Reference</h4>
<p>Syntax: Identifier
<p>The language of expressions is lexically scoped. There are two
types of variables, lexical and global.
<p>Every lexical variable is introduced by a binding construct, which
is either a block expression, a function constant, or a do loop. A
binding construct binds lexical variables to values. A reference to
the variable evaluates to the value.
<p>Each global variable is bound to a location. An assignment
statement overwrites the value in the variable's location. A
reference to a global variable evaluates to the value in its location.
The location of a variable which is not predefined initially contains
the empty list of strings.
<h4>Function Call</h4>
<p>Syntax: (Item List,,,)
<p>The operands in List,,, are evaluated in order, and the operator
Item is evaluated. The operator must evaluate to a function which is
invoked with the values of the operands.
<h4>Function Constant</h4>
<p>Syntax: <tt>function</tt> (Identifier,,,) Block end
<p>A function constant evaluates to a function. When the value is
invoked with some arguments, the lexical variables named by Identifier,,,
are bound to the arguments and the block is evaluated.
<a name="block"></a>
<h4>Block</h4>
<p>Syntax: { Block }
<br>
where Block <tt>-></tt> Assignment... List
<p>A block is a sequence of zero or more lexical assignments followed
by a list. When the block is a list, the block evaluates to the value
of the list. Otherwise the block has the form
<blockquote>
<p>Identifier = List ; Block
</blockquote>
<p>where Identifier names a lexical variable.
When List is not a function constant, the value is equivalent to
evaluating List, binding the variable to value of the list, and then
evaluating Block.
<p>For example,
<blockquote>
<pre>
z = "a"; z z
</pre>
</blockquote>
<p>Evaluates to <tt>"a" "a"</tt>.
<p>When List is a function constant, the scope of the variable
includes List in addition to Block.
<p>For example,
<blockquote>
<pre>
g = function(x, y)
if y then
(g x y,)
else
x
end
end;
(g "a", "b")
</pre>
</blockquote>
<p>Evaluates to <tt>"a" "b"</tt>.
<a name="conditional_expressions"></a>
<h4>Conditional Expression</h4>
<p>Syntax: <tt>if</tt> List <tt>then</tt> Block1 <tt>else</tt> Block2 <tt>end</tt>
<p>If List evaluates to a nonempty list of strings, the conditional
evaluates to the value of Block1. If List evaluates to the empty
list strings, the conditional evaluates to the value of Block2.
<p>For example, to compute the directories under edu that contain
source files,
<blockquote>
<pre>
# Predicate for filter
dir_has_src = function(dir)
(glob (cat dir "/*.java"))
end;
# Filter out elements of list
# that do not satisfy pred
filter = function(pred, list)
if list then
if (pred (first list)) then
(first list) (filter pred, (rest list))
else
(filter pred, (rest list))
end
else
end
end;
dirs_with_source
= (filter dir_has_src, (dirs "edu"));
</pre>
</blockquote>
<h4>Do Loop</h4>
<p>Syntax: <tt>do</tt> Identifier0 (Initializer,,,) Block end
<br>
where Initializer <tt>-></tt> Identifier1 = List1
<p>A do loop is an abbreviation for
<blockquote>
<p>{ Identifier0 = <tt>function</tt>(Identifier1,,,) Block <tt>end</tt>;
(Identifier0 List1,,,) }
</blockquote>
<p>For example,
<blockquote>
<pre>
do h(x = "a", y = "b")
if y then
(h x y,)
else
x
end
end
</pre>
</blockquote>
<p>Evaluates to <tt>"a" "b"</tt>.
</blockquote>
<H3><a name="example">Example</a></H3>
<blockquote>
<pre>
# $Id: jmk.html,v 1.3 2001/12/06 14:48:39 ramsdell Exp $
# To make the system, run the command:
# $ java -jar jmk.jar
# in the root directory.
# jmk can be found at http://jmk.sourceforge.net.
# Other make targets: all clean doc
# Edit the following three assignments to fit your system.
# Names to invoke Sun's tools:
javac = "javac";
jar = "jar";
javadoc = "javadoc";
# javac flags
classpath = "." ;
javaflags = "-O" "-deprecation"
"-sourcepath" "src"
"-classpath" classpath
"-d" ".";
# sources file names
srcs = (glob (join (dirs "src"), "/*.java"));
resources = "resources";
includes = (glob (join resources, "/*"));
files = "makefile.jmk" "dutmv.html" "license.txt" "dutmv.sh" "pack.sh";
target = "dutmv.jar";
mf="src/dutmv.mf";
timestamp = "timestamp";
# Packages for javadoc
pkg = "org.mitre.treemap" "org.mitre.dutmv";
"all": timestamp target;
timestamp: srcs; {
exec javac javaflags ?;
create timestamp;
}
target: srcs includes files; {
exec jar "cfm" @ mf "org" resources "src" files;
}
"clean": ; {
delall timestamp "org" target;
}
"api": ; {
mkdir @;
}
"doc": "api"; {
exec javadoc
"-sourcepath" "src"
"-classpath" classpath
"-d" "api"
pkg;
}
".PHONY": "all" "clean" "doc";
</pre>
<h4>The Makefile used by jmk</h4>
<pre>
# A makefile file for jmk -- Make in Java
javaflags = "-O";
# jmk is in one package.
pkg = "edu.neu.ccs.jmk";
srcdir = (subst ".", "/", pkg);
# srcs contains all the Java source files.
srcs = (glob (join srcdir, "/*.java"));
jar = "jmk.jar";
"all": jar; # all is the default target.
# The following rule only compiles out of date
# source files. Sometimes the clean target
# must be used to force the compilation of the
# entire system, such as when an inherited class
# is changed.
jar: srcs;
{
exec "javac" javaflags ?;
exec "jar" "cf" @ "edu";
}
# doc is the target for running javadoc.
"doc": "docs" "docs/index.html";
"docs":;
{
mkdir @;
}
"docs/index.html": srcs;
{
exec "javadoc" "-package" "-d" "docs" pkg;
}
"clean":;
{
delete (join srcdir, "/*.class") jar;
}
".PHONY": "clean" "doc" "all";
</pre>
</blockquote>
<H3><a name="grammar">Grammar</a></H3>
<blockquote>
<p>The makefile loader expects input to conform to the grammar given
below. Comments start with the sharp sign character
(<tt>#</tt>) and continue to the end of the line. In the grammar,
syntactic categories begin with an uppercase letter. The pattern
Thing... indicates zero or more Things, Thing,,, indicates one or more
Things separated by commas, and vertical bar indicates alternatives.
<blockquote>
<p>Makefile <tt>-></tt> Statement Statement...
<br>
Statement <tt>-></tt> Assignment | Rule | Inclusion | Conditional
<br>
Assignment <tt>-></tt> Identifier = List ;
<br>
List <tt>-></tt> Item...
<br>
Item <tt>-></tt> String | Identifier | (Item List,,,)
| { Block }
| <tt>if</tt> List <tt>then</tt> Block <tt>else</tt> Block <tt>end</tt>
| <tt>function</tt> (Identifier,,,) Block <tt>end</tt>
| <tt>do</tt> Identifier (Initializer,,,) Block <tt>end</tt>
<br>
Block <tt>-></tt> Assignment... List
<br>
Initializer <tt>-></tt> Identifier = List
<br>
Rule <tt>-></tt> Item List : List ; Commands
<br>
Commands <tt>-></tt> | { Command... }
<br>
Command <tt>-></tt> Ignore Operator List ;
<br>
Ignore <tt>-></tt> | -
<br>
Operator <tt>-></tt> <tt>exec</tt> | <tt>delete</tt> |
<tt>delall</tt> | <tt>mkdir</tt> |
<tt>mkdirs</tt> | <tt>copy</tt> | <tt>rename</tt>
| <tt>create</tt> | <tt>note</tt> | <tt>forname</tt>
<br>
Inclusion <tt>-></tt> <tt>include</tt> List ;
<br>
Conditional <tt>-></tt> <tt>if</tt> List <tt>then</tt>
Statement... Alternative <tt>end</tt>
<br>
Alternative <tt>-></tt> | <tt>else</tt> Statement...
<br>
String <tt>-></tt> <tt>"</tt> Characters... <tt>"</tt>
<br>
Identifier <tt>-></tt> JavaIdentifier | <tt>@</tt> | <tt><</tt> |
<tt>?</tt> | <tt>%</tt>
</blockquote>
<p>The JavaIdentifiers that are reserved and not available as
Identifiers are <tt>include</tt>, <tt>if</tt>, <tt>then</tt>,
<tt>else</tt>, <tt>end</tt>, <tt>function</tt>, and <tt>do</tt>.
</blockquote>
<h2><a name="options">OPTIONS</a></h2>
<blockquote>
<dl>
<dt><tt>-f</tt> <em>filename</em>
<dd>
Use <em>filename</em> for the makefile.
The default is <tt>makefile.jmk</tt>.
<dt><tt>-d</tt>
<dd>
Print additional information during a <tt>jmk</tt> run.
<dt><tt>-n</tt>
<dd>
Print but do not run commands during a <tt>jmk</tt> run.
<dt><tt>-w</tt>
<dd>
Use an AWT window for <tt>jmk</tt> output.
<dt><tt>-s</tt>
<dd>
Use a Swing window for <tt>jmk</tt> output.
<dt><tt>-v</tt>
<dd>
Print the version number.
</dl>
</blockquote>
<h2><a name="properties">PROPERTIES</a></h2>
<blockquote>
<p>Window properties are set by placing the file <tt>jmk.properties</tt>
in the class path. The following properties can be set in the
properties file.
<dl>
<dt><tt>jmk.columns:</tt> <em>columns</em>
<dd>
Create a transcript window that displays <em>columns</em> characters
on a line of text.
<dt><tt>jmk.rows:</tt> <em>rows</em>
<dd>
Create a transcript window that displays <em>rows</em> lines of text.
<dt><tt>jmk.font:</tt> <em>font</em>
<dd>
Use <em>font</em> as the default font.
</dl>
</blockquote>
<h2>ACKNOWLEDGMENTS</h2>
<blockquote>
<p>Make in Java was inspired by and is loosely based on the Unix <a
href="#POSIX92">make</a> utility. Thanks go to Richard Stallman and
Roland McGrath for making the sources and documentation for <a
href="#StallmanMcGrath96">GNU make</a> available to all.
</blockquote>
<h2>REFERENCES</h2>
<blockquote>
<dl>
<dt><a name="POSIX92"></a>[POSIX92]
<dd>
IEEE Computer Society.
<em>IEEE Standard for Information Technology--Portable Operating
System Interface (POSIX)--Part 2: Shell and Utilities</em>, volume 1.
Institute of Electrical and Electronics Engineers, Inc., New York,
NY, USA, 1992.
Std 1003.2-1992.
pp. 666-679.
<dt><a name="StallmanMcGrath96"></a>[StallmanMcGrath96]
<dd>
Richard M. Stallman and Roland McGrath.
<em>GNU Make</em>.
Free Software Foundation, 0.51 edition, 1996.
</dl>
</blockquote>
<h2>LICENSE</h2>
<blockquote>
<p>The <tt>jmk</tt> program including its sources and documentation
is covered by the <a href="lesser.txt">GNU Lesser General Public License</A>.
</blockquote>
<h2>AUTHOR</h2>
<blockquote>
<p><a href="http://jmk.sourceforge.net">John D. Ramsdell</a>
</blockquote>
<p>[<a href="#top">Top</a>]
</BODY>
</HTML>
|