/*\v
% write table of contents (only in single file mode):
\ifmfiles\else\pagenumbering{roman}
\tableofcontents\newpage\pagenumbering{arabic}\fi
\centerline{\huge\bf File tiny\_c2l.l}
*/
/*\b
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<***********************>>>>>>>>>>>>>>>>>>>>>>>>
<* filename : tiny_c2l.l *>
<* purpose : this is a little lex file as an example for a simple *>
<* : converter using the position macros. Only a few *>
<* : basic conversions are implemented; all fonts etc. are *>
<* : hard-coded. You may use this file as example for use *>
<* : of the position macros or as starting point for an own *>
<* : converter project. *>
<* : *>
<* cvt2ltx : This file is the tiny version of c2ltx; keywords, *>
<* equiv. : strings and comments are recognized. A very simple *>
<* : version of embedded LaTeX is implemented (only append *>
<* : mode and verbatim mode; everything is copied verbatim *>
<* : to the output file in both cases. *>
<* : *>
<* version : 1.4.0 from 25-feb-2000 *>
<* author : Michael Plugge <
[email protected]> *>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<***********************>>>>>>>>>>>>>>>>>>>>>>>>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
*/
%{
/*\v \section{Declaration Part} */
#define VERSION "1.4.0"
#define VERSION_DATE "25-feb-2000"
#define TAB2SPC 3
#define BASE_FONT "basefont"
#define BLOCK_FONT "blockfont"
#define KEYWORD_FONT "keywordfont"
#define STRING_FONT "stringfont"
#define COMMENT_FONT "commentfont"
#define HEADFONT "headfont"
#define FOOTFONT "footfont"
#define LHEAD ""
#define CHEAD "Produced from %f on %D %t"
#define RHEAD ""
#define LFOOT ""
#define CFOOT "Page %p"
#define RFOOT ""
#define L2E_STYLE " \\documentclass[10pt]{article}\n\
\\usepackage{a4,position,fancyhdr}\n\
\\usepackage[latin1]{inputenc}\n\
\\textwidth18cm\\textheight25cm\\hoffset-3cm\\voffset-1cm"
#define L209_STYLE " \\documentstyle[a4,position,fancyhdr]{article}\n\
\\textwidth18cm\\textheight25cm\\hoffset-3cm\\voffset-1cm"
#define L2E_STYLE_LINE " \\documentclass[10pt]{article}\n\
\\usepackage{a4,position,fancyhdr}\n\
\\usepackage[latin1]{inputenc}\n\
\\textwidth18cm\\textheight25cm\\hoffset-3cm\\voffset-1cm"
#define L209_STYLE_LINE " \\documentstyle[a4,position,fancyhdr]{article}\n\
\\textwidth18cm\\textheight25cm\\hoffset-3cm\\voffset-1cm"
/*\f The following definition controls the behavior of linebreaks
* for comments: after this ASCII position, continuation lines use
* the current indentation */
#define ALIGN_CMT_LIMIT 50
#define LEN(val) if((leng+=val)>70){leng=0; fprintf(yyout,"%%\n ");}
#if VMS
#undef ECHO
#define ECHO yyleng==1 ? fputc(*yytext,yyout) : fprintf(yyout,"%s",yytext)
#endif
#include <string.h>
#include <time.h>
char *ptr,*ptr1,*kern,*inputname,buffer[256],init=1,cmt_mode;
int pos,old_pos,brace_open,tmp,leng,tab2spc=TAB2SPC,sc,sc1,
pes_old= -1,cmt_blanks,skip_cnt,cmt_pos,line=1,show_lines,use_header=1;
long year;
time_t time_val;
struct tm *atime;
char *lhead=LHEAD,*chead=CHEAD,*rhead=RHEAD,*headfont=HEADFONT,
*lfoot=LFOOT,*cfoot=CFOOT,*rfoot=RFOOT,*footfont=FOOTFONT,
*latex_prolog1=
"%%%% This file was generated by tiny_c2l (version %s, %s)\n\n\
\\ifx\\getformat\\undefined\n\
\\newcount\\getformat\\getformat0\n\
\\else\n\
\\mfilestrue\\getformat3\n\
\\fi\n\
\\ifx\\documentclass\\undefined\\advance\\getformat1\\fi\n\n\
\\ifcase\\getformat\n\
%s\n\
\\or\n\
%s\n\
\\else\\fi %% multiple file input: don't load format\n%s",
*latex_prolog2="\\gdef\\cmt#1#2{\\psinit{#1}{\\hphantom{/}$\\ast$\\mblank{#2}}\\%s}\n\
\\gdef\\cmtpp#1#2{\\psinit{#1}{//\\mblank{#2}}\\%s}\n\
\\gdef\\ccmtend{\\setbox\\pstartbox=\\hbox{\\hphantom{/}}}\n\
\\ifmfiles\\else\\begin{document}\\fi\\begin{flushleft}\n\n",
*month[]={
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
},
*local_month[]={
"Januar",
"Februar",
"M�rz",
"April",
"Mai",
"Juni",
"Juli",
"August",
"September",
"Oktober",
"November",
"Dezember"
},
*month1[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"},
*local_month1[]={"Jan","Feb","Mrz","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dez"},
*usage_text1=" Usage: tiny_c2l [options] [infile [outfile]] [options]\n\
infile and/or outfile may be omitted; in this case stdin/stdout are used.\n\
valid options are:\n\
-hn don't generate header or footer text\n\
-hl<txt> header text: left side (default \"\")\n\
-hc<txt> header text: center (default \"Produced from %f on %D %t\")\n\
-hr<txt> header text: right side (default \"\")\n\
-fl<txt> footer text: left side (default \"\")\n\
-fc<txt> footer text: center (default \"Page %p\")\n\
-fr<txt> footer text: right side (default \"\")\n\
possible escape sequences for the -h. and -f. switches are:\n\
%f: input file name %m: month (numeric value)\n\
%p: page number %n: (english) name of month (full form)\n\
%t: time (HH:MM) %s: (english) name of month (short form)\n\
%D: date (DD-MMM-YYYY) %N: (local) name of month (full form)\n\
%h: hour %S: (local) name of month (short form)\n\
%M: minute %y: year\n\
%d: day of month %: the `%' character itself\n\
-l[cnt] output line numbers\n\
-+ C++ mode\n\
-j java mode\n\
-o outputname (if stdin is used for input)\n\
-t<cnt> number of spaces per tab character (default: ",
*usage_text2=")\n\
-d debug (debug output is written to tiny_c2l.dbg)\n\
-? show this help screen\n";
void keyword(void);
void skip_msg(void);
void chk_cmt(void);
void print_jmpo(int linebegin);
void init_out(int mode);
int die(char *cmd,int mode);
void substitute_format(char *format);
char *subst(int c);
void current_line(void);
%}
/* preprocessor keywords (without the leading #) */
PP_KEY (define[ \t])|(undef[ \t])|(ifn?(def)?[ \t(])|(elif[ \t(])|(else[ \t\n])|(endif[ \t\n])|(error[ \t])|(line[ \t])|(pragma[ \t])|(include[ \t<\"])
SP [ \t]+
SPO [ \t]*
WS [ \t\n]
WSO [ \t\n]*
WSSEMI [ \t\n;]
WSBRSEMI [ \t\n(;]
WSBR [ \t\n(]
WSBR2 [ \t\n)]
WSBC [ \t\n{]
WSS [ \t\n*]
WSSB [ \t\n*)]
WSC [ \t\n:]
OPER [ \t\n+\-*/%|&^~!=<>\[(,]
CA [ \t\n<]
WSB2 [ \t\n\[(]
NEW_DEL [ \t\n\[(<]
%x LINE_BEGIN OMIT
%x STRING C_CMT CPP_CMT FILL_CMT FILL_CPP_CMT
%x EL_CMT1 EL_CMT2 EL_CMT3 PREPROCESSOR
%s JAVA CPLUSPLUS
%option 8bit noyywrap outfile="tiny_c2l.c" debug
%%
/*\v \section{Rules section}\subsection{\LaTeX Prolog} */
if(show_lines)
fprintf(yyout,latex_prolog1,VERSION,VERSION_DATE,L2E_STYLE_LINE,
L209_STYLE_LINE,use_header?"\\pagestyle{fancy}\n":"");
else
fprintf(yyout,latex_prolog1,VERSION,VERSION_DATE,L2E_STYLE,
L209_STYLE,use_header?"\\pagestyle{fancy}\n":"");
fprintf(yyout,"\\plcntmargin{777}\n");
if(use_header){
fprintf(yyout,"\\lhead{\\%s ",headfont);
substitute_format(lhead);
fprintf(yyout,"\\chead{\\%s ",headfont);
substitute_format(chead);
fprintf(yyout,"\\rhead{\\%s ",headfont);
substitute_format(rhead);
fprintf(yyout,"\\lfoot{\\%s ",footfont);
substitute_format(lfoot);
fprintf(yyout,"\\cfoot{\\%s ",footfont);
substitute_format(cfoot);
fprintf(yyout,"\\rfoot{\\%s ",footfont);
substitute_format(rfoot);
}
if(!show_lines)
fprintf(yyout,"\\plinenowidth0pt\n");
else
fprintf(yyout,"\\plcntmargin{77}\n");
fprintf(yyout,latex_prolog2,COMMENT_FONT,COMMENT_FONT);
BEGIN(LINE_BEGIN);
/*\v \subsection{Rules for Line Begin} */
<LINE_BEGIN>{
/* special cases: blank lines, Blanks at end of line */
^{SPO}\n {
fprintf(yyout,"\\init0");
current_line();
fprintf(yyout,"\\n\\ped\n");
pos=brace_open=0;
line++;
}
{SP}$ /* ignore spaces at end of line */
/* general line begin (we need the \init macro here) */
^" " pos++; fprintf(yyout,"\\init1"); current_line(); fprintf(yyout,"\\njo{-1}{"); brace_open=1; leng=16; BEGIN(sc);
^{SP} print_jmpo(1); BEGIN(sc);
^[^ \t\n] {
fprintf(yyout,"\\init0"); current_line(); fprintf(yyout,"\\njo0{");
yyless(0);
pes_old= -1;
brace_open=1;
leng=14;
cmt_pos=1;
BEGIN(sc);
}
. yyless(0); cmt_pos=pos+1; BEGIN(sc1);
}
/*\v \subsection{Rules for Blanks and Tabs} */
<INITIAL,CPLUSPLUS,JAVA,PREPROCESSOR,C_CMT,CPP_CMT,FILL_CMT,FILL_CPP_CMT>{
" " {
pos++;
if(brace_open)fputc('}',yyout);
chk_cmt();
fprintf(yyout,"\\njo{%d}{",pos);
brace_open=1;
LEN(10);
}
{SP} print_jmpo(0);
}
<C_CMT>{
\n{SPO}"*/" {
if(brace_open)fputc('}',yyout);
line++;
pos=leng=brace_open=cmt_mode=0;
fprintf(yyout,"\\n\n\\initc{0}{5}{0}");
current_line();
fprintf(yyout,"\\ccmtend\\%s",BASE_FONT);
leng=30;
init_out(0);
fprintf(yyout,"/}");
brace_open=cmt_mode=0;
LEN(17+strlen(BASE_FONT));
BEGIN(sc1);
}
\n{SPO}\*{SPO} {
if(brace_open)fputc('}',yyout);
line++;
for(ptr=yytext+yyleng-1,cmt_blanks=0;*ptr==' ';ptr--)cmt_blanks++;
pos=cmt_pos+cmt_blanks;
fprintf(yyout,"\\n\n\\initc{0}{5}{%d}",cmt_blanks);
current_line();
leng=brace_open=0;
LEN(25);
}
\n{SPO}\*+\/? {
if(brace_open)fputc('}',yyout);
line++;
LEN(15);
for(ptr=yytext+yyleng-1,cmt_blanks=0;*ptr==' ';ptr--)cmt_blanks++;
pos=cmt_pos;
for(ptr=yytext,tmp=0;*ptr;)if(*ptr++=='*')tmp++;
if(*(yytext+yyleng-1)=='/'){
fprintf(yyout,"\\ccmtend\\%s",BASE_FONT);
BEGIN(sc1);
}
fprintf(yyout,"\\n\n\\initc{0}{5}{0}");
current_line();
if(tmp>4){
LEN(31);
fprintf(yyout,"\\mpout{%d}{%d}{%s}{%s}",cmt_pos,cmt_pos+tmp-2,"$\\ast$","2pt");
if(*(yytext+yyleng-1)=='/')fprintf(yyout,"\\njo0{/}");
}
else{
fprintf(yyout,"\\njo0{\\mast{%d}/}",tmp);
if(*(yytext+yyleng-1)=='/')fputc('/',yyout);
LEN(10+strlen(BASE_FONT)+yyleng);
}
brace_open=0;
}
\n{SPO} {
if(brace_open)fputc('}',yyout);
line++;
leng=brace_open=0;
for(pos=0,ptr=yytext+1;*ptr;ptr++){
if(*ptr=='\t')
pos+=tab2spc-pos%tab2spc;
else
pos++;
}
LEN(20);
fprintf(yyout,"\\n\n\\initc{%d}{0}{0}",pos);
current_line();
}
}
<INITIAL,CPLUSPLUS,JAVA,CPP_CMT,FILL_CMT,FILL_CPP_CMT>\n {
if(brace_open)fputc('}',yyout);
line++;
pos=leng=brace_open=0;
fprintf(yyout,"\\n\\ped\n");
pes_old= -1;
if(YY_START==CPP_CMT || YY_START==FILL_CPP_CMT){
sc=sc1;
fprintf(yyout,"\\%s ",BASE_FONT);
LEN(2+strlen(BASE_FONT));
}
else
sc=YY_START;
BEGIN(LINE_BEGIN);
}
<INITIAL,CPLUSPLUS,JAVA,STRING,C_CMT,CPP_CMT,FILL_CMT,FILL_CPP_CMT>{
{SP}$ /* ignore spaces at end of line */
/*\v \subsection{Rules for special characters} */
\<{2,9} init_out(0); fprintf(yyout,"\\mlt{%d}",yyleng); LEN(7);
\>{2,9} init_out(0); fprintf(yyout,"\\mgt{%d}",yyleng); LEN(7);
\\{2,} init_out(0); fprintf(yyout,"\\bs{%d}",yyleng); LEN(6);
\*{2,9} init_out(0); fprintf(yyout,"\\mast{%d}",yyleng); LEN(8);
/*\v \subsection{``Leader'' rules} */
\<{10,} |
\>{10,} |
\+{10,} |
\${10,} |
\#{10,} |
\%{10,} |
\~{10,} |
\*{10,} {
switch(*yytext){
case '<': kern="-2pt"; ptr="$<$"; break;
case '>': kern="-2pt"; ptr="$>$"; break;
case '+': kern="0pt"; ptr="+"; break;
case '$': kern="0pt"; ptr="\\$"; break;
case '#': kern="0pt"; ptr="\\#"; break;
case '%': kern="0pt"; ptr="\\%"; break;
case '~': kern="0pt"; ptr="$\\sim$"; break;
case '*': kern="2pt"; ptr="$\\ast$"; break;
default: kern="0pt"; ptr=""; break;
}
if(brace_open)fputc('}',yyout);
fprintf(yyout,"\\mpout{%d}{%d}{%s}{%s}",pos,pos+yyleng-1,ptr,kern);
pos+=yyleng;
brace_open=0;
LEN(strlen(kern)+strlen(ptr)+19);
}
}
/*\v \subsection{Rules for Preprocessor Keywords} */
/* (first handle just the leading #) */
\#{SPO}{PP_KEY} {
yyless(1);
init_out(0);
fprintf(yyout,"{\\%s \\#}}\\pes{ \\bs{1}}{%d}",KEYWORD_FONT,pos+2);
pes_old=pos+2;
brace_open=0;
LEN(18+strlen(KEYWORD_FONT));
BEGIN(PREPROCESSOR);
}
<PREPROCESSOR>.|\n yyless(0); BEGIN(sc1); /* this should not occur */
<PREPROCESSOR>{PP_KEY} yyless(yyleng-1); keyword();
/*\v \subsection{Rules for common C/C++/Java Keywords} */
break[ \t\n;] |
case[ \t\n(] |
char[ \t\n*)] |
continue[ \t\n;] |
default[ \t\n:] |
do[ \t\n{] |
double[ \t\n*)] |
else[ \t\n{] |
float[ \t\n*)] |
for[ \t\n(] |
goto{WS} |
if[ \t\n(] |
int[ \t\n*)] |
long[ \t\n*)] |
return[ \t\n(;] |
short[ \t\n*)] |
static[ \t\n*)] |
switch[ \t\n(] |
void[ \t\n)] |
volatile{WS} |
while[ \t\n(] yyless(yyleng-1); keyword();
/*\v \subsection{Rules for C/C++ only Keywords} */
<INITIAL,CPLUSPLUS>{
auto{WS} |
const{WS} |
defined[ \t\n(] |
enum{WS} |
extern{WS} |
register{WS} |
sizeof[ \t\n(] |
struct[ \t\n{] |
typedef{WS} |
union[ \t\n{] yyless(yyleng-1); keyword();
/*\v \subsection{Rules for special VMS Keywords} */
_align[ \t\n(] |
globaldef[ \t\n{] |
globalref[ \t\n{] |
globalvalue[ \t\n{] |
main_program[ \t\n{] |
MAIN_PROGRAM[ \t\n{] |
noshare[ \t\n{] |
readonly[ \t\n{] |
variant_struct[ \t\n{] |
variant_union[ \t\n{] yyless(yyleng-1); keyword();
}
/*\v \subsection{Rules for C++ Keywords} */
<CPLUSPLUS>{
and[ \t\n(] |
and_eq[ \t\n(] |
asm[ \t\n{] |
bitand[ \t\n(] |
bitor[ \t\n(] |
bool{WS} |
compl{WS} |
const_cast[ \t\n<] |
dynamic_cast[ \t\n<] |
explicit{WS} |
export{WS} |
friend{WS} |
inline[ \t\n{] |
mutable[ \t\n*)] |
namespace[ \t\n{] |
not[ \t\n(] |
not_eq[ \t\n(] |
or[ \t\n(] |
or_eq[ \t\n(] |
reinterpret_cast[ \t\n<] |
static_cast[ \t\n<] |
template[ \t\n:] |
typeid[ \t\n(] |
typename[ \t\n(] |
using{WS} |
virtual{WS} |
wchar_t[ \t\n*)] |
xor[ \t\n(] |
xor_eq[ \t\n(] yyless(yyleng-1); keyword();
}
/*\v \subsection{Rules for Java only Keywords} */
<JAVA>{
abstract{WS} |
boolean{WS} |
byte{WS} |
byvalue{WS} |
extends{WS} |
final{WS} |
finally[ \t\n{] |
implements{WS} |
import{WS} |
inner{WS} |
instanceof{WS} |
interface{WS} |
native{WS} |
null[ \t\n)] |
package{WS} |
super[ \t\n(] |
synchronized{WS} |
throws{WS} |
transient{WS} keyword();
}
/*\v \subsection{Rules for C++/Java Keywords} */
<CPLUSPLUS,JAVA>{
catch[ \t\n(] |
class{WS} |
const[ \t\n*] |
delete[ \t\n\[(<] |
false[ \t\n;] |
new[ \t\n\[(<] |
operator[ \t\n+\-*/%|&^~!=<>\[(,] |
private[ \t\n:] |
protected[ \t\n:] |
public[ \t\n:] |
this[ \t\n\-.*] |
throw[ \t\n(] |
true[ \t\n;] |
try[ \t\n{] yyless(yyleng-1); keyword();
}
/*\v \subsection{Rules for Strings} */
\"\" init_out(0); fprintf(yyout,"{\\tt \"\"}"); LEN(8);
\\*\" {
if(yyleng%2){ /* even number of `\': begin string */
init_out(0);
if(yyleng>1)
fprintf(yyout,"\\bs{%d}\\qql}\\%s\\pes{\\bs{1}}{0}",yyleng-1,STRING_FONT);
else
fprintf(yyout,"\\qql}\\%s\\pes{\\bs{1}}{0}",STRING_FONT);
LEN(21+strlen(STRING_FONT));
brace_open=0;
BEGIN(STRING);
}
else{ /* odd number of `\': no string */
init_out(0);
fprintf(yyout,"\\bs{%d}{\\tt \"}",yyleng-1);
LEN(14);
}
}
<STRING>{
\n {
if(brace_open)fputc('}',yyout);
line++;
pos=leng=brace_open=0;
fprintf(yyout,"\\n\n\\initc000");
current_line();
LEN(20);
}
" "+ init_out(0); for(tmp=0;tmp<yyleng;tmp++)fputc('~',yyout); fputc('}',yyout); brace_open=0; LEN(yyleng+1);
\t print_jmpo(0);
\\+n init_out(0); fprintf(yyout,"\\bs{%d}n}",yyleng-1); LEN(9); brace_open=0;
\\*\" {
if(yyleng%2){ /* even number of `\': end string */
init_out(0);
if(yyleng>1)
fprintf(yyout,"\\bs{%d}\\%s \\qqr}\\%s",yyleng-1,BASE_FONT,BASE_FONT);
else
fprintf(yyout,"\\%s \\qqr}\\%s",BASE_FONT,BASE_FONT);
if(pes_old>=0)
fprintf(yyout,"\\pes{ \\bs{1}}{%d}\\njo0{",pes_old);
else
fprintf(yyout,"\\ped\\pstart\\pstarta\\njo0{");
LEN(36+strlen(BASE_FONT));
BEGIN(sc1);
}
else{ /* odd number of `\': no string */
init_out(0);
fprintf(yyout,"\\bs{%d}{\\tt \"}",yyleng-1);
LEN(14);
}
}
}
/*\v \subsection{Rules for Comments} */
"/*\\f"[ ]* {
if(pos<ALIGN_CMT_LIMIT)cmt_pos=pos+2;
init_out(1);
cmt_mode=3;
old_pos=pos-yyleng>ALIGN_CMT_LIMIT ? -2 : pos-yyleng;
fprintf(yyout,"/$\\ast$\\%s",COMMENT_FONT);
cmt_blanks=0;
if(*(yytext+yyleng-1)==' ')
for(ptr=yytext;*ptr;)if(*ptr++==' '){
fputc('~',yyout);
cmt_blanks++;
}
LEN(13+strlen(COMMENT_FONT));
BEGIN(FILL_CMT);
}
"/*"(\\b)?[ ]* {
if(pos<ALIGN_CMT_LIMIT)cmt_pos=pos+2;
init_out(1);
if(*(yytext+3)!='b'){ /* no block comment */
cmt_mode=1;
old_pos=pos-yyleng>ALIGN_CMT_LIMIT ? -2 : pos-yyleng;
}
else
cmt_mode=2;
cmt_blanks=0;
fprintf(yyout,"/$\\ast$");
if(*(yytext+yyleng-1)==' '){
if(cmt_mode==1){
fprintf(yyout,"\\%s",COMMENT_FONT);
LEN(13+strlen(COMMENT_FONT));
}
else{
fprintf(yyout,"\\%s",BLOCK_FONT);
LEN(13+strlen(BLOCK_FONT));
}
for(ptr=yytext;*ptr;)if(*ptr++==' '){
fputc('~',yyout);
cmt_blanks++;
}
}
BEGIN(C_CMT);
}
\/\*+\/ |
\/\*{2,}(\\b)? {
if(pos<ALIGN_CMT_LIMIT)cmt_pos=pos+2;
init_out(1);
if(*(yytext+yyleng-1)!='b'){ /* no block comment */
cmt_mode=1;
old_pos=pos-yyleng>ALIGN_CMT_LIMIT ? -2 : pos-yyleng;
}
else
cmt_mode=2; /* block comment */
cmt_blanks=0;
if(yyleng==2 || yyleng==4 && *(yytext+3)=='b')
fprintf(yyout,"/$\\ast$");
else if(*(yytext+2)=='*' && yyleng<11){
for(ptr=yytext+1,tmp=0;*ptr++=='*';tmp++);
fprintf(yyout,"/\\mast{%d}}",tmp);
brace_open=0;
}
else{
fprintf(yyout,"/}");
brace_open=0;
if(cmt_mode==1)
tmp=pos;
else
tmp=pos-2;
fprintf(yyout,"\\mpout{%d}{%d}{%s}{%s}",
tmp-yyleng+1,tmp-1,"$\\ast$","2pt");
}
LEN(15);
if(*(yytext+yyleng-1)=='/'){
yyless(yyleng-1);
cmt_mode=0;
}
else
BEGIN(C_CMT);
}
<CPLUSPLUS,JAVA>{
"//\\f"[ ]* |
\/{2,}[ ]* {
init_out(2);
if(*(yytext+3)=='f')
BEGIN(FILL_CPP_CMT);
else
BEGIN(CPP_CMT);
fprintf(yyout,"//");
for(ptr=yytext,cmt_blanks=0;*ptr;)if(*ptr++==' '){
fputc('~',yyout);
cmt_blanks++;
}
old_pos=pos-yyleng>ALIGN_CMT_LIMIT ? -2 : pos-yyleng;
fprintf(yyout,"}\\cmtpp{%d}{%d}",old_pos,cmt_blanks);
brace_open=0;
}
}
<C_CMT>\*+\/ {
if(brace_open)fputc('}',yyout);
brace_open=cmt_mode=0;
fprintf(yyout,"\\ccmtend\\%s",BASE_FONT);
pos+=yyleng;
if(yyleng>5){
LEN(31);
fprintf(yyout,"\\mpout{%d}{%d}{%s}{%s}\\njo0{/}",
pos-yyleng,pos-2,"$\\ast$","2pt");
}
else{
fprintf(yyout,"\\njo0{\\mast{%d}/}",yyleng-1);
LEN(10+strlen(BASE_FONT)+yyleng);
}
BEGIN(sc1);
}
<C_CMT,FILL_CMT>{
" :" {
yyless(1);
if(cmt_mode==2 || cmt_mode==5)
print_jmpo(0);
else{
pos++;
if(brace_open)fputc('}',yyout);
chk_cmt();
fprintf(yyout,"\\njo{%d}{",pos);
brace_open=1;
LEN(10);
}
}
[ ][^ \t\n]\n {
yyless(1);
if(brace_open)fputc('}',yyout);
chk_cmt();
if(cmt_mode==2 || cmt_mode==5){
fprintf(yyout,"\\jmpo{%d}{",++pos);
LEN(10);
}
else{
fprintf(yyout,"\\njo{%d}{",++pos);
LEN(9);
}
brace_open=1;
}
}
<FILL_CMT>{ /* special rules for / *\f (fill comments for C) */
"*/" |
\n{SPO}\*\/ {
if(brace_open)fputc('}',yyout);
for(ptr=yytext;*ptr;)if(*ptr++=='\n')line++;
chk_cmt();
brace_open=cmt_mode=0;
fprintf(yyout,"\\ccmtend\\%s",BASE_FONT);
pos+=yyleng;
fprintf(yyout,"\\jmpo{%d}{$\\ast$/}",pos+=100); /* force line break */
LEN(20);
BEGIN(sc1);
}
{SPO}\n{SPO} |
\n{SPO}\*{SPO} {
if(brace_open)fputc('}',yyout);
line++;
chk_cmt();
fprintf(yyout,"\\njo{%d}{",++pos); /* replace pattern by a blank */
LEN(9);
brace_open=1;
}
(\n{SPO}\*{SPO}){2,} {
if(brace_open)fputc('}',yyout);
for(ptr=yytext;*ptr;)if(*ptr++=='\n')line++;
fprintf(yyout,"\\jmpo{%d}{}\\jmpo{%d}{",pos+100,pos+200); /* empty line with star */
pos+=200;
LEN(23);
brace_open=1;
}
(\n{SPO}){2,}(\*{SPO})? |
\n{SPO}@\n{SPO} |
\n{SPO}\*{SPO}@\n{SPO}\*{SPO} {
if(brace_open)fputc('}',yyout);
for(ptr=yytext;*ptr;)if(*ptr++=='\n')line++;
fprintf(yyout,"\\n\\jmpo{%d}{",pos+=100); /* empty line */
LEN(12);
brace_open=1;
}
{SP}@\n{SPO} |
{SP}@\n{SPO}\*{SPO} {
if(brace_open)fputc('}',yyout);
line++;
chk_cmt();
fprintf(yyout,"\\jmpo{%d}{",pos+=100); /* force linebreak */
LEN(9);
brace_open=1;
}
}
<FILL_CPP_CMT>{ /* special rules for //\f (fill comments for C++/Java ) */
\n{SPO}"//"{SPO} {
if(brace_open)fputc('}',yyout);
line++;
chk_cmt();
fprintf(yyout,"\\njo{%d}{",++pos); /* replace pattern by a blank */
LEN(9);
brace_open=1;
}
\n{SPO}"//"{SPO}@?\n{SPO}"//"{SPO} {
if(brace_open)fputc('}',yyout);
for(ptr=yytext;*ptr;)if(*ptr++=='\n')line++;
fprintf(yyout,"\\jmpo{%d}{}\\jmpo{%d}{",pos+100,pos+200); /* empty line */
pos+=200;
LEN(23);
brace_open=1;
}
{SP}@\n{SPO}"//"{SPO} {
if(brace_open)fputc('}',yyout);
line++;
chk_cmt();
fprintf(yyout,"\\jmpo{%d}{",pos+=100); /* force linebreak */
LEN(9);
brace_open=1;
}
}
<C_CMT,CPP_CMT,FILL_CMT,FILL_CPP_CMT,STRING>[`'] init_out(0); fprintf(yyout,"{%c}",*yytext);
/*\v \subsection{Rules for line breaking without spaces} */
\-{2,} { /* don't split ++ -- */
init_out(0);
fputc('{',yyout);
for(tmp=0;tmp<yyleng;tmp++)fprintf(yyout,"\\mm");
fputc('}',yyout);
LEN(yyleng*3+2);
}
\+{2,} init_out(0); ECHO; LEN(yyleng);
"<<=" |
">>=" {
/* allow a linebreak before these patterns */
if(brace_open)fputc('}',yyout);
fprintf(yyout,"\\njo0{");
if(*ptr=='<')
fprintf(yyout,"\\mlt{2}=");
else
fprintf(yyout,"\\mgt{2}=");
brace_open=1;
LEN(8);
}
"||" |
"&&" |
"+=" |
"-=" |
"*=" |
"/=" |
"&=" |
"|=" |
"%=" |
"<=" |
">=" |
"==" |
"!=" |
[+\-*/%={] {
/* allow a linebreak before these patterns */
if(brace_open)fputc('}',yyout);
brace_open=0;
init_out(0);
for(ptr=yytext;*ptr;ptr++)fprintf(yyout,"%s",subst(*ptr));
LEN(9);
}
[,;}] init_out(0); fprintf(yyout,"%s}",subst(*yytext)); brace_open=0;
[a-zA-Z0-9$_]+ { /* C identifier: print them out */
init_out(0);
for(ptr=yytext;*ptr;ptr++)switch(*ptr){
case '_':
case '$': fprintf(yyout,"%s",subst(*ptr)); break;
default: fputc(*ptr,yyout); break;
}
LEN(yyleng);
}
<INITIAL,CPLUSPLUS,JAVA>\'.\' {
init_out(0);
fprintf(yyout,"{\\sq}%s{\\sq}",subst(*(yytext+1)));
}
<INITIAL,CPLUSPLUS,JAVA,STRING,C_CMT,CPP_CMT,FILL_CMT,FILL_CPP_CMT>{
. {
init_out(0);
fprintf(yyout,"%s",subst(*yytext));
}
\f\n? fprintf(yyout,"\\newpage\n"); if(*(yytext+yyleng-1)=='\n')line++;
[a-zA-Z0-9]+ init_out(0); fprintf(yyout,"%s",yytext);
}
/*\v \subsection{Rules for omitting Code} */
<LINE_BEGIN>{
{SPO}"/*"\\o[q+]"*/"{SPO}\n {
for(ptr=yytext;*ptr++!='o';);
if(*ptr=='+')
skip_cnt=0;
else
skip_cnt= -1;
tmp= -1;
sc=YY_START;
BEGIN(OMIT);
line++;
}
{SPO}"/*"\\o[1-9]+q?"*/"{SPO}\n {
for(ptr=yytext;*ptr++!='o';);
tmp=atoi(ptr);
skip_cnt= -1;
for(;*ptr && *ptr!='q';ptr++)if(*ptr=='*')skip_cnt=0;
BEGIN(OMIT);
line++;
}
}
<OMIT>{
{SPO}"/*\\o-*/"{SPO}\n {
if(sc==C_CMT)chk_cmt();
if(sc==STRING)fprintf(yyout,"\\%s",STRING_FONT);
skip_msg();
brace_open=0;
BEGIN(LINE_BEGIN);
line++;
}
\/\*+(\\b)? sc=C_CMT; if(*(yytext+yyleng-1)=='b')cmt_mode=2; else cmt_mode=1;
\*+\/ sc=sc1; cmt_mode=0;
\\*\" {
if(yyleng%2 && sc!=C_CMT)
if(sc!=STRING)
sc=STRING; /* begin of string */
else
sc=sc1; /* end of string */
}
\*+
\/+
\\
[^\\\"*\/\n]+ /* skip */
\n {
if(skip_cnt>=0)skip_cnt++;
line++;
if(!--tmp){
if(sc==C_CMT)chk_cmt();
skip_msg();
brace_open=0;
BEGIN(LINE_BEGIN);
}
}
<<EOF>> skip_msg(); yyterminate();
}
/*\v \subsection{Rules for Embedded \LaTeX} */
<CPLUSPLUS>"//\\a " init_out(0); fprintf(yyout,"}// "); brace_open=0; BEGIN(EL_CMT3);
<EL_CMT3>\n yyless(0); BEGIN(CPLUSPLUS);
<INITIAL,CPLUSPLUS,LINE_BEGIN>{
"/*\\a" init_out(0); fprintf(yyout,"}\\ped{}/$\\ast$"); brace_open=0; BEGIN(EL_CMT1);
{SPO}"/*\\v" |
{WSO}"/*\\v1" {
for(ptr=yytext;*ptr;)if(*ptr++=='\n')line++;
if(brace_open)fputc('}',yyout);
brace_open=0;
fprintf(yyout,"\\ped{}\n");
BEGIN(EL_CMT2);
}
}
<EL_CMT1,EL_CMT2>{
\n ECHO; line++;
"*/"{SPO}\n? {
if(YY_START==EL_CMT1)fprintf(yyout,"$\\ast$/");
if(*(yytext+yyleng-1)=='\n'){
pos=leng=brace_open=0;
sc=sc1;
line++;
fputc('\n',yyout);
BEGIN(LINE_BEGIN);
}
else{
BEGIN(sc1);
LEN(7);
}
}
}
<EL_CMT1,EL_CMT2,EL_CMT3>[^ \t\n*]+ ECHO;
%%
/*\v \section{C Code section}\subsection{Function chk\_cmt(void)} */
void chk_cmt(void)
{
/* values for cmt_mode:
* cmt_mode==1: normal comment mode (first line)
* cmt_mode==2: block comment mode
* cmt_mode==3: fill mode (Started with / *\f)
* cmt_mode==4: normal comment mode (not in the first line)
* cmt_mode==5: block comment mode (continuation)
*/
if(cmt_mode==1 || cmt_mode==3){
fprintf(yyout,"\\cmt{%d}{%d}",old_pos,cmt_blanks);
cmt_mode=0;
}
else if(cmt_mode==2){
fprintf(yyout,"\\%s ",BLOCK_FONT);
LEN(2+strlen(BLOCK_FONT));
cmt_mode=5;
}
}
/*\v \subsection{Function skip\_msg(void)} */
void skip_msg(void)
{
if(skip_cnt==1)
fprintf(yyout,"\\par\\centerline{/\\mast{20}{ \\commentfont SKIP A LINE }\\mast{20}/}\\par\n");
else if(skip_cnt>1)
fprintf(yyout,"\\par\\centerline{/\\mast{20}{ \\commentfont SKIP %d LINES }\\mast{20}/}\\par\n",skip_cnt);
}
/*\v \subsection{Function keyword(void)} */
void keyword(void)
{
init_out(0);
fprintf(yyout,"{\\%s ",KEYWORD_FONT);
for(ptr=yytext;*ptr;)fprintf(yyout,"%s",subst(*ptr++));
fputc('}',yyout);
LEN(3+strlen(KEYWORD_FONT)+yyleng);
yy_set_bol(0);
if(YY_START==PREPROCESSOR)BEGIN(sc1);
}
/*\v \subsection{Function init\_out(void)} */
void init_out(int mode)
{
/* mode==0: kein \cmtinit
* mode==1: \cmtinit f�r C-Kommentar
* mode==2: \cmtinit f�r C++-Kommentar
*/
pos+=yyleng;
if(mode==0){
if(!brace_open){
chk_cmt();
fprintf(yyout,"\\njo0{");
leng+=7;
}
}
else{
if(brace_open)fputc('}',yyout);
if(pos-yyleng>ALIGN_CMT_LIMIT){ /* position is too far right; omit \cmtinit */
fprintf(yyout,"\\njo0{");
leng+=7;
}
else{
fprintf(yyout,"\\cmtinit\\njo0{");
leng+=15;
}
}
brace_open=1;
}
/*\v \subsection{Function print\_jmpo(int linebegin)} */
void print_jmpo(int linebegin)
{
int old=pos;
for(ptr=yytext;*ptr==' ' || *ptr=='\t';ptr++){
if(*ptr=='\t')
pos+=tab2spc-pos%tab2spc;
else
pos++;
}
if(linebegin){
fprintf(yyout,"\\init{%d}",pos);
current_line();
fprintf(yyout,"\\njo{%d}{",-pos);
leng=18;
}
else if(brace_open){
fputc('}',yyout);
chk_cmt();
if(YY_START==FILL_CMT || YY_START==FILL_CPP_CMT){
fprintf(yyout,"\\xnjo{%d}{%d}{",pos-old,pos);
LEN(13);
}
else{
fprintf(yyout,"\\jmpo{%d}{",pos);
LEN(10);
}
}
else{
chk_cmt();
if(YY_START==FILL_CMT || YY_START==FILL_CPP_CMT){
fprintf(yyout,"\\xnjo{%d}{%d}{",pos-old,pos);
LEN(13);
}
else{
fprintf(yyout,"\\jmpo{%d}{",pos);
LEN(10);
}
}
brace_open=1;
}
/*\v \subsection{Function die(char *cmd,int mode)} */
int die(char *cmd,int mode)
{
switch(mode){
case 1:
fprintf(stderr,"Can't open %s for read; exit\n",cmd);
exit(4);
case 2:
fprintf(stderr,"Can't open %s for write; exit\n",cmd);
exit(4);
case 3:
fprintf(stderr,"%s\n",cmd);
exit(4);
default:
return 0;
}
}
/*\v \subsection{Function subst(int c)} */
char *subst(int c)
{
static char retbuffer[2];
if(c<0)c+=256;
switch(c){
case '#': leng+=2; return "\\#";
case '$': leng+=2; return "\\$";
case '%': leng+=2; return "\\%";
case '&': leng+=2; return "\\&";
case '\'': leng+=3; return "\\sq{}";
case '*': leng+=6; return "$\\ast$";
case '-': leng+=5; return "{\\mm}";
case '<': leng+=3; return "$<$";
case '>': leng+=3; return "$>$";
case '[': leng+=3; return "{[}";
case '\\': leng+=4; return "\\bs{1}";
case ']': leng+=3; return "{]}";
case '^': leng+=9; return "$\\hat{~}$";
case '_': leng+=5; return "{\\ul}";
case '`': leng+=3; return "{`}";
case '{': leng+=6; return "\\brl{}";
case '|': leng+=6; return "$\\mid$";
case '}': leng+=6; return "\\brr{}";
case '~': leng+=6; return "$\\sim$";
case '"': leng+=7; return "{\\tt \"}";
default: leng++; *retbuffer=c; return retbuffer;
}
}
/*\v \subsection{Function substitute\_format(char *format)} */
void substitute_format(char *format)
{
char c,*ptr1;
for(ptr=format;*ptr;ptr++){
if(*ptr=='%'){ /* escape sequences: */
switch(*++ptr){
case 'd': /* %d: day of month */
fprintf(yyout,"%d",atime->tm_mday);
break;
case 'D': /* %D: date (format DD-MMM-YYYY) */
fprintf(yyout,"%d{\\mm}%s{\\mm}%ld",atime->tm_mday,month1[atime->tm_mon],year);
break;
case 'f': /* %f: input file name */
for(ptr1=inputname;*ptr1;)fprintf(yyout,"%s",subst(*ptr1++));
break;
case 'h':
fprintf(yyout,"%02d",atime->tm_hour);
break;
case 'm': /* %m: month (numeric value) */
fprintf(yyout,"%d",atime->tm_mon+1);
break;
case 'M': /* %M: minute */
fprintf(yyout,"%02d",atime->tm_min);
break;
case 'n': /* %n: (english) name of month (full form) */
fprintf(yyout,"%s",month[atime->tm_mon]);
break;
case 'N': /* %N: (local) name of month (full form) */
fprintf(yyout,"%s",local_month[atime->tm_mon]);
break;
case 's': /* %s: (english) name of month (short form) */
fprintf(yyout,"%s",month1[atime->tm_mon]);
break;
case 'S': /* %S: (local) name of month (short form) */
fprintf(yyout,"%s",local_month1[atime->tm_mon]);
break;
case 'p': /* %p: page (in the LaTeX file) */
fprintf(yyout,"\\thepage");
break;
case 't': /* %t: time (format HH:MM) */
fprintf(yyout,"%02d:%02d",atime->tm_hour,atime->tm_min);
break;
case 'y': /* %y: year */
fprintf(yyout,"%ld",year);
break;
case '%': /* %%: the `%' character itself */
fputc('\\',yyout);
fputc('%',yyout);
break;
default: /* unknown escape sequence: just print it out */
fprintf(stderr,"Unknown escape sequence `%%%c' detected; print it out.\n",*ptr);
fprintf(stderr,"(format string was >%s<)\n",format);
fputc('%',yyout);
fprintf(yyout,"%s",subst(*ptr));
break;
}
}
else
fprintf(yyout,"%s",subst(*ptr));
}
fprintf(yyout,"}\n");
}
/*\v \subsection{Function current\_line(void)} */
void current_line(void)
{
if(show_lines>0 && line%show_lines==0){
fprintf(yyout,"{%d}",line);
}
else
fprintf(yyout,"{}");
LEN(10);
}
/*\v \subsection{Function main(int argc, char **argv)} */
int main(int argc, char **argv)
{
int i;
#ifdef FLEX_DEBUG
yy_flex_debug=0;
#endif /* FLEX_DEBUG */
time(&time_val);
atime=localtime(&time_val);
year=time_val/(365L*24L*60L*60L)+1970L;
sc=sc1=INITIAL;
for(i=1;i<argc;i++){
if(*argv[i]=='-'){
for(ptr=argv[i]+1;*ptr;)switch(*ptr++){
case 'd':
#ifdef FLEX_DEBUG
yy_flex_debug=1;
#else
fprintf(stderr,"tiny_c2l was compiled without debug info; ignore switch -d\n");
#endif
break;
case '+':
sc=sc1=CPLUSPLUS;
break;
case 'j':
sc=sc1=JAVA;
break;
case 'h':
switch(*ptr++){
case 'n': use_header=0; break; /* no header */
case 'l': lhead=ptr; break; /* left header text */
case 'c': chead=ptr; break; /* center header text */
case 'r': rhead=ptr; break; /* right header text */
default: break;
}
while(*ptr)ptr++; /* forget the rest of the argument */
break;
case 'l':
if(*ptr)
show_lines=atoi(ptr);
else
show_lines=5;
while(*ptr)ptr++; /* forget the rest of the argument */
break;
case 'f':
switch(*ptr++){
case 'l': lfoot=ptr; break; /* left footer text */
case 'c': cfoot=ptr; break; /* center footer text */
case 'r': rfoot=ptr; break; /* right footer text */
default: break;
}
while(*ptr)ptr++; /* forget the rest of the argument */
break;
case 'o': /* output name */
if(!yyout)(yyout=fopen(ptr,"w")) || die(ptr,2);
break;
case 't':
tab2spc=atoi(ptr);
break;
case '?':
fprintf(stderr,"tiny_c2l Version %s (%s)\n%s%d%s",
VERSION,VERSION_DATE,usage_text1,TAB2SPC,usage_text2);
#if VMS
exit(1);
#else
exit(0);
#endif
default:
break;
}
}
else if(!yyin) /* argument without leading '-': input or output name */
(yyin=fopen(inputname=argv[i],"r")) || die(inputname,1);
else if(!yyout)
(yyout=fopen(argv[i],"w")) || die(argv[i],2);
}
if(!yyin)yyin=stdin; /* no inputname specified */
if(!yyout)yyout=stdout; /* no outputname specified */
if(inputname){
for(ptr=inputname,ptr1=buffer;*ptr;)
switch(*ptr){
case '_':
case '$': *ptr1++='\\';
default:
*ptr1++= *ptr++;
break;
}
*ptr1=0;
}
else
strcpy(buffer,inputname="(stdin)");
#ifdef FLEX_DEBUG
if(yy_flex_debug){
/* FLEX gives very much debug info; write the stuff to a file */
fprintf(stderr,"redirect stderr to file tiny_c2l.dbg\n");
(freopen("tiny_c2l.dbg","w",stderr))
|| die("error opening file tiny_c2l.dbg for stderr (freopen)",3);
}
#endif /* FLEX_DEBUG */
yylex();
/* write the end of the LaTeX file */
if(brace_open)fputc('}',yyout);
fprintf(yyout,"\\end{flushleft}\n\
\\ifmfiles\\def\\END{\\relax}\\else\\def\\END{\\end{document}}\\fi\n\
\\END\n");
fclose(yyin);
fclose(yyout);
}