g+
g+ Communities
Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014 
<== Date ==> <== Thread ==>

Subject: RE: Creating INLINK/OUTLINK in record support
From: "Laznovsky Michael" <Michael.Laznovsky@psi.ch>
To: <tech-talk@aps.anl.gov>
Date: Fri, 24 Aug 2012 12:02:36 +0200
Hi- I know this isn't quite what you're asking for, since you 
already have your huge .dbd file, but perhaps others can use it.

I wrote an awk script some years ago to help me generate dbd's for 
records with potentially hundreds of fields whose names were easily 
automatically generated, like for example ".[A-D][X][0-9][0-9]", 
which would be (4*1*10*10)=400 fields (ie. .AX00, .AX01, .AX02, 
..., .BX00, ..., all the way to .DX99).

If I recall correctly, the resulting file could be #include'd 
unmodified into a top-level .dbd, but I haven't tried it lately.

See attached.

cheers,
Mike

ps- I second the nomination for SNL when run-time dynamic PV 
assignment is desired.

#!/bin/sh
#
# 2012-08-24 updated comments [laznovsky@psi.ch]
# 2006-01-10 changed "dim" to "for" [lazmo@slac.stanford.edu]
# 2005-04-05 original [lazmo@slac.stanford.edu]
#
# fxplode -- combinatorial EPICS field generation
#
# Usage:
#       fxplode inputfile > outfile
#
# This script accepts input blocks of the form:
#
#       begin DBF_FLOAT
#       prompt("int_coef")
#       promptgroup(GUICOMMON)
#       pp(TRUE)
#         <... any other arbitrary field specs, e.g. interest(1), &c >
#       for II IQ QI QQ
#       for 0 1 2 3
#       for A B C
#       end
#
# and outputs EPICS "record field" definitions suitable for inclusion in a 
# .dbd file, generating all possible combinations of the (up to 4) nested "for"s.
#
# The "for" values need not be single characters, but any possible combinations 
# must not exceed 4 chars total (EPICS field-name limit).
#
# Input is processed in blocks, starting with "begin" and ending with "end" lines:
#
#   lines starting with "begin" reset things, and save the field type
#   lines starting with "for" specify one of up to 4 lists of nested substrings
#   lines starting with "end" starts processing with current specs
#   lines starting with "#" are ignored (and passed through)
#   all other lines are saved and written out unchanged in each output field
#
#   All input lines are also output as comments (prepended with "# ").
#
# The example above will output 4*4*3=48 field specs:
#	
#	field(II0A,DBF_FLOAT) {
#		prompt("int_coef")
#		promptgroup(GUICOMMON)
#		pp(TRUE)
#		interest(1)
#	}
#	field(II0B,DBF_FLOAT) { ...
#	field(II0C,DBF_FLOAT) { ...
#	  ... all the way to:
#	field(QQ3B,DBF_FLOAT) { ...
#	field(QQ3C,DBF_FLOAT) { ...
#
# A comment is added at the end showing how many fields were generated, and if any 
# duplicates were found; duplicates are listed without a "#" so they intentionally 
# cause run-time load errors.

cat $* | /bin/nawk '

BEGIN {
    print "#================================================"
    print "#=== GENERATED FILE... do not edit!"
    print "#=== fxplode v1.0"
    print "#================================================"
    print "#"
    ntot = 0
}

{		# count all lines, and output as comments
    lineno++
    print "# " $0
}

/^#/ {		# skip input comments
    next
}

{		# process all others
    if ($1 == "begin") {
	type = $2
	for (x = 0; x < 4; x++) {
	    din[x]   = 1
	    dim[x 0] = ""
	}
	x = kex = 0
	next
    }
    if ($1 == "for") {
	din[x] = NF - 1
	for (y = 0; y < NF-1; y++) {
	    dim[x y] = $(y+2)
	}
	if (x++ >= 4) {
	    print "too many \"for\"s (max 4)... line " lineno
	    exit
	}
	next
    }
    if ($1 == "end") {
	splode()
	next
    }
    if (NF > 0) extra[kex++] = $0
}

END {		# done; check for duplicates
    dup = 0
    for (i = 0; i < ntot; i++) {
	if (num[name[i]] > 1) {
	    print "*** [fxplode] *** duplicate field: " name[i] " (" num[name[i]] " times)"
	    dup++
	}
    }
    print "# " ntot " fields, " dup " duplicates"
}    

function splode()
{
    for (i0 = 0; i0 < din[0]; i0++) {
    for (i1 = 0; i1 < din[1]; i1++) {
    for (i2 = 0; i2 < din[2]; i2++) {
    for (i3 = 0; i3 < din[3]; i3++) {

	name[ntot] = dim[0 i0] dim[1 i1] dim[2 i2] dim[3 i3]

	num[name[ntot]]++

	if (length(name[ntot]) > 4) {
		print "*** [fxplode] *** field name too long (max 4): " name[ntot]
	}
	else {
		print "\tfield(" name[ntot] "," type ") {"
		for (k = 0; k < kex; k++) printf("\t\t%s\n", extra[k])
		print "\t}"
	}

	ntot++

    }}}}
}
'

References:
Re: Creating INLINK/OUTLINK in record support Andrew Johnson
RE: Creating INLINK/OUTLINK in record support Zhang, Dehong

Navigate by Date:
Prev: RE: Creating INLINK/OUTLINK in record support Zhang, Dehong
Next: Re: Creating INLINK/OUTLINK in record support Tim Mooney
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014 
Navigate by Thread:
Prev: RE: Creating INLINK/OUTLINK in record support Zhang, Dehong
Next: Re: Creating INLINK/OUTLINK in record support Tim Mooney
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  <20122013  2014 
ANJ, 18 Nov 2013 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICSv4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·