Monday, October 12, 2009

Doxygen Example

Doxygen is a documentation system for use with many languages, including C++, C, Java, and Python.

First, install Doxygen. Using Ubuntu, I installed the package with:
$ apt-get install doxygen
Next. enter the source directory of a project you're working on and run:
$ doxygen -g
That will create a config file named Doxyfile in the current directory. You can customize it, but we'll accept the defaults for now.

Now begin writing your documentation. Here's an example of documenting a simple C++ program:

#include <iostream>

using namespace std;

/**
* @brief Example class to demonstrate basic Doxygen usage
* @author MLA
*
* This is a simple class to demonstrate how Doxygen is used.
* It implements the Euclidean algorithm to compute the greatest
* common divisor of two numbers.
*/

class Euclid {
public:

/**
* Compute the greatest common divisor of two integers.
*
* @param a first integer
* @param b second integer
* @return greatest common divisor of a and b
*/
static const int gcd(const int a, const int b) {
if (0 == b) return a;
return gcd(b, a % b);
}
};

Finally, run doxygen, which will process the files and generate documentation in the html subdirectory:
$ doxygen
For more details, see the Doxygen homepage.

Monday, August 17, 2009

C++ Constant for PI

Where's the definition for pi? Doesn't C++ provide a constant? What about C?

The C++ standard doesn't provide a value for pi but it's simple to define yourself:

#include <iostream>
#include <cmath> // M_PI is not standard

using namespace std;

class MathConst {
public:
static const long double PI;
};

const long double MathConst::PI = acos((long double) -1);

int main() {
cout.precision(100);
cout << "PI ~ " << MathConst::PI << endl;
}
Output:

$ g++ MathConst.cpp -o pi
$ ./pi
PI ~ 3.14159265358979323851280895940618620443274267017841339111328125
That is accurate to 18 decimal places.

Here's a definition in C:

#include <math.h>
#include <stdio.h>

double pi() {
const double pi = acos((double) - 1);
return pi;
}

int main() {
printf("%.20f\n", pi());
return 0;
}

Wednesday, August 5, 2009

Postgresql: Indexes on Foreign Keys

This query identifies foreign keys that are potentially missing indexes (Postgresql does not create indexes on foreign keys automatically).
/*
  Look for foreign key constraints that are missing indexes on the
  referencing table.

  Orders results by the size of the referencing table, largest first,
  on the assumption that, all else being equal, they are the most likely
  to benefit from the addition of indexes.

  This is only meant as a starting point, and isn't perfect.
  It's possible, for example, that it will report a missing index
  when in fact one is available. e.g., it won't realize that an index on
  (f1, f2) could be used with a fk on (f1). However, it will recognize
  that an index on (f1, f2) can be used with a fk on (f2, f1).

  Usage: psql -q dbname -f pg-find-missing-fk-indexes.sql
*/

CREATE FUNCTION pg_temp.sortarray(int2[]) returns int2[] as '
  SELECT ARRAY(
      SELECT $1[i]
        FROM generate_series(array_lower($1, 1), array_upper($1, 1)) i
    ORDER BY 1
  )
' language sql;

  SELECT conrelid::regclass
         ,conname
         ,reltuples::bigint
    FROM pg_constraint
         JOIN pg_class ON (conrelid = pg_class.oid)
   WHERE contype = 'f'
         AND NOT EXISTS (
           SELECT 1
             FROM pg_index
            WHERE indrelid = conrelid
                  AND pg_temp.sortarray(conkey) = pg_temp.sortarray(indkey)
         )
ORDER BY reltuples DESC
;

Saturday, August 1, 2009

Linux: Download YouTube Videos

Install the youtube-dl script. With Ubuntu:

sudo apt-get install youtube-dl
Next, find the YouTube video you want to download and pass it to the script:

youtube-dl -b -t "http://www.youtube.com/watch?v=aEXFUbSbg1I"
Command-line options:

Usage: youtube-dl [options] video_url

Options:
-h, --help print this help text and exit
-v, --version print program version and exit
-u USERNAME, --username=USERNAME
account username
-p PASSWORD, --password=PASSWORD
account password
-o FILE, --output=FILE
output video file name
-q, --quiet activates quiet mode
-s, --simulate do not download video
-t, --title use title in file name
-l, --literal use literal title in file name
-n, --netrc use .netrc authentication data
-g, --get-url print final video URL only
-2, --title-too used with -g, print title too
-f FORMAT, --format=FORMAT
append &fmt=FORMAT to the URL
-b, --best-quality alias for -f 18
See also: youtube-dl Homepage

Sunday, July 26, 2009

Eight Ways to Convert Tabs to Spaces

A collection of various ways to convert tabs to spaces in Unix/Linux/OS X with standard programs and utilities.
#1 expand/unexpand utilities
expand < input.txt > output.txt

#2 Sed
sed 's/\t/ /g' < input.txt > output.txt

#3 Awk
awk '{ gsub(/\t/, "  "); print }' < input.txt > output.txt

#4 Perl
perl -pe 's/\t/  /g' < input.txt > output.txt

#5 Ruby
ruby -pe '$_.gsub!(/\t/, "  ")' < input.txt > output.txt

#6a Vim editor
:set expandtab
:%retab! 

#6b Vim editor
:%s/\t/  /g

#7 Emacs editor
Set 'indent-tabs-mode' to nil to have tabs automatically converted to spaces.
To convert a region, "M-x untabify" will change tabs to spaces and "M-x tabify" will do the inverse.

#8 cut
cut -f1- --output-delimiter='  ' < input.txt > output.txt

Saturday, July 25, 2009

Web: HTML Encoder

This page will convert HTML special characters into HTML entities. The encoded text can then be inserted into another HTML document or blog posting and the reserved characters (such as < and &) will show up normally.

Enter your text in the form field below. The encoded result will be displayed in the lower field as you type.

Enter HTML to Encode:


HTML Encoded Result: (Click to Select All)

The HTML encoding is performed with this Javascript function:

/* encode html entities */
var char2entity = { '"' : '&quot;', '<' : '&lt;', '>' : '&gt;', '&' : '&amp;', "'" : '&#39;' }; /* IE can't handle &apos; */
function encode_entities(str) {
var rv = '';
for (var i = 0; i < str.length; i++) {
var ch = str.charAt(i);
rv += char2entity[ch] || ch;
}
return rv;
}
See also: handy shell function for html encoding.

Keywords: html encoding, html encoder

Web: Multiple Firefox Profiles with Linux

To run multiple instances of Firefox simultaneously, or run multiple copies with different settings/plugins, start Firefox like this:
firefox -P -no-remote
That will bring up a dialog box that lets you select a profile or create a new one.

Other Firefox command-line options:

Usage: firefox [ options ... ] [URL]
where options include:

X11 options
--display=DISPLAY X display to use
--sync Make X calls synchronous
--no-xshm Don't use X shared memory extension
--xim-preedit=STYLE
--xim-status=STYLE
--g-fatal-warnings Make all warnings fatal

Mozilla options
-height <value> Set height of startup window to <value>.
-h or -help Print this message.
-width <value> Set width of startup window to <value>.
-v or -version Print Firefox version.
-P <profile> Start with <profile>.
-ProfileManager Start with ProfileManager.
-no-remote Open new instance, not a new window in running instance.
-UILocale <locale> Start with <locale> resources as UI Locale.
-safe-mode Disables extensions and themes for this session.
-jsconsole Open the Error console.
-g or --debug Start within /usr/bin/gdb (Must be first)

Wednesday, July 22, 2009

Patch: Perl Module HTTP::Proxy 0.23 Hop-By-Hop Test Failure

HTTP::Proxy 0.23 is failing test t/50hopbyhop:

t/50hopbyhop........1/28
# Failed test 'Hop-by-hop Foo'
# at t/50hopbyhop.t line 38.
# got: undef
# expected: 'foofoo'

# Failed test 'Hop-by-hop Bar'
# at t/50hopbyhop.t line 39.
# got: undef
# expected: 'barbar'

# Failed test 'Connection header removed'
# at t/50hopbyhop.t line 45.
# got: 'foofoo'
# expected: undef

# Failed test 'Connection header removed'
# at t/50hopbyhop.t line 46.
# got: 'barbar'
# expected: undef
I've submitted a patch that's been accepted by the author; it should be in the next release.

Update: the patch is included as of version 0.24.

Sunday, July 19, 2009

Blogger: Exclude Your Visits from Google Analytics

Google Analytics has a way of excluding certain visits to a site based on the presence of a special cookie. Many resources suggest that you create a "hidden" Web page to accomplish this, but that's difficult to do with Blogger. There is a workaround, however.

First, make sure you have Google Analytics installed and running on your blog.

Next, from each Web browser you use, pull up your blog. Once the page has fully loaded, enter the following javascript in the browser's location bar and press return/enter:
javascript:pageTracker._setVar('notrack');alert('cookie set');
That will set a "notrack" cookie on your browser.

Finally, sign into your Google Analytics account and create a custom filter to exclude all visitors that have the "notrack" cookie set. The filter values should be:

Filter Type: Custom filter > Exclude
Filter Field: User Defined
Filter Pattern: notrack
Case Sensitive: No
Google Analytics should now begin ignoring your visits.

This approach isn't specific to Blogger; it should work on any site, including other blogging platforms such as Wordpress and Movable Type.

Also, to make it simpler to set the cookie, you may want to create a bookmark with the above javascript. Once added, simply go to your blog and select the bookmark.

Keywords: blogger ignore visits, blogger exclude, blogger hide

Saturday, July 18, 2009

Perl: Using LWP with a SOCKS Proxy

For this example, we'll use LWP to connect through a SOCKS proxy to the Tor anonymizing network. Under Ubuntu/Debian, installation of Tor is as simple as:
sudo apt-get install tor
Next, install the LWP::Protocol::socks Perl module to add support for the "socks" scheme. Installing from CPAN:
sudo cpan LWP::Protocol::socks
You should now be able to use LWP with Tor:

#!/usr/bin/perl
use strict;
use LWP::UserAgent;

my $ua = LWP::UserAgent->new(
agent => q{Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; YPC 3.2.0; .NET
CLR 1.1.4322)},
);
$ua->proxy([qw/ http https /] => 'socks://localhost:9050'); # Tor proxy
$ua->cookie_jar({});
my $rsp = $ua->get('http://www.yahoo.com/');
print $rsp->content;

Friday, July 17, 2009

Web: Resizing the Browser Window

Use this javascript snippet to test web pages at different browser sizes:
javascript:resizeTo(1024, 768)
Enter that into your browser's location bar and it should resize your window to 1024x768 (the most common resolution, currently). The first value is the width in pixels. The second is the height.

Here are resize links to the five most popular resolutions. Bookmark these or drag them to your toolbar for quick access.
There are also browser plugins that can adjust the window size, such as Firefox's Web Developer Toolbar.

Bash: Iterating Over Command-Line Arguments

Shell script parameters are available through the positional variables $1, $2, $3, etc. They are also placed in the "special" variables $* and $@. The following script illustrates how those values are expanded.

#!/bin/bash

print_arguments () {
idx=1
for arg; do
echo " param $idx: $arg"
let idx++
done
echo
}

echo "\$* - arguments with spaces are split"
print_arguments $*

echo "\$@ - same"
print_arguments $@

echo "\"\$*\" - expands to single value"
print_arguments "$*"

echo "\"\$@\" - preserves arguments exactly as passed"
print_arguments "$@"

Example output:

$ ./test-param-expansion orange 9 "Bringing Up Baby"
$* - arguments with spaces are split
param 1: orange
param 2: 9
param 3: Bringing
param 4: Up
param 5: Baby

$@ - same
param 1: orange
param 2: 9
param 3: Bringing
param 4: Up
param 5: Baby

"$*" - expands to single value
param 1: orange 9 Bringing Up Baby

"$@" - preserves arguments exactly as passed
param 1: orange
param 2: 9
param 3: Bringing Up Baby

So to preserve the command-line arguments exactly as supplied, use the special variable "$@" when iterating. Mnemonic: quote at the right place.

Example for loops:

#!/bin/sh

# loop over all args
for arg in "$@"; do
echo $arg
done

# short-cut; same as above
for arg; do
echo $arg
done

See also: Bash Manual: Special Parameters

Wednesday, July 15, 2009

Linux: Encrypted Filesystem on a Regular Disk File

Some notes on creating a LUKS-based encrypted filesystem on a regular disk file with Ubuntu 9.04 Jaunty.


Create the Encrypted Filesystem:

# create a 10M file
$ dd if=/dev/urandom of=testfs bs=1M count=10

# associate it with the loop device
$ losetup /dev/loop0 testfs

# encrypt it (will ask for password to use)
$ cryptsetup luksFormat /dev/loop0

# open the encrypted loop device
$ cryptsetup luksOpen /dev/loop0 testfs

# format it with ext2 (or whatever you prefer)
$ mkfs.ext2 /dev/mapper/testfs

# mount it
$ mount /dev/mapper/testfs /mnt/test

# confirm mount
$ df -h /mnt/test
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/testfs    9.2M   88K  8.7M   1% /mnt/test


Unmount the Filesystem:

# unmount it
$ umount /mnt/test

# close encryption
$ cryptsetup luksClose /dev/mapper/testfs

# release loop device
$ losetup -d /dev/loop0


Mount an Encrypted Filesystem:

# associate file with the loop device
$ losetup /dev/loop0 testfs

# open the encrypted loop device
$ cryptsetup luksOpen /dev/loop0 testfs

# mount it
$ mount /dev/mapper/testfs /mnt/test

Shell: Aliases for Escaping/Unescaping Query Parameters

Here are a couple more Unix aliases, this time for quickly escaping and unescaping URL query parameters. These are defined in my ~/.bash_aliases file.

alias urlencode="perl -MURI::Escape -ple '\$_=uri_escape(\$_); s/%20/+/g'"
alias urldecode="perl -MURI::Escape -ple '\$_=uri_unescape(\$_); s/\+/ /'"
To escape/encode all unsafe characters in a query parameter:

$ echo "blue socks?" | urlencode
blue+socks%3F
And to unescape/decode a parameter:

$ echo blue+socks%3F | urldecode
blue socks?
These aliases depend on Perl and the URI::Escape module which are standard on most modern Unixes.

Monday, July 13, 2009

Shell: Linux Password Generator

A simple bash function to generate secure passwords with standard Unix programs:

function mkpw() { head /dev/urandom | uuencode -m - | sed -n 2p | cut -c1-${1:-8}; }
Add that to your ~/.bashrc file. The password length can be specified as an argument (defaults to 8).
Example usage:

$ mkpw
B5PcCWC3
$ mkpw 10
V8T7ZrTQuN
On Ubuntu, the uuencode program is in the sharutils package. Alternatively, you could replace uuencode with md5sum or sha1sum, which would restrict the passwords to hex digits (and which would therefore make them appropriate for WEP keys and the like):

function mkpw_md5() { head /dev/urandom | md5sum | cut -c1-${1:-8}; }
function mkpw_sha1() { head /dev/urandom | sha1sum | cut -c1-${1:-8}; }

Saturday, July 11, 2009

Blogger Syntax Highlighting

How to add syntax highlighting to Blogger with Alex Gorbatchev's open-source SyntaxHighlighter.
  • Log into your blogspot account, select the "Layout" tab, and then click "Edit HTML."

  • Click "Download Full Template" to make a backup of your current template.

  • Make a copy of your template, open it in an editor, and find the </head> closing tag. Before that tag, add the following:
    <link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
    <link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>
    <!-- add brushes here -->
    <script type='text/javascript'>
    SyntaxHighlighter.config.bloggerMode = true;
    SyntaxHighlighter.all();
    </script>

  • After the comment that says "add brushes here," add the languages you plan to use. For example, I'm using brushes for Javascript, Bash, SQL, XML/HTML, and C++:
    <!-- add brushes here -->
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>
    <script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'/>
    See the full list of supported syntaxes.

  • Save your modified template, and upload it to Blogger (again, under Layout > Edit HTML).

  • You should now be able to add syntax highlighting to your blog. Wrap your code in a <pre> tag and specify the brush to use in the class attribute. For example, to highlight a block of SQL:

    <pre class="brush:sql">
    SELECT *
    FROM users
    WHERE user_id = 1212;
    </pre>

    Here's how that looks when rendered:

    SELECT *
    FROM users
    WHERE user_id = 1212;

  • The code you're formatting should be HTML encoded first. Also note that the Blogger preview won't show the formatting; you'll need to either go ahead and publish it or post it to a test blog first.

Syntax Highlighting with JS and CSS

The code syntax highlighting in this blog is being done with SyntaxHighlighter by Alex Gorbatchev. See the instructions on configuring syntax highlighting with Blogger.

Shell: Aliases for Encoding/Decoding HTML Strings

Here are a couple of simple Unix aliases for quickly encoding and decoding HTML strings. I have these defined in my ~/.bash_aliases file.

alias htmlencode="perl -MHTML::Entities -pe 'encode_entities(\$_)'"
alias htmldecode="perl -MHTML::Entities -pe 'decode_entities(\$_)'"
To encode/escape all unsafe characters in a string with their HTML entities:

$ echo "This is <b>bold</b>" | htmlencode
This is &lt;b&gt;bold&lt;/b&gt;
And to decode/unescape HTML entities:

$ echo "This is &lt;b&gt;bold&lt;/b&gt;" | htmldecode
This is bold
These aliases depend on Perl and the HTML::Entities module which are standard on most modern Unixes.

See also: Web-based HTML encoder.

C++ Whitespace Trimming Functions

Some simple functions for removing leading or trailing whitespace from strings in C++. It uses isspace() and your current locale (by default) to determine what is considered whitespace (e.g., space, tab, newline, etc.) and modifies the strings in-place.

The header file, btrim.hpp:

#ifndef BTRIM_HPP
#define BTRIM_HPP

#include <string>
#include <locale>

/**
* Strip leading whitespace from a string.
*
* @param[in] str Reference to the string to be trimmed. Modified in-place.
* @param[in] loc Locale to use (optional).
* @return void
*/
void ltrim(std::string& str, const std::locale& loc = std::locale());

/**
* Strip trailing whitespace from a string.
*
* @param[in] str Reference to the string to be trimmed. Modified in-place.
* @param[in] loc Locale to use (optional).
* @return void
*/
void rtrim(std::string& str, const std::locale& loc = std::locale());

/**
* Strip both leading and trailing whitespace from a string.
*
* @param[in] str Reference to the string to be trimmed. Modified in-place.
* @param[in] loc Locale to use (optional).
* @return void
*/
void btrim(std::string& str, const std::locale& loc = std::locale());

#endif // BTRIM_HPP

The implementation file, btrim.cpp:

#include "btrim.hpp"

using namespace std;

void ltrim(string& str, const locale& loc) {
string::size_type pos = 0;
while (pos < str.size() && isspace(str[pos], loc)) pos++;
str.erase(0, pos);
}

void rtrim(string& str, const locale& loc) {
string::size_type pos = str.size();
while (pos > 0 && isspace(str[pos - 1], loc)) pos--;
str.erase(pos);
}

void btrim(string& str, const locale& loc) {
ltrim(str, loc);
rtrim(str, loc);
}

Example usage:

// Example use of trim whitespace functions
#include <string>
#include <iostream>
#include "btrim.hpp"

using namespace std;

int main () {
string s = " zort ";
btrim(s); /* trim spaces, both leading and trailing */
cout << "Trimmed string: |" << s << "|" << endl;
}

Saturday, July 4, 2009

SSH Tunnel with FreeNX

To use FreeNX to access a machine that's behind a firewall, you can tunnel an SSH connection:
ssh -L 2222:desktop:22 user@firewall
Configure FreeNX to connect to port 2222 on localhost, and log in as normal.

Sunday, June 28, 2009

Access Linux From Windows with FreeNX

FreeNX is a cross-platform remote desktop application. It's similar to VNC but is faster and leverages SSH for security. Installation on Ubuntu is simple (I'm using Jaunty).
  1. Edit /etc/apt/sources.list and add the FreeNX repository:

    # Ubuntu FreeNX Repository for Jaunty
    # sudo apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 2a8e3034d018a4ce
    deb http://ppa.launchpad.net/freenx-team/ppa/ubuntu jaunty main
    deb-src http://ppa.launchpad.net/freenx-team/ppa/ubuntu jaunty main
  2. Update your packages list: sudo apt-get update
  3. Install the FreeNX server: sudo apt-get install freenx-server
  4. Install the appropriate FreeNX client software for Windows or Mac, and try logging into your Linux machine remotely.