## Tcl, 515

    set d [read stdin]
    if {![regexp {^[hq9\+HQ]*$} $d]} {puts "Source code contains invalid characters"}
    lmap c [split $d {}] {set b { bottles of beer}
    switch -- $c H {puts "Hello, world"} Q {puts $d} 9 {for {set i 99} {$i>3} {incr i -1} {puts "$i$b on the wall,
    $i$b.
    Take one down, pass it around,
    [expr $i-1]$b on the wall.
    "}
    puts "2$b on the wall,
    2$b.
    Take one down, pass it around,
    1 bottle of beer on the wall.
    
    1 bottle of beer on the wall,
    1 bottle of beer.
    Take one down, pass it around,
    No$b on the wall."}}

Just a bit golfed, still smaller than C and the correct 99 Bottles of beer end verse.