Native shebang: Difference between revisions

Content deleted Content added
m →‎{{header|C}}: fix vim typo
→‎{{header|C}}: add {{header|UNIX_shell}}
Line 21: Line 21:
=={{header|C}}==
=={{header|C}}==
'''File: script_gcc.c'''
'''File: script_gcc.c'''
<lang c>#include <errno.h>
<lang c>#!/usr/local/bin/script_gcc.sh
#include <errno.h>
#include <libgen.h>
#include <libgen.h>
#include <stdarg.h>
#include <stdarg.h>
Line 30: Line 31:
#include <unistd.h>
#include <unistd.h>


/* the shebang is:
/* the actual shebang for C targets is:
#!/usr/local/bin/script_gcc
#!/usr/local/bin/script_gcc.c
*/
*/


Line 148: Line 149:


'''Test Source File: echo.c'''
'''Test Source File: echo.c'''
<lang c>#!/usr/local/bin/script_gcc
<lang c>#!/usr/local/bin/script_gcc.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char **argv, char **envp){
char ofs = '\0';
for(argv++; *argv; argv++){
if(ofs)putchar(ofs); else ofs=' ';
fwrite(*argv, strlen(*argv), 1, stdout);
}
putchar('\n');
exit(EXIT_SUCCESS);
}</lang>

'''Test Execution:'''
<pre>
$ ./echo.c Hello, world!
</pre>
'''Test Output:'''
<pre>
Hello, world!
</pre>

=={{header|UNIX Shell}}==
{{works with|Bourne Again SHell}}
Note: this '''Native shebang''' task does not exactly apply to [[bash]] because is interpretive, but as a skeleton template the following script is an example of how compiled languages can implement the shebang. Also: this bash code can be used to ''automatically'' compile the C code in /usr/local/bin/script_gcc.c above.
'''File: script_gcc.sh'''
<lang bash>#!/bin/bash

# Alternative:
#!/bin/bash /usr/local/bin/gcc_script.sh
# CACHE=No # to turn off caching...

# Note: this shell should be re-written in actual C! :-)

DIALECT=c # or cpp
CC="gcc"
COPTS="-lm -x $DIALECT"
IEXT=.$DIALECT
OEXT=.out

ENOENT=2

srcpath="$1"; shift # => "$@"
#basename="$(basename "$srcpath" ."$DIALECT")"
basename="$(basename "$srcpath")"

# Warning: current dir "." is in path, AND */tmp directories are common/shared
paths="$(dirname "$srcpath")
$HOME/bin
/usr/local/bin
.
$HOME/tmp
$HOME
$HOME/Desktop"
#/tmp

while read dirnamew; do
[ -w "$dirnamew" ] && break
done << end_here_is
$paths
end_here_is

compile(){
sed -n '2,$p' "$srcpath" | "$CC" $COPTS -o "$binpath" -
}

if [ "'$CACHE'" = "'No'" ]; then
binpath="$dirnamew/$basename-v$$$OEXT"
if compile; then
( sleep 0.1; exec rm "$binpath" ) & exec "$binpath" "$@"
fi
else
while read dirnamex; do
binpath="$dirnamex/$basename$OEXT"
if [ -x "$binpath" -a "$binpath" -nt "$srcpath" ];
then exec "$binpath" "$@"; fi
done << end_here_is
$paths
end_here_is

binpath="$dirnamew/$basename$OEXT"
if compile; then exec "$binpath" "$@"; fi

echo "$binpath: executable not available" 1>&2
exit $ENOENT
fi</lang>
'''Test Source File: echo.c'''
<lang c>#!/usr/local/bin/script_gcc.sh
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <string.h>