From: briang@sdd.hp.com (Brian Gragg)
Newsgroups: comp.sys.amiga.programmer
Subject: AutoDocs -> AmigaGuide creater
Date: 17 Nov 1992 21:36:57 GMT
Organization: Hewlett-Packard, San Diego Division
Distribution: world
NNTP-Posting-Host: hpsdlm16.sdd.hp.com

Hi all,

I've written a relatively small C program (using SAS/C 6.0) to read in the
Commodore Autodocs and create an amigaguide data file.  It isn't perfect
since there are some typos in the Autodocs.  The program is small enough that
I've included it here.  Please no flames as they just go to /dev/null.

It converts any entry in the Autodocs with a    NAME -    (name spaces dash)
as in FREEMEM -- frees memory  to be made into a FREEMEM() entry in the
amigaguide data file.  You will find a few places that didn't work quite
right, but you can edit the database and fix them as you find them.  I've only
run across 4 so far.  Also, if you see a mention of a function (like
AllocMem() ) you can click on the word (even if it isn't highlighted) to 
jump you straight to the AllocMem() entry (in amigaguide of course).  
If the AutoDocs just say  AllocMem  you would need to edit the file and add 
the ()'s to be able to automatically jump it.

It is easy to then add a command to your editor (like in sc) that will look
up the word under your cursor.  So from the editor, I can type 
BltClear, put the cursor on it, hit a key sequence, and have the autodoc for
BltClear() brought up for me in amigaguide.

The data file created is around 1.2 meg (as I remeber) but it includes the
entire autodocs.  The code here is not elegent, especially since I have no 
documentation on how amigaguide works or the format of the files.

You will find it creates a amigaguide file that is first broken up by 
library/device and then the funcions found in that library or device file.

Have fun and let me know what you think.

  Brian Gragg    briang@sdd.hp.com   hp-sdd!briang  uunet!ucsd!hp-sdd!briang

-------------------------------cut here----------------------------------- 

/*  GenADocGuide.c
 *
 *  Generates an amigaguide database for the Commodore Amiga AutoDocs
 *
 *  1992 Brian Gragg, San Diego, CA  (31.10.92)
 *  Released to the Public Domain.  
 */

#define DEFAULTGUIDEFILE "autodocs.guide"
#define CANCEL           (0)
#define OK               (1)
#define NAMEBYTES        (4000)
#define CTRL_L           (12)
#define BSIZE            (255)
#define SPACE            (32)

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <dos.h>
#include <sys/dir.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <libraries/asl.h>
#include <intuition/intuition.h>

#include <proto/all.h>
/*
#include <clib/sys_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/intuition_protos.h>
#include <clib/asl_protos.h>
*/

/* VERSION STRING */
UBYTE vers[] = "\0$VER: GenADocGuide 1.1  (11-1-92)";

/*extern struct DosLibrary *DOSBase = NULL;*/
/*extern struct IntuitionBase *IntuitionBase;*/
/*extern struct Library *SysBase;*/
extern int _OSERR;

struct EasyStruct failedES = {
    sizeof(struct EasyStruct), 0, vers,
    "%s",
    "OK",
};

struct EasyStruct OkCanES = {
    sizeof(struct EasyStruct), 0, vers,
    "%s",
    "OK|CANCEL",
};

#ifdef LATTICE
int  CXBRK(void) { return(0); }  /* Disable Lattice CTRL/C handling */
void chkabort(void) { return; } 
#endif


char  buffer[BSIZE];
char  *nullstr      = "";
char  adDir[BSIZE];
char  adGuide[BSIZE]= DEFAULTGUIDEFILE;
BPTR  adDirLock     = NULL;
BPTR  adGuideLock   = NULL;
FILE  *guidefp      = NULL;
char  *names        = NULL;


/* my protos */
void cleanExit(char *);
void Usage (void);
void doFile (char *);
void doMainMenu (char *);
int getbasename (FILE *, char *, char **);

void
main(int argc, char *argv[])
{
    char    exten[100];
    long    t;
    int     count, i;
    char    *name_ptrs[60];
    char    adGuidename[100];
    int     args = argc - 1;

    /* Check for valide autodocs directory */
    if (( args < 1 ) || ( !stricmp(argv[1],"?")) || (!stricmp(argv[1],"H")) ||
       ( args > 2 ))
   
    {
        Usage();
        cleanExit(nullstr);
    }
        if ( NULL == (adDirLock = Lock(argv[1],ACCESS_READ))) 
        {
            sprintf(buffer,"AutoDocs directory %s not found.\n",argv[1]);
            cleanExit(buffer);
        }
   
    /* Get autodocs directory */
    if (getpath(adDirLock, adDir))
    {
        sprintf(buffer,"Unable to get path for %s.\n",argv[1]);
        cleanExit(buffer);
    }
   
    /* Get output guide file - note adGuide is already set to the default */
    if ( args==2 ) 
    {
        strcpy(adGuide,argv[2]);
        stcgfe(exten, adGuide);
        
        if (strcmpi(exten,"guide"));
            strcat(adGuide,".guide");
        
        if ( -1 != (adGuideLock = findpath(adGuide))) 
        {
            sprintf(buffer,"File %s exists.\nDelete and overwrite file?",argv[2]);
            if (OK != EasyRequest(NULL, &OkCanES, NULL,buffer))
                cleanExit(nullstr);
            
            UnLock(adGuideLock);
            adGuideLock = NULL;
            
            if (!remove(argv[2])) 
            {
                sprintf(buffer,"Couldn't delete %s.",argv[2]);
                cleanExit(buffer);
            }
        }
    }
    adGuideLock = NULL;
    
    /* Open Guide file for output */
    if (NULL == (guidefp = fopen( adGuide, "w" )))
    {
        sprintf(buffer,"Couldn't open %s.",adGuide);
        cleanExit(buffer);
    }
    
    /* Initialize the guide file */
    if ( stcgfn(adGuidename,adGuide) < 1 )  /* strip the file path */
        strcpy(adGuidename,adGuide);
    fprintf(guidefp,
        "@database \"%s\"\n\n",strncpy(buffer,adGuide,strlen(adGuide)-6));
    fprintf(guidefp,"\n\n@master \"%s\"\n\n",adGuidename);
        time(&t);
    fprintf(guidefp,"@Remark $VER: %s, built %s",adGuidename,ctime(&t));
    fprintf(guidefp,"@Remark AutoDocs database for amigaguide.\n");
    fprintf(guidefp,"@Remark Produced with %s\n\n",vers+7);
    fprintf(guidefp,"@Node Main \"%s\"\n",adGuidename);

    /* Read the files in the directory */
    if (NULL == (names = (UBYTE *) AllocMem( NAMEBYTES, MEMF_CLEAR )))
        cleanExit("Couldn't allocate space for filenames.");
  
    sprintf(buffer,"%s/#?.doc",adDir);
    (count = getfnl(buffer,names,NAMEBYTES,0));
    if ( count <= 0 )
    {
        if ( _OSERR )
        {
            sprintf(buffer,"Error accessing the files\nin %s.",adDir);
            cleanExit(buffer);
        }
        else
            cleanExit("Too many files in the\nAutoDocs directory!");
    }
         
    if (strbpl(name_ptrs,300,names) != count)
        cleanExit("Too many file names in the \nAutoDocs directory!");

    tqsort(name_ptrs,count);

    for ( i=0; i<count; i++ )
        doMainMenu(name_ptrs[i]);
    
    fprintf(guidefp,"@EndNode\n\n");         

    for ( i=0; i<count; i++ )
        doFile(name_ptrs[i]);
        
    /* All Done */
    cleanExit(nullstr);
}


/*************************************************************************
*   cleanExit("ExitMsg")
*
*   puts "ExitMsg" up in a requester and then quits.
*************************************************************************/
void
cleanExit(char *exitMsg)
{
    if ( strlen(exitMsg) > 0 )
        EasyRequest(NULL, &failedES, NULL, exitMsg);
    
    if ( guidefp     != NULL )   fclose( guidefp );
    if ( adDirLock   != NULL )   UnLock( adDirLock );
    if ( adGuideLock != NULL )   UnLock( adGuideLock );
    if ( names       != NULL )   FreeMem( names, NAMEBYTES );
           
    exit(0);
}

/***************************************************************************
*   Usage()
*
*   displays the usage 
***************************************************************************/
void
Usage(void)
{
    printf("%s\n\n",vers);
    printf("USAGE: GenADocGuide directory [guidefile]\n");
    printf("       default guidefile is %s\n",DEFAULTGUIDEFILE);
}

/***************************************************************************
*   doFile(*fname)
*
*   Creates the amigaguide database for the file fname
***************************************************************************/
void
doFile(char *fname)
{
    FILE *docfp;
    char *dashptr;
    char *slashptr;
    char *nodename;
    char nodeline[BSIZE];
    char basename[BSIZE];
    char mybuf[BSIZE];
    char *fail;
    
    if (NULL == (docfp = fopen( fname, "r" )))
    {
        sprintf(buffer,"Couldn't open %s",fname);
        EasyRequest(NULL, &failedES, NULL,buffer);
        return;
    }
 
    if (getbasename(docfp, basename, &slashptr))
    {
        /* Couldn't get base name from inside file.  Use filename instead. */
        if (stcgfn(basename,fname) == 0)
        {
           sprintf(buffer,"Couldn't get name from file %s",fname);
           EasyRequest(NULL, &failedES, NULL,buffer);
           fclose(docfp);
           return;
        }
        basename[strlen(basename)-4] = '\0';  /* strip off the .doc */
        fprintf(guidefp,"@Node \"%s\"\n",basename);
    }
    else
        fprintf(guidefp,"@Node \"%s\"\n",basename);

    /* Build node list */
    /* 1st node was already found in getbasename */
    slashptr[strlen(slashptr+1)] = '\0';   /* get rid of trailing \n */
    fprintf(guidefp,"@{\" %s() \" Link \"%s()\"}\n",slashptr+1,slashptr+1);
    
    fail = fgets( mybuf, BSIZE, docfp );
    
    while (( mybuf[0] != CTRL_L ) && ( fail != NULL ))
    {
        if (NULL == (slashptr = strchr(mybuf,'/')))
            break;
        slashptr[strlen(slashptr+1)] = '\0';   /* get rid of trailing \n */
        fprintf(guidefp,"@{\" %s() \" Link \"%s()\"}\n",slashptr+1,slashptr+1);
        fail = fgets( mybuf, BSIZE, docfp );
    }
    fprintf(guidefp,"@EndNode\n\n");

    
    /* Do functions in file as nodes */
    while (fail != NULL)
    {
       /* Wait for NAME field */
       fail = fgets( nodeline, BSIZE, docfp );
       if (fail == NULL) break;
   
       while ( strstr(nodeline,"NAME") == NULL )
           if (NULL == (fail = fgets( nodeline, BSIZE, docfp ))) break;
       
       fail = fgets( nodeline, BSIZE, docfp );
       while (( fail != NULL ) && ( strlen(nodeline) < 3 )) 
           (fail = fgets( nodeline, BSIZE, docfp ));
       
       if (fail == NULL) break;
       
       if (NULL == (dashptr = strchr(nodeline,'-')))
           dashptr = nodeline + strlen(nodeline);  /* just use full line */
       strcpy(mybuf,nodeline);
       
     /* Set nodename & first line of data*/
       *(dashptr-1) = '\0';
       nodename = nodeline;
       while ( nodename[0] <= SPACE )  /* remove spaces, tabs, etc... */
           nodename++;

       nodename[strlen(nodename)] = '\0';   /* get rid of trailing \n */

       fprintf(guidefp,"@Node \"%s()\"\n",nodename);
       fprintf(guidefp,"   NAME                                          %s\n",basename);
       
   
       /* Transfer the rest of the data for this node */
       while ((mybuf[0] != CTRL_L) && (fail != NULL))
       {
           fprintf(guidefp,"%s",mybuf);
           fail = fgets( mybuf, BSIZE, docfp );
       }
       fprintf(guidefp,"@EndNode\n\n");
    }
    
    fclose(docfp);
    return;
}
 
    
/***************************************************************************
*   doMainMenu(*fname)
*
*   Creates the amigaguide main index for the file 
***************************************************************************/
void
doMainMenu(char *fname)
{
    FILE *docfp;
    char *slashptr;
    char mybuf[BSIZE];
    
    if (NULL == (docfp = fopen( fname, "r" )))
    {
        sprintf(buffer,"Couldn't open %s.",fname);
        EasyRequest(NULL, &failedES, NULL,buffer);
        return;
    }
 
    if (getbasename(docfp, mybuf, &slashptr))
    {
        /* Couldn't get base name from inside file.  Use filename instead. */
        if (stcgfn(mybuf,fname) == 0)
        {
           sprintf(buffer,"Couldn't get name from file %s",fname);
           EasyRequest(NULL, &failedES, NULL,buffer);
           fclose(docfp);
           return;
        }
        mybuf[strlen(mybuf)-4] = '\0';  /* strip off the .doc */
    }

    fprintf(guidefp,"   @{\" %s \" link \"%s\"}\n",mybuf,mybuf);

    fclose(docfp);
}    


/***************************************************************************
*   success = getbasename(*fileptr, *buf, *slashptr)
*
*   Sets buf to point to the base name of the opend file and slashptr to point
*   to the slash before the first function.
*   success = 0 if ok   1 if failed
***************************************************************************/
int
getbasename(FILE *fileptr, char *buf, char **slashptrptr)
{
    BOOL cont;
    char *fail;
    
    do
    {
       cont = FALSE;
       fail = fgets( buf, BSIZE, fileptr );
       while ((( buf[0] == '\n' ) || ( strnicmp(buf,"TABLE",5) == 0 )) 
                                 && (fail != NULL ))
           fail = fgets( buf, BSIZE, fileptr );
       
       if ( fail == NULL ) 
           return(1);
       
       if ( (*slashptrptr = strchr(buf,'/')) == NULL )
           cont = TRUE;
    } while (cont == TRUE);
              
    **slashptrptr = '\0';
    
    return(0);
}
           


Xref: sparky comp.sys.amiga.programmer:16073 comp.sys.amiga.hardware:19945