Building Racket in Linux

The Racket website has documentation on how to clone the PLT repository.

git clone git://git.racket-lang.org/plt.git

Next, the src/README file has all the gory details on how to build Racket. The procedure is rather straightforward for Linux:

mkdir build
cd build
../configure
make
make install

I’m yet to figure out how to successfully build racket in Visual C++ (2008 Professional), so that’s the next item on my list.

Update (03/11/11): Actually rather straightforward for Visual C++ as well, run vsvars32.bat to ensure that devenv and other commands are in the path:

cd plt\src\worksp\
"C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat"
build

I got the hint from this thread.


Implementing canvas putImageData’s optional arguments

Bug 498826 is about the HTML canvas putImageData method. It did not implement the optional arguments specified in the WHATWG spec. These optional arguments specify the dirty rectangle for the image data transfer (specifically, these arguments are the coordinates of the top left corner and the dimensions of the dirty rectangle, any of which are allowed to be negative). A quick glance at the description of the algorithm for handling of the optional arguments may not reveal the overall intent of the algorithm. Some of its key aspects are:

  1. Adjusting the dimensions of the rectangle to be positive by shifting the top left corner if necessary (step 2).
  2. Ensuring the top left corner of the dirty rectangle is in the first quadrant (step 3) which effectively eliminates all negative arguments.
  3. Clipping the dirty rectangle to ensure its lower right corner does not extend beyond the bounds of the incoming imagedata’s dimensions (step 4).
  4. Verifying that the newly adjusted dirty rectangle has positive dimensions (step 5), and if so, using the region bounded by the dirty rectangle on the incoming imagedata object as the source for the operation.

The patch is rather straightforward (although admittedly, it was not as straightforward to create on my part). If there are enough arguments to specify a dirty rectangle, then the JS_ValueToECMAInt32 function is used to convert the JavaScript values into integers. The CheckedInt32 and the gfxRect classes do most of the heavy lifting in the patch, and then only the dirty rectangle is redrawn.


Remove unused nsCookieService::SetCookieString argument

Bug 520914 is the only Bugzilla item I got to look at this month – since it required the least amount of time :). All that needed to be done was to remove the aPrompt argument currently in nsICookieService’s SetCookieString method. The locations in need of change were easily located with a simple MXR search.


Practical Example of Artificial Intelligence Principles

While digging around in Bugzilla (as is now my usual daily custom), I came across Bug 580468 – JM: Tune Trace JIT Heuristics. It was interesting following the discussion since it was a perfect illustration of the principles being taught in CS470. Therefore, I wrote up this brief summary of the bug discussion to reinforce to myself how practical these issues are: Practical AI.


Categories: Version Control

Git Exercise

Having not used git that much, I cloned an ANTLR repository and then did my main development (and the associated commits) on the main branch. In order to submit my work, I needed to create one patch file with all the necessary changes. However, git format-patch was creating one .patch file for each commit. Some googling around led me to stackoverflow where the basic outline of how to fix this situation was clear. Based on those suggestions, and the fact that there had been no remote changes that I needed to merge, I came up with:

git checkout -b submission 76b45
git merge --squash master
git commit -a -m "Submission of work..."
git format-patch 76b45

Make location.host and location.hostname return “” for host-less URIs

In the rather straightforward bug 562433, Firefox’s location.host and location.hostname need to return the empty string for host-less URIs instead of throwing an exception. What ends up wasting my time with such 1-minute fixes is figuring out the right test location and the right command to run the test. At least documenting this should save a few minutes next time:

TEST_PATH=dom/tests/mochitest/bugs/test_bug562433.html make -C /c/mozilla/obj mochitest-plain

See the Mochitest automated testing framework documentation for details.


Changing Screen Resolution of Ubuntu in Virtual Box

As suggested on one of the Ubuntu forums, the key here is to install the VirtualBox guest  additions. Having done so on my system, I ran these commands:

cd /media/VBOXADDITIONS_3.2.6_63112/
sudo ./VBoxLinuxAdditions-x86.run

Rebooting my virtual machine and maximizing the VirtualBox window left me running Ubuntu at my native screen resolution of 1680×1050 :).

Update: On VirtualBox 4.1.2, use the virtual machine’s Devices -> Install Guest Additions … menu item. The ISO Disc should be automatically mounted, and allowing autorun to continue should complete the installation. The Virtualbox website has more information on guest additions.


Excel Macro to Merge First Two Cells of Each Column

Once in a while you may run into an Excel spreadsheet in which the first two rows have been used for column labels as a way to wrap text. Cleaning this up involves the straightforward task of merging the first two cells of each column. This rather tedious task is thankfully easily automated with an Excel VBA macro. See the code samples below:

Sample 1:

Sub MergeFirstTwoCellsInEachColumn()
    ' Bound the range selection as Ctrl+End would.
    ' See http://www.ozgrid.com/forum/showthread.php?t=17070
    Dim lastCol As Integer
    Dim row1LastCol As Integer
    Dim row2LastCol As Integer

    row1LastCol = Range("A1").currentRegion.End(xlToRight).Column
    row2LastCol = Range("B1").currentRegion.End(xlToRight).Column

    lastCol = WorksheetFunction.Max(row1LastCol, row2LastCol)

    ' Select the first two rows
    Rows("1:2").Select

    ' Merge the first two cells of each column
    For i = 1 To lastCol
        Dim columnCells

        columnCells = Selection.Columns(i).Cells

        Dim finalColumnText

        ' Concatenate contents of cells in rows 1 and 2 in this column
        ' separating them with a space
        finalColumnText = Trim(columnCells(1, 1) & " " & columnCells(2, 1))

        ' Clear both cells and store the new value in the first cell
        Selection.Columns(i).Value = ""
        Selection.Columns(i).Cells(1, 1) = finalColumnText

        ' Merge the cells
        Selection.Columns(i).Merge
    Next i
End Sub

One side effect of this code is that it merges cells in the columns up to the end of the range that would be selected if you pressed Ctrl + End. The columns to the right of this range are not merged, in effect leaving two rows in the spreadsheet for the headings. Enter Sample 2:

Sub MergeFirstTwoCellsInEachColumn2()
    ' Select the first two rows
    ' Bound the range selection as Ctrl+End would.
    ' See http://www.ozgrid.com/forum/showthread.php?t=17070
    Dim lastCol As Integer
    Dim row1LastCol As Integer
    Dim row2LastCol As Integer

    row1LastCol = Range("A1").currentRegion.End(xlToRight).Column
    row2LastCol = Range("B1").currentRegion.End(xlToRight).Column

    lastCol = WorksheetFunction.Max(row1LastCol, row2LastCol)

    ' Select the first two rows
    Rows("1:2").Select

    ' Combine the contents of the first two cells of each column
    For i = 1 To lastCol
        Dim columnCells
        Dim finalColumnText

        columnCells = Selection.Columns(i).Cells

        ' Concatenate contents of cells in rows 1 and 2 in this column
        ' separating them with a space
        finalColumnText = Trim(columnCells(1, 1) & " " & columnCells(2, 1))

        ' Store the new value in the first cell
        Selection.Columns(i).Cells(1, 1) = finalColumnText
    Next i

    ' Delete row 2
    Rows("2").Delete
End Sub

In MergeFirstTwoCellsInEachColumn2, the new column headings are simply written to the top cell and when this has been done for all columns, row two is deleted. This is perhaps the more elegant solution for most spreadsheets. A few comments on the code:

row1LastCol = Range("A1").currentRegion.End(xlToRight).Column

This line determines the last non-blank column in row 1. The currentRegion property of the Range object returns a “range bounded by any combination of blank rows and blank columns”. When called on the Range(“A1”) object, it effectively selects the same region as Ctrl + End. It’s then straightforward to inspect the End property and get the corresponding Column.

lastCol = WorksheetFunction.Max(row1LastCol, row2LastCol)

lastCol is the greater of the last columns in the first two rows (needed in case both rows don’t have the same column number as the last column). This lastCol value is important because without it, Excel will chew lots of CPU running the macro on all the columns beyond those spanned by the input data.


Categories: JPF

Where is the org.apache.bcel package located?

While reading through the JPF core source code (and other JPF extensions as well), you may come across classes like JavaClass, ClassParser, etc. These classes are part of the Byte Code Engineering Library and are in the org.apache.bcel package. In case you are interested in easily reading the corresponding source in your favorite editor (Eclipse in my case), download the appropriate source from the BCEL download page.


Categories: JPF

Installing and Running Java Path Finder (JPF)

The NASA AMES site has the necessary documentation for this procedure (and all else JPF). Nonetheless, I’m documenting the process here to save me some time the next time I need to do this since all commands will be in one spot.

For this project, I was running a Windows 7 box but these instructions should be easy to port to Linux other platforms. You will need to install the latest version of the Java Runtime Environment (JRE) and the Java Development Kit (JDK). Without the JDK installed (and included in your PATH environment variable), you will get the famous “javac is not recognized as an internal or external command.” These tools can be found on Sun’s website. Proceed to the command line and verify that these commands list the most up to date recent Java version available (JDK 6 Update 20 as of this posting).

javac -version
java -version

You will also need Mercurial to install JPF. For windows users, it may be easier to install TortoiseHg since it will automatically add the hg command to the PATH [needs confirmation]. On my system, I installed the JPF core into a JPF folder I created in my home folder. To do so, drop to the command line then:

cd %HOMEPATH%
mkdir jpf
cd jpf
hg clone http://babelfish.arc.nasa.gov/hg/jpf/jpf-core

To build the source and run the test suite:

cd jpf-core
bin/ant test

This ant script requires the JAVA_HOME environment variable to be set (on Windows anyway). I set it to my JDK installation path.

Note: for my initial checkout, I cloned http://babelfish.arc.nasa.gov/hg/jpf but expecting to get the whole tree, but the subrepositories were empty! All the extensions must be separately cloned. Before running the Racer example mentioned on the JPF page, you need to set up the site.properties file. This file should be placed in a folder called “.jpf” in the user’s home directory. Attempting to run the example before setting up this file will give you the error message: “gov.nasa.jpf.JPFClassLoaderException: no classpath entry for gov.nasa.jpf.JPF found (check site.properties)”.

cd %HOMEPATH%
mkdir .jpf
cd .jpf

echo # JPF site configuration > site.properties
echo # >> site.properties
echo jpf-core = ${user.home}/jpf/jpf-core >> site.properties
echo # >> site.properties
echo # numeric extension >> site.properties
echo jpf-numeric = ${user.home}/jpf/jpf-numeric >> site.properties
echo extensions+=${jpf-numeric} >> site.properties
echo # >> site.properties
echo # annotation-based program properties extension >> site.properties
echo jpf-aprop = ${user.home}/jpf/jpf-aprop >> site.properties
echo extensions+=,${jpf-aprop} >> site.properties
echo # >> site.properties
echo #... and all your other installed projects >> site.properties
echo # >> site.properties

Verify that site.properties has been successfully created. Now we can run the example:

java -jar build/RunJPF.jar src/examples/Racer.jpf

Et voila! You should now see output like:

JavaPathfinder v5.0 - (C) 1999-2007 RIACS/NASA Ames Research Center

====================================================== system under test
application: Racer.java

====================================================== search started: 7/1/10 5:51 PM
10
10

====================================================== error #1
gov.nasa.jpf.listener.PreciseRaceDetector
race for: "int Racer.d"
  main at Racer.main(Racer.java:16)
                "int c = 420 / racer.d;               // (4)"  : getfield
  Thread-0 at Racer.run(Racer.java:7)
                "d = 0;                               // (2)"  : putfield

====================================================== snapshot #1
thread index=0,name=main,status=RUNNING,this=java.lang.Thread@0,target=null,priority=5,lockCount=0,suspendCount=0
  call stack:
        at Racer.main(Racer.java:16)

thread index=1,name=Thread-0,status=RUNNING,this=java.lang.Thread@272,target=Racer@271,priority=5,lockCount=0,suspendCount=0
  call stack:
        at Racer.run(Racer.java:7)

====================================================== results
error #1: gov.nasa.jpf.listener.PreciseRaceDetector "race for: "int Racer.d"    main at Racer.main(Race..."

====================================================== statistics
elapsed time:       0:00:00
states:             new=9, visited=1, backtracked=4, end=2
search:             maxDepth=5, constraints=0
choice generators:  thread=8, data=0
heap:               gc=8, new=278, free=32
instructions:       2956
max memory:         15MB
loaded code:        classes=68, methods=988

====================================================== search finished: 7/1/10 5:51 PM