aboutsummaryrefslogtreecommitdiff
path: root/plicl
blob: e2671f3e87bbd56bfba05ba03590f66390989f8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
#!/bin/sh

SELF="$( basename $0 )"
VERSION="0.0.1"

# default executable filename
EXE="a.out"

# default plic options. -ewd makes it exit with 0 status if there
# were warnings, and print its warnings to stderr where we can see them.
OPTS="-ewd"

# default to non-verbose. --verbose sets this to 1.
V=0

usage() {
  if ! type -p perldoc; then
    echo "$SELF: can't find perldoc on PATH, printing raw POD." 1>&2
    exec sed -n '/^=pod/,/^=cut/p' $0
  fi

  exec perldoc "$0"
}

manpage() {
  exec pod2man --stderr -s1 -c"PL/I Support" -r$VERSION "$0"
}

# this really should check for tabs and newline, too...
check_spaces() {
  case "$1" in
    *' '*) echo "$SELF: input filenames may not contain spaces." 1>&2
           exit 1 ;;
  esac
}

while [ -n "$1" ]; do
  case "$1" in
    --verbose) V=1 ;;
    --help) usage; exit 0 ;;
    --man)  manpage; exit 0 ;;
    -c|-C)  C=1; EXE="" ;;
    -o)     O=1; EXE="$2"; shift ;;
    -o*)    O=1; EXE="$( printf "%s" "$1" | sed 's,^-o,,' )" ;;
    -*)     OPTS="$OPTS $1" ;;
    *.o)    check_spaces "$1"; OBJS="$OBJS $1" ;;
    *)      check_spaces "$1"; SRCS="$SRCS $1"
            OBJS="$OBJS $( printf "%s" "$1" | sed 's,\(\.[^.]*\)\?$,.o,' )"
            ;;
  esac
  shift
done

if [ "$C" = "1" -a "$O" = "1" ]; then
  echo "$SELF: -o option not allowed in combination with -c." 1>&2
  exit 1
fi

if [ "$V" = "1" ]; then
  echo "EXE: $EXE"
  echo "SRCS: $SRCS"
  echo "OBJS: $OBJS"
  echo "OPTS: $OPTS"
fi

if [ -z "$OBJS" ]; then
  echo "$SELF: fatal error: no input files. Try '$SELF --help'." 1>&2
  exit 1
fi

if [ -z "$EXE" -a -z "$SRCS" ]; then
  echo "$SELF: nothing to do (-c used, but no source files given)." 1>&2
  exit 1
fi

for i in $SRCS; do
  set -e
  if [ "$V" = "1" ]; then
    echo "Compiling '$i'"
    set -x
  fi

  # annoying: there's no way to make plic exit non-zero if the
  # input file wasn't found (though it will, if there were compile errors).
  if [ ! -r "$i" ]; then
    echo "$SELF: Input file not found or not readable: '$i'." 1>&2
    exit 1
  fi

  ${PLIC:-plic} -C $OPTS "$i"
  set +x
done

if [ -n "$EXE" ]; then
  if [ "$V" = "1" ]; then
    echo "Linking '$EXE'"
    set -x
  fi

  # adapted from SA_make in the pli distribution.
  ${LD:-ld} -z muldefs -Bstatic -M -e main -t \
     -o "$EXE" \
     $OBJS \
     --oformat=elf32-i386 -melf_i386 -lprf $LIBS > "$EXE".map

  X="$?"
  set +x
  [ "$V" = "1" ] && echo "Linker exit status: $X"
  exit $X
fi

exit 0

# Rest of the file is perldoc.
: <<EOF
=pod

=head1 NAME

B<plicl> - compile and link PL/I programs

=head1 SYNOPSIS

B<plicl> [--verbose] -c [plic-options] input-file [input-file ...]

B<plicl> [--verbose] -o output-file [plic-options] input-file [input-file ...]

B<plicl> [--man | --help | --version]

=head1 DESCRIPTION

B<plicl> (rhymes with I<pickle>) is a wrapper script for B<plic>(1)
(the Iron Spring PL/I compiler) and B<ld>(1) (the GNU linker, at least
on most Linux systems). It allows you to compile PL/I code from the
command line without having to create a Makefile or manually execute
separate compile and link commands.

Input files may be any combination of PL/I source or object files
already compiled by B<plic>.

By default (without B<-c>) all source files are compiled and linked
together with any object files, to create an executable named "a.out"
by default. Use the B<-o> option to give the executable a different
name.

B<plicl> is deliberately kept simple. If you have a PL/I project that's
too complex for B<plicl>, you should be using B<plic> and ld directly, with
a Makefile such as the SA_make that's distributed with the compiler.

B<plicl> can't handle input filenames with spaces in them,
though spaces are OK in the outfile filename. Filenames with shell
metacharacters may or may not work if quoted properly; they're best
avoided.

=head1 OPTIONS

All options other than B<-c>, B<-o>, B<--verbose>, B<--man>, and
B<--help> are passed as-is to B<plic>.

=over

=item B<-c>

Compile only; do not link. Each PL/I source file is compiled to an
object file. The B<-o> option is not allowed when using B<-c>; object
file names are based on the source file names, with the extension
changed to ".o". Any object files given as arguments are ignored.

=item B<-o>

Set output executable's filename. By default, this is I<a.out>. This
option only makes sense to use when linking an executable, so it's not
valid when B<-c> is used.

=item B<--verbose>

Print some (possibly) useful information about what what B<plicl> is doing.

=item B<--help>

Print this help to standard output and exit. Since the help is long,
it will be passed through your pager.

=item B<--man>

Print this help in man page (troff) format to standard output and exit.

=back

=head1 ENVIRONMENT

=over

=item B<PLIC>

Set the path to the PL/I compiler. By default, this is I<plic>, which
will be searched for in B<PATH>. This could be set to an absolute
path, e.g. if you had multiple versions of B<plic> installed and
wanted to choose between them.

=item B<LD>

Set the path to the linker. By default, this is I<ld>, which will
be searched for in B<PATH>. Has no meaning if B<-c> option is used.

=item B<LIBS>

Additional libraries to link the executable with. Default is
empty. This could be set to e.g. B<LIBS=-lpbl> to link the ISAM
library, or something like B<LIBS="foo.a bar.a"> to link with a
library you've created with B<ar>(1). Has no meaning if B<-c> option is used.

=back

=head1 EXAMPLES

  # compile and link a single PL/I source file into an executable:
  plicl -o hello hello.pli

  # compile and link multiple PL/I source files into an executable:
  plicl -o foobarbaz foo.pli bar.pli baz.pli

  # compile all PL/I source files in the current directory to objects:
  plicl -c *.pli

  # link all the object files in the current directory to create an executable:
  plicl -o my_executable *.o

=head1 AUTHOR

B<plicl> was written by B. Watson (yalhcru@gmail.com).

=head1 COPYRIGHT

B<plicl> is licensed under the WTFPL: do WTF you want to with this.
See http://www.wtfpl.net/txt/copying/ for details.

=cut
EOF