delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/10/15/13:45:26

Message-ID: <34435C6E.356D@acm.org>
Date: Tue, 14 Oct 1997 06:50:06 -0500
From: Randall Maas <rcmaas AT piper DOT hamline DOT edu>
Reply-To: rcmaas AT piper DOT hamline DOT edu
MIME-Version: 1.0
Newsgroups: comp.os.msdos.djgpp
Subject: Re: texinfo / makeinfo
References: <01bcd2f5$27209b00$1e621ecb AT cybercafe DOT effect DOT net DOT au>
NNTP-Posting-Host: 208.153.214.48
Lines: 335
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019