08/09: grr, Internet Explorer sucks
[pfisher@rockstar ~]$ alias bold='tput bold'
[pfisher@rockstar ~]$ alias unbold='tput rmso'
[pfisher@rockstar ~]$ alias highlight='tput smso'
[pfisher@rockstar ~]$ alias unhighlight='tput rmso'
[pfisher@rockstar ~]$ cat font-test.sh
#!/bin/bash
function bold { tput bold; }
function unbold { tput rmso; } # reset mode stand-out
function highlight { tput smso; } # set mode stand-out
function unhighlight { tput rmso; }
echo "normal text"
bold
echo "bold text"
unbold
echo "normal text"
highlight
echo "highlighted text"
unhighlight
echo "normal text"
bold
highlight
echo "bold and highlighted"
unbold
unhighlightAt least, that's a simple way to pretend it works. In reality, though, unbold and unhighlight are the same thing, they each undo both bold and highlighting.
00230 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
00231 That was relevant to code that was here before. */
01/09: Reinventing the square wheel
But I don't feel too bad because everywhere I look I see yet another bad implementation of getopt. Come on people, GNU style is cool style.
I feel like I might fix up my PHP command line options parser to conform more closely with what I'd call "expected" behavior, and support alternative syntaxes. I also half want to write my own in Bash, because everything I've found sucks in one way or another.
I think the best one I've seen so far (clean code, sensible syntax) is the getopt parser in the Python library. Even better, though, is the whole system provided by the Python optparse module. Makes me want to use Python.
Damn good documentation, here. This really explains everything there is to know about command line argument parsing:
- option
an argument used to supply extra information to guide or customize the execution of a program. There are many different syntaxes for options; the traditional Unix syntax is a hyphen (“-“) followed by a single letter, e.g. "-x" or "-F". Also, traditional Unix syntax allows multiple options to be merged into a single argument, e.g. "-x -F" is equivalent to "-xF". The GNU project introduced "--" followed by a series of hyphen-separated words, e.g."--file" or "--dry-run". These are the only two option syntaxes provided by optparse.
Some other option syntaxes that the world has seen include:
- a hyphen followed by a few letters, e.g. "-pf" (this is not the same as multiple options merged into a single argument)
- a hyphen followed by a whole word, e.g. "-file" (this is technically equivalent to the previous syntax, but they aren’t usually seen in the same program)
- a plus sign followed by a single letter, or a few letters, or a word, e.g."+f", "+rgb"
- a slash followed by a letter, or a few letters, or a word, e.g. "/f","/file"
These option syntaxes are not supported by optparse, and they never will be. This is deliberate: the first three are non-standard on any environment, and the last only makes sense if you’re exclusively targeting VMS, MS-DOS, and/or Windows.
<workspace>\.metadata\.plugins\org.tigris.subversion.subclipse.core\.svnProviderState
Repositories which are currently checked out in your workspace will be detected and regenerated. Worked for me, YMMV.
#!/usr/bin/perl -MSVN::Notify::Config=$0
--- #YAML:1.0
'':
PATH: /usr/bin:/bin:/usr/local/subversion/bin
###
# DEV MIRROR
#
# Update local working copy of dev branch and rsync it to the web root of live dev mirror.
#
'/branches/3.0/html':
handler: Mirror::Rsync
to: /var/deploy/svn/sites/example.com/versions/3/branches/3.0/html
rsync-host: dev.example.com
rsync-dest: /var/www/sites/example.com/versions/3/branches/3.0/html
rsync-delete: yes
rsync-args:
compress: 1
archive: 1
exclude:
- html/assets
- html/staticNote that the "exclude" rsync parameter is expected to be an array. Also, the local working copy must already exist.
>> View as plain text
<?php
/**
* CommandLine class
*
* @package Framework
*/
/**
* Command Line Interface (CLI) utility class.
*
* @author Patrick Fisher <patrick@pwfisher.com>
* @since August 21, 2009
* @package Framework
* @subpackage Env
*/
class CommandLine {
public static $args;
/**
* PARSE ARGUMENTS
*
* This command line option parser supports any combination of three types
* of options (switches, flags and arguments) and returns a simple array.
*
* [pfisher ~]$ php test.php --foo --bar=baz
* ["foo"] => true
* ["bar"] => "baz"
*
* [pfisher ~]$ php test.php -abc
* ["a"] => true
* ["b"] => true
* ["c"] => true
*
* [pfisher ~]$ php test.php arg1 arg2 arg3
* [0] => "arg1"
* [1] => "arg2"
* [2] => "arg3"
*
* [pfisher ~]$ php test.php plain-arg --foo --bar=baz --funny="spam=eggs" --also-funny=spam=eggs \
* > 'plain arg 2' -abc -k=value "plain arg 3" --s="original" --s='overwrite' --s
* [0] => "plain-arg"
* ["foo"] => true
* ["bar"] => "baz"
* ["funny"] => "spam=eggs"
* ["also-funny"]=> "spam=eggs"
* [1] => "plain arg 2"
* ["a"] => true
* ["b"] => true
* ["c"] => true
* ["k"] => "value"
* [2] => "plain arg 3"
* ["s"] => "overwrite"
*
* @author Patrick Fisher <patrick@pwfisher.com>
* @since August 21, 2009
* @see http://www.php.net/manual/en/features.commandline.php
* #81042 function arguments($argv) by technorati at gmail dot com, 12-Feb-2008
* #78651 function getArgs($args) by B Crawford, 22-Oct-2007
* @usage $args = CommandLine::parseArgs($_SERVER['argv']);
*/
public static function parseArgs($argv){
array_shift($argv);
$out = array();
foreach ($argv as $arg){
// --foo --bar=baz
if (substr($arg,0,2) == '--'){
$eqPos = strpos($arg,'=');
// --foo
if ($eqPos === false){
$key = substr($arg,2);
$value = isset($out[$key]) ? $out[$key] : true;
$out[$key] = $value;
}
// --bar=baz
else {
$key = substr($arg,2,$eqPos-2);
$value = substr($arg,$eqPos+1);
$out[$key] = $value;
}
}
// -k=value -abc
else if (substr($arg,0,1) == '-'){
// -k=value
if (substr($arg,2,1) == '='){
$key = substr($arg,1,1);
$value = substr($arg,3);
$out[$key] = $value;
}
// -abc
else {
$chars = str_split(substr($arg,1));
foreach ($chars as $char){
$key = $char;
$value = isset($out[$key]) ? $out[$key] : true;
$out[$key] = $value;
}
}
}
// plain-arg
else {
$value = $arg;
$out[] = $value;
}
}
self::$args = $out;
return $out;
}
/**
* GET BOOLEAN
*/
public static function getBoolean($key, $default = false){
if (!isset(self::$args[$key])){
return $default;
}
$value = self::$args[$key];
if (is_bool($value)){
return $value;
}
if (is_int($value)){
return (bool)$value;
}
if (is_string($value)){
$value = strtolower($value);
$map = array(
'y' => true,
'n' => false,
'yes' => true,
'no' => false,
'true' => true,
'false' => false,
'1' => true,
'0' => false,
'on' => true,
'off' => false,
);
if (isset($map[$value])){
return $map[$value];
}
}
return $default;
}
}
?>Just for fun, here is a compacted version:
<?php
function parseArgs($argv){
array_shift($argv); $o = array();
foreach ($argv as $a){
if (substr($a,0,2) == '--'){ $eq = strpos($a,'=');
if ($eq !== false){ $o[substr($a,2,$eq-2)] = substr($a,$eq+1); }
else { $k = substr($a,2); if (!isset($o[$k])){ $o[$k] = true; } } }
else if (substr($a,0,1) == '-'){
if (substr($a,2,1) == '='){ $o[substr($a,1,1)] = substr($a,3); }
else { foreach (str_split(substr($a,1)) as $k){ if (!isset($o[$k])){ $o[$k] = true; } } } }
else { $o[] = $a; } }
return $o;
}
?>14/07: SQL Antipatterns Strike Back
"Common blunders of SQL database design, queries, and software development. Presented as a tutorial at the MySQL Conference & Expo 2009."
When an exception is raised, and independent of any subsequent exception handling, Ruby places a reference to the Exception object associated with the exception in the global variable $! (the exclamation point presumably mirroring our surprise that any of our code could cause errors). (src)