home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-08-26 | 54.5 KB | 1,554 lines |
- Newsgroups: comp.sources.misc
- From: Lutz Prechelt <prechelt@i41s14.ira.uka.de>
- Subject: v22i064: crefine - C-Refine preprocessor, Part02/04
- Message-ID: <1991Aug26.032408.15153@sparky.IMD.Sterling.COM>
- X-Md4-Signature: f783b54bbb32f724abc7cd619662fd4d
- Date: Mon, 26 Aug 1991 03:24:08 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: Lutz Prechelt <prechelt@i41s14.ira.uka.de>
- Posting-number: Volume 22, Issue 64
- Archive-name: crefine/part02
- Environment: UNIX, MS-DOS, TOS, C, C++, Objective-C
-
- #! /bin/sh
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: INSTALL crefine.cr crefine.man
- # Wrapped by kent@sparky on Sun Aug 25 21:56:46 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 2 (of 4)."'
- if test -f 'INSTALL' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'INSTALL'\"
- else
- echo shar: Extracting \"'INSTALL'\" \(280 characters\)
- sed "s/^X//" >'INSTALL' <<'END_OF_FILE'
- XTo install crefine just put the executable file "crefine" into
- Xa directory where executables reside, such as "/usr/local/bin" or
- X"/tools/bin" under Unix and put the Manualpage into a directory where
- XManpages reside such as "/usr/local/man/man1" or "/tools/man/man1".
- X
- XThat's all.
- END_OF_FILE
- if test 280 -ne `wc -c <'INSTALL'`; then
- echo shar: \"'INSTALL'\" unpacked with wrong size!
- fi
- # end of 'INSTALL'
- fi
- if test -f 'crefine.cr' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'crefine.cr'\"
- else
- echo shar: Extracting \"'crefine.cr'\" \(29204 characters\)
- sed "s/^X//" >'crefine.cr' <<'END_OF_FILE'
- X/*************************************************************************
- XProject : C-Refine Precompiler
- XModule : main module
- XAuthor : Lutz Prechelt, Karlsruhe
- XDate : 10.06.91 Version 16
- XCompiler: ANSI C, C-Refine 2.3 (bootstrapped)
- X**************************************************************************/
- X/*
- X Copyright (C) 1988,89,90,91 by Lutz Prechelt, Karlsruhe
- X
- X This program is free software; you can redistribute it and/or modify
- X it under the terms of the GNU General Public License as published by
- X the Free Software Foundation; either version 1, or (at your option)
- X any later version.
- X This program is distributed in the hope that it will be useful,
- X but WITHOUT ANY WARRANTY; without even the implied warranty of
- X MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X GNU General Public License for more details.
- X You should have received a copy of the GNU General Public License
- X along with this program; if not, write to the Free Software
- X Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X*/
- X
- X/************************************************************************
- X*********************** C - R e f i n e *********************************
- X*************************************************************************/
- X
- X#if 0
- XREMARK:
- X This program was originally written using german identifiers and
- X comments. I worked through it to change this (at least in most parts)
- X but please do not flame me if there are relicts from this state.
- X I did not find a sensible replacement for the german word 'Klammer' that
- X may stand for any of the characters ( ) [ ] { } so sometimes I still
- X use the german one.
- X
- XVariants:
- X#define deutsch fuer deutsche Meldungen statt englische
- X#define ms_dos for MS-DOS Operating System (Compiler Microsoft C 5.0)
- X#define unix for Unix
- X#define vms for VMS
- X#define ansi for ANSI-C Compiler
- X
- XFor version changes see refinement startup message and file cr_texts.h
- X
- X============================== History: ====================================
- X
- X
- XVersion 1.0 (Alpha) (0, 1)
- X
- X1987
- X procedural refinements only
- X not comfortable, few error messages
- X
- X
- XVersion 2.0 (Alpha) (2, 3)
- X
- XFeb. 88
- X value-returning refinements,
- X improved error handling,
- X Options comment, feedback, list, numbering, refinementsymbol, small
- X
- X
- XVersion 2.1 (Beta) (4, 5)
- X
- X09.04.88 ( --> Martin, Ihno, Volker, Beat)
- X improved error handling
- X triple error messages (german, english, german nonsense),
- X Context description in error messages,
- X Options anyway, feedback, ibm chars, message type, tabsize, warning level
- X Expires 31.07.88
- X
- X
- XVersion 2.2 (6, 7, 8)
- X
- X08.07.88 ( --> Martin)
- X corr: Changes blanks in namen to underscrores again (like in Version 1.0)
- X (otherwise error in goto occur)
- X corr: Removed semicolon after value-returning refinements kept
- X (via introduction of refcallr)
- X improved error handling: Warning for "often used" only for
- X "big" refinements.
- X03.08.88
- X corr: When inserting file names in "#line"-commands, backslashes
- X are doubled (backslash is Escape symbol in C string denoters)
- X13.09.88
- X corr: empty refinements will not give syntax errors anymore.
- X
- X
- XVersion 2.3 (9, 10, 11, 12, 13)
- X
- X29.09.88 ( --> Martin, Ihno)
- X corr: refinements with just 1 semicolon are enclosed in braces also
- X (to avoid "else"-conflict)
- X C++ Mode (i.e. // Kommentare) as option p
- X17.03.89
- X "std.h" introduced, #ifdefs for environment switches introduced.
- X Look-through, further "refinementized", several small corrections
- X ported to SUN-OS (Berkeley-Unix)
- X Size restrictions released (500 -> 800 lines, 50 -> 100 Refinements)
- X18.03.89
- X dito, expires 31.07.89
- X11.09.89
- X ported to PCS maschine under Munix 5.3 (System V)
- X further #ifdefs for deutsch, expire
- X The switches are given in the Makefile
- X11.09.89
- X dito, expires 31.10.89
- X
- X
- XVersion 2.4 (14, 15, 16)
- X
- X27.08.90 ( --> Uni)
- X Line numbering switchable in 4 levels.
- X Quiet-Option
- X Buffersizes selectable via option.
- X New name handling for input/output files
- X
- X23.01.91 ( --> Uni, Usenet announcement, iraun1)
- X Names and Comments changed to english (was german before)
- X error in level switching of line numbering fixed.
- X
- X10.06.91 ()
- X History translated to english
- X some small corrections
- X corr: REF_INFO storage has to be 0-initialized,
- X so use calloc instead of malloc
- X Eliminated duplication of function declarations for ansi and non-ansi
- X by introduction of the A(a) macro in std.h
- X
- X=============================================================================
- X#endif
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <malloc.h>
- X#include <time.h>
- X
- X#define DATA_HERE /* Here the data declarations are NOT extern */
- X#include "cr_decl.h" /* global Functions, Types and Data */
- X#include "getargs.h"
- X
- X
- X/******************* lokal Functions ************************************/
- X
- Xextern int main A((int argc, charp *argv));
- Xextern int crefine A((int argc, charp *argv));
- Xstatic void process_c_refine A((FILE *in, FILE *out));
- Xstatic void process_line A((FILE *out, int semicolons));
- Xstatic void insert_refinements A((FILE *out));
- Xstatic void insert_refinement A((FILE *out, LINE_INFO *l, int startindent,
- X int recursive_level));
- Xstatic void line_cmd A((FILE* out, int nr, int indent, int min_level));
- Xstatic void put_indent A((FILE *out, int how_much));
- Xstatic void put_line A((FILE *out, LINE_INFO *line, int additional_indent,
- X int min_linenumbering_level));
- Xstatic int refinement_nr A((char *refinementname));
- Xstatic void allocate A((charp *buffer, unsigned *size, unsigned minsize));
- Xstatic void copy_with_doubled_backslashes A((char *string, char *copy));
- Xstatic void do_expire A((int day, int month, int year_in_century));
- Xstatic void reset_l_r_s A((void));
- X
- X/*********************** Lokal Data ************************************/
- X
- X/***** line info, refinement info *****/
- Xstatic LINES l; /* line info */
- Xstatic int l_pos;
- X
- Xstatic REFS r; /* refinement info */
- Xstatic int r_pos;
- X
- X/***** Status *****/
- Xstatic int old_level, /* level at line before */
- X commanded_line_no; /* line_no according to last line_cmd */
- X
- X/***** Sonstiges *****/
- Xstatic char blanks[] = /* indents are made from this. */
- X " ";
- X/* "blanks" is taken as 72 Blanks long (see put_indent) */
- X
- Xstatic option_msg;
- X
- X#define refdecl_line(i) /* line no of refinement head of r[i] */\
- X (l [r[i].firstentry].line_no)
- X
- X/******************************** crefine *********************************/
- X
- Xextern int main (argc, argv) /* MAIN */
- X int argc;
- X charp argv[];
- X{
- X return (crefine (argc, argv));
- X}
- X
- Xstatic ARG argtab[] = {
- X#if deutsch
- X {'a', BOOLEAN, &option_anyway,
- X "alle: Ausgabedatei trotz Fehlern nicht loeschen" },
- X {'c', BOOLEAN, &option_comment, "Refinementnamen-Kommentare in Ausgabe" },
- X {'e', BOOLEAN, &option_indent, "#line Kommandos einruecken" },
- X {'f', BOOLEAN, &option_feedback, "Fortschrittsanzeige (Zeilennummern)" },
- X#if ms_dos
- X {'I', BOOLEAN, &option_ibmchars,
- X "erlaube IBM internationale Zeichen fuer Namen" },
- X#endif
- X {'k', BOOLEAN, &option_comment, "Refinementnamen-Kommentare in Ausgabe" },
- X {'l', BOOLEAN, &option_list, "liste alle Refinementnamen" },
- X {'m', CHARACTER, &option_msg,
- X "Meldungen in: d=deutsch, e=english, sonst humorig" },
- X {'n', INTEGER, &numbering_level,
- X "Stufe der Numerierung mit #line Kommandos" },
- X {'p', BOOLEAN, &option_cplusplus,"C++ Modus" },
- X {'q', BOOLEAN, &option_cplusplus,"keine Startmeldung ausgeben" },
- X {'r', CHARACTER, &refinementsymbol, "Refinementsymbol (als Zeichen)" },
- X {'R', INTEGER, &refinementsymbol, "Refinementsymbol (als Zahl)" },
- X {'s', BOOLEAN, &option_small, "strippen: Kompaktifizierte Ausgabe" },
- X {'w', INTEGER, &warning_level, "Warnstufe (0 - 3)" }
- X {'F', INTEGER, &maxerrors, "Max. Anzahl Fehler" },
- X {'L', INTEGER, &b_size, "Max. Zeilenlaenge" },
- X {'N', INTEGER, &maxref, "Max. Refinements je Funktion" },
- X {'P', INTEGER, &s_size, "Codepuffer in Bytes" },
- X {'T', INTEGER, &tabsize, "Tabulatorgroesse" },
- X {'W', INTEGER, &maxwarnings, "Max. Anzahl Warnungen" },
- X {'Z', INTEGER, &maxline, "Max. Zeilen je Funktion" },
- X#else
- X {'a', BOOLEAN, &option_anyway, "anyway: don't delete output on errors" },
- X {'c', BOOLEAN, &option_comment, "comment refinement names in output" },
- X {'f', BOOLEAN, &option_feedback, "feedback that you work" },
- X {'i', BOOLEAN, &option_indent, "indent the #line commands" },
- X#if ms_dos
- X {'I', BOOLEAN, &option_ibmchars,
- X "enable IBM International Charset for names" },
- X#endif
- X {'l', BOOLEAN, &option_list, "list all refinement names" },
- X {'m', CHARACTER, &option_msg,
- X "Messages in: g=german, e=english, else sense of humor ?" },
- X {'n', INTEGER, &numbering_level,
- X "level of numbering with #line commands" },
- X {'p', BOOLEAN, &option_cplusplus,"C++ mode" },
- X {'q', BOOLEAN, &option_quiet, "quiet mode (no startup message)" },
- X {'r', CHARACTER, &refinementsymbol, "refinementsymbol (character form)" },
- X {'R', INTEGER, &refinementsymbol, "refinementsymbol (decimal form)" },
- X {'s', BOOLEAN, &option_small, "small compactified output" },
- X {'w', INTEGER, &warning_level, "warning level (0 - 3)" },
- X {'B', INTEGER, (int*)&s_size, "code buffer in bytes" },
- X {'E', INTEGER, &maxerrors, "max errors" },
- X {'L', INTEGER, (int*)&maxline, "max lines per function" },
- X {'N', INTEGER, (int*)&maxref, "max refinements per function" },
- X {'T', INTEGER, &tabsize, "tab size" },
- X {'W', INTEGER, &maxwarnings, "max warnings" },
- X#endif
- X};
- X
- X
- Xextern int crefine (argc, argv) /* C-REFINE */
- X int argc;
- X charp argv[];
- X{
- X /* Analyses options and opens files.
- X Then calls process_c_refine and closes files again.
- X Returns the number of errors that have been found
- X */
- X bool two_filenames_given;
- X int wrong_options;
- X FILE *in, *out;
- X `analysis of options;
- X if (wrong_options || argc>>1 != 1) {
- X print_usage (argv[0], usagestring[msg_type],
- X argtab, ARGTABSIZE (argtab));
- X `startup message;
- X exit (100);
- X }
- X if (!option_quiet)
- X `startup message;
- X `open files and complain if necessary;
- X `reserve memory and complain if necessary;
- X /* here we go: */
- X rewind (in); /* Begin at the beginning, then proceed until you come */
- X /* to the end, there stop. (from: Alice in Wonderland) */
- X process_c_refine (in, out);
- X fclose (in);
- X fclose (out); /* Schliessen vor unlink noetig ! */
- X if (errors && !option_anyway) /* don't produce errorneous outputfiles */
- X unlink (name_out); /* delete file */
- X if (errors || warnings)
- X#if deutsch
- X fprintf (stderr, "%d Fehler%s %d Warnung%s Ausgabedatei %s\n",
- X errors, errors != 1 ? "" : "",
- X warnings, warnings != 1 ? "en" : "",
- X errors && !option_anyway ?
- X "geloescht" : (errors ? "dennoch erhalten"
- X : "ist fragwuerdig"));
- X#else
- X fprintf (stderr, "%d error%s %d warning%s Output %s\n",
- X errors, errors != 1 ? "s" : "",
- X warnings, warnings != 1 ? "s" : "",
- X errors && !option_anyway ?
- X "deleted" : (errors ? "kept anyway" : "is doubtful"));
- X#endif
- X return (errors);
- X
- X`analysis of options:
- X option_anyway = option_feedback = option_indent = option_comment
- X = option_list = option_ibmchars = option_cplusplus
- X = false;
- X option_small = true;
- X numbering_level = 3;
- X#if deutsch
- X option_msg = 'd';
- X msg_type = 0; /* deutsche Meldungen als Standard */
- X#else
- X option_msg = 'e';
- X msg_type = 1; /* english warnings and errors as default */
- X#endif
- X refinementsymbol = std_refinementsymbol;
- X tabsize = 1;
- X warning_level = 3;
- X maxline = STD_MAXLINE;
- X maxref = STD_MAXREF;
- X b_size = STD_MAXLINELENGTH;
- X s_size = STD_S_SIZE;
- X maxerrors = STD_MAXERRORS;
- X maxwarnings = STD_MAXWARNINGS;
- X wrong_options = getargs (&argc, argv, argtab, ARGTABSIZE (argtab));
- X if (option_small) {
- X tabsize = 1;
- X }
- X if (option_msg == 'd' || option_msg == 'D' ||
- X option_msg == 'g' || option_msg == 'G')
- X msg_type = 0;
- X else if (option_msg == 'e' || option_msg == 'E')
- X msg_type = 1;
- X else
- X msg_type = 2;
- X two_filenames_given = argc == 3;
- X
- X`startup message:
- X fprintf (stderr,
- X "C-Refine Precompiler %s\n", versionstring[msg_type]);
- X fprintf (stderr,
- X "Copyright (C) 1988,89,90,91 Lutz Prechelt, Karlsruhe\n");
- X
- X`open files and complain if necessary:
- X strcpy (name_in, argv[1]); /* get */
- X#if ms_dos
- X in = fopen (name_in, "rt"); /* read, translated mode */
- X#else
- X in = fopen (name_in, "r"); /* read */
- X#endif
- X if (in == NULL || ferror (in)) {
- X fprintf (stderr, Eopen[msg_type], name_in);
- X exit (100);
- X }
- X copy_with_doubled_backslashes (name_in, modified_name_in);
- X if (two_filenames_given) { /* if second name given */
- X strcpy (name_out, argv[2]); /* take it as it is */
- X }
- X else { /* else */
- X strcpy (name_out, argv[1]); /* take first name */
- X if (name_out[strlen(name_out)-1] == 'r')
- X name_out[strlen(name_out)-1] = 0; /* remove 'r' from end */
- X else
- X strcat (name_out, "RRR"); /* or append 'RRR' */
- X }
- X#if ms_dos
- X out = fopen (name_out, "wt"); /* write, translated mode */
- X#else
- X out = fopen (name_out, "w"); /* write */
- X#endif
- X if (out == NULL || ferror (out)) {
- X fprintf (stderr, Eopen[msg_type], name_out);
- X exit (100);
- X }
- X
- X`reserve memory and complain if necessary:
- X b = malloc (b_size);
- X r = (REFS)calloc ((maxref+1), sizeof (REF_INFO));
- X l = (LINES)malloc ((maxline+1) * sizeof (LINE_INFO));
- X s_root = malloc (s_size);
- X if (!(b && s_root && r && l)) {
- X fprintf (stderr, Ememory[msg_type]);
- X exit (100);
- X }
- X
- X}
- X
- X/************************ process_c_refine *********************************/
- X
- Xstatic void process_c_refine (in, out)
- X FILE *in, *out;
- X{
- X /* Reads the file 'in' to the end line by line via 'get_line' and
- X generates the C source code by inserting the refinement bodies for
- X the calls.
- X Generates error messages for undeclares refinements and warnings for
- X unused or often used ones.
- X Uses the variables stop_processing, errors, warnings,
- X s, l, r and the option indicators.
- X */
- X commanded_line_no = line_no = 0;
- X reset_l_r_s ();
- X if (numbering_level > 0)
- X /* we get a linefeed anyway! */
- X fprintf (out, "#line 1 \"%s\"", modified_name_in);
- X while (!stop_processing)
- X `handle next line;
- X if (option_feedback)
- X cout (line_no);
- X free (s_root);
- X
- X`handle next line:
- X int semicolons = 0;
- X if (option_feedback && line_no % FEEDBACK_INTERVAL == 0)
- X cout (line_no);
- X if (ferror (in))
- X fatal_error (Ereadinput, l[l_pos-1].start, line_no);
- X if (ferror (out))
- X fatal_error (Ewriteoutput, NULL, line_no);
- X get_line (in, l+l_pos, &semicolons);
- X process_line (out, semicolons);
- X}
- X
- X/************************** process_line ************************************/
- X
- Xstatic void process_line (out, semicolons)
- X FILE *out;
- X int semicolons;
- X{
- X /* Works on the lines up to the current line l[l_pos] in the way that
- X it decides whether a function has ended and thus the insertion of
- X refinements has to be started.
- X On level 0 all lines are copied from in to out immediately.
- X After a state change from level 0 to level 1 all lines (along with
- X a lineinfo) are kept until the next transition to level 0 and the
- X refinement info is being built.
- X If necessary, error messages for overflow or refinement errors and
- X warnings for not or multiply used refinements are generated.
- X */
- X if (r_pos > 0)
- X r[r_pos - 1].semicolons += semicolons;
- X if (old_level == 0)
- X `we came from level 0;
- X else
- X `we were inside a function or so;
- X
- X`we came from level 0:
- X assert (l_pos == 0); /* nothing can be stored from level 0 */
- X if (l[0].level == 0 || stop_processing)
- X `remains on level 0 so just copy it;
- X else
- X `function has begun;
- X
- X`remains on level 0 so just copy it:
- X if (l[0].type != normal && l[0].type != empty)
- X error (Elevel0_ref, l[0].start, line_no);
- X put_line (out, &l[0], 0, 1);
- X reset_l_r_s ();
- X
- X`function has begun:
- X error_in_this_function = false;
- X old_level = l[0].level; /* neuen Level merken */
- X if (l[0].type == refdecl && r_pos < maxref) { /* empty function */
- X r[r_pos].name = l[0].start;
- X r[r_pos].firstentry = 0;
- X r[r_pos].active = false;
- X r[r_pos++].semicolons = 0;
- X warning (Wempty_function, NULL, line_no - 1, 3);
- X }
- X l_pos++; /* store line */
- X
- X`we were inside a function or so:
- X if (l[l_pos].level == 0 || stop_processing)
- X `but now we are outside;
- X else
- X `and still keep being in;
- X
- X`but now we are outside:
- X insert_refinements (out);
- X put_line (out, &l[l_pos-1], 0, 1); /* last line (Blockklammer) */
- X put_line (out, &l[l_pos], 0, 1); /* the level 0 line */
- X error_in_this_function = false;
- X reset_l_r_s ();
- X
- X`and still keep being in:
- X if (l[l_pos].type == refdecl && r_pos < maxref) {
- X r[r_pos].name = l[l_pos].start; /* enter Refinement */
- X r[r_pos].active = false;
- X r[r_pos].firstentry = l_pos;
- X r[r_pos++].semicolons = 0;
- X }
- X old_level = l[l_pos].level;/* store new level */
- X l_pos++; /* store line */
- X if (l_pos >= maxline)
- X fatal_error (Elines_in_func, l[l_pos].start, line_no);
- X if (s - s_root >= s_size - 150) /* Reserve too small */
- X fatal_error (Ebytes_in_func, l[l_pos].start, line_no);
- X}
- X
- X/************************ insert_refinements ******************************/
- X
- Xstatic void insert_refinements (out)
- X FILE *out;
- X{
- X /* Replaces the refinement calls with the bodies, after the whole function
- X has been read in.
- X In the output #line statements are generated, except if option
- X numbering_level is zero.
- X Comments and indentations are thrown away if option_small is true.
- X Comments stating the refinement names are inserted in the output if
- X option_comment is true.
- X */
- X int i, end;
- X bool extern_stop = stop_processing; /* Protect last function against */
- X stop_processing = false; /* local use of this variable */
- X r[r_pos].firstentry = l_pos-1; /* line of Blockklammer */
- X r[r_pos].name = NULL;
- X `generate refinement list if necessary;
- X `find last line to insert;
- X for (i = 0; i <= end; i++) { /* lines up to first ref. declaration */
- X switch (l[i].type) {
- X case refcall :
- X case refcallr :
- X `insert refinement;
- X break;
- X case leave :
- X `whatshallthatbe;
- X break;
- X case normal :
- X `insert normal line;
- X break;
- X case empty :
- X putc ('\n', out);
- X commanded_line_no++;
- X break;
- X case refdecl :
- X default :
- X assert (false);
- X }
- X }
- X `maybe give sermon on refinements;
- X stop_processing = stop_processing || extern_stop; /* Merging-Restore */
- X
- X`generate refinement list if necessary:
- X if (option_list && r_pos > 0) {
- X fputc ('\n', stdout);
- X for (i = 0; i < r_pos; i++)
- X fprintf (stdout, "(%d) %s\n", refdecl_line (i), r[i].name);
- X }
- X
- X`find last line to insert:
- X end = r[0].firstentry - 1;
- X while (l[end].type == empty) /* suppress trailing empty lines */
- X end--;
- X
- X`insert refinement:
- X insert_refinement (out, l+i, l[i].indent, 1);
- X if (stop_processing)
- X return;
- X
- X`whatshallthatbe:
- X assert (false);
- X
- X`insert normal line:
- X put_line (out, &l[i], 0, 1);
- X
- X`maybe give sermon on refinements:
- X for (i = 0; i < r_pos; i++)
- X if (r[i].semicolons > 50)
- X warning (Wlong_ref, l[r[i].firstentry].start,
- X refdecl_line (i), 3);
- X else if (r[i].calls > 5 && r[i].semicolons > 2)
- X warning (Wref_often_used, l[r[i].firstentry].start,
- X refdecl_line (i), 3);
- X else if (r[i].calls == 0)
- X warning (Wref_unused, l[r[i].firstentry].start,
- X refdecl_line (i), 1);
- X}
- X
- X/************************* insert_refinement ******************************/
- X
- Xstatic void insert_refinement (out, z, startindent, recursive_level)
- X FILE *out;
- X LINE_INFO *z;
- X int startindent, recursive_level;
- X{
- X /* Looks for the refinement to insert by its name, computes the range
- X of lines to work on and does then do the same as insert_refinements
- X does.
- X If necessary the refinement name is given as a comment before the
- X body is inserted.
- X The refinement body is enclosed in delimiters:
- X if ref.semicolons == 0 in parentheses (on first and last line)
- X if ref.semicolons >= 1 in curly braces (on separate lines)
- X The refinement calls are counted and maybe messages generated.
- X In case of leave-statements the refinement that shall be leave'd is
- X marked, so a label can be generated.
- X Errors:
- X 1. Refinement is not declared
- X 2. recursive call to refinement
- X 3. leave is impossible because the refinement is not
- X present in static call hierarchy
- X */
- X int i;
- X int nr, ref_startindent, end;
- X assert (startindent > 0);
- X nr = refinement_nr (`name); /* search for refinement */
- X if (nr == -1) {
- X error (Eref_not_decl, `name, z->line_no);
- X return;
- X }
- X else if (r[nr].active)
- X `complain for recursive refinement call;
- X else {
- X r[nr].calls++; /* register the call */
- X r[nr].active = true;
- X r[nr].leave_it = false;
- X }
- X end = r[nr+1].firstentry - 1;
- X while (l[end].type == empty) /* suppress trailing empty lines */
- X end--;
- X i = r[nr].firstentry + 1;
- X if (i > end)
- X warning (Wref_empty, l[r[nr].firstentry].start, refdecl_line (nr), 2);
- X else
- X `insert the refinement;
- X r[nr].active = false;
- X return;
- X
- X`complain for recursive refinement call:
- X error (Erecursive_ref, `name, z->line_no);
- X stop_processing = true;
- X return;
- X
- X`insert the refinement:
- X /* for an empty refinement, this is not called at all! */
- X `write indentation and opening klammer;
- X ref_startindent = l[i].indent;
- X for ( ; i <= end; i++) {
- X switch (l[i].type) {
- X case refcall :
- X case refcallr :
- X `insert refinement;
- X break;
- X case leave :
- X `insert goto statement;
- X break;
- X case normal :
- X `insert normal line;
- X break;
- X case empty :
- X putc ('\n', out);
- X commanded_line_no++;
- X break;
- X case refdecl :
- X default :
- X assert (false);
- X }
- X }
- X if (r[nr].leave_it)
- X `generate label;
- X `write closing klammer;
- X
- X`write indentation and opening klammer:
- X int sc = r[nr].semicolons;
- X if (sc > 0)
- X put_indent (out, startindent);
- X putc (sc > 0 ? '{' : '(', out); /* Klammer auf */
- X if (option_comment && sc > 0)
- X fprintf (out, Tlistline[msg_type], `name, recursive_level);
- X
- X`insert refinement:
- X insert_refinement (out, l+i,
- X startindent + l[i].indent
- X - ref_startindent,
- X recursive_level+1);
- X
- X`insert goto statement:
- X int leave_nr = refinement_nr (l[i].start);
- X if (leave_nr == -1)
- X error (Eunknown_leave, l[i].start, l[i].line_no);
- X else if (!r[leave_nr].active)
- X error (Eleave_unpresent, l[i].start, l[i].line_no);
- X else {
- X r[leave_nr].leave_it = true;
- X put_indent (out, startindent);
- X fprintf (out, "goto %s_%d;",
- X l[i].start, r[leave_nr].calls);
- X }
- X
- X`insert normal line:
- X put_line (out, &l[i], startindent - ref_startindent, `num level);
- X
- X`num level:
- X r[nr].semicolons == 0 ? 3 : 2
- X
- X`generate label:
- X fprintf (out, "\n%s_%d: ;", `name, r[nr].calls);
- X commanded_line_no++;
- X
- X`write closing klammer:
- X int sc = r[nr].semicolons;
- X if (sc > 0) {
- X put_indent (out, startindent);
- X putc ('}', out);
- X }
- X else {
- X putc (')', out);
- X if (z->type == refcallr) /* semicolon has been removed illegaly */
- X putc (';', out);
- X }
- X
- X`name:
- X z->start
- X}
- X
- X/************************* line_cmd **************************************/
- X
- Xstatic void line_cmd (out, nr, indent, min_level)
- X FILE *out;
- X int nr;
- X int indent;
- X int min_level;
- X{
- X /* Writes a "preprocessor #line directive" including file name if
- X requested.
- X Is suppressed, if min_level is less than numbering_level.
- X Using numbering_level, option_indent, commanded_line_no and name_in
- X */
- X if (numbering_level >= min_level) {
- X if (option_indent)
- X put_indent (out, indent);
- X else
- X putc ('\n', out);
- X fprintf (out, "#line %d \"%s\"", nr, modified_name_in);
- X commanded_line_no = nr-1; /* #line 3 means: next comes line 3 ! */
- X }
- X}
- X
- X/********************** put_indent **************************************/
- X
- Xstatic void put_indent (out, how_far)
- X FILE *out;
- X int how_far;
- X{
- X putc ('\n', out); /* begin newline */
- X commanded_line_no++;
- X if (!option_small)
- X fwrite (blanks, how_far > 72 ? 72 : (how_far < 0 ? 0 : how_far),
- X 1, out);
- X}
- X
- X/*************************** put_line ***********************************/
- X
- Xstatic void put_line (out, line, additional_indent, min_level)
- X FILE *out;
- X LINE_INFO *line; /* pointer for efficiency (is big object) */
- X int additional_indent;
- X int min_level;
- X{
- X /* Writes the line 'line' to 'out' with the appropriate indentation
- X (which is the line's indentation plus additional_indent).
- X If the current line numbering is not right a line_cmd is made before.
- X */
- X if (line->line_no != commanded_line_no + 1)
- X line_cmd (out, line->line_no, line->indent + additional_indent,
- X min_level);
- X if (line->type == empty) { /* for empty lines: nothing */
- X putc ('\n', out);
- X commanded_line_no++;
- X return;
- X }
- X else if (option_small || (!option_indent && *line->start == '#')) {
- X putc ('\n', out);
- X commanded_line_no++;
- X }
- X else
- X put_indent (out,
- X line->indent + additional_indent); /* starts new line */
- X assert (line->start != NULL);
- X fputs (line->start, out);
- X#if debug
- X fprintf (stdout, "put:\"%s\"\n", line->start);
- X#endif
- X}
- X
- X/********************** refinement_nr ************************************/
- X
- Xstatic int refinement_nr (name)
- X char *name;
- X{
- X /* computes the number of a refinement from its name 'name'.
- X Uses r from 0 to r_pos. Returns the number or -1 if undeclared.
- X If the refinement is declared more than once an error message is
- X generated.
- X */
- X int i, match = -1, matches = 0;
- X assert (name != NULL);
- X for (i = 0; i < r_pos; i++)
- X if (!strcmp (name, r[i].name)) {
- X match = i;
- X matches++;
- X }
- X if (matches > 1)
- X error (Eref_multi_decl, r[match].name, refdecl_line (match));
- X return (match);
- X}
- X
- X/********************* Auxiliary functions ******************************/
- X
- Xstatic void copy_with_doubled_backslashes (string, copy)
- X char *string, *copy;
- X{
- X /* copies the string string to the location copy. All backslash
- X characters (code 92) in string are copied twice, so for example
- X "back\slas\\h" is copied to "back\\slas\\\\h".
- X The purpose of this is to make the copy usable as a C string denoter,
- X in which the backslash is interpreted as an escape symbol.
- X No checks are made, thus there must be enough memory allocated
- X to make the copy.
- X */
- X assert (string != NULL);
- X assert (copy != NULL);
- X while (*string != 0) {
- X *copy = *string;
- X string++;
- X if (*copy == 92) { /* is backslash ? */
- X *(copy + 1) = 92; /* then put another and */
- X copy += 2; /* proceed two bytes */
- X }
- X else /* else */
- X copy++; /* proceed one byte */
- X }
- X *copy = 0;
- X}
- X
- X
- Xstatic void do_expire (day, month, year)
- X int day, month, year;
- X{
- X long act_time;
- X struct tm *t;
- X time (&act_time);
- X t = localtime (&act_time);
- X month--; /* localtime uses months 0 - 11 ! */
- X if (`has expired) {
- X fprintf (stderr, "\n%s\n\n", Thas_expired[msg_type]);
- X exit (100);
- X }
- X
- X`has expired :
- X t->tm_year > year || (t->tm_year == year && t->tm_mon > month) ||
- X (t->tm_year == year && t->tm_mon == month && t->tm_mday > day)
- X}
- X
- X
- Xstatic void reset_l_r_s ()
- X{
- X /* Sets LINE_INFO- and REF_INFO-Arrays 'l' and 'r' into
- X their empty state.
- X */
- X int i;
- X for (i = 0; i <= r_pos; i++) { /* Alle Refinements loeschen */
- X r[i].name = NULL;
- X r[i].calls = 0;
- X }
- X s = s_root; /* Zeilenspeicher loeschen */
- X l_pos = r_pos = old_level = 0;
- X}
- X
- X
- END_OF_FILE
- if test 29204 -ne `wc -c <'crefine.cr'`; then
- echo shar: \"'crefine.cr'\" unpacked with wrong size!
- fi
- # end of 'crefine.cr'
- fi
- if test -f 'crefine.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'crefine.man'\"
- else
- echo shar: Extracting \"'crefine.man'\" \(22380 characters\)
- sed "s/^X//" >'crefine.man' <<'END_OF_FILE'
- X
- X
- X
- XCREFINE(1) USER COMMANDS CREFINE(1)
- X
- X
- X
- XNAME
- X crefine - refinement preprocessor for C and C++
- X
- XSYNOPSIS
- X crefine [ options ] inputfile [
- Xoutputfile ]
- X
- XDESCRIPTION
- X crefine (C-Refine) (spoken like 'see refine') is a prepro-
- X cessor that adds a new language construct to C and C++: the
- X refinement. crefine massages a source code
- Xfile to produce
- X plain C output from C input with refinements or plain C++
- X from C++ with refinements. The syntax of refinements is
- X described in the USAGE section. Only a single source file
- X may be processed with one call; the name of the output file,
- X if not given, is derived from the name of the input file by
- X removing its last character, if that is an r (which is the
- X filename convention for C-Refine). If the last character of
- X the input filename is not an r , the output filename is
- X derived from it by appending RRR instead. Input and output
- X is always to and from named files. Error messages go to the
- X standard output. The startup message, if not suppressed,
- X goes to standard error.
- X
- X C-Refine does not act in any way upon the directives for the
- X C preprocessor. This especially means that include files
- X have to be processed separately. Usually, this will not be
- X necessary, since they do not typically contain anything that
- X C-Refine should work on. A second consequence is, that it
- X is possible for C-Refine to give error messages on correct
- X programs, because it does not see the effects of running the
- X preprocessor. In these cases you either have to change your
- X source code or run the C preprocessor before C-Refine.
- X
- XOPTIONS
- X -a anyway. Normally, if any error was detected by
- X C-Refine, the output file will automatically be
- X deleted. This option says not to do so.
- X
- X -c comment refinement names in the output. Any inserted
- X refiement body in the output is titled by a comment
- X giving the refinement name and the refinement nesting
- X level.
- X
- X -f feedback that you work. For the homo ludens in the pro-
- X grammer or people with incredibly overloaded machines.
- X Shows running line numbers on standard error.
- X
- X -i indent the #line directives in the resulting output to
- X the appropriate indentation level as indicated by the
- X nesting of refinements. Not an especially important
- X option, but since this is a true UNIX program, it is
- X present anyway.
- X
- X
- X
- XSun Release 4.1 Last change: 22 August 1991 1
- X
- X
- X
- X
- X
- X
- XCREFINE(1) USER COMMANDS CREFINE(1)
- X
- X
- X
- X -l list all refinement names. The names of all processed
- X refinements are listed to the standard output along
- X with their line numbers. I do not know exactly what
- X this option may be good for, but I believe someday
- X somebody will need it.
- X
- X -m<ch>
- X message language. Originally, C-Refine was written by a
- X typical german programmer in the typical german pro-
- X grammer schizophrenia situation: as a german the native
- X tongue is german, as a programmer the native tongue is
- X english. So both languages were supported for the error
- X messages. Even worse, since I believe the whole data
- X processing world is much too serious, I liked to have a
- X humourous version either. So now any of the characters
- X d,D,g,G immediately after the option character m gives
- X you german error and warning messages, e or E gives
- X english ones (which, for sake of internationality, is
- X the default) and every other letter lets you stick to
- X (german) humor.
- X
- X -n<num>
- X numbering with #line commands. By default, every inser-
- X tion of a refinement body is accompanied by a #line
- X preprocessor directive in the output. This is the
- X default numbering level 3. By giving a smaller number
- X just after the option character n , the amount of #line
- X directives used can be reduced (level 2 or 1) or set to
- X zero (level 0). What is best depends on the behavior of
- X your local C or C++ compiler. Just try it out, begin-
- X ning with the default level 3.
- X
- X -p plus. The C++ mode. The only difference between C mode
- X and C++ mode for C-Refine is, that in C++ mode the C++
- X doubleslash comment convention is obeyed, while in C
- X mode it is not. This is possible because C-Refine knows
- X very little about the actual syntax of these two
- X languages. So in most cases, this difference makes no
- X difference at all.
- X
- X -q quiet mode. Suppresses the startup message of C-Refine.
- X
- X -r<ch>
- X refinement symbol. Select what character shall be
- X recognized as the refinement symbol in the input file.
- X The character to chose must be given on the command
- X line immediately after the option character r. This is
- X the backquote (ASCII code 95) by default. Since there
- X are only two printable ASCII characters that are unused
- X in the syntax of C (the backquote, code 96, and the
- X dollar or currency sign, code 36) there is very little
- X choice on a machine with 7 bit character set. This
- X
- X
- X
- XSun Release 4.1 Last change: 22 August 1991 2
- X
- X
- X
- X
- X
- X
- XCREFINE(1) USER COMMANDS CREFINE(1)
- X
- X
- X
- X choice is further restricted because on some systems
- X (such as VMS) the dollar sign is acutally being allowed
- X and used for identifiers. Some more possiblilities
- X arise when having an 8 bit character set, such as the
- X IBM international character set (proposed symbol there
- X is the little double right angle bracket, code 175,
- X which really looks nice), but take into account that
- X any change in refinement symbol is bad for the porta-
- X bility of your source files.
- X
- X -R<num>
- X refinement symbol. Same as before, but the new symbol
- X is given by its character code instead of by itself.
- X
- X -s strip. Produces smaller output by stripping of all
- X indentation, whether present in the input or generated
- X by C-Refine, and all comments. This is on by default.
- X To switch it off, use the syntax -s-
- X
- X -w<num>
- X warning level. C-Refine is able to give various warn-
- X ings about your source code. These can be suppressed in
- X three stages. The default warning level is 3 (all warn-
- X ings). You can chose any level from 0 (no warnings) to
- X 3 by giving the appropriate number right after the
- X option character w on the command line.
- X
- X -B<num>
- X buffer. Select the size of the source code buffer in
- X which C-Refine holds the code for a function while pro-
- X cessing it. The default is 150000 bytes.
- X
- X -E<num>
- X errors. Select the maximum number of errors that may
- X occur in the input before C-Refine stops processing
- X prematurely. The default is 20.
- X
- X -L<num>
- X lines. Select the maximum number of source code lines
- X per single function that C-Refine is able to hold. The
- X default is 2500.
- X
- X -N<num>
- X number of refinements per function. Selects the max-
- X imum number of refinement declarations that may be
- X present within any single function. The default is 200.
- X
- X -T<num>
- X tab size. Select the number of spaces to which a TAB
- X character expands. C-Refine expands all TAB characters
- X at the beginning of a line, i.e. those that act as
- X indentation. Other TABs are left untouched. The default
- X
- X
- X
- XSun Release 4.1 Last change: 22 August 1991 3
- X
- X
- X
- X
- X
- X
- XCREFINE(1) USER COMMANDS CREFINE(1)
- X
- X
- X
- X is 1.
- X
- X -W<num>
- X warnings. Select the maximum number of warnings that
- X may occur before C-Refine stops processing prematurely.
- X The default is 30.
- X
- XUSAGE
- X There are three new syntactic elements with C-Refine: the
- X refinement definition, the refinement call and the leave
- X construct. The purpose of refinements is to support the
- X Top-Down style of programming (a) within a function and (b)
- X in both, thinking and writing. Essentially, refinements are
- X just parameterless macros with long descriptive names.
- X Refinements are in any case local to a function. They may be
- X called before they are declared; declaration and definition
- X of a refinement are one. The syntax of refinements as
- X defined by C-Refine is not format free, but lays signifi-
- X cance upon whether a special symbol (the refinement symbol)
- X is occuring in column 0 or somewhere else.
- X
- X Along with the new language constructs are some layout res-
- X trictions for the program text being defined. This is neces-
- X sary, because (a) the syntax of the refinement constructs
- X breaks basic syntactic rules of C and (b) the C-Refine
- X preprocessor relies on some simple formatting rules, so its
- X algorithms can be kept simple and the whole thing small,
- X portable, robust, reliable and fast.
- X
- X Here are the (very informal) descriptions of the syntax and
- X semantics of the language elements introduced by C-Refine:
- X
- X refinement names
- X A refinement name is just a
- Xnormal C identifier, with
- X one important addition: blanks are allowed within (!)
- X it (i.e. anywhere after the first nonblank character of
- X the name and before the last nonblank one); they are
- X equivalent to underscores. The end of a refinement name
- X is always detected by the appearence of a special sym-
- X bol, typically a semicolon, a colon or an operator. A
- X refinement name must, however, be on a single line.
- X
- X refinement calls
- X A refinement call consists of
- Xthe refinement symbol,
- X immediately followed by a refinement name. The refine-
- X ment symbol must not be in colums 0 of the source line.
- X Refinement calls are principally allowed anywhere
- X within a function. The called refinement must be
- X defined in that function, although the definition may
- X (and usually will) appear later than the call. The
- X semantics of a refinement call is as follows: A pro-
- X cedural refinement (i.e.
- Xone that contains at least one
- X
- X
- X
- XSun Release 4.1 Last change: 22 August 1991 4
- X
- X
- X
- X
- X
- X
- XCREFINE(1) USER COMMANDS CREFINE(1)
- X
- X
- X
- X semicolon in its body) is inserted instead of its call,
- X surrounded by a pair of curly braces. This insertion is
- X recursively applied to nested refinements. A valued
- X refinement (i.e. one that contains just
- Xan expression
- X and no semicolon in its body) is inserted instead of
- X its call, surrounded by a pair of parentheses. This
- X insertion is recursively applied to nested valued
- X refinements. So procedural refinements can be called
- X anywhere where a block statement is legal. Valued
- X refinements can be called anywhere where a parenthesed
- X expression is legal. An illegal form of refinement
- X call will be detected by C-Refine.
- X
- X refinement definitions
- X a refinement definition consists of the refinement sym-
- X bol, immediately followed by a refinement name, fol-
- X lowed by a colon. The refinement symbol must be in
- X column 0 of the source line. Refinement definitions are
- X allowed only on block nesting level 1, i.e. in the
- X outermost block of a function. The body of a refine-
- X ment is examined to decide what type of refinement it
- X is: All refinements that contain one or more semicolons
- X in their body, that are not part of a comment, charac-
- X ter denoter or string denoter, are called
- Xprocedural
- X refinements, since they contain
- Xstatements. All other
- X refinements are called valued
- Xrefinements, since they
- X only contain an expression and thus return a value.
- X Illegal syntax of a refinement declaration and the
- X declaration of refinements that are never used will be
- X detected by C-Refine.
- X
- X leave
- X The leave construct may be used
- Xfrom within any pro-
- X cedural refinement at any place where a statement is
- X legal. It consists of the keyword leave followed by the
- X refinement symbol, followed by a refinement name ref.
- X The semantics of this construct is, that a goto state-
- X ment is inserted instead of the leave construct, that
- X jumps to a point right after the last statement of the
- X refinement ref. For this to be legal ref must be
- X present in the current static nesting of refinement
- X calls. This means that not only the current refinement
- X can be left with leave, but any number of refinements
- X that are statically nested at that point of your code.
- X Illegal use of the leave construct is detected by
- X C-Refine.
- X
- X As by now, I assume, almost any understanding that may
- X initially have been there, will probably have vanished.
- X I will try to get it back to you by means of the fol-
- X lowing example. This is a (very simple-minded) version
- X of the Sieve of Eratosthenes. It should not be thought
- X
- X
- X
- XSun Release 4.1 Last change: 22 August 1991 5
- X
- X
- X
- X
- X
- X
- XCREFINE(1) USER COMMANDS CREFINE(1)
- X
- X
- X
- X that I believe the refinement technique to be espe-
- X cially well suited to this problem, but this was the
- X smallest 'real' problem I could think of to demonstrate
- X at least most of what the possibilities of C-Refine
- X are. So here it is:
- X
- X #define MAX 10000
- X #define PRIME 0
- X #define NON_PRIME 1
- X
- X static int sieve[MAX+1];
- X
- X int main ()
- X {
- X `initialize;
- X `do sieve;
- X `make output;
- X return (0);
- X
- X `initialize:
- X int current;
- X for (current = 2; current <= MAX; current++)
- X sieve[current] = PRIME;
- X
- X `do sieve:
- X int current_prime = 1;
- X for (;;) {
- X `find next bigger prime; /* perhaps STOP here */
- X `delete all multiples of current_prime;
- X }
- X
- X `find next bigger prime:
- X int current_candidate = current_prime + 1;
- X while (sieve[current_candidate] == NON_PRIME)
- X if (current_candidate == MAX)
- X leave `do sieve; /* leave two refinements at once */
- X else
- X current_candidate++;
- X /* now current_candidate is a prime (or we leave `sieve) */
- X current_prime = current_candidate;
- X
- X `delete all multiples of current_prime:
- X int current = `first multiple of current_prime;
- X while (current <= MAX) {
- X sieve[current] = NON_PRIME;
- X current += current_prime;
- X }
- X
- X `first multiple of current_prime:
- X 2 * current_prime
- X
- X `make output:
- X
- X
- X
- XSun Release 4.1 Last change: 22 August 1991 6
- X
- X
- X
- X
- X
- X
- XCREFINE(1) USER COMMANDS CREFINE(1)
- X
- X
- X
- X int current; /* different from 'current' above */
- X printf ("The primes between 2 and %d are0, MAX);
- X for (current = 2; current <= MAX; current++)
- X if (`current is prime)
- X printf ("%5d ", current);
- X
- X `current is prime:
- X sieve[current] == PRIME
- X
- X } /* end of main() */
- X
- X /***** End of example *****/
- X To make the self documentation aspect of C-Refine more
- X clear, look at the following example: A function that
- X tests, whether its parameters form a pythagorean tri-
- X ple:
- X bool pythagorean (double x, double y, double z)
- X {
- X return (`all legs positive && `one is hypotenuse)
- X
- X `all legs positive:
- X x > 0 && y > 0 && z > 0
- X
- X `one is hypotenuse:
- X `x is hypotenuse || `y is hypotenuse || `z is hypotenuse
- X
- X `x is hypotenuse:
- X x*x == y*y + z*z
- X
- X `y is hypotenuse:
- X y*y == x*x + z*z
- X
- X `z is hypotenuse:
- X z*z == x*x + y*y
- X
- X }
- X This is good style: you write down just what you want
- X to express and with an optimizing compiler such code
- X will also be perfectly efficient. Try to imagine what
- X this would have looked like, if it had all been in a
- X single parenthesesed expression.
- X
- XFILES
- X bin/crefine the executable program
- X filename.cr C-with-refinements input file.
- X filename.c C output file.
- X filename.ccr C++-with-refinements input file.
- X filename.cc C++ output file.
- X otherfileRRR output file from input file otherfile
- X
- XEXAMPLES
- X crefine firsttest.cr
- X
- X
- X
- XSun Release 4.1 Last change: 22 August 1991 7
- X
- X
- X
- X
- X
- X
- XCREFINE(1) USER COMMANDS CREFINE(1)
- X
- X
- X
- X process the input file firsttest.cr producing the out-
- X put file firsttest.c
- X
- X crefine -p+ -q+ -w2 next.ccr outfile
- X process the C++ inputfile next.ccr producing the output
- X file outfile. The startup message is suppressed, C++
- X mode is selected and the warning level is reduced to 2.
- X
- X crefine -pqw2 next.ccr outfile
- X same as before.
- X
- X crefine -p+a-l-qw2 next.ccr outfile
- X same as before.
- X
- X crefine -c -s- -n0 -T8 last.cr
- X process the inputfile last.cr in order to get a read-
- X able C source. Comments and indentation are not
- X stripped, inserted refinement bodies are tagged by an
- X additional comment giving the refinement name, all
- X #line preprocessor directives are left out and leading
- X tabs expand to 8 spaces.
- X
- X crefine -cs-n0T8 last.cr
- X same as before.
- X
- XDIAGNOSTICS
- X The warnings and error messages are intended to be self
- X explanatory. If you do not understand one of them anyway:
- X chose a different language for the messages (see option -m),
- X get yourself a dictionary or interpreter and try again.
- X
- XSEE ALSO
- X cc(1), cpp(1), make(1)
- X
- XBUGS
- X Since preprocessor directives are not handled by C-Refine,
- X strange things can happen if you use #ifdef or #if. This is
- X especially the case, if you use these directives to put
- X large comments into your source files: if there are any com-
- X ments or string literals (double quotes) or char literals
- X (single quotes) beginning in that area that are not properly
- X closed within it, C-Refine will run to nirvana searching for
- X their end and give you lots of wrong error and warning mes-
- X sages. Watch out for apostrophes (e.g. in "don't") espe-
- X cially!
- X
- X C-Refine should be able to act according to #line commands,
- X so that the above problems could be avoided by running the
- X preprocessor first.
- X
- X Those people, who use such stupid macros as
- X #define BEGIN {
- X
- X
- X
- XSun Release 4.1 Last change: 22 August 1991 8
- X
- X
- X
- X
- X
- X
- XCREFINE(1) USER COMMANDS CREFINE(1)
- X
- X
- X
- X #define END }
- X or similar craizy stuff, will have to change their habits in
- X order to use C-Refine.
- X
- X The output of C-Refine may be code that exceeds certain com-
- X piler limits of your C or C++ compiler. Since the body of
- X every procedural refinement is enclosed in a block and the
- X body of every value returning refinement is enclosed in
- X parentheses, the block nexting limits or expression complex-
- X ity limits of your compiler may be reached when you make
- X very heavy use of nested refinements.
- X
- X Some compilers may handle the #line directive improperly,
- X yielding wrongly tagged error messages.
- X
- X Probably C-Refine will also work with Objective-C, but I am
- X not absolutely sure about that.
- X
- X There should be a mode to use C-Refine for Lisp also.
- X
- X C-Refine reacts poor on some types of syntactic errors.
- X
- X It should optionally be possible to let C-Refine run the C
- X preprocessor and react correctly to #line directives.
- X
- X In C++, when a "leave" has to jump across a variable ini-
- X tialization, some Compilers will complain, that the goto is
- X illegal. This is not true, because the goto jumps to (or
- X even beyond) the very end of the block where that variable
- X is in [precisely: the jump is to an empty statement, which
- X is the last statement in the block], but these compilers do
- X not recognize that fact.
- X
- XVERSION
- X This is for C-Refine Version 2.4
- X
- X It is likely that the command syntax be changed in the next
- X version in the following way: multiple filenames can be
- X given, all of which must end with an 'r'. The output
- X filename is constructed implicitly by removing that 'r' from
- X the inputfilename. So you better do not use output file
- X names in your makefiles.
- X
- XAUTHOR
- X Lutz Prechelt, Institut fuer Programmstrukturen und Datenor-
- X ganisation, Universitaet Karlsruhe, D-7500 Karlsruhe, Ger-
- X many. (prechelt@ira.uka.de)
- X
- X
- X
- X
- X
- X
- X
- X
- XSun Release 4.1 Last change: 22 August 1991 9
- X
- X
- X
- END_OF_FILE
- if test 22380 -ne `wc -c <'crefine.man'`; then
- echo shar: \"'crefine.man'\" unpacked with wrong size!
- fi
- # end of 'crefine.man'
- fi
- echo shar: End of archive 2 \(of 4\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- rm -f ark[1-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-