Ivor O’Connor

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 2, 2009

JavaScriptLint, Vim, And Ubuntu

Filed under: debugging, Firefox, Lint — Tags: , , , , , , — ioconnor @ 7:30 pm

In my blog https://ioconnor.wordpress.com/2009/04/24/javascript-testing/ I looked into some tools to help in my JavaScript development. I haven’t had the time, (or urge?), to do anything until this morning. This morning though I got JavaScriptLint working. The documentation at the site is less than adequate so I’m adding notes here to help me if I need to install it again in the future.

  1. The Linux download is here: http://www.javascriptlint.com/download.htm
  2. After decompressing it you’ll notice there is only a single horribly wrong README.html file. To get things working compile it by going to the src directory and typing:
    make -f Makefile.ref
  3. A jsl will now be found in jsl-0.3.0/src/Linux_All_DBG.OBJ/jsl. To make it generally accessible do something like:
    ln -s /whatever/jsl-0.3.0/src/Linux_All_DBG.OBJ /my/bin/jsl
  4. Running jsl will show the parameters that are needed. If you are like me you’ll wonder where the configuration file is that they mention. It’s not on their website and it certainly is nowhere on my disk. So I googled around until I found it, or close to what it should probaly be, and have copied it down below. I called the file “jsl.conf” and stuck it in /my/bin/jsl.conf.
  5. It’s all fine and good running it on the command line. It even looks at the javascript code in html files. I found quite a few questionable pieces of code and one clear mistake on my part that fortunately was not causing any problems. From the command line type something like:
    jsl -conf /my/bin/jsl.conf -process /my/dev/taxes2.html
    The -conf /my/bin/jsl.conf is optional.
  6. To run it from within vim by pressing the <F9> key edit the vimrc file and include something like:
    map <F9> : call JavaScriptLint()<CR>
    func! JavaScriptLint()
    exec “w” “Save the file
    exec “!jsl -conf /my/bin/jsl.conf -process % ”
    endfunc

I might change this so the editor dumps me on the line that’s bad with an error message. Or into an error file that can be toggled back and forth from. However it is usable enough for me in it’s current form.

The conf file I’m using looks like this:

#
# Configuration File for JavaScript Lint 0.3.0
# Developed by Matthias Miller (http://www.JavaScriptLint.com)
#
# This configuration file can be used to lint a collection of scripts, or to enable
# or disable warnings for scripts that are linted via the command line.
#

### Warnings
# Enable or disable warnings based on requirements.
# Use “+WarningName” to display or “-WarningName” to suppress.
#
+no_return_value # function {0} does not always return a value
+duplicate_formal # duplicate formal argument {0}
+equal_as_assign # test for equality (==) mistyped as assignment (=)?{0}
+var_hides_arg # variable {0} hides argument
+redeclared_var # redeclaration of {0} {1}
+anon_no_return_value # anonymous function does not always return a value
+missing_semicolon # missing semicolon
+meaningless_block # meaningless block; curly braces have no impact
+comma_separated_stmts # multiple statements separated by commas (use semicolons?)
+unreachable_code # unreachable code
+missing_break # missing break statement
+missing_break_for_last_case # missing break statement for last case in switch
+comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==)
+inc_dec_within_stmt # increment (++) and decrement (–) operators used as part of greater statement
+useless_void # use of the void type may be unnecessary (void is always undefined)
+multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x—y) signs
+use_of_label # use of label
+block_without_braces # block statement without curly braces
+leading_decimal_point # leading decimal point may indicate a number or an object member
+trailing_decimal_point # trailing decimal point may indicate a number or an object member
+octal_number # leading zeros make an octal number
+nested_comment # nested comment
+misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma
+ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement
+empty_statement # empty statement or extra semicolon
-missing_option_explicit # the “option explicit” control comment is missing
+partial_option_explicit # the “option explicit” control comment, if used, must be in the first script tag
+dup_option_explicit # duplicate “option explicit” control comment
+useless_assign # useless assignment
+ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity
+ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent)
+missing_default_case # missing default case in switch statement
+duplicate_case_in_switch # duplicate case in switch statements
+default_not_at_end # the default case is not at the end of the switch statement
+legacy_cc_not_understood # couldn’t understand control comment using /*@keyword@*/ syntax
+jsl_cc_not_understood # couldn’t understand control comment using /*jsl:keyword*/ syntax
+useless_comparison # useless comparison; comparing identical expressions
+with_statement # with statement hides undeclared variables; use temporary variable instead
+trailing_comma_in_array # extra comma is not recommended in array initializers
+assign_to_function_call # assignment to a function call
+parseint_missing_radix # parseInt missing radix parameter

### Output format
# Customize the format of the error message.
# __FILE__ indicates current file path
# __FILENAME__ indicates current file name
# __LINE__ indicates current line
# __ERROR__ indicates error message
#
# Visual Studio syntax (default):
+output-format __FILE__(__LINE__): __ERROR__
# Alternative syntax:
#+output-format __FILE__:__LINE__: __ERROR__

### Context
# Show the in-line position of the error.
# Use “+context” to display or “-context” to suppress.
#
-context

### Semicolons
# By default, assignments of an anonymous function to a variable or
# property (such as a function prototype) must be followed by a semicolon.
#
+lambda_assign_requires_semicolon

### Control Comments
# Both JavaScript Lint and the JScript interpreter confuse each other with the syntax for
# the /*@keyword@*/ control comments and JScript conditional comments. (The latter is
# enabled in JScript with @cc_on@). The /*jsl:keyword*/ syntax is preferred for this reason,
# although legacy control comments are enabled by default for backward compatibility.
#
+legacy_control_comments

### JScript Function Extensions
# JScript allows member functions to be defined like this:
# function MyObj() { /*constructor*/ }
# function MyObj.prototype.go() { /*member function*/ }
#
# It also allows events to be attached like this:
# function window::onload() { /*init page*/ }
#
# This is a Microsoft-only JavaScript extension. Enable this setting to allow them.
#
-jscript_function_extensions

### Defining identifiers
# By default, “option explicit” is enabled on a per-file basis.
# To enable this for all files, use “+always_use_option_explicit”
-always_use_option_explicit

# Define certain identifiers of which the lint is not aware.
# (Use this in conjunction with the “undeclared identifier” warning.)
#
# Common uses for webpages might be:
#+define window
#+define document

### Interactive
# Prompt for a keystroke before exiting.
#+pauseatend

### Files
# Specify which files to lint
# Use “+recurse” to enable recursion (disabled by default).
# To add a set of files, use “+process FileName”, “+process Folder\Path\*.js”,
# or “+process Folder\Path\*.htm”.
#
#+process jsl-test.js

April 24, 2009

JavaScript Testing

I’m finding my JavaScript code is not behaving as I’d like it to. Code I thought was solid and have been using consistently is less than solid. Code involving money. So it’s time to start rigorously testing things as if I were coding in C/C++. At http://www.opensourcetesting.org/unit_javascript.php is a list of free tools that can help.

  1. CrossCheck. It seems to concentrate on verifing the code will run on multiple browsers. Making sure things work on buggy browsers like IE is not big on my list.
  2. JavaScript Assertion Unit. Assertion testing. Might be all I need. Probably not though. I don’t want to complicate the code itself. I’d like to have a separate unit supplying the input and comparing it to expected results that can be used by code coverage tests too.
  3. JSCoverage. This runs the latest Linux and Firefox distros and looks very promising. It only checks coverage though. Nothing else.
  4. JSMock. The documentation is less than clear. I can’t tell if it can be automated, if it runs on Linux, or even what it does. Hopefully it allows test scripts to suppy and perhaps change values within the called functions and compare the results. However if it does do this it does not plainly say it.
  5. JSNUnit. A product made for M$ environments. Does not work in Linux.
  6. JSUnit. Tests multiple browser javascript on multiple OSs. It looks very promising in that you can write test scripts to run the pages, functions, and possibly even alter values. Hopefully allowing the JSCoverage to run at the same time. I’ll probably start with this tool.
  7. JSUnit. I’m not sure how this one differs from the other JSUnit. I’d best compare the two carefully before deciding which one to use.
  8. RhinoUnit. It is tied to ANT. It mentions having integrated support for JSLint.
  9. JSLint. I’m not sure if this can be run standalone. Perhaps this page will explain it better: http://www.jslint.com/rhino/index.html
  10. JavaScript Lint. Hmmm.

Some of the criteria I’m looking for are:

  1. Fully Automatable.
  2. Speed.
  3. Ease.
  4. Runs on Linux.
  5. Coverage Check.
  6. Free.
  7. Actively supported.
  8. RegEx comparisons.

The Lints are the natural place to start. I’ll somehow make some bash scripts to test them and go from there.

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!

November 27, 2008

bashdb

Filed under: bash, debugging, ubuntu — Tags: , , — ioconnor @ 7:06 pm

http://www.linux.com/feature/153383 has an article on bash debugging. Something I did not know was possible. I don’t need this now but it’s good to know it exists.

The debugging project is located at http://bashdb.sourceforge.net/

Blog at WordPress.com.