Tuesday, November 25, 2008

Syntac Checking for PHP in Emacs

Syntax checking for PHP in Emacs

When programming PHP I often find it useful to see parse errors that are created as I type. A missing semicolon at the end of the line, a missing quotation mark, a dot in the wrong place, stuff like that that triggers PHP Fatal or Parse Errors. On-the-fly syntax checking is a common feature of good programming IDE’s and editors. Emacs is no exception – there’s flymake minor mode that is meant to help you discover errors at the time of writing code. Flymake is currently a part of Emacs distribution and it covers on-the-fly syntax checks for a lot of popular programming languages like C, C++, Java, Perl and others. Unfortunately PHP syntax checks are not included in that package. I have been looking around trying to find an extension for flymake to make it work with PHP

but couldn’t find any so I decided to write my own.

Flymake-php.el is a bit os Lisp code that plays nicely with flymake and PHP on-the-fly syntax checking. Below you can see this extension in action:

!Flymake and PHP in action

How to install ?

1. Copy the following code to your Emacs library path (for example ~/.emacs.d/flymake-php.el)
    ;; Flymake PHP Extension

(require 'flymake)

(defconst flymake-allowed-php-file-name-masks '(
(".php3'" flymake-php-init)
(".inc'" flymake-php-init)
(".php'" flymake-php-init))
"Filename extensions that switch on flymake-php mode syntax checks")

(defconst flymake-php-err-line-pattern-re '("(Parse|Fatal) error: (.*) in (.*) on line ([0-9]+)" 3 4 nil 2)
"Regexp matching PHP error messages")

(defun flymake-php-init ()
(let* ((temp-file (flymake-init-create-temp-buffer-copy
'flymake-create-temp-inplace))
(local-file (file-relative-name
temp-file
(file-name-directory buffer-file-name))))
(list "php" (list "-f" local-file "-l"))))

(defun flymake-php-load ()
(setq flymake-allowed-file-name-masks (append flymake-allowed-file-name-masks flymake-allowed-php-file-name-masks))
(setq flymake-err-line-patterns (cons flymake-php-err-line-pattern-re flymake-err-line-patterns))
(flymake-mode t)
(local-set-key "C-cd" 'flymake-display-err-menu-for-current-line))

(provide 'flymake-php)
2. Make sure the library path is present in your .emacs, for example:
    (add-to-list 'load-path "~/.emacs.d/")
3. Require the flymake-php extension
    (require 'flymake-php)
4. If you’re using php-mode (I bet you are if you program in PHP) you can add a hook to this extension, so that every time a php-mode is switched on you’ll have flymake minor mode running. 5.
(add-hook 'php-mode-user-hook 'flymake-php-load)

Usage

Now every time you open a php file that has an extension specified in flymake-allowed-php-file-name-masks a flymake minor mode will be switched on with on-the-fly syntax checking. If you see a highlighted line you can position the cursor on the line and press C-c d to see a popup window with an error message (similar to the screenshot above).

M-x flymake-goto-next-error and M-x flymake-goto-prev-error functions allow for easy navigation to the next/previous erroneous line, respectively. You can also bind these functions to the keys of your choice (local-set-key function).

How does this work ?

Quote from flymake-info manual:

Flymake runs the pre-configured syntax check tool (compiler for C++ files, `perl’ for perl files, etc.) in the background, passing it a temporary copy of the current buffer, and parses the output for known error/warning message patterns. Flymake then highlights erroneous lines (i.e. lines for which at least one error or warning has been reported by the syntax check tool), and displays an overall buffer status in the mode line. Status information displayed by Flymake contains total number of errors and warnings reported for the buffer during the last syntax check.
Syntax check is done ‘on-the-fly’. It is started whenever

- buffer is loaded - a newline character is added to the buffer - some changes were made to the buffer more than `0.5’ seconds ago (the delay is configurable).

Customise your flymake

You can further customise your flymake-mode. For example to disable a syntax check every time a newline is added to a buffer you can set flymake-start-syntax-check-on-newline variable to nil, eg.:

(setq flymake-start-syntax-check-on-newline nil) 

You can also customise the look of the error line “face” (font, size and color of the error line) by setting flymake-errline-face. Please refer to flymake info manual for all the available options.

php.ini settings Because flymake will call php -l temp-buffer every time a request is trigger it’s a good idea to disable error logging in php.ini (cli version)

; Log errors into a log file (server-specific log, stderr, or error_log (below)) ; As stated above, you’re strongly advised to use error logging in place of ; error displaying on production web sites. log_errors = Off

What about warnings ?

If you’re an adventurous soul (by this I mean “hacking Lisp code” type of adventure :) ), you may extend this a little bit and add support for PHP warning messages.

Sunday, November 16, 2008

Bluetooth PAND (Personal Area Network) Howto For Debian Etch

Overview

I wanted to access the internet over bluetooth instead of GPRS/3G network from my mobile phone (SE K800i). After a lot of searching I couldn't find a clear explanation as how to accomplish this. I did manage to set it up with Windows XP, using the "Personal Area Network" in the bluetooth utility and doing internet connection sharing. After another fruitless search, I managed to figure out how to make a bluetooth internet profile instead of GPRS or 3G on the phone. Since I work in Linux most of the time, I decided to have a go and do it with Debian, my workstation's main OS. After spending a few hours, I had it working using the steps below.

This howto is for Debian Etch, current "testing" branch soon to be 4.0. May work on Ubuntu or other Debian based distros. Settings for older versions may be similar. In Debian 3 the bluetooth daemon maybe regarded to as hcid.

Requirements

  • Kernel 2.6.x, may work under 2.4, not tested.
  • iptables is needed if you want to access other computers or the internet.

Install:

apt-get install bluetooth

install apt get install bluez-utils

install apt-get install dhcp3-server

Optional:

apt-get install kdebluetooth

Has the kde pinhelper application for easy pairing.

Note: Pairing your bluetooth devices is beyond the scope of this howto. It assumes you can pair you device to your system.

As root:

Edit /etc/bluetooth/hcid.conf. Change

lm accept;

to

lm accept, master;

Edit /etc/default/bluetooth.Change

PAND_ENABLED=0

to

PAND_ENABLED=1

and

PAND_OPTIONS=""

to

PAND_OPTIONS="--listen --role=NAP --devup /etc/bluetooth/pan/dev-up"

mkdir /etc/bluetooth/pan

touch /etc/bluetooth/pan/dev-up

Put the following in /etc/bluetooth/pan/dev-up:

#!/bin/sh
echo 1 > /proc/sys/net/ipv4/ip_forward
ifup bnep0
sleep 2
/etc/init.d/dhcp3-server restart

Make it executable:

chmpd +x /etc/bluetooth/pan/dev-up

In /etc/network/interfaces add the bluetooth interface as follows:

iface bnep0 inet static
address 10.0.254.1
netmask 255.255.255.240

post-up iptables -t nat -A POSTROUTING -s 10.0.254.0/24 -j MASQUERADE
post-up iptables -A FORWARD -i bnep0 -o eth0 -j ACCEPT
post-up iptables -A FORWARD -o bnep0 -i eth0 -j ACCEPT
pre-down /etc/init.d/dhcp3-server stop

eth0 is the interface you will be NAT-ed behind. Your external interface.

Change the IPs and network settings as you like, just make sure to also reflect it in your dhcp.

In /etc/dhcp3/dhcpd.conf make sure you set

option domain-name "somedomainname.com";
option domain-name-servers ip-of-dns-server-goes-here;

where ip-of-dns-server-goes-here is the IP address of the dns server to use. You can see the server you're using in /etc/resolv.conf.

Declare a subnet for the PAN segment, should be the subnet you used for the bnetp device in /etc/network/interfaces. Replace the option routers 10.0.254.1; with the IP you have given your bnep0 interface in /etc/network/interfaces.

subnet 10.0.254.0 netmask 255.255.255.0 {
range 10.0.254.1 10.0.254.10;
option domain-name-servers 10.0.1.1;
option domain-name "bluetoothap.int.yourdomain.com";
option routers 10.0.254.1;
option broadcast-address 10.0.254.255;
default-lease-time 600;
max-lease-time 7200;
}

Now restart the bluetooth daemon:

/etc/init.d/bluetooth restart

Pair your device with the machine. Once paired you should be able to access the network using the bluetooth PAN service for another computer, PDA or mobile phone.

Troubleshooting

1. See if your bnep0 device is going up when a connection is requested and the interface is asked to come up. You can watch this with the following command as root:

watch -n1 “ifconfig”

You should see bnep0 coming up when you fire up your bluetooth client device to try and access the PAN network.

2. See that the script /etc/bluetooth/pan/dev-up is being executed.

3.Watch the output of syslog to see if the dhcp server is asinign an IP to your device.

tail -f /var/log/syslog

tail -f /var/log/messages

4. Once you see the IP, try to ping your device with the ping command.

Bluetooth PAN settings for Sony Ericsson k800i

Menu:

Settings -> Connectivity -> Data Accounts.

In the list you should see your bluetooth AP.

Go to

Settings -> Connectivity -> Internet Settings -> Internet Profiles -> New profile

In Name enter a name for the connection. eg. PAN.

For Connect Using choose the bluetooth icon with the name of your bluetooth machine, the one showing in the data accounts, and also the PC you paired your k800i with.

Now make this profile active for internet, java and streaming.

Make sure you press save.

Now you should be able to browse the internet trough your k800k. Enjoy!

How to use your blackberry as a modem in Debian

After aquiring a BlackBerry cellphone, I wanted to use it as a modem for my laptop, running Debian. Here's how to do it via USB:

I recommend you read all this procedure before starting


  • Install barry (so you can use the cellphone via USB, this makes it chargeable too

  • Install XmBlackBerry

  • connect your mobile phone to your computer, via USB

  • sudo XmBlackBerry

  • clicking in the options menu you'll see in the stderr (console where you
    run this app) a /dev/pts/something , which is your GPRS device

  • click "connect" and see if your phone tells you that you're connected to the desktop

  • sudo vi /etc/chatscripts/blackberry :


    ABORT BUSY ABORT ‘NO CARRIER’ ABORT VOICE ABORT ‘NO DIALTONE’ ABORT ‘NO DIAL TONE’ ABORT ‘NO ANSWER’ ABORT DELAYED ABORT ERROR
    SAY “Initializing\n”
    ” ATZ
    SAY "ATE\n"
    OK 'AT+CGDCONT=1,"IP","wap.voicestream.com"'
    OK 'AT'OK 'ATDT*99***1#'
    SAY "Dialing\n"


  • (change "device" here) sudo vi /etc/ppp/peers/blackberry


    debug debug debug
    nodetach
    /dev/pts/device
    115200
    connect "/usr/sbin/chat -f /etc/chatscripts/blackberry"
    nomultilink
    defaultroute
    noipdefault
    ipcp-restart 7
    ipcp-accept-local
    ipcp-accept-remote
    lcp-echo-interval 0
    lcp-echo-failure 999
    modem
    noauth
    nocrtscts
    noipdefault
    novj
    usepeerdns
    user ""
    password ""


  • sudo pppd call blackberry



And you're on!

Yeah, but how to install XmBlackBerry?



Here are the steps to install XmBlackBerry:

* get and install libmotif 2.3.0 debian packages here
* aptitude install xaw3dg-dev xorg-dev x11proto-print-dev autoconf libtool libopensync-dev libcurl4-openssl-dev
* As root, run
ln -s /usr/include/X11/Xaw3d /usr/include/X11/Xaw
* Install Xlt (tested with 13.0.13): get it here, untar it and, in its directory...
*

./configure --with-motif-libraries=/usr/X11R6/lib --prefix=/usr
make && make install

* Install XmBlackBerry:

cvs -d:pserver:anonymous@xmblackberry.cvs.sourceforge.net:/cvsroot/xmblackberry co XmBlackBerry
cd XmBlackBerry/
cvs -d :pserver:anonymous@libusb.cvs.sourceforge.net:/cvsroot/libusb co libusb
cd libusb
make && make install
cd ..
./CVSMake
./configure --enable-maintainer-mode --disable-shared --with-motif-libraries=/usr/X11R6/lib
make
sudo make install
sudo ln -s /usr/X11R6/lib/libXm.so.4 /usr/lib/libXm.so.4


And how to install Barry?


In Pearl's case you need CVS version of it.

* Install barry:
cvs -d:pserver:anonymous@barry.cvs.sourceforge.net:/cvsroot/barry login
cvs -z3 -d:pserver:anonymous@barry.cvs.sourceforge.net:/cvsroot/barry co -P barry
cd barrysh
buildgen.sh
./configure --prefix=/usr
make
sudo make install
sudo cp udev/*b* /etc/udev/rules.d/.

Howto setting up bluetooth audio under Debian

This is a quick how to setting up bluetooth audio under Debian.

First off we need to install a couple packages:

# apt-get install bluez-utils bluez-gnome bluez-audio

Now we need to run ‘hcitool scan‘ to get the address of the bluetooth device. For example,

$ hcitool scan
Scanning ...
00:00:00:00:00:00 Nokia BH-501

Now to get the audio part to work:

Modify or create your ~/.asoundrc to contain

  1. pcm.bluetooth {
  2. type plug
  3. slave {
  4. pcm "bluetooth_hw"
  5. }
  6. }

  7. pcm.bluetooth_hw {
  8. type bluetooth
  9. device 00:11:22:33:44:55
  10. profile "auto"
  11. }

Where 00:11:22:33:44:55 is the bluetooth address of your headset that you got from ‘hcitool scan‘ output

Now to test the bluetooth headset audio is working with ‘arecord‘ and ‘aplay‘ for example,

$ arecord -Dplug:bluetooth -f S16_LE | aplay -Dplug:bluetooth -f S16_LE
Recording WAVE 'stdin' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono
Playing WAVE 'stdin' : Signed 16 bit Little Endian, Rate 8000 Hz, Mono
Aborted by signal Interrupt...
Aborted by signal Interrupt...

Finally configure your audio applications to use the alsa device ‘bluetooth’.

Example fro setting up Skype to use the bluetooth headset:
Right click on the Skype icon on the gnome-panel and go Options => Sound Devices and change the ‘Sound In’ and ‘Sound Out’ to ‘bluetooth’ and click apply.