~ubuntu-branches/debian/stretch/haserl/stretch

« back to all changes in this revision

Viewing changes to README.BashExtensions

  • Committer: Bazaar Package Importer
  • Author(s): Chow Loong Jin
  • Date: 2011-05-11 01:53:02 UTC
  • Revision ID: james.westby@ubuntu.com-20110511015302-hu025896t08mskgy
Tags: upstream-0.9.29
ImportĀ upstreamĀ versionĀ 0.9.29

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
April 2008
 
2
 
 
3
The following documents the modifications to the haserl parser
 
4
when --enable-bash-extensions is enabled.  The following was 
 
5
written by Scott, and should not be considered as a core part
 
6
of haserl.  (Ask on the mailing list if you need help)
 
7
 
 
8
--------------------------------------------------------------
 
9
 
 
10
Haserl supports four tags by default. These are generic and
 
11
suitable for use with a great variety of shells. If, like
 
12
me, you write your scripts with vi (vim) with the syntax
 
13
highlighting enabled, then you will have noted how badly
 
14
this looks in the editor.
 
15
 
 
16
I also prefer the tags to be a bit more intelligent, as I
 
17
find it makes the source that much more readable.
 
18
 
 
19
To this end I have added the following tags (again, these
 
20
are designed with bash in mind, may not work with other
 
21
sh-type shells, and are not at all supported if you are
 
22
using LUA/LUAC.)
 
23
 
 
24
 
 
25
     Tag version:               Expands to:
 
26
     ------------------------   ------------------------
 
27
     <%if list %>               if [[ list ]] ; then
 
28
     <%elif list %>             elif [[ list ]] ; then
 
29
     <%else [comment] %>        else [# comment]
 
30
     <%endif [comment] %>       fi [# comment]
 
31
 
 
32
     <%case word %>             case word in
 
33
     <%when pattern %>          pattern)
 
34
     <%otherwise [comment] %>   *) : [comment] ;;
 
35
     <%endcase [comment] %>     esac [# comment]
 
36
 
 
37
     <%while list %>            while list ; do
 
38
     <%endwhile %>              done [# comment]
 
39
 
 
40
     <%until list %>            until list ; do
 
41
     <%enduntil [comment] %>    done [# comment]
 
42
 
 
43
     <%for name in word %>      for name in word ; do
 
44
     <%endfor [comment] %>      done [# comment]
 
45
 
 
46
     <%unless list %>           if [[ ! list ]] ; then
 
47
     <%elun list %>             elif [[ ! list ]] ; then
 
48
     <%unelse [comment] %>      else [#comment]
 
49
     <%endunless [comment %>    fi [# comment]
 
50
 
 
51
 
 
52
To simplify parsing, and to reduce confusion when reading
 
53
your source, unique words are used. For example, the use of
 
54
endwhile, enduntil and endfor instead of done. Also, for
 
55
clarity I have used endif/endcase instead of fi/esac.
 
56
 
 
57
------
 
58
UNLESS
 
59
------
 
60
 
 
61
Note the last command, the unless...endunless. I find it is
 
62
often more clear to express an unless condition than an if
 
63
not condition. For example, and to show the streamlining of
 
64
code these tags provide:
 
65
 
 
66
     <% if [[ ! IsLogged ]] ; then %>
 
67
          something
 
68
     <% fi %>
 
69
 
 
70
This is the improved (IMHO) version:
 
71
 
 
72
     <%unless IsLogged %>
 
73
          something
 
74
     <%endunless %>
 
75
 
 
76
Personally, I find no use for "else unless", but I decided
 
77
to include it for consistency.
 
78
 
 
79
--------------------
 
80
CONDITIONAL COMMANDS
 
81
--------------------
 
82
 
 
83
There is one syntactic problem, concerning the use of the
 
84
<%if %>, <%while %>, <%until %> and <%unless %> tags. The
 
85
default action is to create a test-style condition; however,
 
86
sometime you need to do this:
 
87
 
 
88
     <% if grep "text" file &>/dev/null ; then %>
 
89
 
 
90
If you simply write this:
 
91
 
 
92
     <%if grep "text" file &>/dev/null %>
 
93
 
 
94
Then it is expanded to:
 
95
 
 
96
     if [[ grep "text" file &>/dev/null ]] %>
 
97
 
 
98
That is obviously incorrect. To allow for this the parser
 
99
provides a bit of syntactic sugar. It checks the first
 
100
character of the expression list and if it is, then it
 
101
rewrites the list as a command. For example:
 
102
 
 
103
     <%if |grep "text" file &>/dev/null %>
 
104
 
 
105
Becomes:
 
106
 
 
107
     if grep "text" file &>/dev/null ; then
 
108
 
 
109
--------------
 
110
CASE STATMENTS
 
111
--------------
 
112
 
 
113
The case statement provided another challenge, namely how to
 
114
handle the pesky ;; required at the end of each case. I am
 
115
not a C person, so personally I find the next instance of a
 
116
case to be sufficient to terminate the first. Given that the
 
117
shell version of case can accept multiple conditions, there
 
118
is really no reason to worry with cases falling through as
 
119
they do in C. In other words, I'm all for ditching the ;;
 
120
construct altogether.
 
121
 
 
122
So I did.
 
123
 
 
124
The enhanced <%case %> tag operates without an explicit ;;
 
125
being required. It is perhaps easier to show than explain,
 
126
so here's an example:
 
127
 
 
128
     <%case "$FRUIT" %>
 
129
     <%when apple %>
 
130
          echo "It's an apple!"
 
131
     <%when orange %>
 
132
          echo "It's an orange!"
 
133
     <%otherwise something else %>
 
134
          echo "Not what I expected."
 
135
     <%endcase %>
 
136
 
 
137
The parser renders this as follows:
 
138
 
 
139
     case "$FRUIT" in
 
140
     "\000\012\004") :
 
141
     ;;
 
142
     apple)
 
143
     echo "It's an apple!"
 
144
     ;;
 
145
     orange)
 
146
     echo "It's an orange!"
 
147
     ;;
 
148
     *) # something else
 
149
     echo "Not what I expected."
 
150
     ;;
 
151
     esac
 
152
 
 
153
Note the odd first case. The parser inserts this so ensure
 
154
that each subsequent when/otherwise/endcase can be preceded
 
155
by ;;. This eliminates the need to remember the ;;, and I
 
156
believe makes for cleaner code. There is, of course, a small
 
157
performance penalty for always having to evaluate this extra
 
158
case. In real life I find this not to be a problem, however,
 
159
if you are processing inside a loop and expect a large chunk
 
160
of items, then it is something to be aware of.
 
161