Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!mcsun!i2unix!ctr!nicb From: nicb@ctr@italy.eu.net (Nicola Bernardini) Newsgroups: comp.lang.c++ Subject: inline management (source included) Keywords: inline, preprocessing Message-ID: <1991Jan22.213115.8716@ctr@italy.eu.net> Date: 22 Jan 91 21:31:15 GMT Reply-To: nicb@ctr.UUCP (Nicola Bernardini) Organization: Centro Tempo Reale, Firenze Lines: 509 Is there anybody that has an evident solution to managing inline functions in a decent way? My problem is the following: 1) I do not want to keep inlines in the definition files (.h) because I want to be able to move my functions in and out of inlining whenever I need to do so, without changing header files to my clients. 2) If I do not inline inside the header file, I have to provide inline declarations wherever I actually use these inlines thus generating a lot of duplicate code. Up to now I haven't found a solution to this, but I made a very simple hackwork which extracts inlines out of source files. This way I can produce inline header files (<.inl> ?) that I can include wherever they are needed. The whole process can be taken care by make and I do not need to worry about it. But, again, it is far from elegant I must admit. Anybody knows better? (source to the inline extractor is right after the signature) ------------------------------------------ Nicola Bernardini - nicb%ctr@italy.eu.net - nicb@ctr.UUCP Centro Tempo Reale Villa Strozzi Via Pisana, 77 50143 Firenze I T A L I A Tel. ++3955/702444 Fax. ++3955/717712 ----------------------CUT HERE #! /bin/sh # this is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh to create the files: # README # ie.l # ie.LC # This archive created: Tue Jan 22 22:08:01 MET 1991 by nicb # # export PATH; PATH=/bin:$PATH # if test -f README then echo shar: will not over-write existing file README else echo shar: extracting 'README', 699 characters sed 's/^X//' > README <<'SHAR_EOF' X X X ie - by Nicola Bernardini X X This is an inline function extractor. It allows X extraction of c++ inline functions out of regular X c++ syntax files. X ie accepts input from the standard in and produces X its output on the standard out. X X It's written in the lex language, so you will have X to lex it and then compile it (no -ll options, though). X X You may use this code freely provided you do not X try to sell it. Please retain the name of the author X wherever you find it so that other people you pass X this code to will be able to report bugs. X X report any bugs to: X X nicb%ctr@italy.eu.net (Nicola Bernardini) X nicb@ctr.i2unix.UUCP X XFILES X X ie.l - the code X ie.LC - the man page X README - this file SHAR_EOF len=`wc -c < README` if test $len != 699 ; then echo error: README was $len bytes long, should have been 699 fi fi # end of overwriting check if test -f ie.l then echo shar: will not over-write existing file ie.l else echo shar: extracting 'ie.l', 4432 characters sed 's/^X//' > ie.l <<'SHAR_EOF' X%{ X/* X ie.l X X This is an inline function extractor. It allows X extraction of c++ inline functions out of regular X c++ syntax files. X ie accepts input from the standard in and produces X its output on the standard out. X X*/ X#include X#include X#include X#include X#include X X#define LINE_SIZE 256 X#define outs(x) { fprintf (yyout, "%s", (char *) x); } X Xtypedef enum X{ X true, X false X} boolean; X Xtypedef struct X{ X int ac; X char **av; X} Args; X Xint numgraphs = 0; Xboolean flag = false; Xboolean pflag = false; Xlong lineno = 1; X Xchar *file_name; X#define set_name(s) { file_name = (char *) s; } X#define get_name() file_name X#define USAGE_STRING "Usage [-p] [file ...]\n" X#define set_pflag() { pflag = true; } X#define reset_pflag() { pflag = false; } X X%} X XEMPTY ^$ X X%% X"inline" { X char buffer [LINE_SIZE]; X flag = true; X sprintf (buffer, "#line %ld \"%s\"\n", X lineno, get_name()); X outs (buffer); X outs (yytext); X } X"{" { X if (flag == true) X { X ++numgraphs; X output (yytext[0]); X } X else numgraphs = 0; X } X"}" { X if (flag == true) X { X --numgraphs; X output (yytext[0]); X } X else numgraphs = 0; X if (!numgraphs) X { X flag = false; X output ('\n'); X } X else X flag = true; X } X{EMPTY} { ; } X. { if (flag == true) output (yytext[0]); } X\n { ++lineno; if (flag == true) output (yytext[0]); } X%% X#ifdef _SCO_SYSV_ X# ident "@(#)ie.l 1.2 9/27/90" X#endif /* _SCO_SYSV_ */ X Xyywrap() X{ X /* this call must exist */ X} X Xtypedef enum X{ X FATAL, X NON_FATAL X} Errcode; X Xchar *version() X{ X char *string = "ie version 1.2 9/27/90"; X X return string; X} X Xvoid stop (c) Xint c; X{ X exit(c); X} X Xvoid error (s, ec) Xchar *s; XErrcode ec; X{ X fputs (s, stderr); X switch (ec) X { X default: X case FATAL: X stop (1); X break; X case NON_FATAL: X break; X } X} X X XFILE *getfile (s) Xchar *s; X{ X int faccess = access (s, R_OK | F_OK); X FILE *retvalue; X X if (faccess) X { X char buf [LINE_SIZE]; X sprintf (buf, "file %s not found\n", s); X error (buf, NON_FATAL); X retvalue = (FILE *) NULL; X } X else X retvalue = fopen (s, "r"); X X return retvalue; X} X XFILE *setfile (s) Xchar *s; X{ X int faccess = access (s, W_OK); X FILE *retvalue; X extern int errno; X X if (faccess && errno != ENOENT) X { X char buf [LINE_SIZE]; X sprintf (buf, "Cannot create file %s. I die.\n", s); X error (buf, FATAL); X retvalue = (FILE *) NULL; X } X else X retvalue = fopen (s, "w"); X X return retvalue; X} X Xchar *outname(s) Xchar *s; X{ X char *suffix = ".inl", *place; X static char buffer [LINE_SIZE]; /* only one name at a time allowed */ X X strncpy (buffer, s, (size_t) LINE_SIZE); X X if ((place = strrchr (buffer, '.')) == (char *) NULL) X { X strcat (buffer, suffix); X } X else X strcpy (place, suffix); X X return buffer; X} X Xvoid lexit (fp) XFILE *fp; X{ X yyin = fp; X X while (!feof(yyin)) X yylex(); X} X Xchar *strsub (s, old, new) Xchar *s, old, new; X{ X char *p; X X for (p = s; *p != '\0'; ++p) X if (*p == old) X *p = new; X X return s; X} X Xchar *head_define (s) Xchar *s; X{ X static char name_define [LINE_SIZE]; /* only one name at a time */ X X sprintf (name_define, "_%s_", s); X strsub (name_define, '.', '_'); X X return name_define; X} X Xvoid header (s) Xchar *s; X{ X char buffer [LINE_SIZE]; X char *name = head_define(s); X X sprintf (buffer, "/*\n\tFile %s: created by %s\n*/\n#ifndef %s\n#define %s\n", outname(s), version(), name, name); X outs (buffer); X} X Xvoid trailer (s) Xchar *s; X{ X char buffer [LINE_SIZE]; X char *name = head_define(s); X X sprintf (buffer, "#endif /* %s */\n", name); X outs (buffer); X} X XArgs *getargs (ac, av) Xint ac; Xchar **av; X{ X int c, errflg = 0; X static Args files; X extern char *optarg; X extern int optind; X X while ((c = getopt(ac,av, "p")) != -1) X switch (c) X { X case 'p': X set_pflag(); X break; X case '?': X errflg++; X break; X default: X ++errflg; X break; X } X X if (errflg) X error (USAGE_STRING, FATAL); X X files.ac = ac - optind + 1; X files.av = &av[optind-1]; X X return &files; X} X Xmain(ac, av) Xint ac; Xchar **av; X{ X FILE *in; X Args *files = getargs (ac, av); X X if (files->ac < 1) X lexit (stdin); X else X while (--files->ac) X { X lineno = 1; X set_name (*++files->av); X in = getfile(get_name()); X X if (in != (FILE *) NULL) X { X yyout = (pflag == true) ? stdout : X setfile (outname(get_name())); X header (get_name()); X lexit (in); X trailer (get_name()); X } X X if (pflag == false) X fclose (yyout); X } X} SHAR_EOF len=`wc -c < ie.l` if test $len != 4432 ; then echo error: ie.l was $len bytes long, should have been 4432 fi fi # end of overwriting check if test -f ie.LC then echo shar: will not over-write existing file ie.LC else echo shar: extracting 'ie.LC', 2054 characters sed 's/^X//' > ie.LC <<'SHAR_EOF' X.\"#ident "@(#)ie manpage (nicb@trxp7.UUCP) 1.2.1.1 91/01/22" X.TH IE LOCAL "local addition" "Tempo Reale" X.SH NAME X.P Xie \- \f2C++\fP inline extractor X.SH SYNOPSIS X.P X\f3ie\fP [ -p ] [ \f2file\fP ... ] X.SH DESCRIPTION X.P X.B ie Xis a utility that allows Xextraction of \f2C++\fP syntax inline functions Xout of source code files. X.P XSeparated inline functions that appear in X\f2C++\fP source code must be externally declarated Xfor linkage purposes. XThis process is a boring and Xparticularly error prone one. XCalled upon in a make process, X.B ie Xextracts and builds automatically Xthe files that contain the external inline declarations, Xthus relieving the user Xfrom doing it manually. X.P X.B ie Xtakes its input from one or more X.I file s Xor from stdin if no files are explicitly written Xin the command line. X.B ie Xproduces its output Xon files created appending the suffix \f2.inl\fP Xto \f2file\fP or substituting the last suffix of the file. XIf the X.B -p Xoption is specified, Xthe output of X.B ie Xappears on stdout and no files are created. X.P XThe created files are surrounded by X.I #ifdef 's Xand X.I #endif s Xto permit exclusion of the content of the file Xby control of the definition. X.P XAs an example, consider the code: X.sp X.ft CW X.nf X #define _foo_inl_ X #include "foo.inl" X.fi X.sp XThe definition \f(CW_foo_inl_\fP is needed if Xexclusion of the contents of foo.inl is wanted. XThe \f(CWdefine\fP name is created by substituting Xall dots by underscores (_) and by inserting Xand appending underscores at the beginning Xand at the end of the string. X.ft X.SH "SEE \ALSO" X\f3CC\fP(1) X.SH AUTHOR X.nf XNicola Bernardini XCentro di Ricerca, Produzione e Didattica Musicale \f3Tempo Reale\fP XVilla Strozzi XVia Pisana, 77 X50143 Firenze XITALIA Xe-mail: nicb@trxp7.UUCP X.fi X.SH IDENTIFICATION X.nf XAuthor: Nicola Bernardini XAffiliation: Centro Tempo Reale XRelease: 1.2.1.1 XThis is free software and it is not copyrighted. X.SH BUGS XI think X.B ie Xis too simple to have significant bugs, Xbut you never know. XLet the author know if you find bugs, Xand he'll be glad to work on it. SHAR_EOF len=`wc -c < ie.LC` if test $len != 2054 ; then echo error: ie.LC was $len bytes long, should have been 2054 fi fi # end of overwriting check exit 0 -- ------------------------------------------ Nicola Bernardini - nicb%ctr@italy.eu.net Centro Tempo Reale Villa Strozzi