Server IP : 195.201.23.43 / Your IP : 18.218.96.239 Web Server : Apache System : Linux webserver2.vercom.be 5.4.0-192-generic #212-Ubuntu SMP Fri Jul 5 09:47:39 UTC 2024 x86_64 User : kdecoratie ( 1041) PHP Version : 7.1.33-63+ubuntu20.04.1+deb.sury.org+1 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals, MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /usr/share/shtool/ |
Upload File : |
## ## scpp -- Sharing C Pre-Processor ## Copyright (c) 1999-2008 Ralf S. Engelschall <rse@engelschall.com> ## ## This file is part of shtool and free software; you can redistribute ## it and/or modify it under the terms of the GNU General Public ## License as published by the Free Software Foundation; either version ## 2 of the License, or (at your option) any later version. ## ## This file is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ## USA, or contact Ralf S. Engelschall <rse@engelschall.com>. ## str_tool="scpp" str_usage="[-v|--verbose] [-p|--preserve] [-f|--filter <filter>] [-o|--output <ofile>] [-t|--template <tfile>] [-M|--mark <mark>] [-D|--define <dname>] [-C|--class <cname>] <file> [<file> ...]" gen_tmpfile=yes arg_spec="1+" opt_spec="v.p.f+o:t:M:D:C:" opt_alias="v:verbose,p:preserve,f:filter,o:output,t:template,M:mark,D:define,C:class" opt_v=no opt_p=no opt_f="" opt_o="lib.h" opt_t="lib.h.in" opt_M="%%MARK%%" opt_D="cpp" opt_C="intern" . ./sh.common srcs="$*" output="${opt_o}.n" # find a reasonable Awk awk='' paths=`echo $PATH |\ sed -e 's%/*:%:%g' -e 's%/$%%' \ -e 's/^:/.:/' -e 's/::/:.:/g' -e 's/:$/:./' \ -e 's/:/ /g'` for name in gawk nawk awk; do for path in $paths; do if [ -r "$path/$name" ]; then awk="$path/$name" break fi done if [ ".$awk" != . ]; then break fi done if [ ".$awk" = . ]; then echo "$msgprefix:Error: cannot find a reasonable Awk" 1>&2 shtool_exit 1 fi # parse source file(s) if [ ".$opt_v" = .yes ]; then echo "Parsing:" | $awk '{ printf("%s", $0); }' 1>&2 fi for src in $srcs; do if [ ".$opt_v" = .yes ]; then echo $src | $awk '{ printf(" %s", $0); }' 1>&2 fi if [ ".$opt_f" != . ]; then inputcmd="sed" OIFS="$IFS"; IFS="$ASC_NL"; set -- $opt_f; IFS="$OIFS" for e do inputcmd="$inputcmd -e '$e'" done inputcmd="$inputcmd '$src'" else inputcmd="cat '$src'" fi eval $inputcmd |\ $awk ' BEGIN { ln = 0; fln = 0; level = 0; mode = ""; store = ""; } { ln++; } /^#if.*/ { level++; } /^#if [a-zA-Z_][a-zA-Z0-9_]* *$/ { if ($2 == define) { mode = "D"; printf("D:#line %d \"%s\"\n", ln, src); next; } } /^#endif.*/ { level--; if (mode == "D" && level == 0) { mode = ""; next; } } /^[a-zA-Z_][a-zA-Z0-9_].*;.*/ { if ($1 == class) { printf("V:#line %d \"%s\"\n", ln, src); printf("V:%s\n", $0); printf("J:%s\n", $0); next; } } /^[a-zA-Z_][a-zA-Z0-9_].*=.*/ { if ($1 == class) { printf("V:#line %d \"%s\"\n", ln, src); printf("V:%s\n", $0); printf("J:%s\n", $0); next; } } /^[a-zA-Z_][a-zA-Z0-9_]*/ { if ($1 == class) { fln = ln; store = $0; mode = "F"; next; } } /^\{ *$/ { if (mode == "F") { printf("F:#line %d \"%s\"\n", fln, src); printf("F:%s;\n", store); printf("I:%s;\n", store); store = ""; mode = ""; next; } } { if (mode == "D") printf("D:%s\n", $0); else if (mode == "F") store = store " " $0; } ' "src=$src" "define=$opt_D" "class=$opt_C" >>$tmpfile done if [ ".$opt_v" = .yes ]; then echo "" 1>&2 fi # start generating output header echo "/* $opt_o -- autogenerated from $opt_t, DO NOT EDIT! */" >$output echo "#line 1 \"$opt_t\"" >>$output sed <$opt_t -e "1,/^${opt_M} *\$/p" -e 'd' |\ sed -e "/^${opt_M} *\$/d" >>$output # merge in the define blocks grep '^D:' $tmpfile | sed -e 's/^D://' >>$output # generate standard prolog echo "#line 1 \"_ON_THE_FLY_\"" >>$output echo "" >>$output echo "/* make sure the scpp source extensions are skipped */" >>$output echo "#define $opt_D 0" >>$output echo "#define $opt_C /**/" >>$output # generate namespace hiding for variables echo "" >>$output echo "/* move intern variables to hidden namespace */" >>$output grep '^J:' $tmpfile | sed >>$output \ -e 's/^J://' \ -e 's/ */ /g' \ -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\)\[\];.*$/#define \1 __\1/' \ -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\)\[\] =.*$/#define \1 __\1/' \ -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\);.*$/#define \1 __\1/' \ -e 's/^[^=;]*[ *]\([a-zA-Z0-9_]*\) =.*$/#define \1 __\1/' # generate namespace hiding for functions echo "" >>$output echo "/* move intern functions to hidden namespace */" >>$output grep '^I:' $tmpfile | sed >>$output \ -e 's/^I://' \ -e 's/\([ (]\) */\1/g' \ -e 's/ *\([),]\)/\1/g' \ -e 's/^[^(]*[ *]\([a-zA-Z0-9_]*\)(.*$/#define \1 __\1/' # generate prototypes for variables echo "" >>$output echo "/* prototypes for intern variables */" >>$output grep '^V:' $tmpfile | sed >>$output \ -e 's/^V://' \ -e 's/ */ /g' \ -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\[\]\);.*$/\1;/' \ -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\[\]\) =.*$/\1;/' \ -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\);.*$/\1;/' \ -e 's/^\([^=;]*[ *][a-zA-Z0-9_]*\) =.*$/\1;/' \ -e 's/ ;/;/g' \ -e "s/^$opt_C /extern /" # generate prototypes for functions echo "" >>$output echo "/* prototypes for intern functions */" >>$output grep '^F:' $tmpfile | sed >>$output \ -e 's/^F://' \ -e 's/\([ (]\) */\1/g' \ -e 's/ *\([),]\)/\1/g' \ -e 's/\([* ]\)[a-zA-Z0-9_]*,/\1,/g' \ -e 's/\([* ]\)[a-zA-Z0-9_]*);/\1);/g' \ -e 's/(\*[a-zA-Z0-9_]*)(/(*)(/g' \ -e 's/\([ (]\) */\1/g' \ -e 's/ *\([),]\)/\1/g' \ -e "s/^$opt_C /extern /" # finish generating output header n=`(echo ''; sed <$opt_t -e "1,/^${opt_M} *\$/p" -e 'd') |\ wc -l | sed -e 's;^ *\([0-9]*\) *$;\1;'` echo "#line $n \"$opt_t\"" >>$output sed <$opt_t -e "/^${opt_M} *\$/,\$p" -e 'd' |\ sed -e "/^${opt_M} *\$/d" >>$output # create final output file if [ -f $opt_o ]; then if [ ".$opt_p" = .yes ]; then grep -v '^#line' $opt_o >$tmpfile.o grep -v '^#line' $output >$tmpfile.n out_old="$tmpfile.o" out_new="$tmpfile.n" else out_old="$opt_o" out_new="$output" fi if cmp -s $out_old $out_new; then : else cp $output $opt_o fi else cp $output $opt_o fi rm -f $output rm -f $tmpfile $tmpfile.* >/dev/null 2>&1 shtool_exit 0 ## ## manual page ## =pod =head1 NAME B<shtool-scpp> - B<GNU shtool> C source file pre-processor =head1 SYNOPSIS B<shtool scpp> [B<-v>|B<--verbose>] [B<-p>|B<--preserve>] [B<-f>|B<--filter> I<filter>] [B<-o>|B<--output> I<ofile>] [B<-t>|B<--template> I<tfile>] [B<-M>|B<--mark> I<mark>] [B<-D>|B<--define> I<dname>] [B<-C>|B<--class> I<cname>] I<file> [I<file> ...] =head1 DESCRIPTION This command is an additional ANSI C source file pre-processor for sharing cpp(1) code segments, internal variables and internal functions. The intention for this comes from writing libraries in ANSI C. Here a common shared internal header file is usually used for sharing information between the library source files. The operation is to parse special constructs in I<file>s, generate a few things out of these constructs and insert them at position I<mark> in I<tfile> by writing the output to I<ofile>. Additionally the I<file>s are never touched or modified. Instead the constructs are removed later by the cpp(1) phase of the build process. The only prerequisite is that every I<file> has a ``C<#include ">I<ofile>C<">'' at the top. This command provides the following features: First it avoids namespace pollution and reduces prototyping efforts for internal symbols by recognizing functions and variables which are defined with the storage class identifier ``I<cname>''. For instance if I<cname> is ``intern'', a function ``C<intern void *foobar(int quux)>'' in one of the I<file>s is translated into both a ``C<#define foobar __foobar>'' and a ``C<extern void *foobar(int quux);>'' in I<ofile>. Additionally a global ``C<#define> I<cname> C</**/>'' is also created in I<ofile> to let the compiler silently ignore this additional storage class identifier. Second, the library source files usually want to share C<typedef>s, C<#define>s, etc. over the source file boundaries. To achieve this one can either place this stuff manually into I<tfile> or use the second feature of B<scpp>: All code in I<file>s encapsulated with ``C<#if >I<dname> ... C<#endif>'' is automatically copied to I<ofile>. Additionally a global ``C<#define> I<dname> C<0>'' is also created in I<ofile> to let the compiler silently skip this parts (because it was already found in the header). =head1 OPTIONS The following command line options are available. =over 4 =item B<-v>, B<--verbose> Display some processing information. =item B<-p>, B<--preserve> Preserves I<ofile> independent of the generated ``#line'' lines. This is useful for Makefiles if the real contents of I<ofile> will not change, just line numbers. Default is to overwrite. =item B<-f>, B<--filter> I<filter> Apply one or more pre-processing sed(1) I<filter> commands (usually of type ``C<s/.../.../>'') to each input file before their input is parsed. This option can occur multiple times. =item B<-o>, B<--output> I<ofile> Output file name. Default is C<lib.h>. =item B<-t>, B<--template> I<tfile> Template file name. Default is C<lib.h.in>. =item B<-M>, B<--mark> I<mark> Mark to be replaced by generated constructs. Default is C<%%MARK%%>. =item B<-D>, B<--define> I<dname> FIXME. Default is C<cpp>. =item B<-C>, B<--class> I<cname> FIXME. Default is C<intern>. =back =head1 EXAMPLE # Makefile SRCS=foo_bar.c foo_quux.c foo_p.h: foo_p.h.in shtool scpp -o foo_p.h -t foo_p.h.in \ -M %%MARK%% -D cpp -C intern $(SRCS) /* foo_p.h.in */ #ifndef FOO_P_H #define FOO_P_H %%MARK%% #endif /* FOO_P_H */ /* foo_bar.c */ #include "foo_p.h" #if cpp #define OURS_INIT 4711 #endif intern int ours; static int myone = 0815; intern int bar(void) { ours += myone; } /* foo_quux.c */ #include "foo_p.h" int main(int argc, char *argv[]) { int i; ours = OURS_INIT for (i = 0; i < 10; i++) { bar(); printf("ours now %d\n", ours); } return 0; } =head1 HISTORY The B<GNU shtool> B<scpp> command was originally written by Ralf S. Engelschall E<lt>rse@engelschall.comE<gt> in 1999 for B<GNU shtool>. Its was prompted by the need to have a pre-processing facility in the B<GNU pth> project. =head1 SEE ALSO shtool(1), cpp(1). =cutPrivate