September 14th, 2007

Regular expressions for converting code-indentation spaces to tabs in TextPad

I’ve never been a fan of using tabs to indent my code; I prefer spaces. Writing code is an art form, and when you use tabs to indent, you can’t assume that it will still look pretty on someone else’s machine, or in another application, etc., since tab sizes are platform-dependent and–although usually user-definable–the default size (typically 8 spaces, I think) tends to be much larger than my own 2-4 space indentation style.

However, some of my co-workers indent with tabs, and others indent with spaces. I’ve found that it’s easier for me to avoid inadvertently messing up existing code when I just bite the bullet and use tabs.

So, what follows are a couple of search/replace regular expressions I’ve recently used in TextPad, to make some existing code more consistent, by converting the spaces to tabs in certain relevant locations.


1. Regular expressions for aligning inline comments with tabs

Find what:   \;( *) {2}(\t*)\/\/
 
Replace with:   \;\1\t\2//

Customization: The number 2, in curly braces (above), should be replaced with the number of spaces that are used for indentation, in the code you’re running this on. In this case, the code was indented in increments of 2 spaces. Sometimes I deal with code that’s indented in increments of 4 spaces, in which case that 2 would change to a 4.

Manner of execution: Run via Replace All, repeatedly, until there are no more matches.

Recommended scope: I used it on a very specific block of selected code. Keep reading for the specific format.

When I used this on a block of code that consisted of variable declarations and //-style comments, it ended up making the comment blocks all line up nicely. Here is an animated GIF1 of a series of screenshots, showing how repeatedly running this expression transformed the comments into tab-indented comments that lined up nicely:

animated progression of screenshots showing comments separated from code with spaces, and eventually just tabs (and all lined up nicely)

I’m not sure how useful this will be, in general, because I think I just kind of lucked out when I got the results that I did. I thought it was worth sharing, though, because it impressed me when it produced results that were better than I had actually envisioned. :)

Two important things to note are:

  • The actual variable declarations (beginning of each line) were already indented with 1 tab.
  • There were a consistent number of spaces between the semicolons ending the variable declarations, and the double slashes starting the comments. While this didn’t help them line up, as spaces, it did make things pretty when the spaces were replaced with tabs.

If you’d like, you can see what my TextPad Replace dialog looked like, so you can see things like which checkboxes are checked, etc. Also, please note that in my TextPad preferences, I have it set to Use POSIX regular expression syntax (as previously mentioned, in another TextPad search/replace expression entry, a couple years ago).


2. Regular expressions for changing leading indentation spaces to tabs

Find what:   ^(\t*) {4}
 
Replace with:   \1\t

Customization: As with the first expression, above, the number in curly braces should be changed to the spacing increment used for indentation, in the code you’re running this on.

Manner of execution: Run via Replace All, repeatedly, until there are no more matches.

Recommended scope: It can be used on a block of selected text, the entire active document, or even on all open documents, if you’re brave and somewhat evil. :)


Footnotes

1 Sorry for using an animated GIF. I’d rather not have something constantly flashing on the page, because it distracts, and resembles an advertisement. I would have preferred another solution, but I racked my brain for over two hours, trying to decide how to present this series of 9 screenshots. I didn’t want to alienate readers who might read this using a feed reader that doesn’t support javascript, and I hate making people click through from the feed to the main site–I strongly prefer full-text rss feeds! Laying the 9 images out horizontally or vertically took up either too much space, or required making the images too tiny to read. In the end, this animated GIF seemed like the best portable way to show the effect I was trying to show. I won’t make a habit of using them, though. :)

[return to top] / [expression 1] / [expression 2]

July 15th, 2006

perl urlencode without libs

$url = “Foo bar com.dx?q=23″;
$url =~ s/([^\w\-\.\@])/$1 eq ” “?”+”:
sprintf(”%%%2.2x”,ord($1))/eg;

print $url;

I don’t remember where I got this, but it must have come in handy for me at some point. Never hurts to have this kind of stuff laying around, just in case.

June 28th, 2006

Making System.out.println() return a String

At some point, recently, I needed to do both of these things in one little Java expression:
- output a String to stdout
- return the same String

System.out.println() returns ‘void’, and you can’t cast void to String, so I struggled with this for a little while. Here’s what I came up with (download here if it looks ugly in the blog):

public class VoidToString
{
public static void main(String[] args)
{
System.out.println(”returned value: [” +
new Object()
{
public String q(String p)
{
System.out.println(”stdout: [” + p + “]”);
return p;
}
}.q(”blah”) + “]”);
}
}


It ended up not working in the context I was trying to use it in, because the 3rd-party API I was using did not appreciate the inner class, but I still thought it was a neat little trick.

April 28th, 2006

Talking over SSL from Java

For the first time in this blog, I’m pleased to present to you a
guest post from my good friend, Jeff Scanlon:


Talking over SSL from Java
————————–When using SSLFactory to talk SSL with a server, or using
the URL class to open an https connection, an error you
might encounter is:

sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target

One solution that worked for me is to add the server certificate
to the cacerts file in the appropriate Java runtime.

Steps:

  1. You must have the server certificate. If you don’t have this
    handy, navigate to the secure website, click on the lock icon
    (in Internet Explorer). Click on “Details” tab and then click
    the “Copy to File…” button. Export the certificate to a DER
    encoded binary X.509 (.CER) file. Let’s say you chose the
    filename example.cer
  2. Copy example.cer to the jre/lib/security directory in the Java
    runtime you are using. If you’re on Windows and the JDK/JRE
    is in C:\jdk1.5.0_04, then the full path is:
    C:\jdk1.5.0_04\jre\lib\security
  3. Import the certificate into the cacerts file by using the
    following command [editor’s note: this is all one command, broken
    into multiple lines for blogging
    ]:

    keytool -import -storepass changeit -file
    example.cer -keystore cacerts
    -alias example

    ‘changeit’ is the default password to the cacerts keystore
    ‘example.cer’ is the filename you used in step #1
    ‘example’ is an arbitrary alias you choose for the certificate
  4. Now try your code and see if it can establish the SSL
    connection. If you get an error like ‘HTTPS hostname
    wrong: should be ____’, then add this code:

    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLSession; // ————————————————-

    HostnameVerifier hv = new HostnameVerifier() {
    public boolean verify(String hostName,
    SSLSession session)
    {
    System.out.println(
    “hostName is [” + hostName +
    “] and session peer host is [” +
    session.getPeerHost() + “]”);
    return(true);
    }
    };

    HttpsURLConnection.setDefaultHostnameVerifier(hv);


    The above code provides a hostname verifier replacement that
    will cause hostname verification to succeed (by always
    returning true). Be aware that using this code does have
    security implications. However, this simplistic verify
    replacement should solve SSL communication problems and
    provide a starting point for implementing a custom verify
    that maintains security.


Jeff has been a good friend of mine for about 16 years, now.
He has been published several times (such as here,
here, and here), and is usually the first person I turn
to for ideas/advice on any programming/computer-related topic. He will definitely be contributing to this blog again in the future.

September 29th, 2005

Comparison of Multiple Select Box Population Performance

I was recently working on developing a web application for a team project at school, when I ran into a little problem. We had a list of 1881 items to put in a select box. That, in itself, was a no-brainer. The problem was, we wanted to have 10 select boxes on this page, each with all 1881 items in it.

So, since I was using JSP, I pulled the entire list of OPTION tags out and stuck it in a separate file, then used the include directive, like:

< %@ include file=”optionList.jsp” % >

inside each of the 10 sets of SELECT tags, so the list was only stored in one place. However, this optionList.jsp file was 59KB, and this page needed to load reasonably fast, despite being served off my home server with a cable modem, and viewed at school with a flaky, unreliable wireless connection. Therefore, a page with over 590KB worth of text/html was just not going to work.

Well, I’ve dealt with manipulating select boxes using JavaScript before, so I decided to try putting all the options into an array of strings, and looping through each select box, and each element of the option array, to add all the options. Well, this worked fine in Firefox, but in IE, it took a ridiculous amount of time (roughly 2 minutes). With that kind of performance, we might as well just load the 590+ KB original page!

So, I did some research into javascript optimization, and explored the W3C DOM spec extensively. I created about 10 different methods of populating the select boxes, and ran each of them with timing code around them, in IE and Firefox. Eventually, I found a solution that performed reasonably well in IE and Firefox, and used it for the team project.

The key lines of code are:

var tmp = document.getElementById(’selectBox_0′).cloneNode(true);
// …
var selectN = document.getElementById(’selectBox_’ + pickNum);
// …
selectN.parentNode.replaceChild(tmp, selectN);

Basically, I created the first select box one option at a time, then cloned that select box object (with the ‘true’ parameter, to clone all child nodes as well) and replaced all the other select boxes with the clones. Then, I set some properties on the clones to make them unique (IDs, default blank options, etc). Dramatically faster than the other.

I’ve put together a benchmark page to test/demonstrate the original method of populating the select boxes (adding one option at a time, to one select box at a time), versus the method I found that worked so well. Then I ran the benchmark on several browsers, on several computers, and had some friends and co-workers try it, too. You can find the benchmark page here:

http://www.oatmealcookies.org/blogdl/
performance/MultiSelectPerformance.html

The benchmark results, as I’ve recorded them so far, can be found in a comma-delimited text file at:

http://www.oatmealcookies.org/blogdl/
performance/MultiSelectPerformance.csv

I recently found out that Opera 8.02 works about as fast as Firefox, even faster in some cases. I was impressed that the code that I’d tested thoroughly in IE and Firefox (but not Opera) actually RAN without errors, but the fact that it ran so fast was pretty cool.

Please feel free to run the benchmark and send me your results! The way that these measurements have been recorded is:

Click ‘Run All’.. when tests are complete (ranges from 12 seconds to 5 minutes, depending on browser and platform), click ‘Save Data’, which populates a textarea at the bottom of the page, and selects it, so you can then copy it to your clipboard and post it in a comment on this blog entry. Please include all fields that are in that CSV file, including browser versions, OS, processor speed, etc.