.TH mklicence 1 "May 2001" .\" Copyright (c) 2001, MeepZor Consulting. .\" All rights reserved. .\" .\" The use and distribution of this code or document is .\" governed by version 1.0.1 of the MeepZor Consulting Public .\" Licence (MCPL), which may be found on the Internet at .\" . .\" .\" Some macros so we can avoid excessive leaning toothpicks. .char \[.] \N'46' .char \[op] \N'40' .char \[cp] \N'41' .SH NAME mklicence \- A Simple Text Transformer .SH SYNOPSIS .B mklicence .B \-f .I format [\fB\-l\fP \fIinput-file\fP] [\fB-d\fP] [\fB-h\fP] [\fB-s\fP] [\fB-u\fP \fIundefined-string\fP] [\fB-v\fP] [\fIname\fP\fB:\fP\fIvalue\fP ...] .br .SH DESCRIPTION .B mklicence is a very simple-minded tool for transforming text into comments in a variety of languages. The input text can be tailored at run-time. It was originally developed for converting generic software licence into comment blocks in various languages, and was then enhanced to allow conditional inclusion of text, variable definitions, and other 'interesting' things. .PP The transformed text is emitted on the stdout stream. .SH OPTIONS Option values may be separated from their keywords by either an equals-sign ('=') or a space; the following are equivalent: .IP \fB\-f\~html .br \fB\-f=html .P Option descriptions: .IP \fB\-d\fP Causes \fImklicence\fP to operate in debugging mode. This will cause status statements to be emitted on stderr. It also enables the \fP.dump\fP directive and sets the \fIDEBUG\fP symbol to '1'. .IP \fB\-f\fP\~\fIformat\fP Identifies the initial format of the transformed text. The format of tranformed text may be changed in mid-stream with the \fB\[.]format\fP directive, so the output may actually contain multiple fragments in different formats. .IP This format name can be any of the following: .IP \~\~\~\fBhtml\fP The emitted text will be enclosed in \fB\fP HTML comments, one enclosure \fIper\fP line. The closing comment delimiters will be right-justified at a margin determined by the longest text line in the block. .IP \~\~\~\fBtext\fP\~|\~\fBtxt\fP\~|\~\fBplain\fP\~|\~\fBplaintext\fP The transformed text will be simply copied to stdout after substitutions, with no additional formatting. .IP \~\~\~\fBc\fP\~|\~\fBcblock\fP\~|\~\fBc-block\fP Transformed text will be emitted as block C comments, such as .IP /* .br \~* Comment .br \~*/ .IP \~\~\~\fBcline\fP\~|\~\fBc-line\fP Each line of transformed text will be emitted as a C inline comment, for example: .IP /* Comment */ .IP \~\~\~\fBc++\fP\~|\~\fBcxx\fP This will cause each line of transformed text to be emitted as a C++ '//' comment, such as .IP // Comment .IP \~\~\~\fBman\fP Lines of transformed text will be emitted with '.\e"' prepended: .IP \[.]\e" Comment .IP \~\~\~\fBperl\fP\~|\~\fBpl\fP All emitted lines of transformed text will begin with '#\~'. .IP \fB\-h\fP Causes \fImklicence\fP to display its version and usage information and then exit. .IP \fB\-l\fP\~\fIinput-file\fP This is the name of the file which is to be read and transformed. Only a single file may be specified \fIper\fP invocation. If it is omitted, or is specified as '\fB-l -\fP', then the stdin stream is read. .IP \fB\-s\fP The presence of this option causes definitions made on the command line to be marked as 'locked'; they cannot be redefined by directives in the input file. In addition, all of the predefined symbols are locked as well. .IP \fB\-u\fP\~\fIundefined-string\fP This specifies the replacement string for undefined symbol references. By default, such references are replaced with an empty string; '\fB${foo}\fP' will be replaced with '' if \fIfoo\fP hasn't been defined. Using this option permits that default replacement text to be overridden. The text may include symbol references for any of the predefined symbols (see '\fBPREDEFINED SYMBOLS\fP'). .IP \fB\-v\fP Causes \fImklicence\fP to display its version information and then exit. .SH DIRECTIVES Directives in the input file begin with a period in column one. If a line begins with a period and isn't recognisable as a directive, it is treated as part of the raw text and is not interpreted. .IP \fB.#\fP If this appears at the beginning of a line, it indicates that all of the remaining text up to and including the end of the line is a comment. Comments are ignored. .IP \fB.\fIname\fB:\fIvalue\fP Define \fIname\fP with the specified value. The definition is available for use in the input file from the point at which it occurs onward. If \fIname\fP is already defined, it will be assigned the new value. If \fIname\fP was defined on the command line and the \fI\-s\fP option was supplied, an error message will be displayed, \fIname\fP will not be redefined, and processing will continue as though the directive hadn't been present. .IP The \fIvalue\fP may contain references to other definitions, but not to Perl expressions. For example, .IP \fB\[.]a:12\fP .br \fB\[.]b:${a}3 .IP will result in the symbol \fIa\fP being defined as '12', and \fIb\fP as '123'. .IP \fB.dump\fP This is a debugging directive, and is only regarded as a directive when the \fB-d\fP option has been specified on the command line. Otherwise, it is treated as normal text, and will be copied to the output stream. Therefore, it shouldn't be used in production-quality input files, or if it is, it should be conditionalised with something like this: .IP \fB\[.]if ${DEBUG}\fP .br \fB\[.]dump\fP .br \fB\[.]endif\fP .IP Note that \fB.dump\fP directives are processed \fIas they are encountered\fP, and their output is directed to stderr. The emission of the normal transformed text, on the other hand, is deferred until the entire input file has been read and processed. Therefore, if stderr and stdout are directed to the same stream (such as a tty), \fIall\fP of the \fB.dump\fP output(s) will be displayed before any transformed text is. .IP \fB.fill\fP\~/\~\fB.endfill\fP [\fINot yet implemented.\fP] \fI\[.]fill\fP begins a block in which short lines will be filled from those following to pad the text to as close as possible to the margin (see the \fI\[.]margin\fP directive). Leading whitespace on a line being padded will be maintained on subsequent adjusted lines. The fill block is terminated by an \fI\[.]endfill\fP directive. .IP \fB\[.]if\fP\~/\~\fB\[.]else\fP\~/\~\fB\[.]endif\fP These directives provide for conditional inclusion of text (and processing of directives). The string on the \fI\[.]if\fP directive will be interpreted as a Perl expression; if it evaluates to a true value, the following text, up to a corresponding \fI\[.]else\fP or \fI\[.]endif\fP directive, will be interpolated and included in the output stream. Directives will be processed normally. If there is a corresponding \fI\[.]else\fP directive, text between it and the appropriate \fI\[.]endif\fP directive will be ignored. .IP If the expression evaluates to a false value, the following text will be ignored until a corresponding \fI\[.]else\fP or \fI\[.]endif\fP directive is encountered. Interpolation and processing will resume at that point. .IP \fI\[.]if\fP-blocks may be nested. The conditional expression will have symbols interpolated before being evaluated. .IP \fB\[.]format\fP Changes the format for subsequent transformed text. The argument can be a fixed string or a symbol expression to be interpolated. If the new format isn't recognised, a message is displayed on the stderr stream and processing continues as though it hadn't been encountered at all. .IP \fB.literal\fP\~/\~\fB.endliteral\fP Flags that input text between the \fB.literal\fP and \fB.endliteral\fP directives should not be interpreted. No symbol interpolations will be performed, and all directives lose their special meaning, until a corresponding \fB.endliteral\fP directive is encountered. .IP \fB\[.]margin\fP This sets the right margin used in fill-blocks (see the \fI\[.]fill\fP directive). It takes a single argument, which may be either a number or a symbol that can be interpolated to a number. This is particularly useful for saving and restoring the value, as in: .IP \[.]save-margin:${MARGIN} .br \[.]margin 40 .br \~\~\~\~: .br \[.]margin ${save-margin} .br Text lines that are longer than the margin and that cannot be wrapped (such as long URLs) are not affected. .SH SYMBOL DEFINITION AND INTERPOLATION \fBmklicence\fP's symbol table is controlled by the \fB.\fP\fIname\fP\fB:\fP\fIvalue\fP directives found in the input file, the predefined symbol list, and symbols defined on the command line. Processing of the input file is performed in a single pass, so each definition or redefinition of a symbol takes effect immediately and applies to all subsequent lines of the input file -- until the symbol is redefined. .PP Symbol names may contain any printable character \fIexcept\fP colons ('\fB:\fP') or whitespace. Therefore, the following is a perfectly valid definition: .IP \fB\[.]F&6$w--3:12\fP .PP However, because of Perl regexp processing during the interpolation process, results may be unexpected or undefined if you use any characters that have meaning in a regexp. .PP Symbol values are inserted whenever a reference to them is encountered. A symbol reference looks like .IP \fB${\fP\fIsymbolname\fP\fB}\fP .PP Symbol references will be replaced ('interpolated') with the symbol's value whenever they are encountered -- except in the name portion of a symbol definition. In other words, .IP \fB\[.]a:12\fP .br \fB\[.]b${a}:13\fP .PP will \fInot\fP result in a symbol named '\fBb12\fP' being created with the value '\fB13\fP'. Instead, the symbol \fBb${a}\fP will be created with that value. .PP Symbol references are interpolated as they are encountered, so if the symbol in question hasn't been defined by the time the reference is made, the default replacement text will be substituted. (See the \fB-u\fP option description.) This is particularly important for symbols defined on the command line whose values include references; very few symbols are actually defined at that point. .PP There is a single symbol table for all files processed, so symbols defined in included files are available in outer files, and \fIvice versa\fP. The only exceptions is the predefined \fIINPUT_LINE\fP symbol, which is reset to 1 for the first line of an input file, and restored when the inclusion is finished. .SH COMMAND-LINE SYMBOL DEFINITIONS .PP Symbols may be pre-defined on the command line by specifying them in \fIname\fP\fB:\fP\fIvalue\fP syntax, just as they would appear in the input file (minus the leading period; see the \fB.\fP\fIname\fP\fB:\fP\fIvalue\fP directive description). Such definitions may even include interpolations, such as .IP \fBmklicence -f text -l file v:'${VERSION}' .PP Care must be taken to protect such interpolation expressions from shell expansion. .SH PREDEFINED SYMBOLS The following symbols are all defined before any input or command-line definitions are processed. If the \fI-s\fP option is specified, they are also marked as unmodifiable. Otherwise they may be altered like any other symbols. .PP Note that redefining these symbols \fIwill not\fP affect \fImklicence\fP's processing; for example, .IP \fB\[.]MARGIN:100 .PP is \fInot\fP equivalent to .IP \fB\[.]margin\~100 .PP \fImklicence\fP will continue using the same margin setting, but that setting will no longer be available through the \fIMARGIN\fP symbol until a \fB\[.]margin\fP directive changes the margin and resets the symbol value. .IP \fIDEBUG\fP This is either undefined, or defined as '1', depending upon whether then \fI-d\fP option was specified on the command line. .IP \fIFILL\fP \fImklicence\fP sets this to either 1 or 0, depending upon whether a \fI\[.]fill\fP-block is active or not. [\fINot yet implemented.\fP] .IP \fIFORMAT\fP This is the general format that was selected. It will be one of the following: \fIC++\fP \fIC-block\fP \fIC-line\fP \fIHTML\fP \fIman\fP \fIPerl\fP \fItext\fP .br or other formats if the tool has been augmented appropriately. The precise value of the \fI-f\fP option can be obtained from the \fIFORMAT_EXACT\fP symbol. .IP \fIFORMAT_EXACT\fP This is the exact value of the \fI-f\fP option from the command line or the \fI\[.]format\fP directive; it indicates the specific transformation format selected. .IP \fIINPUTFILE\fP This is the name of the input file specified on the command line with the \fI-l\fP option. .IP \fIINPUT_LINE\fP This is the current input line number in the file being processed. This symbol is redefined at each line, so trying to change its value is completely futile. .IP \fIMARGIN\fP This is the setting of the current right margin. The margin is only meaningful within a \fI\[.]fill\fP-block. [\fINot currently implemented.\fP] .IP \fIOUTPUT_LINE\fP This is the number of the current output line. This is redefined each time the output line pointer is incremented, so changes made to it using \fB\[.]OUTPUT_LINE:\fP\fIvalue\fP directives will only last until the next line of text to be transformed is encountered. .IP \fIVERSION\fP This is defined as the version of the transformation tool, such as '1.4'. .SH MESSAGES The following messages may be displayed by \fBmklicence\fP on the stderr diagnostic output stream. .IP \fBmklicence:\~.fill\~not\~active;\~.endfill\~ignored\~at\~\fP\fIfilename\fP\fB:\fP\fIn\fP Self-explanatory; a \fI\[.]endfill\fP directive was encountered when line filling was not active. [\fINot yet implemented.\fP] .IP \fBmklicence:\~malformed\~.margin\~directive\~at\~\fP\fIfilename\fP\fB:\fP\fIn\fP The argument to the \fI\[.]margin\fP directive does not evaluate to a number. .IP \fBmklicence:\~can't\~access\~include\~file\~'\fIfilename\fB'\~at\~\fP\fIfilename\fP\fB:\fP\fIn\fP This is a warning message only; text processing continues as though the \fI\[.]include\fP directive hadn't been specified. .IP \fBmklicence:\~including\~contents\~of\~'\fP\fIfilename\fP\fB'\~at\~\fP\fIfilename\fP\fB:\fP\fIn\fP This is an informational message, and is only displayed if debug mode is active. .IP \fBmklicence:\~format\~changed\~to\~\fP\fIformat\fP\fB\~at\~\fP\fIfilename\fP\fB:\fP\fIn\fP This is a debugging message only encountered when the \fI-d\fP option is specified. The message indicates that a \fI\[.]format\fP directive in the input file has been processed. .IP \fBmklicence:\~unrecognised\~format\~'\fP\fIformat\fP\fB'\~at\~\fP\fIfilename\fP\fB:\fP\fIn\fP A \fI\[.]format\fP directive was encountered, but the argument wasn't (or didn't interpolate to) a recognised format. The directive has been ignored. .IP \fBmklicence:\~'\fIsymbolname\fB'\~=\~'\fIvalue\fB'\fP This is a debugging message generated by the \fI.dump\fP directive when debugging is enabled (with the \fB-d\fP option). One such line will be displayed for each symbol that is defined. .IP \fBmklicence:\~.if\~at\~\fIfilename\fP\fB:\fP\fIn\fB\~has\~no\~corresponding\~.endif\fP This should be pretty self-explanatory; the input file has an unclosed conditional block. Perhaps the \fI.endif\fP is inside a \fI.literal\fP block. .\" .\" The following bit of funk is my hacked attempt to get the message .\" line to wrap correctly (though it's a hard wrap) w/o inserting .\" vertical whitespace. Also, to get the parens in; they were screwing .\" up the macros somehow. .\" Bleh. .\" .PP \fBmklicence:\~.if-expression\~'\fP\fIexp1\fP\fB'\~\[op]'\fP\fIexp2\fP\fB'\[cp]\fP\fB\~at\~\fP\fIfilename\fP\fB:\fP\fIn\fP .br \fB\~evaluated\~to\~'\fP\fIvalue\fP\fB'\fP .IP This message will only appear when debugging has been enabled with the \fB-d\fP option. It shows the evaluation of a \fI.if\fP-condition; \fIexp1\fP is the actual expression from the input file, \fIexp2\fP is the expression after symbol interpolation has occurred, and \fIvalue\fP is the actual evaluated result of the condition expression. .IP \fBmklicence:\~ignored\~attempt\~to\~redefine\~locked\~value\~for\~'\fIsymbolname\fB'\fP This message will be displayed if the input file tries to set or change the value of a symbol that was set on the command line. Such changes are only disallowed when the \fB-s\fP option has been specified. .IP \fBmklicence:\~can't\~access\~input\~file\~\fIfilename\fP Self-explanatory; the input file cannot be read. It may not exist, or may have incompatible permissions. .IP \fBmklicence:\~invalid\~value\~for\~-f\fP The format that was specified on the command line is not recognised by the \fBmklicence\fP tool. .IP \fBmklicence:\~keyword\~'\fIsymbolname\fB'\~defined\~to\~'\fIvalue\fB'\fP Debugging message displayed when \fB-d\fP is in effect and a symbol is created. .IP \fBmklicence:\~keyword\~'\fIsymbolname\fB'\~redefined\~to\~'\fIvalue'\fP Similar to the preceding message; this is a debugging message displayed when an existing symbol is given a new value. .IP \fBmklicence:\~required\~option\~-f\~missing\fP Self-explanatory. .IP \fBmklicence:\~superfluous\~.else\~at\~line\~\fIfilename\fP\fB:\fP\fIn\fP A \fI.else\fP directive was encountered when no conditional block was open. Perhaps some conditional directives are inside a \fI.literal\fP block. .IP \fBmklicence:\~superfluous\~.endif\~at\~line\~\fIfilename\fP\fB:\fP\fIn\fP Self-explanatory; a \fI.endif\fP directive was encountered when no conditional block was open. Perhaps some conditional directives are in a \fI.literal\fP block. .SH EXIT STATUS .B mklicence returns an exit status of 1 if there are problems with the \fB-f\fP or \fB-l\fP command-line options. Otherwise, the exit status is zero indicating a successfully processed file. .SH EXAMPLES Given an input file such as the following (named 'example.moof' for this example): .IP \fB.a:12\fP \fB.# Comment 1\fP \fB.b:${a}3\fP \fB.sump\fP \fB.dump\fP \fB.literal\fP \fB.b:321\fP \fB.# Comment 2\fP \fB.dump\fP \fB.endliteral\fP \fBb=${b}\fP \fB.# Comment 3\fP \fB.dump\fP .PP \fImklicence\fP will produce the following when \fB-d\fP is \fInot\fP specified: .IP \fB.sump\fP \fB.dump\fP \fB.b:321\fP \fB.# Comment 2\fP \fB.dump\fP \fBb=123\fP \fB.dump\fP .PP and the following output if \fB-d\fP \fIis\fP specified: .IP \fBmklicence: keyword 'DEBUG' defined to '1'\fP \fBmklicence: keyword 'DEPTH' defined to '-1'\fP \fBmklicence: keyword 'MARGIN' defined to '65'\fP \fBmklicence: keyword 'FILL' defined to '0'\fP \fBmklicence: keyword 'FORMAT' defined to 'text'\fP \fBmklicence: keyword 'FORMAT_EXACT' defined to 'text'\fP \fBmklicence: keyword 'VERSION' defined to '1.7'\fP \fBmklicence: keyword 'INPUTFILE' defined to 'example.moof'\fP \fBmklicence: keyword 'DEPTH' redefined to '0'\fP \fBmklicence: keyword 'a' defined to '12'\fP \fBmklicence: keyword 'b' defined to '123'\fP \fBmklicence: 'DEBUG' = '1'\fP \fBmklicence: 'DEPTH' = '0'\fP \fBmklicence: 'FILL' = '0'\fP \fBmklicence: 'FORMAT' = 'text'\fP \fBmklicence: 'FORMAT_EXACT' = 'text'\fP \fBmklicence: 'INPUTFILE' = 'example.moof'\fP \fBmklicence: 'MARGIN' = '65'\fP \fBmklicence: 'VERSION' = '1.7'\fP \fBmklicence: 'a' = '12'\fP \fBmklicence: 'b' = '123'\fP \fBmklicence: 'DEBUG' = '1'\fP \fBmklicence: 'DEPTH' = '0'\fP \fBmklicence: 'FILL' = '0'\fP \fBmklicence: 'FORMAT' = 'text'\fP \fBmklicence: 'FORMAT_EXACT' = 'text'\fP \fBmklicence: 'INPUTFILE' = 'example.moof'\fP \fBmklicence: 'MARGIN' = '65'\fP \fBmklicence: 'VERSION' = '1.7'\fP \fBmklicence: 'a' = '12'\fP \fBmklicence: 'b' = '123'\fP \fBmklicence: keyword 'DEPTH' defined to '-1'\fP \fB.sump\fP \fB.b:321\fP \fB.# Comment 2\fP \fB.dump\fP \fBb=123\fP .SH SECURITY CONSIDERATIONS None. .SH RESTRICTIONS .IP o If a conditional block contains multiple \fI.else\fP directives, only the first is interpreted. .IP o If a symbol name includes characters that are significant in a Perl regular expression, results are unpredictable and undefined. .IP o Currently, control blocks are not terminated at EOF, so an unterminated \fI\[.]literal\fP block started in an included file will cause text following the \fI\[.]include\fP directive to continue to be regarded as literal. This applies to conditional blocks as well. .SH FILES Only the \fBmklicence\fP script and the user-specified input file. .SH AUTHOR Ken Coar .SH REPORTING BUGS Report bugs to .SH COPYRIGHT Copyright \(co 2000-2001 MeepZor Consulting. .br This is open-source software; see the source for copying conditions. .SH SEE ALSO Perl module Getopt::Long.