Mail Archives: djgpp/1997/10/15/13:45:26
This is a multi-part message in MIME format.
--------------4A24292D746A
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
I've written one awhile ago, it it is of any use. it uses "@txh" and
"@end txh" to indicate the start and end of formatting.
You'll have to tinker with it for your own purposes. Let me know how it
goes.
Randy Maas
randym AT acm DOT org
--------------4A24292D746A
Content-Type: text/plain; charset=us-ascii; name="c2txh.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="c2txh.c"
/*
C to TXH translator
Copyright 1997, Randall Maas. (randym AT acm DOT org)
@txh
@node c2txh, utils
@subheading Usage
@example
c2txh -[flags] < file.c >file.txh
@end example
@subheading Description
This will strip out of the comments all of the texinfo documentation
within a program. All of the leading white space is also removed,
except within an example block. Comments must start and end in the
ANSI C standard fashion: /* *@/.
To enable texinfo documentation within source code, simply use the
marking "@@txh" on line by itself. To disable texinfo, use
"@@end txh" on line by itself. Neither of these are marks are
outputted.
@subheading Flags
@table @code
@item -s, --strip
This prints the file as it would be without the txh markup.
@item -h, --help
Has info display this help screen.
@end table
@subheading @@ Commands
@table @code
@item @@@@
This will produce an @@ in the txh file.
@item @@txh
This marks the begining of a TXH block.
@item @@end txh
This marks the end of a TXH block.
@item @@/
This will put a / in the TXH file.
@item @@example
This works just like @@example should, but it also outputs the
non-commented C Code as well.
@item @@end example
This stops doing the above.
@end table
@subheading Note
Future version will require that the headings be contained within braces
@{ @}, to improve processing and reduce potential misunderstandings with
TeXInfo. (Note: TeXInfo does not support these and so they will be
removed.)
@end txh
*/
# include "mylibs.h"
// --- Tests for string equality. -------------------------------------------
# define strneq(A,B,N) (strncmp(A,B,N)==0)
# define strieq(A,B) (stricmp(A,B)==0)
# define Help(x)
// --- Working flags --------------------------------------------------------
# define F_Strip (0x1)
# define F_Comment (0x2)
# define F_TXH (0x4)
static unsigned Flags = 0;
/* Example is a count of the nestings */
static unsigned Example = 0;
typedef struct
{
char* Begin, Begin_Len;
char* End, End_Len;
} Block_Mark;
# define B_Comment (0)
# define B_Example (1)
# define B_TXH (2)
# define B_At (3)
# define B_Slash (4)
Block_Mark Block_Marks[]=
{
{"/*", 2, "*/", 2}, /* Comment */
{"@example", 8, "@end example", 12}, /* Example */
{"@txh", 4, "@end txh", 8}, /* TXH */
{"@@", 2, NULL, 0}, /* At */
{"@/", 2, NULL, 0} /* Slash */
};
static char* Block_Begin(Line, B)
char* Line;
int B;
{
/* Determines if we are at the start of a block
Return Value
Pointer where to process next, if the block began
NULL otherwise
*/
if (!Line) return NULL;
if (strneq(Line, Block_Marks[B].Begin, Block_Marks[B].Begin_Len))
return Line + Block_Marks[B].Begin_Len;
return NULL;
}
static char* Block_End(Line, B)
char* Line;
int B;
{
if (!Line) return NULL;
if (strneq(Line, Block_Marks[B].End, Block_Marks[B].End_Len))
return Line + Block_Marks[B].End_Len;
return NULL;
}
static char* Active_Process(Line)
char* Line;
{
/* Check for each and ever possible active command and do the proper
startup processing */
char* X;
/* Check for TXH */
X = Block_Begin(Line, B_TXH);
if (X) {Line = X; Flags |= F_TXH;}
if (!Example && !(Flags & F_TXH)) return Line;
X = Block_End(Line, B_TXH);
if (X) {Line = X; Flags &= ~F_TXH;}
if (!Example && !(Flags & F_TXH)) return Line;
/* Check for Example */
X = Block_Begin(Line, B_Example);
if (X)
{
Line = X;
Example++;
if (!(Flags & F_Strip)) fputs(Block_Marks[B_Example].Begin, stdout);
}
X = Block_End (Line, B_Example);
if (X)
{
Line = X;
Example=Example?Example-1:0;
if (!(Flags & F_Strip)) fputs(Block_Marks[B_Example].End, stdout);
}
/* Check for a literal */
X = Block_Begin(Line, B_At);
if (X)
{
Line = X;
if (!(Flags & F_Strip)) fputc('@', stdout);
}
X = Block_Begin(Line, B_Slash);
if (X)
{
Line = X;
if (!(Flags & F_Strip)) fputc('/', stdout);
}
return Line;
}
static char* Actives_Process(Line)
char* Line;
{
for (; Line;)
{
char* X;
if (!Example)
{
int S =0;
while (isspace(Line[0]))
{
S++;
if (!Line[0])
{
if (!(Flags & F_Strip)) fputc('\n', stdout);
return Line;
}
else
if ((Flags & (F_TXH|F_Strip)) == F_Strip)
fputc(Line[0], stdout);
Line++;
}
if (S && (Flags & (F_TXH|F_Strip)) == F_TXH) fputc(' ', stdout);
}
X = Active_Process(Line);
if (X == Line) break;
Line = X;
}
return Line;
}
static char* Line_Active(Line)
char* Line;
{
/* Mode == Comment && !Example */
for(;Line;)
{
Line = Actives_Process(Line);
if (!Line || !Line[0])
{
if (!Example && !(Flags & F_Strip)) fputc('\n', stdout);
return NULL;
}
if (Flags & F_Comment)
{
char* X = Block_End(Line, B_Comment);
if (X)
{
/* End of comment */
Flags &= ~F_Comment;
Line = X;
if (Flags & F_Strip)
fputs(Block_Marks[B_Comment].End, stdout);
}
}
if (!Example && !(Flags & F_Comment)) return Line;
if ((Example && !(Flags & F_Strip)) ||
(Flags & (F_TXH|F_Strip)) == F_TXH ||
(!Example && (Flags & (F_TXH|F_Strip)) == F_Strip))
fputc(Line[0], stdout);
Line++;
}
return NULL;
}
static char* Line_Proc(Line)
char* Line;
{
char* X;
if (Flags & F_Comment) Line = Actives_Process(Line);
/* Determine if we can process this line or not */
if ((Flags & (F_Comment|F_TXH)) == (F_Comment|F_TXH))
Line = Line_Active(Line);
if (Example) Line = Line_Active(Line);
/* Mode == Code */
while(Line && Line[0])
{
if (!(Flags & F_Comment))
{
/* We are in C Code area, scan for the start of comments */
char* Y = Block_Begin(Line, B_Comment);
if (Y)
{
Flags |= F_Comment;
Line = Y;
if (Flags & F_Strip)
fputs(Block_Marks[B_Comment].Begin, stdout);
Line = Line_Proc(Line);
}
}
else
{
if (Line[0])
{
/* Determine if we should print the character */
if (Flags & F_Strip) fputc(Line[0], stdout);
Line++; /* Go to the next character in the line */
}
}
}
return Line;
}
int main(int argc, char** argv)
{
unsigned I;
char Buffer[255];
/* Parse the command line arguments */
for (I = 1; I < argc; I++)
{
/* The help flag */
if (strieq("-h", argv[I]) || strieq("--help", argv[I]))
{
Help(argv[0]);
exit(0); /* We don't process on a help request */
}
/* The strip flag */
if (strieq("-s", argv[I]) || strieq("--strip", argv[I]))
Flags |= F_Strip;
}
while (!feof(stdin) && fgets(Buffer, 254, stdin)) Line_Proc(Buffer);
return 1;
}
--------------4A24292D746A--
- Raw text -