Shlomi Fish avatar Shlomi Fish committed cff8ff8

Add a test for trailing space.

It is currently failing, but a lot of trailing space was removed.

We need to whitelist some files whose trailing space we'd like to keep.

Comments (0)

Files changed (105)

 LATEMP_WML_FLAGS := $(shell latemp-config --wml-flags)
 
-COMMON_PREPROC_FLAGS = -I $$HOME/conf/wml/Latemp/lib 
+COMMON_PREPROC_FLAGS = -I $$HOME/conf/wml/Latemp/lib
 WML_FLAGS += --passoption=2,-X3074 --passoption=3,-I../lib/ \
 	--passoption=3,-w -I../lib/ $(LATEMP_WML_FLAGS) \
 	-DROOT~. -DLATEMP_THEME=better-scm \
 include include.mak
 include rules.mak
 
-make-dirs: $(T2_DIRS_DEST) 
+make-dirs: $(T2_DIRS_DEST)
 
 FORTUNES_DIR = humour/fortunes
 T2_FORTUNES_DIR = t2/$(FORTUNES_DIR)
 
 copy_fortunes: $(T2_DEST_FORTUNES)
 
+test: all
+	prove Tests/*.t
+
+runtest: all
+	runprove Tests/*.t
+
 upload_deps: all
 
 upload_local: upload_deps
 T2_PHILOSOPHY_DOCS = \
 	$(filter $(T2_DEST)/philosophy/%,$(T2_DOCS_DEST)) \
 	$(filter $(T2_DEST)/prog-evolution/%,$(T2_DOCS_DEST)) \
-	$(filter $(T2_DEST)/DeCSS/%,$(T2_DOCS_DEST)) 
+	$(filter $(T2_DEST)/DeCSS/%,$(T2_DOCS_DEST))
 
 $(T2_PHILOSOPHY_DOCS): %: $(PHILOSOPHY_DEPS)
 
 
 $(T2_HUMOUR_DOCS_DEST): $(HUMOUR_DEPS)
 
-VIPE_HUMOUR_DOCS_SRC = 
+VIPE_HUMOUR_DOCS_SRC =
 
 $(VIPE_HUMOUR_DOCS_SRC): $(VIPE_SRC_DIR)/%.wml: $(HUMOUR_DEPS)
 	touch $@
 
 FICTION_TEXT_SOURCES_ON_DEST = $(T2_DEST)/humour/Pope/The-Pope-Died-on-Sunday-hebrew.txt $(HHFG_HEB_V2_DEST) $(HHFG_HEB_V2_XSLT_DEST)
 
-$(FICTION_DB5S): $(DOCBOOK5_XML_DIR)/%.xml: $(FICTION_XML_XML_DIR)/%.xml 
+$(FICTION_DB5S): $(DOCBOOK5_XML_DIR)/%.xml: $(FICTION_XML_XML_DIR)/%.xml
 	xslt="$(patsubst $(FICTION_XML_XML_DIR)/%.xml,$(FICTION_XML_DB5_XSLT_DIR)/%.xslt,$<)" ; \
 	temp_db5="$(patsubst $(FICTION_XML_XML_DIR)/%.xml,$(FICTION_XML_TEMP_DB5_DIR)/%.xml,$<)" ; \
 	if test -e "$$xslt" ; then \
 
 $(HHGG_CONVERT_SCRIPT_DEST): $(HHGG_CONVERT_SCRIPT_SRC)
 	cp -f $< $@
-	
+
 hhgg_convert: $(HHGG_CONVERT_SCRIPT_DEST)
 
 $(SCREENPLAY_XML_TXT_DIR)/hitchhikers-guide-to-star-trek-tng.txt : $(HHGG_CONVERT_SCRIPT_SRC) t2/humour/by-others/hitchhiker-guide-to-star-trek-tng.txt
 $(T2_DEST)/open-source/projects/XML-Grammar/Fiction/index.html: $(FICTION_XML_TXT_DIR)/fiction-text-example-for-X-G-Fiction-demo.txt
 $(T2_DEST)/open-source/projects/XML-Grammar/Fiction/index.html: $(DOCBOOK5_RENDERED_DIR)/fiction-text-example-for-X-G-Fiction-demo.xhtml
 
-# Rebuild the embedded docbook4 pages in the $(T2_DEST) after they are 
+# Rebuild the embedded docbook4 pages in the $(T2_DEST) after they are
 # modified.
 
 $(T2_DEST)/philosophy/computers/high-quality-software/rev2/index.html : $(DOCBOOK4_RENDERED_DIR)/what-makes-software-high-quality-rev2.html
 
 $(T2_DEST)/philosophy/computers/software-management/perfect-workplace/perfect-it-workplace.xhtml : $(DOCBOOK4_RENDERED_DIR)/perfect-it-workplace.html
 
-# Rebuild the embedded docbook5 pages in the $(T2_DEST) after they are 
+# Rebuild the embedded docbook5 pages in the $(T2_DEST) after they are
 # modified.
 
 $(T2_DEST)/philosophy/psychology/hypomanias/index.html: $(DOCBOOK5_RENDERED_DIR)/dealing-with-hypomanias.xhtml
 SASS_STYLE = compressed
 SASS_CMD = sass --style $(SASS_STYLE)
 
-$(T2_CSS_TARGETS): $(T2_DEST)/%.css: lib/sass/%.sass 
+$(T2_CSS_TARGETS): $(T2_DEST)/%.css: lib/sass/%.sass
 	$(SASS_CMD) $< $@
 
 $(VIPE_CSS_TARGETS): $(VIPE_DEST)/%.css: lib/sass/%.sass
 
 # $(T2_CSS_TARGETS) : $(T2_DEST)/% : lib/%.ttml $(CSS_TARGETS_COMMON_DEPS)
 # 	perl $(CSS_GEN_SCRIPT) -o $@ $(T2_TTML_FLAGS) -DLATEMP_FILENAME=$(patsubst $(T2_DEST)/%,%,$(patsubst %.ttml,%,$@)) $<
-# 
+#
 # $(VIPE_CSS_TARGETS) : $(VIPE_DEST)/% : lib/%.ttml $(CSS_TARGETS_COMMON_DEPS)
 # 	perl $(CSS_GEN_SCRIPT) -o $@ $(VIPE_TTML_FLAGS) -DLATEMP_FILENAME=$(patsubst $(VIPE_DEST)/%,%,$(patsubst %.ttml,%,$@)) $<
-# 
+#
 # $(T2_DEST)/screenplay.css: lib/screenplay-xml/css/screenplay.css.ttml $(CSS_TARGETS_COMMON_DEPS)
 # 	perl $(CSS_GEN_SCRIPT) -o $@ $(T2_TTML_FLAGS) -DLATEMP_FILENAME=$(patsubst $(T2_DEST)/%,%,$(patsubst %.ttml,%,$@)) $<
 #
 docbook_extended: $(DOCBOOK4_FOS) $(DOCBOOK4_PDFS) \
 	$(DOCBOOK5_FOS) $(DOCBOOK5_PDFS) \
 	install_docbook4_pdfs install_docbook4_rtfs \
-	install_docbook5_pdfs install_docbook5_rtfs 
+	install_docbook5_pdfs install_docbook5_rtfs
 
 docbook_indiv: $(DOCBOOK4_INDIVIDUAL_XHTMLS)
 

Tests/style-trailing-space.t

+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 1;
+
+{
+    open my $ack_fh, '-|', 'ack', '-l', q/[ \t]+$/, '.'
+        or die "Cannot open ack for input - $!";
+
+    my $count_lines = 0;
+    while (my $l = <$ack_fh>)
+    {
+        $count_lines++;
+        diag($l);
+    }
+
+    # TEST
+    is ($count_lines, 0, "Count lines is 0.");
+
+    close($ack_fh);
+}

common/404.html.wml

 <h1>404 Not Found</h1>
 
 <p>
-<a href="/" title="Shlomi Fish’s Homepage"><img 
+<a href="/" title="Shlomi Fish’s Homepage"><img
     src="/images/evilphish.png"
     alt="EvilPHish from UserFriendly.org by Illiad" /></a>
 </p>

common/images/domtab.js

 	DOMtab Version 3.1415927
 	Updated March the First 2006
 	written by Christian Heilmann
-	check blog for updates: http://www.wait-till-i.com	
+	check blog for updates: http://www.wait-till-i.com
 	free to use, not free to resell
 */
 
 	init:function(){
 		var temp;
 		if(!document.getElementById || !document.createTextNode){return;}
-		var tempelm=document.getElementsByTagName('div');		
+		var tempelm=document.getElementsByTagName('div');
 		for(var i=0;i<tempelm.length;i++){
 			if(!domtab.cssjs('check',tempelm[i],domtab.tabClass)){continue;}
 			domtab.initTabMenu(tempelm[i]);
 			}
 			domtab.checkURL();
 		}
-		if(document.getElementById(domtab.printID) 
+		if(document.getElementById(domtab.printID)
 		   && !document.getElementById(domtab.printID).getElementsByTagName('a')[0]){
 			var newlink=document.createElement('a');
 			newlink.setAttribute('href','#');
 	},
 	showAll:function(e){
 		document.getElementById(domtab.printID).parentNode.removeChild(document.getElementById(domtab.printID));
-		var tempelm=document.getElementsByTagName('div');		
+		var tempelm=document.getElementsByTagName('div');
 		for(var i=0;i<tempelm.length;i++){
 			if(!domtab.cssjs('check',tempelm[i],domtab.tabClass)){continue;}
 			var sec=tempelm[i].getElementsByTagName(domtab.contentElements);
 				sec[j].style.display='block';
 			}
 		}
-		var tempelm=document.getElementsByTagName('ul');		
+		var tempelm=document.getElementsByTagName('ul');
 		for(i=0;i<tempelm.length;i++){
 			if(!domtab.cssjs('check',tempelm[i],domtab.prevNextClass)){continue;}
 			tempelm[i].parentNode.removeChild(tempelm[i]);
 		}
 	},
 	addEvent: function(elm, evType, fn, useCapture){
-		if (elm.addEventListener) 
+		if (elm.addEventListener)
 		{
 			elm.addEventListener(evType, fn, useCapture);
 			return true;
 	}
 }
 domtab.addEvent(window, 'load', domtab.init, false);
-	
+

common/js/treeview/jquery.treeview.css

-.treeview, .treeview ul { 
+.treeview, .treeview ul {
 	padding: 0;
 	margin: 0;
 	list-style: none;
 	float:none;
 }
 
-.treeview li { 
+.treeview li {
 	margin: 0;
 	padding: 3px 0pt 3px 16px;
 }
 .treeview .expandable-hitarea { background-position: -80px -3px; }
 
 .treeview li.last { background-position: 0 -1766px }
-.treeview li.lastCollapsable, .treeview li.lastExpandable { background-image: url(images/treeview-default.gif); }  
+.treeview li.lastCollapsable, .treeview li.lastExpandable { background-image: url(images/treeview-default.gif); }
 .treeview li.lastCollapsable { background-position: 0 -111px }
 .treeview li.lastExpandable { background-position: -32px -67px }
 
 .treeview div.lastCollapsable-hitarea, .treeview div.lastExpandable-hitarea { background-position: 0; }
 
 .treeview-red li { background-image: url(images/treeview-red-line.gif); }
-.treeview-red .hitarea, .treeview-red li.lastCollapsable, .treeview-red li.lastExpandable { background-image: url(images/treeview-red.gif); } 
+.treeview-red .hitarea, .treeview-red li.lastCollapsable, .treeview-red li.lastExpandable { background-image: url(images/treeview-red.gif); }
 
 .treeview-black li { background-image: url(images/treeview-black-line.gif); }
-.treeview-black .hitarea, .treeview-black li.lastCollapsable, .treeview-black li.lastExpandable { background-image: url(images/treeview-black.gif); }  
+.treeview-black .hitarea, .treeview-black li.lastCollapsable, .treeview-black li.lastExpandable { background-image: url(images/treeview-black.gif); }
 
 .treeview-gray li { background-image: url(images/treeview-gray-line.gif); }
-.treeview-gray .hitarea, .treeview-gray li.lastCollapsable, .treeview-gray li.lastExpandable { background-image: url(images/treeview-gray.gif); } 
+.treeview-gray .hitarea, .treeview-gray li.lastCollapsable, .treeview-gray li.lastExpandable { background-image: url(images/treeview-gray.gif); }
 
 .treeview-famfamfam li { background-image: url(images/treeview-famfamfam-line.gif); }
-.treeview-famfamfam .hitarea, .treeview-famfamfam li.lastCollapsable, .treeview-famfamfam li.lastExpandable { background-image: url(images/treeview-famfamfam.gif); } 
+.treeview-famfamfam .hitarea, .treeview-famfamfam li.lastCollapsable, .treeview-famfamfam li.lastExpandable { background-image: url(images/treeview-famfamfam.gif); }
 
 
 .filetree li { padding: 3px 0 2px 16px; }

common/lecture/index.html.wml

 for Perl Newbies</a></h2>
 
 <p>
-A series of lectures that teach Perl for Perl beginners. No knowledge of 
+A series of lectures that teach Perl for Perl beginners. No knowledge of
 any other programming language is required, but it will be helpful.
 </p>
 
 <h3 id="haskell-for-perlers"><a href="./Perl/Haskell/">Haskell for Perl Programmers</a></h3>
 
 <p>
-A Haskell for Perl Programmers introduction. (part of the Israeli Perl 
-Mongers, Foreign Language Introductions). Perl-specific knowledge is not 
-required and can be substituted by knowledge of a similar programming 
+A Haskell for Perl Programmers introduction. (part of the Israeli Perl
+Mongers, Foreign Language Introductions). Perl-specific knowledge is not
+required and can be substituted by knowledge of a similar programming
 language.
 </p>
 
 <a href="./Gimp/">Do it with the GIMP</a>
 </dt>
 <dd>
-a lecture about the <a href="http://www.gimp.org/">GNU Image 
-Manipulation Program</a>, a free Photoshop-like alternative with many 
+a lecture about the <a href="http://www.gimp.org/">GNU Image
+Manipulation Program</a>, a free Photoshop-like alternative with many
 powerful features.
 </dd>
 <dt>
 <a href="./PostgreSQL-Lecture/">The PostgreSQL Database Server</a>
 </dt>
 <dd>
-A lecture about the Postgres database server, a free and powerful SQL 
+A lecture about the Postgres database server, a free and powerful SQL
 server for UNIX systems.
 </dd>
 <dt>
 A tool for helping generate sophisticated static HTML web-sites.
 </dd>
 <dt>
-<a href="<rellink url="lecture/Vim/beginners/" host="t2" />">The Vim 
+<a href="<rellink url="lecture/Vim/beginners/" host="t2" />">The Vim
 Editor for Beginners</a>
 </dt>
 <dd>
 
 <div class="indent">
 <p>
-Presentation Material that was prepared as part of the 
+Presentation Material that was prepared as part of the
 <a href="http://welcome.linux.org.il/">Israeli Welcome to Linux series</a>.
 Aims to introduce the Linux operating system to beginners.
 </p>
 <h4 id="fcs-the-next-pres"><a href="./Freecell-Solver/The-Next-Pres/">Freecell Solver - The Next Presentation</a></h4>
 
 <p>
-More recent history and development of the project. 
+More recent history and development of the project.
 </p>
 
 <h4 id="fcs-project-intro"><a href="./Freecell-Solver/project-intro/">Freecell Solver: Project Introduction</a></h4>
 .navbar, .menu_floaty, .menu_floaty .sub_menu, .banner,
 .leading_path, .invisible, .page_toc, .wishlist_notice, .lang_switch,
 .bt_nav, img[alt="Back to my Homepage"], p.share
-{ 
+{
     display: none;
 }
 .hebrew
 use File::Find::Object::Rule;
 use IO::All;
 
-my $generator = 
+my $generator =
     HTML::Latemp::GenMakeHelpers->new(
         'hosts' =>
-        [ map { 
+        [ map {
             +{ 'id' => $_, 'source_dir' => $_,
-                'dest_dir' => "\$(ALL_DEST_BASE)/$_-homepage" 
-            } 
+                'dest_dir' => "\$(ALL_DEST_BASE)/$_-homepage"
+            }
         } (qw(common t2 vipe)) ],
     );
-    
+
 $generator->process_all();
 
 
 <!-- See http://docbook.org/ns/docbook -->
 <!--
     This file is part of DocBook V5.0
-    
+
     Copyright 1992-2008 HaL Computer Systems, Inc.,
     O'Reilly & Associates, Inc., ArborText, Inc., Fujitsu Software
     Corporation, Norman Walsh, Sun Microsystems, Inc., and the
     Organization for the Advancement of Structured Information
     Standards (OASIS).
-    
+
     Release: $Id: docbook.rnc 7661 2008-02-06 13:52:59Z nwalsh $
-    
+
     Permission to use, copy, modify and distribute the DocBook schema
     and its accompanying documentation for any purpose and without fee
     is hereby granted in perpetuity, provided that the above copyright
     holders make no representation about the suitability of the schema
     for any purpose. It is provided "as is" without expressed or implied
     warranty.
-    
+
     If you modify the DocBook schema in any way, label your schema as a
     variant of DocBook. See the reference documentation
     (http://docbook.org/tdg5/en/html/ch05.html#s-notdocbook)
     for more information.
-    
+
     Please direct all questions, bug reports, or suggestions for changes
     to the docbook@lists.oasis-open.org mailing list. For more
     information, see http://www.oasis-open.org/docbook/.
-    
+
     ======================================================================
   -->
   <start>

t2/guide2ee/index.html

 
 <p>
 Due to the incredibly kitchy, dysfunctional and non-standards compliant
-<a href="http://www.ee.technion.ac.il">homepage</a> 
+<a href="http://www.ee.technion.ac.il">homepage</a>
 of the Electrical Engineering Department, the site became unusable with many
 browsers, and many of the homepages of the courses disappeared from search
 engines.
 
 <p>
 I decided to create something which is more usable and hopefully allow
-search engines to retrack the homepages of the courses. The contents of 
+search engines to retrack the homepages of the courses. The contents of
 this site will be gradually filled with more information.
 </p>
 

t2/lecture/Autotools/Summary.txt

     Autoconf 2.5 the file configure.ac) and generates the ./configure script
     out of it.
     - ./configure, when ran by the user generates the normal "Makefile"
-    out of "Makefile.in" and optionally processes other files (such as 
+    out of "Makefile.in" and optionally processes other files (such as
     config.h.in -> config.h, an optional RPM Spec, Makefiles in other
     directories, etc)
 

t2/lecture/Autotools/index.html.wml

 GNU <a href="http://www.gnu.org/software/autoconf/">Autoconf</a>,
 <a href="http://www.gnu.org/software/automake/automake.html">Automake</a>
 and <a href="http://www.gnu.org/software/libtool/libtool.html">Libtool</a>
-are the de-facto standard tools for portably building and installing 
+are the de-facto standard tools for portably building and installing
 applications across variable UNIX flavours and systems.
 </p>
 
 
 <li>
 <a href="http://sources.redhat.com/autobook/">The Autobook</a> - a free
-online (or paperback) book that thoroughly covers Autoconf, Automake and 
+online (or paperback) book that thoroughly covers Autoconf, Automake and
 Libtool.
 </li>
 

t2/lecture/Bash/newfangled_summary.txt

 * "./configure" scripts are written in Bourne shell, and knowledge of it
 is required to effectively use GNU autoconf.
 
-* /bin/sh is expected to be available on any UNIX system by virtue of POSIX. 
+* /bin/sh is expected to be available on any UNIX system by virtue of POSIX.
 
 * "Csh Programming Considered Harmful" by Tom Christiansen:
 
 
 ls -l | less
 	pages the output of ls -l
-cat *.c *.h | wc -l 
+cat *.c *.h | wc -l
 	Determines how many lines are in c and h
 ls -l | grep '^d' | wc -l
 	Counts the number of directories in the CWD. (* - what MosheZ noted)
 MYVAR="More than one word"
 
 To retrieve the value use $MYVAR or "$MYVAR" if you wish it to be considered
-as one atom. Another common syntax is ${MYVAR}. 
+as one atom. Another common syntax is ${MYVAR}.
 
 The command "read MYVAR" reads a line from the standard input and places it
 inside MYVAR.
 semicolons, it was possible to write the entire expression on one line, like
 this:
 
-- The output of "expr" is redirected to /dev/null so the "0"'s and "1"'s it 
+- The output of "expr" is redirected to /dev/null so the "0"'s and "1"'s it
 returns will not be displayed.
 
 While:
 
 #!/bin/sh
 
-find . -name '*.c' | 
+find . -name '*.c' |
 (while read T ; do
-	cp $T $T.bak ; 
+	cp $T $T.bak ;
  done)
 
 For:
 && and ||
 ---------
 
-- <Statement 1> && <Statement 2> will execute Statement 2 iff Statement 1 
+- <Statement 1> && <Statement 2> will execute Statement 2 iff Statement 1
     returns a true value.
 
   <Statement 1> || <Statement 2> will execute Statement 2 iff Statement 1
 
 Bash, zsh and ash also offer $( .... ), which does the same operation
 as the backquotes except that it behaves as a sub-shell, not as a string.
-E.g: B=$( A=5 ; echo $A ) will assign 5 to B. Again, I'm not sure if 
+E.g: B=$( A=5 ; echo $A ) will assign 5 to B. Again, I'm not sure if
 proprietary System V sh's offer this functionality.
 
 
 ----------
 
 a ( ... ) wraps a sub-shell, which is a separate process that executes a
-mini-shell script. All modifications to variables inside it will not be 
+mini-shell script. All modifications to variables inside it will not be
 apparent on the main script.
 
-find . -name '*.c' | 
+find . -name '*.c' |
 (
 	while read T ; do
 		A=`echo $T | sed 's/\\.c\$//'`

t2/lecture/Bash/sub_shell.sh

-find . -name '*.c' | 
+find . -name '*.c' |
 (
 	while read T ; do
 		A=`echo $T | sed 's/\\.c\$//'`

t2/lecture/Bash/summary.txt

 * "./configure" scripts are written in Bourne shell, and knowledge of it
 is required to effectively use GNU autoconf.
 
-* /bin/sh is expected to be available on any UNIX system by virtue of POSIX. 
+* /bin/sh is expected to be available on any UNIX system by virtue of POSIX.
 
 * "Csh Programming Considered Harmful" by Tom Christiansen:
 
 ------------
 
 - Executing simple commands: command name followed by parameters
-    Examples: 
+    Examples:
         ls
         ls -l
         cp test.pl old_test.pl
 
 - Filename Matching mechanisms:
-    * 
+    *
     []
     ?
     Examples:
         ls -l *.c
         cp *.c ./bak_dir
-        
+
 - Pipeline: explain a little about standard input/standard output, then show
     the following redirection mechanisms:
     |
         cat *.c *h | wc -l
         ls -l | grep ^d | wc -l
 
-- The ";" - executing more than one statements in the same batch. A 
+- The ";" - executing more than one statements in the same batch. A
     synchronous executions.
     Examples:
         cd ./test_dir ; tar -czvf ../test_dir.tar.gz *
-    
+
 - The "(" .. ")" - grouping statements inside a _subshell_ (separate process).
     Examples:
         ( cd ./bin ; ls d* ) > files_in_bin_that_start_with_a_d.txt
 
 - Introducing comments with "#". They start with a # and extend to the end of
   the line.
-  
+
 Variables:
 ----------
 
         - A=Y
           Y=80
           echo ${$A}
-          
+
 - A little about interpolation: A dollar can appear anywhere. If the shell
   encounters a $ which is not followed by curly brackets ("{" .. "}") it will
-  try to interpolate its name from as many characters as it find, even if 
+  try to interpolate its name from as many characters as it find, even if
   a variable by that name does not exist. Thus, when in doubt, use the
   "${NAME}" form.
 
         - A=hello
           echo $Aworld
           # does not print helloworld
-    
 
-- The "${parameter:-defaultvalue}" form enables you to give the expression a 
+
+- The "${parameter:-defaultvalue}" form enables you to give the expression a
   default value in case the variable is not assigned.
     Examples:
         -
             #!/bin/bash
-            
-            ; 
+
+            ;
             ; Possibly set A
             B=${A:-not_set}
             ; Check if B is equal to not_set and accordingly do something.
-            
+
 - To unset a variable use the "unset" command:
     Examples:
         -
         unset A E
         set | grep '^[A-F]='
 
-- The "read VARNAME" command reads a line from the standard output and puts 
-  it inside the variable "VARNAME". 
+- The "read VARNAME" command reads a line from the standard output and puts
+  it inside the variable "VARNAME".
     Examples:
         echo "Please enter your name:"
         read NAME
         echo Hello $NAME
-       
-  
+
+
     - Note: Be careful not to use "read $VARNAME" when it's not appropriate.
         For example:
             #!/bin/sh
 - A backslash before a character denotes an "actual" character. Hence means,
   it cannot be processed by the shell.
     Examples:
-        - 
+        -
         echo Hello\ \ \ \ \ World        # vs.
         echo Hello     World
         -
-        echo good ; echo you        
+        echo good ; echo you
         echo good \; echo you                    # vs.
         -
         echo \\ - This is a backslash
         #!/bin/sh
         A=Hello
         echo "$A    world!"
-        
+
 - Use the single quotes to group strings which include whitespace, dollars
   and backslashes without doing variable interpolation:
     Examples:
 
     As long as there are semi-colons the commands need not be on separate
     lines. Examples:
-    
+
     -
         #!/bin/sh
         if test -e hello.txt ; then
         else
             echo "hello.txt does not exist"
         fi
-   
+
    Or the same on the same line:
-        
+
         if test -e hello.txt ; then echo "hello.txt exists" ; else echo \
             "hello.txt does not exist" ; fi
 
    The latter syntax is useful for on-the-prompt scripting.
-   
+
    -
         read A
-        if expr $A \< 100 > /dev/null ; then   
+        if expr $A \< 100 > /dev/null ; then
             echo "$A is less than 100"
         fi
 
     done
 
     Examples:
-    - 
+    -
         #!/bin/sh
         A=0
         while expr $A \< 100 > /dev/null ; do
                                # of the command.
                                # More on that later.
         done
-    
+
         This program prints the numbers from 0 to 99.
 
-    - 
+    -
         #!/bin/sh
-        find . -name '*.c' | 
+        find . -name '*.c' |
         (while read T ; do
             cp $T $T.bak ;
         done)
     for VARNAME in value1 value2 value3 ... ; do
         <For Block where you can use $VARNAME>
     done
-    
+
     Examples:
-    -    
-        for I in *.c *.h ; do 
+    -
+        for I in *.c *.h ; do
             cp $I $I.bak
         done
 
-- As far as "if" and "while" are concerned a statement is considered true if 
-    its return code is 0, and false otherwise. The return code of a program is 
+- As far as "if" and "while" are concerned a statement is considered true if
+    its return code is 0, and false otherwise. The return code of a program is
     the return code of its main() function, or what was passed as a parameter
     to exit().
 
-- The statement "true" always returns 0 and the statement "false" always 
+- The statement "true" always returns 0 and the statement "false" always
     returns 1.
 
-- You can find the return code of the last program ran by using the "$?" 
+- You can find the return code of the last program ran by using the "$?"
     variable.
 
-- <Statement 1> && <Statement 2> will execute Statement 2 iff Statement 1 
+- <Statement 1> && <Statement 2> will execute Statement 2 iff Statement 1
     returns a true value.
 
   <Statement 1> || <Statement 2> will execute Statement 2 iff Statement 1
   For example:
 
     (cd hello/ && ls) > hello.files.txt
-    
+
     test -e hello.xcf || {
         echo "hello.xcf does not exist";
         exit
         }
- 
+
 - Functions: syntax:
     function hello() {
         ## Body Of Function ##
 
     Functions are used as simple commands and with the same calling syntax.
 
-    
+
 
 Trapping Command Output
 -----------------------
 - Use the $( ... ) and ` ... ` constructs to trap the output of commands. The
     difference between the two is that `` acts very simliarly to the ""
     quotes, in the fact that it expands variables and so forth. $( ... ) on
-    the other hand, acts much like a sub-shell while differing only in the 
+    the other hand, acts much like a sub-shell while differing only in the
     fact that the output of the command is trapped.
 
     Examples:
-        
+
         A=$(cat hello.txt | grep mystring | head -1)
-        
+
         A=`cat hello.txt | grep mystring | head -1`
 
         C=`expr $A + $B` # Adds A and B and put the result in C
 
     Note: The $( ... ) notation was borrowed from the Korn Shell. It is
-    supported by bash, zsh and ash, but not by /bin/sh's of properitary 
+    supported by bash, zsh and ash, but not by /bin/sh's of properitary
     System V UNIXes. (at least not that of Solaris). Thus, if you care
     about portability you cannot use it. Instead, construct a command inside
     one variable (e.g: A="ls -l | grep ^\$A | wc -l") and then execute this
     single variable (`$A`).
 
 - Another option is to pipe the command output to a sub-shell or sub-script:
-    
+
     Examples:
-    
-    - find . -name '*.[ch]' -print | 
+
+    - find . -name '*.[ch]' -print |
         (
-        while read T ; 
+        while read T ;
             do cp $T $T.bak
         done
         )
 
-    - cat hello.txt | head -3 | { read A ; read B ; read C} # Put the 
+    - cat hello.txt | head -3 | { read A ; read B ; read C} # Put the
                             # first three lines of hello.txt in A, B and C.
 
-    
+
 - You can redirect the standard error to the standard output using the "2>&1"
   consturct. If you wish to put it in a separate file, use "2>". The same can
   be done with other file descriptors assuming they are used by your program.
 
   Note: a shorthand for "make > hello.txt 2>&1" is "make &> hello.txt".
 
-- 
-  
+-
+
 References and Links:
 ---------------------
 
 * Advanced Bash Programming from the LDP.
 
-    
+

t2/lecture/Bash/while_read.sh

 #!/bin/sh
 
-find . -name '*.c' | 
+find . -name '*.c' |
 (while read T ; do
-	cp $T $T.bak ; 
- done)
+	cp $T $T.bak ;
+ done)

t2/lecture/CMake/cmake_examples/basic/CMakeLists.txt

 
 
 add_definitions(-DDEFINE=123) # like set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEFINE=123")
-add_definitions(-g) 
-add_definitions(-g -DDEFINE2=123) 
+add_definitions(-g)
+add_definitions(-g -DDEFINE2=123)
 
 add_subdirectory(sub)
 

t2/lecture/CMake/summary.txt

 Introudction:
 
     CMake - cross platform make.
-    - configure the software build process and generate makefiles (or IDE 
+    - configure the software build process and generate makefiles (or IDE
     project files) automatically on many systems.
     - Advantages over GNU Autotools.
-        - Smaller archive files and downloads (no huge "configure", 
+        - Smaller archive files and downloads (no huge "configure",
         "configure.in"/"configure.ac", Makefile.am, Makefile.in, etc.)
         - Faster configurations (using the CMake command).
             - no excessive forking and running processes in CMake.
         - Its licence is mod-BSDL instead of Autotools' GPL.
 
 Core language:
-    - A Specialised Domain-Specific Language (DSL) with an interpreter written 
+    - A Specialised Domain-Specific Language (DSL) with an interpreter written
     in C++
     - Turing Complete (i.e. you can write complete programs with it).
     - Supports Lists.
         - uses pkg_config.
     - configuration options:
         - SET (MAX_NUM_FREECELLS 8 CACHE STRING "Maximal Number of Freecells")
-            - BOOL, etc.        
+            - BOOL, etc.
     - configure_files
     - CHECK_C_COMPILER_FLAG
     - WIN32 (variable)
     - UNIX (variable)
-    - 
+    -

t2/lecture/CatB/index.html.wml

 </p>
 
 <p>
-This lecture aims to give an overview and summary of the series to give the 
+This lecture aims to give an overview and summary of the series to give the
 reader or hearer a taste of what can be found there.
 </p>
 

t2/lecture/Freecell-Solver/Summary-deprecated.txt

 >From version 0.0 to 0.2
 -----------------------
 
-* Algorithm: 
+* Algorithm:
 
 Solve-State(state, prev_states, ret)
     if (state == empty_state)
    C.
 
 ** Running the program from the command-line gave it a very slow output.
-  
+
 ** Conclusion: perl is slow, if you want your application to be as fast
     as possible, code it in C from the first stage.
 
 
 ** For getting the state information I wrote some macros:
     stack_card_card_num, stack_card_deck() etc.
-    I figured out that they will be used a lot in solve_for_state 
-    so writing them as functions will consume a lot of CPU. 
+    I figured out that they will be used a lot in solve_for_state
+    so writing them as functions will consume a lot of CPU.
     Thus, they were written as macros.
 
 ** In order to avoid a case where two states which differ only with their
     - The freecells were qsorted according to their card.
 
     That way, the possibility is avoided.
-    
+
     - Downside: the order of the stacks and freecells is not preserved.
 
     Show the code of canonize_state, card_compare, stack_compare
 
-** The prev_states were stored in a sorted array, with an unsorted 
-   sort-margin. 
-    - bsearch() was used to search for the current state inside 
+** The prev_states were stored in a sorted array, with an unsorted
+   sort-margin.
+    - bsearch() was used to search for the current state inside
         the sorted array.
     - lfind() was used to search for it inside the sort margin.
-    - A state which had not been previously encountered was placed at 
+    - A state which had not been previously encountered was placed at
         the end of the sort margin.
-    - Once the sort margin grew beyond PREV_STATES_SORT_MARGIN the 
+    - Once the sort margin grew beyond PREV_STATES_SORT_MARGIN the
         array was qsorted(), and the length of the sort margin was
         set to 0.
-    - When the array exceeds its allocated size it is 
+    - When the array exceeds its allocated size it is
         realloc()ed.
 
-    - PREV_STATES_GROW_BY was defined as 256 while 
-        PREV_STATES_SORT_MARGIN was defined as 16. Both could be 
+    - PREV_STATES_GROW_BY was defined as 256 while
+        PREV_STATES_SORT_MARGIN was defined as 16. Both could be
         defined to a different value by the user.
-    
 
-** The various tests conducted: 
+
+** The various tests conducted:
     (Enumerate the tests)
 
-** Two tests are special: moving a freecell or stack card to the foundations. 
+** Two tests are special: moving a freecell or stack card to the foundations.
     Moving a card to the founds where both of the founds of the other colour
     are higher than its card number plus 2. In that case if the child-state is
     not solveable neither is the original state.
 
 ** Note that the entire checking and adding code for new states was
-implemented inside the tests code. (not in a separate function). 
+implemented inside the tests code. (not in a separate function).
     - Show the code of freecell.c
 
 * Testing the final code:
 and ran the function of them.
 
 ** Most of the boards ran fine. Some took too long to solve (several dozen of
-minutes). 
+minutes).
 
-** Out of which, some were terminated in the middle. 
+** Out of which, some were terminated in the middle.
 
 ** Some boards were reported by the program as unsolveable. (as I discovered
 later, they were all solveable).
 
 ** The states are quite large in memory size. Reduce their size by using bytes
     for their representation.
-    
-** Put the "check and add state" code in a separate function, so duplicate code 
+
+** Put the "check and add state" code in a separate function, so duplicate code
 will be avoided.
 
 * Implementing COMPACT_STATES:
    able to rewrite the macros as COMPACT_STATES ones and have most of the work
    done for me.
 
-** I decided to include a compile-time directive to choose between the 
-    COMPACT_STATES and the FAST_STATES. 
+** I decided to include a compile-time directive to choose between the
+    COMPACT_STATES and the FAST_STATES.
 
 ** state_as_string required a thorough modification because it did not use the
     macros in the first place.
 
 ** I noticed that COMPACT_STATES were much faster than the so called
-    FAST_STATES. As some of you remember I posted a message to linux-il 
+    FAST_STATES. As some of you remember I posted a message to linux-il
     asking why.
 
     http://plasma-gate.weizmann.ac.il/Linux/maillists/00/04/msg00356.html
 
 ** Thus, I decided to rename FAST_STATES as DEBUG_STATES because
     they are easier to debug using gdb and friends.
-    
-** Conclusion: use as little bit-space as you need, and use a lot of 
+
+** Conclusion: use as little bit-space as you need, and use a lot of
     typedefs and macros to manage them.
 
 * Implementing check_and_add_state as a separate function:
 
 ** I took a look at the code and realized that the two distinct tests are
-    going to cause me problems. 
+    going to cause me problems.
 
 ** I implemented the function check_and_add_state(), which:
     1. Accepts a pointer to the new state.
     2. Checks if it is already present in prev_states.
     3. If so, returns STATE_ALREADY_EXISTS
     4. If not, calls solve_for_state on it.
-    5. If the inner solve_for_state succeeeds returns STATE_WAS_SOLVED 
+    5. If the inner solve_for_state succeeeds returns STATE_WAS_SOLVED
         to  solve_for_state.
     6. If it didn't return STATE_IS_NOT_SOLVEABLE to solve_for_state.
 
 * Switching from qsort to merge:
 
 ** In my "Introduction to Data Structures and Algorithms" class I learned
-    that Quick Sort has a minimal complexity of n*log(n) and a maximal 
-    complexity of n^2. Plus, when the array is sorted maximal complexity 
+    that Quick Sort has a minimal complexity of n*log(n) and a maximal
+    complexity of n^2. Plus, when the array is sorted maximal complexity
     is achieved.
 
     In FCS, the array of prev_states is mostly sorted, except for the sort
     main prev_states array. That way, I can allocate an extra place at the
     end of the main array for the merging.
 
-** By performing the merge from the end I was able to merge without allocating 
+** By performing the merge from the end I was able to merge without allocating
     a new array and then copying it to the original one.
 
 ** I figured that since the main array will usually be considerably larger
 
 ** The bsearch() function was inadequate because it doesn't the place
     in which an unfound item should be inserted. Thus, I had to write one of
-    my own. 
+    my own.
     - show the code of SFO_bsearch
 
 ** Based on SFO_bsearch I wrote SFO_merge_large_and_small_sorted_arrays.
     - Show the code.
 
 ** SFO_bsearch and SFO_merge_large_and_small_sorted_arrays were originally
-    written in perl, and then translated to C. This time, writing them in perl 
+    written in perl, and then translated to C. This time, writing them in perl
     first was a good idea, because it reduced the development time. Remember
     that the running time for the testing was not that critical.
 
-** SFO_bsearch also allowed me to add a new state at the appropriate place in 
+** SFO_bsearch also allowed me to add a new state at the appropriate place in
     the sort margin.
 
 ** I rewrote check_and_add_state to use the merge.
     - FCS 0.2 takes 1 minute and 11 seconds to solve them.
     - FCS 0.4.1 takes 14 seconds
     A factor of 5 improvement.
-    
+
 
 
 * Implementing INDIRECT_STATE_STORAGE
 
 ** Motivation: I noticed that when I ran FCS on Windows NT 4.0 Workstation,
-    with DEBUG_STATES, I ran out of stack space. The reason: solve_for_state 
+    with DEBUG_STATES, I ran out of stack space. The reason: solve_for_state
     accepts the entire state data structure as a function argument, and the
-    DFS depth of that board was considerable. 
+    DFS depth of that board was considerable.
 
     Therefore, I decided to implement a scheme in which only pointers to the
     states will be passed to solve_for_state.
 ** Because of the algorithm, only the last allocated state needs to be
     released.
 
-** At first, I tried to implement the actual states, to which the 
-    pointers will point as a stack, that will be realloced. Then I realized, 
+** At first, I tried to implement the actual states, to which the
+    pointers will point as a stack, that will be realloced. Then I realized,
     that because of the realloc() call, the physical location of the states
     will change.
 
 ** In Linux, at least on the kernel level, the memory is allocated in
-    powers of 2. Thus, it would be a waste if every state were allocated 
+    powers of 2. Thus, it would be a waste if every state were allocated
     separately. I decided to allocate the states in chunks that fit a 64KB
     boundary. I called these chunks packs.
 
 ** Note that there is a compile-time option to compile with either the
     DIRECT_STATES_STORAGE mechanism or the INDIRECT_STATE_STORAGE.
 
-** check_and_add_state and the sfs_check_state_ macros were adapted to 
+** check_and_add_state and the sfs_check_state_ macros were adapted to
     allocate the states indirectly.
 
-** Some macros make sure that "state", "ptr_state", "new_state" and 
+** Some macros make sure that "state", "ptr_state", "new_state" and
     "ptr_new_state" are all available in the code scope.
 
 ** Benchmarks:
 ** Conclusions:
     - When passing structs as arguments to functions always do that by a
         a pointer.
-    - Never sort, search in, etc with a direct vector of structs. Instead 
+    - Never sort, search in, etc with a direct vector of structs. Instead
         use an array of pointers.
 
 * Usability features:
     - Possibly show the source, although it's just an ugly C parsing
         code.
 
-** Wrote a function check_state_validity that checks that all cards are 
+** Wrote a function check_state_validity that checks that all cards are
     present in an initial board once and only once.
 
-    - When I used the program I noticed that I had many mistakes when 
+    - When I used the program I noticed that I had many mistakes when
         trying to manually input boards.
 
 * I placed Freecell Solver 0.4 on its web-site and posted an announcement
 * Moving the global variables to an instance strucutre.
 
 ** FCS made extensive use of global variables. But I wanted it also to be
-available as a library sooner or later. Now, if only one instance of the 
+available as a library sooner or later. Now, if only one instance of the
 library can be run we are set. But what about multi-threaded applications?
 
 ** I decided to create an instance structure that will be passed as the first
     2. Contain 8 integers that specify the order of the stacks.
     3. Contain 4 integers that specify the order of the freecells.
 
-** I had to modify canonize_state() that it will swap the order specifiers 
-    as well as the stacks or freecells themselves. I could not do that 
-    with C's qsort() so I wrote my own insertion-sort routine. (Show the 
+** I had to modify canonize_state() that it will swap the order specifiers
+    as well as the stacks or freecells themselves. I could not do that
+    with C's qsort() so I wrote my own insertion-sort routine. (Show the
     code of canonize_state() in state.h)
 
-** I also had to modify the code itself to access the s element of the 
+** I also had to modify the code itself to access the s element of the
     state_with_locations stucture. I did some of it using macros.
 
 ** I also had to modify the state_ia routines to manage state_with_locations
 * Adding the fcs_ prefix.
 
 ** Despite moving the global variables to the instance struct, FCS still
-    have a lot of functions. But names like state_as_string may might 
-    as well be names of user's routines. Thus, FCS may interfere with the 
+    have a lot of functions. But names like state_as_string may might
+    as well be names of user's routines. Thus, FCS may interfere with the
     main program of the user.
 
-** Solution: Add a "fcs_" or "freecell_solver" prefixes to the names of 
-    the global functions. That way, they won't collide with names of 
+** Solution: Add a "fcs_" or "freecell_solver" prefixes to the names of
+    the global functions. That way, they won't collide with names of
     other functions, in case Freecell Solver is compiled as a library.
 
 ** Conclusion: Avoid namespace collision. In C++ use the namespaces facility,
 ** Solution: Let the user specify a test order from the command line.
 
 ** Implementation: The code of solve_for_state was splitted into 10 test
-    functions and one main function. Each test function implemented one of 
+    functions and one main function. Each test function implemented one of
     the tests and called check_and_add_state().
 
 ** The solve_for_state() function holds ten pointers to test functions, and
 
 ** Results:
     - For every board there's usually a test order that can solve it very
-        fast. For other orders it usually get stuck and doesn't finish 
+        fast. For other orders it usually get stuck and doesn't finish
         very quickly.
 
     - For example, running FCS 0.6.2 with a limit of 150000 boards with the
 
         Duration: 2:50 minutes
         Number of unsolved boards: 5 (some of them after a complete scan)
-            
+
 
 ** Conclusion: If several things can be done with any given order, make sure
     they are implemented as separate routines. You may wish to play with the
 
 * Interface separation and code cleaning.
 
-** Like I said, I wanted FCS to be also available as a library. 
+** Like I said, I wanted FCS to be also available as a library.
 
 ** I placed the initialization, solution and de-allocation routines in their
     own functions, instead of inside main.
     - freecell_solver_free_instance
     - freecell_solver_init_instance
     - freecell_solver_free_instance
-    
+

t2/lecture/Freecell-Solver/Summary.txt

 
 * A freecell can hold one _single_ card.
 
-* The foundations are built from ace to king and the object of the 
+* The foundations are built from ace to king and the object of the
 game is to move all the cards to the foundations.
 
 * A card can be placed on top of a card that is of the opposite colour,
 * An atomic move consists of:
     - moving a card from a stack to a freecell.
     - moving a card from a freecell to a parent card on a stack.
-    - moving a card from the top of a stack on top of a parent card on a 
+    - moving a card from the top of a stack on top of a parent card on a
       different stack
     - moving a card from the top of a stack or from a freecell to the
       foundation.
 
     * Sometimes, it is useful to move cards to the freecells, so the card
       below them can serve as a basis for a sequence.
-      
+
 The Freecell Solver 0.2 Architecture:
 -------------------------------------
 
 
 * Several tests to get to subsequent moves - give some examples:
     I called them "multi-move" to indicate they may include one or more
-    moves or "supermoves". By coding them I tried to emulate the kind of 
+    moves or "supermoves". By coding them I tried to emulate the kind of
     moves a human player would try to do.
 
     Examples:
 
     Due to their multi-moves heuristic nature, it is possible that some boards
     are solveable, yet cannot be solved by FCS.
-    
-* Once the program finds a solution it outputs the intermediate boards to 
+
+* Once the program finds a solution it outputs the intermediate boards to
     the screen.
 
 * Each state was represented as a relatively large data structure containing
-other data structures. 
+other data structures.
     - A card was { short, short}
     - A stack was { int, card[] },
     - A state was { stack[] }.
 
-* The State collection was implemented as a sorted vector of whole state data 
-    structures. 
+* The State collection was implemented as a sorted vector of whole state data
+    structures.
     - It had a sort margin, so not every new element would require moving
         many states aside.
     - After several elements were collected the array and its sort margin
     * The sort margin is kept outside the main array.
 
     * It is added to the main array by using a binary search-based merge.
-    
+
         - The reason why it was preferred over a normal linear merge
           was because there are usually much more elements in the main
           array so a lot of time would be spent on comparisons.
       3. glib - contains an implementation of a balanced binary tree.
 
       There are others, but I decided to stick to those three.
-    
+
     * By using a balanced binary tree I managed to increase the brute speed
       by %33. (and the net speed times 2 or so).
 
 
         Description: What is a Hash Table?
         ----------------------------------
-        
+
         * A hash table is a vector of linked lists. Each linked list contains
           a set of keys (or key-value pairs).
 
         * The index of the list in which the key is placed is determined by
           a hash function. Usually, the hash function generates an integer
-          in a very large range, and the index is its modulo with the number 
+          in a very large range, and the index is its modulo with the number
           of elements in the hash table.
 
             Rehashing:
             ----------
-            
+
             Sometimes, when a hash becomes two crowded, the number of elements
             in it is increased and all of its existing elements are placed in
             their new place.
-    
-    
-    * I first tried using glib's hash implementation with a 4-byte wide XOR as 
+
+
+    * I first tried using glib's hash implementation with a 4-byte wide XOR as
       the hash function. This generated very awful results.
-      
+
     * Then I tried using the MD5 hash function, and got excellent results
       similar to what I encountered when using a balanced binary tree.
-    
+
     * I coded my own stripped-down hash implementation in my attempt to figure
       out what went wrong with using a hash. It turned out to be a bit faster
       than glib's hash.
       reduce the size. I made a card as a char whose first 4 bits were the
       rank and the two more upper bits the rank.
 
-    * Surprisingly, this made the game even faster. 
-    
-    * I consulted a mailing list of mine with this anomaly and reached the 
-      conclusion that it happened because there were fewer cache misses 
+    * Surprisingly, this made the game even faster.
+
+    * I consulted a mailing list of mine with this anomaly and reached the
+      conclusion that it happened because there were fewer cache misses
       this way.
 
     Pointers to stacks instead of a vector of stacks:
     -------------------------------------------------
-    
-    * I later encountered two variants of Freecell (dubbed Der Katzenschwanz 
-      and Die Schlange) whose stacks could be extremely long (roughly as 
-      long as the number of cards in two decks). 
-    
-    * This made representing the states as a direct vector of constant-sized 
+
+    * I later encountered two variants of Freecell (dubbed Der Katzenschwanz
+      and Die Schlange) whose stacks could be extremely long (roughly as
+      long as the number of cards in two decks).
+
+    * This made representing the states as a direct vector of constant-sized
       stacks very wasteful.
 
     * What I did was store pointers for the stacks in each state, and store
       comparison, it would have costed dearly, because every insert requires
       more than one comparison.
 
-    * The solution: "Indexes out of Bounds of Main Data Structure"<tm> - 
-      anti-patent pending technology. 
+    * The solution: "Indexes out of Bounds of Main Data Structure"<tm> -
+      anti-patent pending technology.
 
     * The original indexes of the stacks and freecells are kept outside the
       main data structure:
 Move Stacks:
 ------------
 
-* In the beginning, the user had to deduce what had happened between two 
+* In the beginning, the user had to deduce what had happened between two
 subsequent states.
 
 * That was:
 * I created the concept of move stacks, which each test loaded with the moves
 that were it performed.
 
-* Those stacks were later collected into one stack, to get the total move 
+* Those stacks were later collected into one stack, to get the total move
 stack from the initial board to the final solution.
 

t2/lecture/Freecell-Solver/fcs-lecture-points-take3.txt

 
 * A freecell can hold one _single_ card.
 
-* The foundations are built from ace to king and the object of the 
+* The foundations are built from ace to king and the object of the
 game is to move all the cards to the foundations.
 
 * A card can be placed on top of a card that is of the opposite colour,
 * An atomic move consists of:
     - moving a card from a stack to a freecell.
     - moving a card from a freecell to a parent card on a stack.
-    - moving a card from the top of a stack on top of a parent card on a 
+    - moving a card from the top of a stack on top of a parent card on a
       different stack
     - moving a card from the top of a stack or from a freecell to the
       foundations.
       cards in a vacant stack.
 
     * Sometimes, it is useful to move cards to the freecells or temporarily
-      to an empty column, so the card below them can serve as a basis for a 
+      to an empty column, so the card below them can serve as a basis for a
       sequence.
-      
+
 
 Pseudo-code for DFS:
 -------------------
     - dirt slow.
 
 2. In C - A sorted array + a sort margin that was qsorted into the array.
-    - O(log(N) lookup and O(n^2*log(n)) (average) O(n^3) cumulative 
+    - O(log(N) lookup and O(n^2*log(n)) (average) O(n^3) cumulative
     complexity.
 
 3. Merging the sort margin instead of qsorting it in.
         - Your hash is only as good as your hash function!
     5.3 - MD5 is a cryptographically secure hash function. Its calculation is
         still very slow. Converting to Perl's hash function, which is faster.
-    5.4 - Hash - a heuristic that gives _on average_ O(1) lookups and O(n) 
-        cumulative complexity. (worst case: O(n) lookups and O(n^2) 
+    5.4 - Hash - a heuristic that gives _on average_ O(1) lookups and O(n)
+        cumulative complexity. (worst case: O(n) lookups and O(n^2)
         cumulative)
     - TODO: Write about Hash optimizations (?)
 
 ------------
 
 1. Meta-moves instead of atomic moves. I do several moves at once while
-trying to achieve a certain "desirable" end in mind. 
+trying to achieve a certain "desirable" end in mind.
     - Examples: (see previous summary)
 
     * Put top stacks cards in the foundations.
     * Move stack cards to different stacks.
     * Move sequences of cards onto free stacks.
     * Etc.
-    
 
-2. I generated a 1000 test boards and saw that some of them were reported 
+
+2. I generated a 1000 test boards and saw that some of them were reported
 unsolvable. After I played one I discovered it was solvable, and realized
 there was one generic type of meta-move that I missed (moving a card to a
 parent on the same stack). So I implemented it and saw that the board could
 now have been solved.
 
-3. Someone reported some of the Microsoft boards to be unsolvable by FCS. 
-    - I realized some of my meta-moves were not generic enough so I 
+3. Someone reported some of the Microsoft boards to be unsolvable by FCS.
+    - I realized some of my meta-moves were not generic enough so I
     generalized them.
     - Now, Freecell Solver can solve all of the Microsoft deals (except 11982
     which was reported to be unsolvable by any human or computerized solver).
 for solving them.
 
 4. Adrian Ettlinger, however, made a thorough "benchmarking" of Freecell Solver
-to test each solvability, and found several boards that could not be solved 
-with a certain number of Freecells. 
-    - This is a known issue, that I do not plan to take care of due to the 
+to test each solvability, and found several boards that could not be solved
+with a certain number of Freecells.
+    - This is a known issue, that I do not plan to take care of due to the
     definition of the FCS strategy.
-    - I found out by tracing a solution to these boards (using Tom Holroyd's 
-    patsolve) that FCS did two moves in a certain way and not in another 
-    permutation of them. This caused it to be reported as unsolved 
+    - I found out by tracing a solution to these boards (using Tom Holroyd's
+    patsolve) that FCS did two moves in a certain way and not in another
+    permutation of them. This caused it to be reported as unsolved
     eventually.
 
 Scanning:
 * Best-First Search is a scan that uses a priority queue to determine
 to which node in the graph to go next.
 
-* Soft-DFS - 
+* Soft-DFS -
     - PySol game #980662 recursed into a depth of over 3000. On NT, this
     caused a stack overflow which resulted in an ugly segfault.
     - I decided to implement Soft-DFS which does not utilize procedural
     - This turned out to have an O(1) suspend and resume time instead
     of O(d) for hard-DFS.
     - (I later on discovered that a Win32 program can be compiled with more
-    stack space, but decided to continue developing Soft-DFS just for the 
+    stack space, but decided to continue developing Soft-DFS just for the
     heck of it and to have a O(1) function depth).
 
 * Optimization Scan -
-    - Stephan Kulow (of KDE fame) complained that after he integrated FCS 
+    - Stephan Kulow (of KDE fame) complained that after he integrated FCS
     into patsolve, he had several games in which the stacks were moved
     back and forth all over the place. This is the property of DFS which
     is not guaranteed to eliminate redundant move.
-    - I suggested to use a BrFS scan restricted to the states that were 
-    found in the solution path to try to eliminate redundant moves. 
+    - I suggested to use a BrFS scan restricted to the states that were
+    found in the solution path to try to eliminate redundant moves.
     - This turned out to be quite beneficial in most cases.
 
     - I later on implemented a scheme in which each state stored a pointer
     - Less memory = less swapping.
     - Operation on chars are just as fast as operations on dwords.
     - Refer to the Linux-IL thread
-    
+
 * Indirect Stack States
     - Collect the stacks in a collection, and keep one copy of each stack.
-    - In every state, every stack would be stored as a pointer to the copy 
+    - In every state, every stack would be stored as a pointer to the copy
     in the collection.
 
 * Remembering the original location
-    - Keep the indices of the stacks or freecells outside the main 
+    - Keep the indices of the stacks or freecells outside the main
       data-structure and sort the two arrays together.
     - The collection considers only the first sizeof(internal) bytes
     when comparing two states.
 sent me a program he prepared to generate the initial boards of GNOME Freecell
 so they can later be inputted into Freecell Solver.
 
-* I thanked him for his effort and later continued the theme, by writing 
+* I thanked him for his effort and later continued the theme, by writing
 programs to generate the board layouts of GNOME AisleRiot, PySol, and the
 Microsoft Freecell/Freecell Pro deals (the latter are considered the standard
 among hard-core Freecell enthusiasts).
 * Why not C++:
 --------------
 
-Markus Oberhumer (of PySol fame) asked me if I thought about converting my 
-solver to C++. (I suppose he meant with STL and all). Here is a full 
+Markus Oberhumer (of PySol fame) asked me if I thought about converting my
+solver to C++. (I suppose he meant with STL and all). Here is a full
 answer why I'm not going to do it:
 
 1. The solver is already working in ANSI C.
 
-2. The code is not overly OO. Whatever OO concepts exist there, fit well 
+2. The code is not overly OO. Whatever OO concepts exist there, fit well
 enough within what ANSI C gives me.
 
 3. C++/STL may make it slower, perhaps even considerably. I'd rather not spend
 
 4. ANSI C compiles much faster. (at least with gcc)
 
-5. ANSI C is cleaner, more portable, and causes less unexpected problems 
+5. ANSI C is cleaner, more portable, and causes less unexpected problems
 than C++.
 
-I'm more willing to integrate C++-derived features there into the ANSI C code. 
+I'm more willing to integrate C++-derived features there into the ANSI C code.
 Things like namespaces, (non-inherited) classes, or inline functions.
 However, for the time being I'd like to maintain the code as pure ANSI C.
 Then again, some of the gcc extensions can prove very useful too, but I cannot
 The fc-solve-discuss flame-war:
 -------------------------------
 
-* Recent versions of Freecell Solver pass the moves from the initial 
+* Recent versions of Freecell Solver pass the moves from the initial
 position to the final solution to the layer above.
 
 * The stack -> stack moves are being outputted with the number of
 cards that are moved.
 
-* Freecell Pro, OTOH, used to ignore the number of cards and expected such 
-moves to comply with what the original Microsoft Freecell would do in that 
+* Freecell Pro, OTOH, used to ignore the number of cards and expected such
+moves to comply with what the original Microsoft Freecell would do in that
 case.
 
 * This caused problems in playback of a large percentage of the games in
 its integration with Freecell solver.
 
-* A post I made to the mailing list about it 
+* A post I made to the mailing list about it
 (http://groups.yahoo.com/group/fc-solve-discuss/message/197) sparked a
 very big flamewar that diverted to cover other topics.
 
 The Story of the User API:
 --------------------------
 
-* Starting of Freecell Solver 1.0.0, FCS had a set of functions 
+* Starting of Freecell Solver 1.0.0, FCS had a set of functions
 entitled freecell_solver_user_ (after their prefix) meant for integration into
 an existing software.
 
 he used the more basic internal functions.
 
 * I told him that "I would sleep better at night" knowing that fcs_user_ will
-be used, and asked him to implement the missing parts himself, and send me 
+be used, and asked him to implement the missing parts himself, and send me
 the patch. He did.
 
 * Markus Oberhumer (of PySol fame), created a Python interface for the
 a lot of functions in the process) to make sure I give the embedding
 application all the functionality that I use.
 
-* I also ended up creating an API to analyze a command line and configure 
-a solver instance accordingly. This made writing programs that behave 
+* I also ended up creating an API to analyze a command line and configure
+a solver instance accordingly. This made writing programs that behave
 in a similar manner to the fc-solve executable so much easier.
 
 * I found it encouraging that <FILL IN>, an engineer who worked on Freecell
 
 * A corresponding Debian package has been initially created by Yotam Rubin and
 is now maintained by Risko Gergely, who also uploads it to the Debian pool of
-packages. 
+packages.
 
 
 The Freshmeat Effect (and how to avoid it)
 I decided to call it "Freecell Solver" in order for it to have a descriptive
 title.
 
-* I posted announcements for the first release and subsequent (usually stable) 
+* I posted announcements for the first release and subsequent (usually stable)
 releases on Freshmeat, and so made many people aware of it.
 
-* Starting at the very first days, a Google search for "freecell solver" 
+* Starting at the very first days, a Google search for "freecell solver"
 yielded its homepage as the first link.
 
 * Today, the situation is much worse: now most of the Google hits have

t2/lecture/Freecell-Solver/index.html.wml

 <latemp_subject "Freecell Solver - Evolution of a C Program" />
 
 <p>
-This presentation covers the evolution of 
+This presentation covers the evolution of
 <a href="http://fc-solve.shlomifish.org/">Freecell Solver</a>, an
 ANSI C library for solving some types of Solitaire games. It explains the
 algorithms, data structures and decisions that were implemented there.

t2/lecture/Freecell-Solver/project-intro/Summary.txt

 Goals:
-    An ANSI C Library (and some stand alone command line programs) for 
+    An ANSI C Library (and some stand alone command line programs) for
     Solving Freecell and several similar Solitaire games.
 
-    Aims for: 
+    Aims for:
     * Modularity
     * Speed
     * Reduced Memory Consumption
     * Incorporating Patsolve's Logic.
 
     * Thread Enabling.
-    
+
     * Writing an Automatic Testing Framework
 
     * Safety from Failed Memory Allocations

t2/lecture/Gimp/1/gimp_lecture_summary.txt

     - Can convert between them, but converting a gray-scaled image to
     RGB will not add colours to it.
 
-    - Demonstrate converting lena_color.jpg to grayscale and back 
+    - Demonstrate converting lena_color.jpg to grayscale and back
     to colour. (<Image> -> Image -> Mode)
 
     - Note: The <Image> menu is accessible by clicking the right mouse button
     or the arrow in the upper-left corner of the image.
 
-    - Some effects are not avialable in all modes.    
+    - Some effects are not avialable in all modes.
 
 * Supports 8-bit per color value RGB and Grayscale image
-    
+
     - Demonstrate with the colour picker.
 
-    - There's a patch available at http://film.gimp.org that adds 16-bit 
-    precision to it. It will be integrated into the main source tree in 
+    - There's a patch available at http://film.gimp.org that adds 16-bit
+    precision to it. It will be integrated into the main source tree in
     Gimp 2.0.
-    
+
 * Supports RGB and HSV modes.
 
     - Demonstrate with the colour selector of the active colour.
 
     - Some explanation about what RGB and HSV is.
-        
+
         - RGB: Red-Green-Black: Additive Colour components added to the graph.
-        
+
         - HSV: Hue (A unit that specifies the "colour" of the colour),
         Saturation which specifies how much black, white or gray is mixed with
         it, and Value which corresponds to its brightness.
     at the moment.
 
         - CMYK stands for Cyan, Magenta, Yellow and blacK and is a
-          substractive method for specifying colours which in a similar 
+          substractive method for specifying colours which in a similar
           manner to mixing paint colours.
 
 * Several Basic effects can be performed using the Toolbox.
-    
+
     Demonstrate:
 
     1. Create a new image (<Toolbox> -> File -> "New ...")
 
 * Effects and filters are implemented using Plug-ins. Plug-ins are separate
 programs that communicate with the main program using pipes. Plug-ins use
-libgimp to interact with the GIMP, and since libgimp is LGPLed, they can be 
-properietary. 
+libgimp to interact with the GIMP, and since libgimp is LGPLed, they can be
+properietary.
 
 There are also Script-Fu (= Scheme), Perl and Python extensions to the GIMP
 which enables one to write filters and scripts in those languages.
 (Demonstrate on tiger_sitting.jpg)
 
 We can normally paint everywhere in the image but if we do a selection with
-any one of the selection tools, we can only operate there. In a similar way, 
+any one of the selection tools, we can only operate there. In a similar way,
 filters only operate on the current selection.
 
-Gimp Selections can be any subset of pixels. One can use the selection tools 
+Gimp Selections can be any subset of pixels. One can use the selection tools
 in combination with the Ctrl, Shift and Alt keys to shape them.
 
 Furthermore, by pressing the Red-Square Button at the bottom one can use
 
         Demonstration:
         --------------
-        
+
         1. Generate an image with:
-        
+
         <Toolbox> -> Xtns -> Script-Fu -> Patterns -> "3D Truchet"
-        
+
         2. Duplicate the layer using <Layers> -> Duplicate Layer
 
         3. Render a nice gradient on the lower layer.
         5. Switch the colours to white as foreground and black as background.
 
         6. Draw a foreground to background RGB gradient around lena's face.
-        
+
             Note:
             -----
 
     ------------
 
     Layers can be merged using other methods beside their Alpha. These are
-    available in the "Mode" combo-box of the layers dialog. 
+    available in the "Mode" combo-box of the layers dialog.
 
         Demonstration:
         --------------
 
     3. Close the histogram.
 
-    4. Access the Brightness and Contrast dialog 
+    4. Access the Brightness and Contrast dialog
         (<Image> -> Image -> Colors -> "Brightness-Contrast...")
-    
+
     5. Modify the Brightness and Contrast in some way.
 
         Note: the entire modified image is displayed in real-time because
 
     7. Repeat if needed.
 
-Gamma Correction: 
+Gamma Correction:
 -----------------
 
-Q: How can we brighten or darken an image causing colour values 
+Q: How can we brighten or darken an image causing colour values
     to overflow?
 
     Concept:
     --------
-    
-    If we assume that the maximal colour value is 1 and the minimal is 0, 
-    then by applying a function of x ** (1/gamma) to every pixel we will 
-    modify the histogram while not overflowing from the image boundaries 
+
+    If we assume that the maximal colour value is 1 and the minimal is 0,
+    then by applying a function of x ** (1/gamma) to every pixel we will
+    modify the histogram while not overflowing from the image boundaries
     (which cannot be said on brightness and contrast manipulations).
 
     The more positive the gamme is the brighter the resultant image will be.
     1. Open the "A-Little-Exercise-3.jpg" image.