Ivor O’Connor

March 9, 2013

The Universal IDE: VI with SPF13

Filed under: bash, git, howto, html5, IDE, JavaScript, Linux, mint 14 xfce, php, sqlite, ubuntu, vi, vim, vundle — ioconnor @ 4:08 am

This is a youtube video I made on how to install SPF13 on Linux Mint 14 XFCE. I like learning from youtube videos whenever possible. If in the future I want to install SPF13 and something is not how I remember it I can return to this video. SPF13 makes VI into a universal IDE. It works on most if not all OSs including windows and the mac.  Sure if you are working with something like AIX, HP-UX, or some platform that does not have vim installed SPF13 will not be for you. I’d recommend you put in your base .vimrc commands directly into the .vimrc.local file and use them along with SPF13. Picking and choosing what you find works.

UPDATE 2013-03-08: Insert the following line into your .bashrc file before starting to get full colors: export TERM=”xterm-256color”

February 18, 2013

Tutorial On Automatically Moving Home To Ram Drive And Back On Startup And Shutdown

Filed under: bash, howto, laptop, Linux, mint 14 xfce, rsync, SSD, tutorial, ubuntu — ioconnor @ 6:36 pm

This posting is meant to compliment the “Linux Mint 14 SSD Settings” and “The Best Linux Directory Structure?“posting. The idea is to move the home directory automatically at start up and shutdown to and from the ram disk. If you are using a ram disk then your computer is very fast. Possibly more importantly you are not wearing out your hard disk or SSD because all the applications that would normally write willy-nilly to the home directory are now fooled into RAM. If you don’t have the computer automatically doing these steps you might forget. So have the computer do them for you!

Firstly everybody should know how to recover in case during boot up the home directory is pointing to a non existent directory. You’ll need to boot up from a USB stick and follow these steps which I do so often I’m pulling them from memory:

  1. sudo mkdir /blah
  2. sudo mount /dev/sda1 /blah
  3. cd /blah/home
  4. sudo rm you
  5. sudo ln -s base you
  6. sudo shutdown -h now

Secondly make a log file in the home directory since this is all about mucking with the home directory

  1. sudo touch /home/log
  2. sudo chmod 777 /home/log

Thirdly follow the directions for /etc/fstab found in my “Linux Mint 14 SSD Settings” posting. I would follow all of the directions there, even for /etc/rc.local, whether or not you have a SSD drive.

Fourthly add the following code which will copy the ram drive back to the hard disk when the computer shutsdown.

Make a file called /etc/init.d/diskhome.sh and put in it something like the following but change the username:

#!/bin/sh

ivorPrintAndLog() {
tStamp=$(date +%Y-%m-%d@%T)
echo “$tStamp $1”
echo “$tStamp $1” >> /home/log
}

argUser=”ivor”
fUserOnDisk=$(ls -l /home | grep “$argUser -> base”)
#echo “fUserOnDisk: ‘$fUserOnDisk'”
fUserOnRam=$(ls -l /home | grep “$argUser -> /tmp/”)
#echo “fUserOnRam: ‘$fUserOnRam'”

if [ “$fUserOnDisk” ]; then
if [ “$fUserOnRam” ]; then # On disk and ram!
sOut=”Script needs fixing because it reports ‘$argUser’ has home on both ram and disk.”
else # On disk but not ram
sOut=”User ‘$argUser’ is already residing on disk so nothing to do.”
fi
else
if [ “$fUserOnRam” ]; then # Not disk but ram
sOut=”Moving ram contents for user: ‘$argUser’ to disk.”
ivorPrintAndLog “$sOut”
rsync -av –delete /tmp/home/base /home
cd /home
sudo rm $argUser
sudo ln -s base $argUser
cd –
sOut=”Moved information to disk successfully”
else # Not disk and not ram
sOut=”Error with script: User: ‘$argUser’ is not on disk or ram.”
fi
fi

ivorPrintAndLog “$sOut”

Make it executable and put links to it from the appropriate places

chmod +x /etc/init.d
cd /etc/rc0.d
sudo ln -s ../init.d/diskhome.sh K99diskhome.sh
cd ../rc6.d
sudo ln -s ../init.d/diskhome.sh K99diskhome.sh

Fifthly update /etc/rc.local so it copies the home directory to ram by adding the following lines into the /etc/rc.local

ivorPrintAndLog() {
tStamp=$(date +%Y-%m-%d@%T)
echo “$tStamp $1”
echo “$tStamp $1” >> /home/log
}

argUser=”ivor”
fUserOnDisk=$(ls -l /home | grep “$argUser -> base”)
echo “fUserOnDisk: ‘$fUserOnDisk'”
#fUserOnRam=$(ls -l /home | grep “$argUser -> /tmp/”)
echo “fUserOnRam: ‘$fUserOnRam'”

blah() {
if [ “$fUserOnDisk” ]; then
if [ “$fUserOnRam” ]; then # On disk and ram!
sOut=”Script needs fixing because it reports ‘$argUser’ has home on both ram and disk.”
else # On disk but not ram
sOut=”Moving disk contents for user: ‘$argUser’ to ram.”
ivorPrintAndLog “$sOut”
rsync -av /home/base /tmp/home
cd /home
sudo rm $argUser
sudo ln -s /tmp/home/base $argUser
cd –
sOut=”Moved information to ram successfully”
fi
else
if [ “$fUserOnRam” ]; then # Not disk but ram
sOut=”User ‘$argUser’ is already residing in ram so nothing to do.”
else # Not disk and not ram
sOut=”Error with script: User: ‘$argUser’ is not on disk or ram.”
fi
fi
ivorPrintAndLog “$sOut”
}

blah

Finally, the sixth step, rename your home directory to “base” and put a link to it. In my case:

    1. sudo mv ivor base
    2. sudo ln -s base ivor

That is all there is to it. The next time you reboot you should find your home directory on the tmp ram drive. Now there are a few problems. Like your home directory is too large. Or you would like to manually backup. The following commands may help:

    1. cd; du -h | sort -h
      Figure out how much space your home directory is using
    2. cd; sudo mkdir /home/Downloads; chmod 777 /home/Downloads; mv Downloads/* /home/downloads/; rm Downloads; ln -s /home/Downloads Downloads
      Basically just moving your Downloads directory which is probably rarely used to another place so it is not copied on to the ram disk. Maybe there are other directories that could also be moved because they take up lots of space and rarely get used. Like pictures, music, etc..
    3. Periodically check your ram disk usage. Mine is usually under 1GB which is less than 50% of it’s capability. (The RAM drives default to half your installed ram and the assumption is you have 4 GBs or more of RAM on your system.)
      df -h
    4. Verify everything is working:
      ls -l /home # Your home drive should be a link pointing to the ram drive.
    5. cat /home/log
      #Your log file should show the files were copied on startup and shutdown.
    6. Backup your ram drive from time to time using the bold red line above. Maybe even make it into an alias like this:
      echo ‘alias bkup=”rsync -av –delete /tmp/home/base /home”‘ >> ~/.bashrc

I’ve used these steps on a few computers and they work for me. However if you run into problems let me know and I’ll update this with the fixes.

January 4, 2013

Linux Mint 14 SSD Settings.

Filed under: howto, laptop, Linux, mint 14 xfce, SSD, ubuntu — ioconnor @ 8:41 pm

2013-01-05 UPDATE: I kept having strange random problems when I turned journaling off so I removed the parts of the script below having to do with journaling.
2013-01-06 UPDATE: Since the RAM drive is being used as the swap drive I reformatted the SSD to recover the swap partition’s space that is setup on a default installation.
2013-01-06 UPDATE: I’m using iotop, “vmstat -p /dev/sda1 60”, “sudo find / -xdev -type f -mmin -9”, and audit to identify disk activity. They go into a list. The list is then used by /etc/rc.local at startup for backup and then to RAM where they are accessed via links. At shutdown etc/init.d moves them back. I’ll keep adding to this list diligently for a few weeks until it is pretty much complete.
2013-01-08 UPDATE: Added samba and sudo directories to the fstab. Still the reads and writes according to vmstat are gradually increasing though a search with find shows nothing has been changed.
2013-01-20 UPDATE: I’m still running with these settings but use scripts to move my home directory to a ram disk and back on startup and shutdown.  Days go by without seeing the hard disk light unless I’m actively making a backup. This approach does force me to keep myself organized. I keep ISO, MP3, MP4, and other big rarely used files on external USB drives. I also keep git repositories in their own /home/git directories. Overall it seems every piece of software wants to write to my home directory willy-nilly-like. So by having my ~ on a ram drive I’m allowing my SSD drive to stay in idle mode for hours at a time.
2013-02-18 UPDATE: Added the “| sudo tee” to three lines of the script in /etc/rc.local. I noticed it was not working on some newer installs until I did that.
2013-02-18 UPDATE: Added a new post called “Tutorial On Automatically Moving Home To Ram Drive And Back On Startup And Shutdown” which nicely compliments this post.

My hard disk went bad and I was forced to upgrade. Seeing as I could get a SSD drive with more than enough space at the same price as a normal drive I got the SSD. The SSD being the Kingston HyperX 3K with 120GBs of space. (It took less than 24 hours from the time I ordered until the time FedEx handed it to me though it was shipped normal.) The 3K in the title means it can only be used for 3,000 writes to any one particular place. Three thousand writes is not a lot. It seems like I go through that many saves on each program I write.

Now they clearly say the MTBF is 1,000,000 hours. That is a tad  over 100 years. (I suppose it’s a little more believable than religion.) The warranty for parts and labor is three years. I’m almost positive they have a counter inside that shows how many times each area has been cycled allowing them to wiggle out of warranties.

So to avoid cycle times I set my system as follows. I also wrote some scripts to verify the settings took. The settings turn on trim, turn off setting access times on files, and avoids writing out to disk unless all memory is full or the computer is being powered down. I want this system to act like a big RAM drive never bothering to write changes to disk. I suspect with the following settings my SSD should last as long as any other component in the laptop. (I do need to do further research to verify my disk is not being written to by anything. Then I’ll feel truly secure.)

/etc/fstab:

#UUID=4f24887d-2948-4e13-bc4e-1e28daa4f778 / ext4 errors=remount-ro 0 1
UUID=4f24887d-2948-4e13-bc4e-1e28daa4f778 / ext4 noatime,discard,errors=remount-ro 0 1

# swap was on /dev/sda5 during installation
UUID=c85a0e3b-ae36-4f5d-9c99-f93d9c19d770 none swap sw 0 0

tmpfs /tmp tmpfs nodev,nosuid,mode=1777 0 0
tmpfs /var/lock tmpfs nodev,nosuid,mode=1777 0 0
tmpfs /var/log tmpfs nodev,nosuid,mode=1777 0 0
tmpfs /var/spool tmpfs nodev,nosuid,mode=1777 0 0
tmpfs /var/run tmpfs nodev,nosuid,mode=1777 0 0
tmpfs /var/cache/samba tmpfs nodev,nosuid,mode=1777 0 0
tmpfs /var/lib/sudo tmpfs nodev,nosuid,mode=0700 0 0

/etc/rc.local:

echo 1 > /proc/sys/vm/swappiness
echo 1 > /proc/sys/vm/vfs_cache_pressure
echo 99 | sudo tee /proc/sys/vm/dirty_ratio
echo 80 | sudo tee /proc/sys/vm/dirty_background_ratio
echo 360000 > /proc/sys/vm/dirty_expire_centisecs
echo 360000 | sudo tee /proc/sys/vm/dirty_writeback_centisecs

December 2, 2012

SSH Over Non-Standard Ports

Filed under: cli, howto, Linux, mint 14 xfce, SSH, tutorial, ubuntu — ioconnor @ 12:35 am

My ~/.ssh/config file had something like:

Host bb
Hostname blahblah.com
Port 1234
User ioconnor

so I only had to type “ssh bb” but it’s confusing. Now I’ve changed the config file to:

Host blahblah.com
Port 1234

and use the familiar form of “ssh ioconnor@blahblah.com”. Now all additional utilities that may ride on top of ssh are not confused and can work as they were designed. Much more elegant though not as fancy.

July 25, 2009

Automatic Backup With Rsync And Cron On Ubuntu

Filed under: BACKUP, CRON, mint 14 xfce, rsync, SSH, ubuntu — Tags: , , , , — ioconnor @ 6:28 pm

Keeping a directory automatically backed up somewhere is always useful. Every few months this is needed on one machine or another. Here are the steps:

  1. First set up ssh keys so passwords are no longer needed.
    1. Test things by verifying a ‘ssh user@yourserver.com’ does require a password.
    2. Make some ssh keys on your client and then move the public key to the server
      1. cd ~/.ssh
      2. ls
      3. ssh-keygen -t dsa (Keep the defaults by just pressing enter a few times.)
      4. ssh-copy-id -i ~/.ssh/id_dsa.pub user@yourserver.com
    3. Test things by verifying a ‘ssh user@yourserver.com’ no longer requires a password.
  2. Determine the directory to be backed up and where it will be backed up and test the command to be used.
    1. time rsync -atvz ~/local-directory-of-your-choosing/ user@youserver.com:remote-directory-of-your-choosing/
    2. log in the server and verify the files are there…
  3. Put the command in cron. Because cron is broken in ubuntu you can’t simply do “crontab -e” anylonger. (How can something so basic be broken?!) Instead follow these instructions:
    1. vi ~/some_file and put in the cron commands
    2. @hourly rsync -atvz ~/local-directory-of-your-choosing/ user@youserver.com:remote-directory-of-your-choosing/
    3. crontab ~/some_file
    4. crontab -l

Now simply test it out…

UPDATED ON 2013-02-02: Used “ssh-copy-id -i ~/.ssh/id_dsa.pub user@yourserver.com” to reduce 10 or so steps and make things vastly simpler.
UPDATED ON 2013-02-05: I came across this article today and realized I should probably update this to use the “–delete” and “-e ssh” commands. I am already a big user of the delete command but I don’t often use ssh because my backups are local for the most part.

June 16, 2009

Ubuntu Hangs On Reboot!

Filed under: Linux, ubuntu — ioconnor @ 4:22 pm

I installed a fresh copy of Ubuntu Jaunty Jackalope 9.04 on a laptop this morning. Unfortunately it hangs on shut-down showing no indication it has hung. The screen is almost completely black execpt for a slowly blinking underscore at the top left of the screen. When ctl-alt-del is struck then the message “md: stopping all md devices” is displayed and the machine continues to reboot normally. Unfortunately a keyboard must be attached to this laptop before the ctl-alt-del can be entered. Granted reboots are not normal. A google search on this problem shows no solutions though many people have encountered the problem. It’s just another example of how poorly the Ubuntu releases are tested. It’s sort of an anything goes that is cool atmosphere with very little testing. Or a “just barely good enough to continue” paradigm. At this point I’m seriously thinking of switching to another distribution. One that hopefully undergoes stringent testing. However I’m afraid it will not support all the hardware like Ubuntu does. Life consists of many trade-offs.

On a related issue Ubuntu needs to reconfigure their boot charts to include how long it took to complete the entire reboot cycle. If it takes two minutes to shut down, another minute to make it through the grub stuff, and only 20 seconds to boot the entire process should say 3:20 instead of just :20 as it now does.

May 7, 2009

How To Install Jslint on Ubuntu

Filed under: bash, cli, debugging, howto, JavaScript, Lint, Linux, tutorial, ubuntu — Tags: , , , , , , — ioconnor @ 5:30 pm

At my entry https://ioconnor.wordpress.com/2009/04/24/javascript-testing/ you’ll notice there are two entirely different lint programs out there for JavaScript. I installed and made an entry on how to install JavaScript Lint here. This posting describes how to install the other version of lint, jslint, under ubuntu. I even tested it under Ubuntu 8.04 and 9.04. Follow these steps:

  1. sudo mkdir -p /my/bin
    I prefer not to much around in the home directory but to create all custom stuff right off the root so I know what is mine. You can choose some other directory if you’d like.
  2. cd /my/bin
  3. sudo wget http://www.jslint.com/rhino/jslint.js
    If they ever remove this send me a mssage and I’ll post it.
  4. sudo chmod a+x jslint.js
    Not sure if this is needed but it’s habit…
  5. sudo apt-get install rhino
    I did not have rhino installed on 9.04 but it does not hurt to verify with this command.
  6. time rhino jslint.js jslint.js
    jslint is written in javascript. So run it on itself to see if there are any errors or warnings.

That’s pretty simple. Too bad their website does not make it simple. In fact their website does not contain enough information. I had to google about for a while to figure it all out. Anyways here is the output when ran on itself. Then further down I use the other lint program on it.

JSLint does allow options. I am going to at some point see if I can make an include file that will specify just the options I want.

JSLint also has a good section on coding standards. I like it.

time rhino /my/bin/jslint.js /my/bin/jslint.js
Lint at line 4 character 236: eval is evil.
“use strict”;JSLINT=(function(){var adsafe_id,adsafe_may,adsafe_went,anonname,approved,atrule={‘import’:true,media:true,’font-face’:true,page:true},banned={apply:true,’arguments’:true,call:true,callee:true,caller:true,constructor:true,’eval’:true,prototype:true,unwatch:true,valueOf:true,watch:true},boolOptions={adsafe:true,bitwise:true,browser:true,cap:true,css:true,debug:true,eqeqeq:true,evil:true,forin:true,fragment:true,immed:true,laxbreak:true,newcap:true,nomen:true,on:true,onevar:true,passfail:true,plusplus:true,regexp:true,rhino:true,undef:true,safe:true,sidebar:true,strict:true,sub:true,white:true,widget:true},browser={alert:true,blur:true,clearInterval:true,clearTimeout:true,close:true,closed:true,confirm:true,console:true,Debug:true,defaultStatus:true,document:true,event:true,focus:true,frames:true,getComputedStyle:true,history:true,Image:true,length:true,location:true,moveBy:true,moveTo:true,name:true,navigator:true,onblur:true,onerror:true,onfocus:true,onload:true,onresize:true,onunload:true,open:true,opener:true,opera:true,Option:true,parent:true,print:true,prompt:true,resizeBy:true,resizeTo:true,screen:true,scroll:true,scrollBy:true,scrollTo:true,setInterval:true,setTimeout:true,status:true,top:true,XMLHttpRequest:true},cssAttributeData,cssAny,cssColorData={“aliceblue”:true,”antiquewhite”:true,”aqua”:true,”aquamarine”:true,”azure”:true,”beige”:true,”bisque”:true,”black”:true,”blanchedalmond”:true,”blue”:true,”blueviolet”:true,”brown”:true,”burlywood”:true,”cadetblue”:true,”chartreuse”:true,”chocolate”:true,”coral”:true,”cornflowerblue”:true,”cornsilk”:true,”crimson”:true,”cyan”:true,”darkblue”:true,”darkcyan”:true,”darkgoldenrod”:true,”darkgray”:true,”darkgreen”:true,”darkkhaki”:true,”darkmagenta”:true,”darkolivegreen”:true,”darkorange”:true,”darkorchid”:true,”darkred”:true,”darksalmon”:true,”darkseagreen”:true,”darkslateblue”:true,”darkslategray”:true,”darkturquoise”:true,”darkviolet”:true,”deeppink”:true,”deepskyblue”:true,”dimgray”:true,”dodgerblue”:true,”firebrick”:true,”floralwhite”:true,”forestgreen”:true,”fuchsia”:true,”gainsboro”:true,”ghostwhite”:true,”gold”:true,”goldenrod”:true,”gray”:true,”green”:true,”greenyellow”:true,”honeydew”:true,”hotpink”:true,”indianred”:true,”indigo”:true,”ivory”:true,”khaki”:true,”lavender”:true,”lavenderblush”:true,”lawngreen”:true,”lemonchiffon”:true,”lightblue”:true,”lightcoral”:true,”lightcyan”:true,”lightgoldenrodyellow”:true,”lightgreen”:true,”lightpink”:true,”lightsalmon”:true,”lightseagreen”:true,”lightskyblue”:true,”lightslategray”:true,”lightsteelblue”:true,”lightyellow”:true,”lime”:true,”limegreen”:true,”linen”:true,”magenta”:true,”maroon”:true,”mediumaquamarine”:true,”mediumblue”:true,”mediumorchid”:true,”mediumpurple”:true,”mediumseagreen”:true,”mediumslateblue”:true,”mediumspringgreen”:true,”mediumturquoise”:true,”mediumvioletred”:true,”midnightblue”:true,”mintcream”:true,”mistyrose”:true,”moccasin”:true,”navajowhite”:true,”navy”:true,”oldlace”:true,”olive”:true,”olivedrab”:true,”orange”:true,”orangered”:true,”orchid”:true,”palegoldenrod”:true,”palegreen”:true,”paleturquoise”:true,”palevioletred”:true,”papayawhip”:true,”peachpuff”:true,”peru”:true,”pink”:true,”plum”:true,”powderblue”:true,”purple”:true,”red”:true,”rosybrown”:true,”royalblue”:true,”saddlebrown”:true,”salmon”:true,”sandybrown”:true,”seagreen”:true,”seashell”:true,”sienna”:true,”silver”:true,”skyblue”:true,”slateblue”:true,”slategray”:true,”snow”:true,”springgreen”:true,”steelblue”:true,”tan”:true,”teal”:true,”thistle”:true,”tomato”:true,”turquoise”:true,”violet”:true,”wheat”:true,”white”:true,”whitesmoke”:true,”yellow”:true,”yellowgreen”:true},cssBorderStyle,cssLengthData={‘%’:true,’cm’:true,’em’:true,’ex’:true,’in’:true,’mm’:true,’pc’:true,’pt’:true,’px’:true},escapes={‘\b’:’\\b’,’\t’:’\\t’,’\n’:’\\n’,’\f’:’\\f’,’\r’:’\\r’,'”‘:’\\”‘,’/’:’\\/’,’\\’:’\\\\’},funct,functions,global,htmltag={a:{},abbr:{},acronym:{},address:{},applet:{},area:{empty:true,parent:’ map ‘},b:{},base:{empty:true,parent:’ head ‘},bdo:{},big:{},blockquote:{},body:{parent:’ html noframes ‘},br:{empty:true},button:{},canvas:{parent:’ body p div th td ‘},caption:{parent:’ table ‘},center:{},cite:{},code:{},col:{empty:true,parent:’ table colgroup ‘},colgroup:{parent:’ table ‘},dd:{parent:’ dl ‘},del:{},dfn:{},dir:{},div:{},dl:{},dt:{parent:’ dl ‘},em:{},embed:{},fieldset:{},font:{},form:{},frame:{empty:true,parent:’ frameset ‘},frameset:{parent:’ html frameset ‘},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{parent:’ html ‘},html:{parent:’*’},hr:{empty:true},i:{},iframe:{},img:{empty:true},input:{empty:true},ins:{},kbd:{},label:{},legend:{parent:’ fieldset ‘},li:{parent:’ dir menu ol ul ‘},link:{empty:true,parent:’ head ‘},map:{},menu:{},meta:{empty:true,parent:’ head noframes noscript ‘},noframes:{parent:’ html body ‘},noscript:{parent:’ body head noframes ‘},object:{},ol:{},optgroup:{parent:’ select ‘},option:{parent:’ optgroup select ‘},p:{},param:{empty:true,parent:’ applet object ‘},pre:{},q:{},samp:{},script:{empty:true,parent:’ body div frame head iframe p pre span ‘},select:{},small:{},span:{},strong:{},style:{parent:’ head ‘,empty:true},sub:{},sup:{},table:{},tbody:{parent:’ table ‘},td:{parent:’ tr ‘},textarea:{},tfoot:{parent:’ table ‘},th:{parent:’ tr ‘},thead:{parent:’ table ‘},title:{parent:’ head ‘},tr:{parent:’ table tbody thead tfoot ‘},tt:{},u:{},ul:{},’var’:{}},ids,implied,inblock,indent,jsonmode,lines,lookahead,member,membersOnly,nexttoken,noreach,option,predefined,prereg,prevtoken,pseudorule={‘first-child’:true,link:true,visited:true,hover:true,active:true,focus:true,lang:true,’first-letter’:true,’first-line’:true,before:true,after:true},rhino={defineClass:true,deserialize:true,gc:true,help:true,load:true,loadClass:true,print:true,quit:true,readFile:true,readUrl:true,runCommand:true,seal:true,serialize:true,spawn:true,sync:true,toint32:true,version:true},scope,sidebar={System:true},src,stack,standard={Array:true,Boolean:true,Date:true,decodeURI:true,decodeURIComponent:true,encodeURI:true,encodeURIComponent:true,Error:true,’eval’:true,EvalError:true,Function:true,isFinite:true,isNaN:true,JSON:true,Math:true,Number:true,Object:true,parseInt:true,parseFloat:true,RangeError:true,ReferenceError:true,RegExp:true,String:true,SyntaxError:true,TypeError:true,URIError:true},standard_member={E:true,LN2:true,LN10:true,LOG2E:true,LOG10E:true,PI:true,SQRT1_2:true,SQRT2:true,MAX_VALUE:true,MIN_VALUE:true,NEGATIVE_INFINITY:true,POSITIVE_INFINITY:true},syntax={},tab,token,urls,warnings,widget={alert:true,animator:true,appleScript:true,beep:true,bytesToUIString:true,Canvas:true,chooseColor:true,chooseFile:true,chooseFolder:true,closeWidget:true,COM:true,convertPathToHFS:true,convertPathToPlatform:true,CustomAnimation:true,escape:true,FadeAnimation:true,filesystem:true,Flash:true,focusWidget:true,form:true,FormField:true,Frame:true,HotKey:true,Image:true,include:true,isApplicationRunning:true,iTunes:true,konfabulatorVersion:true,log:true,md5:true,MenuItem:true,MoveAnimation:true,openURL:true,play:true,Point:true,popupMenu:true,preferenceGroups:true,preferences:true,print:true,prompt:true,random:true,Rectangle:true,reloadWidget:true,ResizeAnimation:true,resolvePath:true,resumeUpdates:true,RotateAnimation:true,runCommand:true,runCommandInBg:true,saveAs:true,savePreferences:true,screen:true,ScrollBar:true,showWidgetPreferences:true,sleep:true,speak:true,Style:true,suppressUpdates:true,system:true,tellWidget:true,Text:true,TextArea:true,Timer:true,unescape:true,updateNow:true,URL:true,Web:true,widget:true,Window:true,XMLDOM:true,XMLHttpRequest:true,yahooCheckLogin:true,yahooLogin:true,yahooLogout:true},xmode,xquote,ax=/@cc|<\/?|script|\]*s\]|<\s*!|&lt/i,cx=/[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,tx=/^\s*([(){}\[.,:;'”~\?\]#@]|==?=?|\/(\*(global|extern|jslint|member|members)?|=|\/)?|\*[\/=]?|\+[+=]?|-[\-=]?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|–)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,hx=/^\s*([‘”=>\/&#]|<(?:\/|\!(?:–)?)?|[a-zA-Z][a-zA-Z0-9_\-]*|[0-9]+|–|.)/,nx=/[\u0000-\u001f&<“\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,nxg=/[\u0000-\u001f&<“\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,ox=/[>&]|<[\/!]?|–/,lx=/\*\/|\/\*/,ix=/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,jx=/^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,ux=/&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i,sx=/^\s*([{:#*%.=,>+\[\]@()”‘;*]|[a-zA-Z0-9_][a-zA-Z0-9_\-]*|<\/|\/\*)/,ssx=/^\s*([@#!”‘};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/,qx=/[^a-zA-Z0-9-_\/ ]/,dx=/[\[\]\/\\”‘*<>.&:(){}+=#]/,rx={outer:hx,html:hx,style:sx,styleproperty:ssx};function F(){}

Lint at line 4 character 6051: eval is evil.
“use strict”;JSLINT=(function(){var adsafe_id,adsafe_may,adsafe_went,anonname,approved,atrule={‘import’:true,media:true,’font-face’:true,page:true},banned={apply:true,’arguments’:true,call:true,callee:true,caller:true,constructor:true,’eval’:true,prototype:true,unwatch:true,valueOf:true,watch:true},boolOptions={adsafe:true,bitwise:true,browser:true,cap:true,css:true,debug:true,eqeqeq:true,evil:true,forin:true,fragment:true,immed:true,laxbreak:true,newcap:true,nomen:true,on:true,onevar:true,passfail:true,plusplus:true,regexp:true,rhino:true,undef:true,safe:true,sidebar:true,strict:true,sub:true,white:true,widget:true},browser={alert:true,blur:true,clearInterval:true,clearTimeout:true,close:true,closed:true,confirm:true,console:true,Debug:true,defaultStatus:true,document:true,event:true,focus:true,frames:true,getComputedStyle:true,history:true,Image:true,length:true,location:true,moveBy:true,moveTo:true,name:true,navigator:true,onblur:true,onerror:true,onfocus:true,onload:true,onresize:true,onunload:true,open:true,opener:true,opera:true,Option:true,parent:true,print:true,prompt:true,resizeBy:true,resizeTo:true,screen:true,scroll:true,scrollBy:true,scrollTo:true,setInterval:true,setTimeout:true,status:true,top:true,XMLHttpRequest:true},cssAttributeData,cssAny,cssColorData={“aliceblue”:true,”antiquewhite”:true,”aqua”:true,”aquamarine”:true,”azure”:true,”beige”:true,”bisque”:true,”black”:true,”blanchedalmond”:true,”blue”:true,”blueviolet”:true,”brown”:true,”burlywood”:true,”cadetblue”:true,”chartreuse”:true,”chocolate”:true,”coral”:true,”cornflowerblue”:true,”cornsilk”:true,”crimson”:true,”cyan”:true,”darkblue”:true,”darkcyan”:true,”darkgoldenrod”:true,”darkgray”:true,”darkgreen”:true,”darkkhaki”:true,”darkmagenta”:true,”darkolivegreen”:true,”darkorange”:true,”darkorchid”:true,”darkred”:true,”darksalmon”:true,”darkseagreen”:true,”darkslateblue”:true,”darkslategray”:true,”darkturquoise”:true,”darkviolet”:true,”deeppink”:true,”deepskyblue”:true,”dimgray”:true,”dodgerblue”:true,”firebrick”:true,”floralwhite”:true,”forestgreen”:true,”fuchsia”:true,”gainsboro”:true,”ghostwhite”:true,”gold”:true,”goldenrod”:true,”gray”:true,”green”:true,”greenyellow”:true,”honeydew”:true,”hotpink”:true,”indianred”:true,”indigo”:true,”ivory”:true,”khaki”:true,”lavender”:true,”lavenderblush”:true,”lawngreen”:true,”lemonchiffon”:true,”lightblue”:true,”lightcoral”:true,”lightcyan”:true,”lightgoldenrodyellow”:true,”lightgreen”:true,”lightpink”:true,”lightsalmon”:true,”lightseagreen”:true,”lightskyblue”:true,”lightslategray”:true,”lightsteelblue”:true,”lightyellow”:true,”lime”:true,”limegreen”:true,”linen”:true,”magenta”:true,”maroon”:true,”mediumaquamarine”:true,”mediumblue”:true,”mediumorchid”:true,”mediumpurple”:true,”mediumseagreen”:true,”mediumslateblue”:true,”mediumspringgreen”:true,”mediumturquoise”:true,”mediumvioletred”:true,”midnightblue”:true,”mintcream”:true,”mistyrose”:true,”moccasin”:true,”navajowhite”:true,”navy”:true,”oldlace”:true,”olive”:true,”olivedrab”:true,”orange”:true,”orangered”:true,”orchid”:true,”palegoldenrod”:true,”palegreen”:true,”paleturquoise”:true,”palevioletred”:true,”papayawhip”:true,”peachpuff”:true,”peru”:true,”pink”:true,”plum”:true,”powderblue”:true,”purple”:true,”red”:true,”rosybrown”:true,”royalblue”:true,”saddlebrown”:true,”salmon”:true,”sandybrown”:true,”seagreen”:true,”seashell”:true,”sienna”:true,”silver”:true,”skyblue”:true,”slateblue”:true,”slategray”:true,”snow”:true,”springgreen”:true,”steelblue”:true,”tan”:true,”teal”:true,”thistle”:true,”tomato”:true,”turquoise”:true,”violet”:true,”wheat”:true,”white”:true,”whitesmoke”:true,”yellow”:true,”yellowgreen”:true},cssBorderStyle,cssLengthData={‘%’:true,’cm’:true,’em’:true,’ex’:true,’in’:true,’mm’:true,’pc’:true,’pt’:true,’px’:true},escapes={‘\b’:’\\b’,’\t’:’\\t’,’\n’:’\\n’,’\f’:’\\f’,’\r’:’\\r’,'”‘:’\\”‘,’/’:’\\/’,’\\’:’\\\\’},funct,functions,global,htmltag={a:{},abbr:{},acronym:{},address:{},applet:{},area:{empty:true,parent:’ map ‘},b:{},base:{empty:true,parent:’ head ‘},bdo:{},big:{},blockquote:{},body:{parent:’ html noframes ‘},br:{empty:true},button:{},canvas:{parent:’ body p div th td ‘},caption:{parent:’ table ‘},center:{},cite:{},code:{},col:{empty:true,parent:’ table colgroup ‘},colgroup:{parent:’ table ‘},dd:{parent:’ dl ‘},del:{},dfn:{},dir:{},div:{},dl:{},dt:{parent:’ dl ‘},em:{},embed:{},fieldset:{},font:{},form:{},frame:{empty:true,parent:’ frameset ‘},frameset:{parent:’ html frameset ‘},h1:{},h2:{},h3:{},h4:{},h5:{},h6:{},head:{parent:’ html ‘},html:{parent:’*’},hr:{empty:true},i:{},iframe:{},img:{empty:true},input:{empty:true},ins:{},kbd:{},label:{},legend:{parent:’ fieldset ‘},li:{parent:’ dir menu ol ul ‘},link:{empty:true,parent:’ head ‘},map:{},menu:{},meta:{empty:true,parent:’ head noframes noscript ‘},noframes:{parent:’ html body ‘},noscript:{parent:’ body head noframes ‘},object:{},ol:{},optgroup:{parent:’ select ‘},option:{parent:’ optgroup select ‘},p:{},param:{empty:true,parent:’ applet object ‘},pre:{},q:{},samp:{},script:{empty:true,parent:’ body div frame head iframe p pre span ‘},select:{},small:{},span:{},strong:{},style:{parent:’ head ‘,empty:true},sub:{},sup:{},table:{},tbody:{parent:’ table ‘},td:{parent:’ tr ‘},textarea:{},tfoot:{parent:’ table ‘},th:{parent:’ tr ‘},thead:{parent:’ table ‘},title:{parent:’ head ‘},tr:{parent:’ table tbody thead tfoot ‘},tt:{},u:{},ul:{},’var’:{}},ids,implied,inblock,indent,jsonmode,lines,lookahead,member,membersOnly,nexttoken,noreach,option,predefined,prereg,prevtoken,pseudorule={‘first-child’:true,link:true,visited:true,hover:true,active:true,focus:true,lang:true,’first-letter’:true,’first-line’:true,before:true,after:true},rhino={defineClass:true,deserialize:true,gc:true,help:true,load:true,loadClass:true,print:true,quit:true,readFile:true,readUrl:true,runCommand:true,seal:true,serialize:true,spawn:true,sync:true,toint32:true,version:true},scope,sidebar={System:true},src,stack,standard={Array:true,Boolean:true,Date:true,decodeURI:true,decodeURIComponent:true,encodeURI:true,encodeURIComponent:true,Error:true,’eval’:true,EvalError:true,Function:true,isFinite:true,isNaN:true,JSON:true,Math:true,Number:true,Object:true,parseInt:true,parseFloat:true,RangeError:true,ReferenceError:true,RegExp:true,String:true,SyntaxError:true,TypeError:true,URIError:true},standard_member={E:true,LN2:true,LN10:true,LOG2E:true,LOG10E:true,PI:true,SQRT1_2:true,SQRT2:true,MAX_VALUE:true,MIN_VALUE:true,NEGATIVE_INFINITY:true,POSITIVE_INFINITY:true},syntax={},tab,token,urls,warnings,widget={alert:true,animator:true,appleScript:true,beep:true,bytesToUIString:true,Canvas:true,chooseColor:true,chooseFile:true,chooseFolder:true,closeWidget:true,COM:true,convertPathToHFS:true,convertPathToPlatform:true,CustomAnimation:true,escape:true,FadeAnimation:true,filesystem:true,Flash:true,focusWidget:true,form:true,FormField:true,Frame:true,HotKey:true,Image:true,include:true,isApplicationRunning:true,iTunes:true,konfabulatorVersion:true,log:true,md5:true,MenuItem:true,MoveAnimation:true,openURL:true,play:true,Point:true,popupMenu:true,preferenceGroups:true,preferences:true,print:true,prompt:true,random:true,Rectangle:true,reloadWidget:true,ResizeAnimation:true,resolvePath:true,resumeUpdates:true,RotateAnimation:true,runCommand:true,runCommandInBg:true,saveAs:true,savePreferences:true,screen:true,ScrollBar:true,showWidgetPreferences:true,sleep:true,speak:true,Style:true,suppressUpdates:true,system:true,tellWidget:true,Text:true,TextArea:true,Timer:true,unescape:true,updateNow:true,URL:true,Web:true,widget:true,Window:true,XMLDOM:true,XMLHttpRequest:true,yahooCheckLogin:true,yahooLogin:true,yahooLogout:true},xmode,xquote,ax=/@cc|<\/?|script|\]*s\]|<\s*!|&lt/i,cx=/[\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,tx=/^\s*([(){}\[.,:;'”~\?\]#@]|==?=?|\/(\*(global|extern|jslint|member|members)?|=|\/)?|\*[\/=]?|\+[+=]?|-[\-=]?|%=?|&[&=]?|\|[|=]?|>>?>?=?|<([\/=!]|\!(\[|–)?|<=?)?|\^=?|\!=?=?|[a-zA-Z_$][a-zA-Z0-9_$]*|[0-9]+([xX][0-9a-fA-F]+|\.[0-9]*)?([eE][+\-]?[0-9]+)?)/,hx=/^\s*([‘”=>\/&#]|<(?:\/|\!(?:–)?)?|[a-zA-Z][a-zA-Z0-9_\-]*|[0-9]+|–|.)/,nx=/[\u0000-\u001f&<“\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/,nxg=/[\u0000-\u001f&<“\/\\\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,ox=/[>&]|<[\/!]?|–/,lx=/\*\/|\/\*/,ix=/^([a-zA-Z_$][a-zA-Z0-9_$]*)$/,jx=/^(?:javascript|jscript|ecmascript|vbscript|mocha|livescript)\s*:/i,ux=/&|\+|\u00AD|\.\.|\/\*|%[^;]|base64|url|expression|data|mailto/i,sx=/^\s*([{:#*%.=,>+\[\]@()”‘;*]|[a-zA-Z0-9_][a-zA-Z0-9_\-]*|<\/|\/\*)/,ssx=/^\s*([@#!”‘};:\-%.=,+\[\]()*_]|[a-zA-Z][a-zA-Z0-9._\-]*|\/\*?|\d+(?:\.\d+)?|<\/)/,qx=/[^a-zA-Z0-9-_\/ ]/,dx=/[\[\]\/\\”‘*<>.&:(){}+=#]/,rx={outer:hx,html:hx,style:sx,styleproperty:ssx};function F(){}

Lint at line 119 character 36: eval is evil.
if(!option.evil&&nexttoken.value===’eval’){warning(“eval is evil.”,nexttoken);}}

Lint at line 350 character 604: eval is evil.
return this;},led:function(){error(“Expected an operator and instead saw ‘{a}’.”,nexttoken,nexttoken.value);}};type(‘(regexp)’,function(){return this;});delim(‘(endline)’);delim(‘(begin)’);delim(‘(end)’).reach=true;delim(‘</’).reach=true;delim(‘<!’);delim(‘<!–‘);delim(‘–>’);delim(‘(error)’).reach=true;delim(‘}’).reach=true;delim(‘)’);delim(‘]’);delim(‘”‘).reach=true;delim(“‘”).reach=true;delim(‘;’);delim(‘:’).reach=true;delim(‘,’);delim(‘#’);delim(‘@’);reserve(‘else’);reserve(‘case’).reach=true;reserve(‘catch’);reserve(‘default’).reach=true;reserve(‘finally’);reservevar(‘arguments’);reservevar(‘eval’);reservevar(‘false’);reservevar(‘Infinity’);reservevar(‘NaN’);reservevar(‘null’);reservevar(‘this’);reservevar(‘true’);reservevar(‘undefined’);assignop(‘=’,’assign’,20);assignop(‘+=’,’assignadd’,20);assignop(‘-=’,’assignsub’,20);assignop(‘*=’,’assignmult’,20);assignop(‘/=’,’assigndiv’,20).nud=function(){error(“A regular expression literal can be confused with ‘/=’.”);};assignop(‘%=’,’assignmod’,20);bitwiseassignop(‘&=’,’assignbitand’,20);bitwiseassignop(‘|=’,’assignbitor’,20);bitwiseassignop(‘^=’,’assignbitxor’,20);bitwiseassignop(‘<<=’,’assignshiftleft’,20);bitwiseassignop(‘>>=’,’assignshiftright’,20);bitwiseassignop(‘>>>=’,’assignshiftrightunsigned’,20);infix(‘?’,function(left,that){that.left=left;that.right=parse(10);advance(‘:’);that[‘else’]=parse(10);return that;},30);infix(‘||’,’or’,40);infix(‘&&’,’and’,50);bitwise(‘|’,’bitor’,70);bitwise(‘^’,’bitxor’,80);bitwise(‘&’,’bitand’,90);relation(‘==’,function(left,right){if(option.eqeqeq){warning(“Expected ‘{a}’ and instead saw ‘{b}’.”,this,’===’,’==’);}else if(isPoorRelation(left)){warning(“Use ‘{a}’ to compare with ‘{b}’.”,this,’===’,left.value);}else if(isPoorRelation(right)){warning(“Use ‘{a}’ to compare with ‘{b}’.”,this,’===’,right.value);}

Lint at line 373 character 34: eval is evil.
if(!option.evil){if(left.value===’eval’||left.value===’Function’||left.value===’execScript’){warning(“eval is evil.”,left);}else if(p[0]&&p[0].id==='(string)’&&(left.value===’setTimeout’||left.value===’setInterval’)){warning(“Implied eval is evil. Pass a function instead of a string.”,left);}}

Lint at line 445 character 248: eval is evil.
if(o.safe){o.browser=false;o.css=false;o.debug=false;o.eqeqeq=true;o.evil=false;o.forin=false;o.nomen=true;o.on=false;o.rhino=false;o.safe=true;o.sidebar=false;o.strict=true;o.sub=false;o.undef=true;o.widget=false;predefined.Date=false;predefined[‘eval’]=false;predefined.Function=false;predefined.Object=false;predefined.ADSAFE=true;predefined.lib=true;}

real    1m52.358s
user    1m52.047s
sys    0m0.232s

Ok, looks like their code is ok if the childish “eval is evil” warnings are ignored. However what does JavaScript Lint say. Turns out it’s much more interesting:

time jsl -conf /my/bin/jsl.conf -process jslint.js
JavaScript Lint 0.3.0 (JavaScript-C 1.5 2004-09-24)
Developed by Matthias Miller (http://www.JavaScriptLint.com)

jslint.js
/my/bin/jslint.js(32): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(32): lint warning: missing default case in switch statement
/my/bin/jslint.js(33): warning: anonymous function does not always return a value
/my/bin/jslint.js(42): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(43): warning: function string does not always return a value
/my/bin/jslint.js(53): lint warning: regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
/my/bin/jslint.js(59): warning: anonymous function does not always return a value
/my/bin/jslint.js(61): warning: anonymous function does not always return a value
/my/bin/jslint.js(62): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(67): lint warning: use of label
/my/bin/jslint.js(71): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(72): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(72): lint warning: missing default case in switch statement
/my/bin/jslint.js(81): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(81): lint warning: missing default case in switch statement
/my/bin/jslint.js(82): warning: anonymous function does not always return a value
/my/bin/jslint.js(83): warning: anonymous function does not always return a value
/my/bin/jslint.js(86): warning: anonymous function does not always return a value
/my/bin/jslint.js(87): warning: anonymous function does not always return a value
/my/bin/jslint.js(90): warning: anonymous function does not always return a value
/my/bin/jslint.js(90): warning: anonymous function does not always return a value
/my/bin/jslint.js(97): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(97): lint warning: missing default case in switch statement
/my/bin/jslint.js(114): lint warning: missing default case in switch statement
/my/bin/jslint.js(160): warning: anonymous function does not always return a value
/my/bin/jslint.js(166): warning: anonymous function does not always return a value
/my/bin/jslint.js(172): warning: function identifier does not always return a value
/my/bin/jslint.js(184): warning: function statement does not always return a value
/my/bin/jslint.js(185): lint warning: regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
/my/bin/jslint.js(193): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(193): lint warning: missing default case in switch statement
/my/bin/jslint.js(222): lint warning: missing default case in switch statement
/my/bin/jslint.js(222): warning: function cssWidth does not always return a value
/my/bin/jslint.js(229): warning: function cssCommaList does not always return a value
/my/bin/jslint.js(230): lint warning: empty statement or extra semicolon
/my/bin/jslint.js(247): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(248): warning: anonymous function does not always return a value
/my/bin/jslint.js(255): lint warning: missing default case in switch statement
/my/bin/jslint.js(261): warning: function styleValue does not always return a value
/my/bin/jslint.js(280): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(282): warning: function stylePattern does not always return a value
/my/bin/jslint.js(289): lint warning: regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
/my/bin/jslint.js(289): lint warning: regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
/my/bin/jslint.js(293): lint warning: regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
/my/bin/jslint.js(306): lint warning: duplicate case in switch statements
/my/bin/jslint.js(306): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(309): lint warning: missing default case in switch statement
/my/bin/jslint.js(343): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(347): lint warning: missing default case in switch statement
/my/bin/jslint.js(349): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(349): lint warning: missing default case in switch statement
/my/bin/jslint.js(349): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(356): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(399): warning: function functionparams does not always return a value
/my/bin/jslint.js(399): warning: function functionparams does not always return a value
/my/bin/jslint.js(411): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(412): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(414): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(414): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(415): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(424): warning: anonymous function does not always return a value
/my/bin/jslint.js(442): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(452): lint warning: missing break statement for last case in switch
/my/bin/jslint.js(466): lint warning: missing default case in switch statement

0 error(s), 64 warning(s)
real 0m0.083s
user 0m0.068s
sys 0m0.008s

So, kind of neat how jslint.js is a JavaScript file but it appears to be weak, wimpy, and worthless. Meaning it doesn’t catch nearly as many possible problems and it took over 1652 times longer than JavaScript Lint.

However. The website version of jslint is much better. It’s faster and allows various options than it’s CLI version. Still it reported what seemed like spurious errors and miscellaneous information that was just plain confusing if even correct. (It was probably correct but I just didn’t have the desire to figure out what it was going on about.) The options are fun to play with but who wants to cut and paste to a website?

May 4, 2009

JavaScript Code Coverage On Ubuntu

Filed under: Code Coverage, Firefox, howto, Linux, tutorial, ubuntu — Tags: , — ioconnor @ 10:24 am

I’ve been playing with JavaScript looking for QA tools, getting JavaScript Lint in vim on Ubuntu, etc.. Now I’ve got code coverage analysis going for it. Follow these instructions to install JavaScript Code Coverage on Ubuntu:

  1. Download from and unpack.
  2. Change directory to where it was unpacked:

    cd jscoverage-0.4/
  3. Configure the environment for Ubuntu:

    ./configure
  4. Compile the program:

    make
  5. Copy jscoverage-server to your personal bin:

    cp jscoverage-server /my/bin
  6. The jscoverage documentation does not mention it but you must start jscoverage-server from the directory where it is to be serving the javascript from. So to run their examples move to the directory where their example code is:

    cd jscoverage-0.4/doc/example/
  7. Now start up the coverage server from the same directory the javascript is located:

    jscoverage-server –verbose
  8. Open up a browser where index.html is the starting point of the code you are going to test:

    firefox http://127.0.0.1:8080/jscoverage.html?index.html
  9. Execute the code a bit and then move to the store tab and press the store button.
  10. Open up another browser to view the results:

    firefox jscoverage-report/jscoverage.html
  11. Possibly open another browser, like opera, and test with it. All the additional tests will be added to the report.
  12. Now if you have the directory available via the network test the code with IE.

At this point it’s a simple matter of writing the javascript as a separate library.
Once in a separate library each function can be called separately.
Unit tests can then be written attempting to maximize code coverage and results can be verified.
Once this is done then the user interfaces can be tested.

There are some caveats listed in the manual. They all seem quite acceptable.

  1. JSCoverage adds instrumentation to JavaScript code, which will slow down execution speed. Expect instrumented code to take at least twice as much time to run.
  2. JSCoverage currently instruments only .js files; it does not instrument code in script elements in HTML files.
  3. HTML files must use relative URLs to reference scripts. If you use an absolute URL, your page will reference the original uninstrumented script rather than the instrumented one, and no code coverage data will be collected.
  4. JSCoverage instruments physical lines of code rather than logical JavaScript statements; it works bests with code that has exactly one statement per line. If you put multiple statements on a line, or split a line across two or more statements, you may get strange results.
  5. JSCoverage uses frames. Some web pages that use frames may not function properly when run under JSCoverage, especially those which try to access the top-level frame (window.top, target=”_top”, etc.).

I don’t see any way of incorporating the results into vim.
It would be nice if that were possible though.
I think the best that can be done would simply be to start a page that would call the various functions with assert statements.
Perhaps via a bash script.
Maybe I’ll learn more when I look into the jsunit tools.
As it now stands all of the error paths are questionable.
Still it’s better than no code coverage.

April 25, 2009

Upgrading To Ubuntu Jaunty From Intrepid

Filed under: Linux, ubuntu — Tags: , , — ioconnor @ 1:46 pm

I just finished upgrading one computer. The boot up process seems much faster but in reality it only dropped from 28 to 21 seconds. I like it. Here are the problems I encountered:

  • I had to install pybootchartgui to see the png files. This was not available in the earlier releases of Ubuntu. You got the png files just fine without them. Not a big deal.
  • The auto login feature was turned off. Again no big deal. “System->Administration->Login Window” then tab to “Security” and click the check off box for “Enable Automatic Login” and supply the proper user.
  • The wireless network is no longer automatically logged into consistently. Actually it’s only worked once out of four boots now. I see the developers claiming it is not a bug and that people must have faulty hardware and such. Same old story with whiny developers. It will probably be taken care of within a week. Until then I have to have a mouse plugged into that machine so I can manually turn on the network and then I can use the regular networked mouse and keyboard through Synergy.
  • The first attempt at upgrading failed after about 5 hours. It was half way through. I restarted it and it finished over night. This is the first time an upgrade between Ubuntu versions has worked for me…
  • I will probably want to wipe the disk and use ext4 at some point. Maybe on the next release of Ubuntu when the bugs have been worked out by actual people using it.

UPDATE 2009.04.27: I installed Jaunty 32 bit desktop on an old computer this weekend from scratch. (After I got the computer working for him.) It was not obvious to me how to install ext4. So I stuck with ext3. Still it starts in only 19 seconds! The system was snappy and everbody was pleased. I’ve now looked into ext4 and it is not ready for use. According to the official Ubuntu site  https://wiki.ubuntu.com/JauntyJackalope/ReleaseNotes#line-145 there are numerous errors with ext4 including hanging when files are deleted, not booting with grub, and possible data losses.

April 4, 2009

Stripped Google Gears Causing Accidents

Filed under: debugging, Firefox, GEARS, GOOGLE, howto, JavaScript, Linux, tutorial, typeof, ubuntu — Tags: , , , , , — ioconnor @ 12:02 am

Attempting to use Google Gears when it is not installed on a user’s browser causes an error. You’d think their library would handle this more gracefully than just crashing but it doesn’t.
UPDATED 2009.04.04: Their library should define the call but return something akin to an alert warning the user/developer

The crash occurs on this line:

g_db = google.gears.factory.create(‘beta.database’);

I pulled out my “JavaScript The Definitive Guide 5th Edition” looking for how to get around this. (This is my primary reference book for all things JavaScript. Perhaps if I were better at JavaScript it would be second nature but I’m not good at JavaScript so I spend lots of time looking things up.) I figured “google…” was not defined. So I looked at the index and put a paperclip on each page in the book referenced by the index. Then I tried all sorts of combinations none of which would work. Things like:

if (google === undefined) {
alert(“A”);
} else {
alert(“B”);
}

and

if (google == undefined) {
alert(“A”);
} else {
alert(“B”);
}

and

if (“gears” in google) {
alert(“A”);
} else {
alert(“B”);
}

and

if (google) {
alert(“A”);
} else {
alert(“B”);
}

and

if (google.gears) {
alert(“A”);
} else {
alert(“B”);
}

and

if (“length” in google) {
alert(“A”);
} else {
alert(“B”);
}

but none of above worked! There were no other solutions in my reference book. My reference book doth sucketh.

So I used a try/catch for a while but I’d still get an error message in the “error console”. The try/catch is ugly but it let me do what I needed and polluting the error console seems to be acceptable. Everybody does it. Just leave the error console open while browsing the web to see how rampant the pollution is.

However I revisited this problem today. After extensive googling seeing all sorts of “solutions” that were similar to the above and which did not work I happened to find the following:

if (typeof(google) == ‘undefined’) {

I’m using Firefox 3.0.8 if this makes any difference. It’s the very latest version as of this month from Mozilla. I’ve got to remember this solution in the future!

Older Posts »

Create a free website or blog at WordPress.com.