1#!/bin/sh 2# 3# nana-sfg.in - the nana shortform generator (aka nana science fiction 4# generator). 5# 6# A shortform is the program minus the implementation 7# (code, variables) but includes REQUIRE and ENSURE calls which 8# are the function pre/postconditions. See below for the translation 9# rules. 10# 11# Usage: 12# 13# % nana-sfg <a.c >sf.c 14# % nana-sfg a.c >sf.c 15# % nana-sfg *.[ch] >system.sf 16# 17# Options: 18# 19# Like all good programs this one has no options, obviously different 20# projects will have different requirements. It is suggested that each 21# of your projects (or groups) keep a version of this file and modify 22# it for local taste. For example some people might want to preserve 23# comments starting in the right hand column. 24# 25# Copyright (c) 1998 Phil Maker <pjm@gnu.org> 26# All rights reserved. 27# 28# Redistribution and use in source and binary forms, with or without 29# modification, are permitted provided that the following conditions 30# are met: 31# 1. Redistributions of source code must retain the above copyright 32# notice, this list of conditions and the following disclaimer. 33# 2. Redistributions in binary form must reproduce the above copyright 34# notice, this list of conditions and the following disclaimer in the 35# documentation and/or other materials provided with the distribution. 36# 37# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 38# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 39# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 40# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 41# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 42# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 43# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 45# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 46# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 47# SUCH DAMAGE. 48# 49# $Id: nana-sfg.in,v 1.1.1.1 1999/09/12 03:26:49 pjm Exp $ 50# 51 52@AWK@ ' 53 54# keep track of previous line for function headers 55{ prev = cur; cur = $0; } 56 57# ignore C/C++ labels even though they occur at column 1 58/[a-zA-Z]*:/ { next } 59 60# various C preprocessor directives 61/^#[ \t]*include/ { emit(); } 62/^#[ \t]*define/ { emit(); } 63/^#[ \t]*/ { next } 64 65# various balanced lists of the form X { ... { ... } ...} 66/^typedef[ \t]+struct/ || 67/^typedef[ \t]+union/ || 68/^typedef[ \t]+enum/ || 69/^class/ || 70/^struct/ || 71/^union/ || 72/^enum/ || 73/^class/ { balanced("{","}"); } 74 75# simple typedef such "typedef int word;" (note: complicated ones are handled 76# in the previous rule) 77/^typedef/ { till(";"); } 78 79# any function definition like object starting in column 1 80/^[a-zA-Z].*\(/ { 81 printprevif("^[a-zA-Z]"); # return type in some styles 82 till("\{"); # 83 } 84 85# closing } in column one (end of function/class/typedef/enum/ 86/^\}[ \t]*$/ { emit(); } 87 88# REQUIRE/ENSURE clauses 89/^[ \t]*REQUIRE/ || 90/^[ \t]*ENSURE/ { till("\)[ \t]*;"); } 91 92# PRE/POST clauses 93/^[ \t]*PRE/ || 94/^[ \t]*POST/ { till("\)[ \t]*;"); } 95 96# ignore blank lines 97/^[ \t]*$/ { next } 98 99# finally all text to be removed is printed out with a 100# leading "@@@" for the next pass to compress into "...". 101# 102# Alternatively you could use a few state variables in here to 103# get this to work but the only good state variable is a dead one. 104# 105{ print "@@@" $0 } 106 107#### end of rules #### 108 109# mustgetline - getline with a fatal error on EOF 110function mustgetline() { 111 if(getline <= 0) { 112 print "Fatal error: unexpected eof" 113 exit(1) 114 } 115} 116 117# emit - just print this line and start looking at the next one 118function emit() { 119 print 120 next 121} 122 123# till - print the current line and advance until we match regexp re 124function till(re) { 125 print 126 while(!match($0,re) && (getline > 0)) 127 print $0 128 next 129} 130 131# printprevif - print the previous line iff current line matches re 132function printprevif(re) { 133 if(match(prev,re)) 134 print prev 135} 136 137# balanced - print a balanced list of lines, in particular: 138# 0. print lines until we get the opening 139# 1. until we reach the end of balanced list print them 140# 141# Note: multiple open/closes on one line are NOT detected 142# 143function balanced(opening,closing, cnt) { 144 if(match($0,opening)) { 145 cnt = 1; 146 while(cnt > 0) { 147 print 148 mustgetline() 149 if(match($0,opening)) { 150 cnt++; 151 } 152 if(match($0,closing)) { 153 cnt--; 154 } 155 } 156 print 157 mustgetline() 158 } else { 159 print 160 mustgetline() 161 if(match($0,opening)) { 162 balanced(opening,closing) 163 return 164 } else { 165 puts "expected " $opening ": not found" 166 } 167 } 168} 169 170 171' $* | 172@AWK@ ' 173 174# print adjacent deleted text as ... starting at the column of the 175# first non-white space character in the first line. 176 177/^@@@/ { 178 sub(/^@@@/,"",$0) 179 print indent($0) "..." 180 while(getline > 0) { 181 if(!match($0,/^@@@/)) { 182 print 183 break 184 } 185 } 186 next 187} 188 189{ print } 190 191# indent - returns the indentation (first bit of white space) 192function indent(s, i) { 193 i = s 194 gsub(/[^ \t].*/,"", i) 195 return i 196} 197 198' 199 200 201 202