home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-02-27 | 32.6 KB | 1,380 lines |
- /*
- Strongtest.c
- Tests StrongHelp manuals for 'dangling' links, etc.
-
- v0.00 Dec '95 Incomplete.
- v1.00 960113 Rewrite becuase I 'accidentally' deleted v0.00
- v1.10 960213 Partial Links implemented
- v1.20 960226 Simple links with Postfix & Prefix implemented
- v1.30 960227/00 Subpage testing implemented
- v1.31 960227/01 added -w option, tidied messages
- v1.32 960227/09 added activity messages
- tidied up messages even more
- v1.33 960227/10 Fixed bug in partial link testing that caused bogus
- successes for partial links.
- v1.40 960227/11 Added test for bad <> (missing \)
- Niceified pluralisation in messages
- v1.41 960227/12 Expanded bad character error message to include code
- Made \r a valid character
- v1.42 960227/13 Expanded -w to include pages of the form xx>yy
-
- © Musus Umbra, 1996.
-
- Sorry about the state of this, C isn't my first language.
- Also, much mucking around has been done, so there are lots of
- commented bits of line here and there - sorry, I guess I'm just
- too paranoid to delete them :-)
- */
-
- #define VERSION "1.42 (27 Feb 1996)"
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include "kernel.h"
- /*#include "swis.h"*/
-
- #define OS_File 0x08
- #define OS_GBPB 0x0c
- #define DDEUtils_ThrowbackStart 0x42587
- #define DDEUtils_ThrowbackSend 0x42588
- #define DDEUtils_ThrowbackEnd 0x42589
-
-
- static char *identity = "StrongTest " VERSION
- " [compiled "__DATE__"]\n"
- "© Musus Umbra, 1996\n\n";
-
-
- typedef struct listnode {
- struct listnode* next;
- char* pagename;
- char* path;
- int referenced;
- } node;
-
- char block[1024]; /* general workspace */
- char manual[256]; /* the manual name we're working on */
- node* head; /* global to save passing it around everywhere */
- _kernel_swi_regs r; /* global to save time */
- _kernel_oserror *e; /* ... */
- int dangling = 0; /* dangling link flag/counter */
- int unaccessible = 0; /* unaccessible page flag/counter */
- int fserror = 0; /* filing system error flag/counter */
- int badchars = 0; /* non-ASCII chars flag/counter */
- int missingslash = 0; /* \ missing in \<> */
- int warnings = 0; /* warnings flag/counter */
- int throwback = 0; /* throwback flag */
- int debugmd = 0; /* debugmdness flag :-) */
- int verbose = 0; /* verbosity flag */
- int warnext = 0; /* whether to raise warnings for external links */
- int throwbackstarted = 0;
-
-
-
- char *plural(int n, char* pe)
- {
- return n==1 ? "" : pe;
- }
-
-
- char* leafname(char* source) /* Function to find leafname of object */
- {
- char* ret;
- char* search;
- for (search=source; *search!=0; search++) { /* find terminator */ };
- for (ret=search; *ret!='.' && ret>=source; ret--) { /* find leaf */ };
- return(ret+1);
- }
-
-
- int isconversion(char *p)
- {
- while (*p++)
- {
- if ( *p=='>' ) { return 1; }
- }
- return 0;
- }
-
-
- /*----------------------------------------------------------------------------
- throwback_start
- => n/a
- <= n/a
- */
- void throwback_start(void)
- {
- e=_kernel_swi(DDEUtils_ThrowbackStart,&r,&r);
- if (e)
- {
- fprintf(stderr,"WARNING - %s\n",e->errmess);
- return;
- }
- r.r[0]=0;
- r.r[2]=(int) manual;
- e=_kernel_swi(DDEUtils_ThrowbackSend,&r,&r);
- if (e)
- {
- if (debugmd)
- {
- fprintf(stderr,"DEBUG: throwback failed - %s\n",e->errmess);
- }
- return;
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- throwback_error(file, line, m, x)
- => x = flag: 1=>already done an error in this file, 0=>first error ...
- file = ->filename
- line = line
- m = ->error message
- <= n/a
- */
- void throwback_error(char* file, int line, char *m, int x)
- {
- if (throwbackstarted==0)
- {
- throwback_start();
- throwbackstarted=1;
- }
- r.r[0]=1;
- r.r[2]=(int) file;
- r.r[3]=line;
- r.r[4]=1;
- r.r[5]=(int) m;
- e=_kernel_swi(DDEUtils_ThrowbackSend,&r,&r);
- if (e)
- {
- if (debugmd)
- {
- fprintf(stderr,"DEBUG: throwback failed - %s\n",e->errmess);
- }
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- throwback_warning(file, line, m, x)
- => x = flag: 1=>already done an error in this file, 0=>first error ...
- file = ->filename
- line = line
- m = ->error message
- <= n/a
- */
- void throwback_warning(char* file, int line, char *m, int x)
- {
- if (throwbackstarted==0)
- {
- throwback_start();
- throwbackstarted=1;
- }
- r.r[0]=1;
- r.r[2]=(int) file;
- r.r[3]=line;
- r.r[4]=0;
- r.r[5]=(int) m;
- e=_kernel_swi(DDEUtils_ThrowbackSend,&r,&r);
- if (e)
- {
- if (debugmd)
- {
- fprintf(stderr,"DEBUG: throwback failed - %s\n",e->errmess);
- }
- }
- }
-
-
-
-
-
- /*---------------------------------------------------------------------------
- throwback_end
- => n/a
- <= n/a
- */
- void throwback_end(void)
- {
- e=_kernel_swi(DDEUtils_ThrowbackEnd,&r,&r);
- if (e)
- {
- if (debugmd)
- {
- fprintf(stderr,"DEBUG: end throwback failed - %s\n",e->errmess);
- }
- }
- }
-
-
-
-
- /*----------------------------------------------------------------------------
- oof(x)
- => x
- <= ->"On" | "Off"
- .
- */
- char* oof(int x)
- {
- return x ? "On" : "Off";
- }
-
-
- /*----------------------------------------------------------------------------
- unpad(s)
- => s = ->string
- <= s modified so that there are no preceding or trailing spaces.
- */
- void unpad(char *s)
- {
- char *c;
-
- c=s+strlen(s);
- while (*--c==' ') /* scan from end for non-space */
- ;
- *++c=0; /* terminate string over first space */
-
- c=s;
- while (*c++==' ')
- ;
- c--;
- if (c==s) { return; }
- while ( (*s++=*c++)!=0 )
- ;
- *s=0;
- }
-
-
-
-
- /*----------------------------------------------------------------------------
- printlist(head)
- => head = ->head node of list
- <= n/a
- debugging function to print out the full contents of the list
- */
- void printlist(node *head)
- {
- if ( !(head->next) )
- {
- printf("---the list is empty\n");
- return;
- }
-
- while (head->next)
- {
- head=head->next;
- printf(" %s - %s\n",head->pagename,head->path);
- }
- }
-
-
- /*----------------------------------------------------------------------------
- lowerise(text)
- => text = ->string
- <= n/a
- Converts the string to lower case.
- */
- void lowerise(char *text)
- {
- while (*text)
- {
- *text=tolower(*text);
- text++;
- }
- }
-
-
-
- /*----------------------------------------------------------------------------
- lowcpy(d,s)
- => d = ->destination string
- s = ->source string
- <= n/a (d updated)
- copies s into d, ensuring that d is all lower case.
- */
- void lowcpy(char *d, char *s)
- {
- while (*s)
- {
- *d++=tolower(*s++);
- }
- *d=0;
- }
-
-
-
- /*----------------------------------------------------------------------------
- sinsert(d,i)
- => d= ->destination string (not empty)
- i= ->string to insert
- <= i is inserted at the start of s
- */
- void sinsert(char *d, char *i)
- {
- int l,m,k;
-
- l=strlen(i);
- m=strlen(d);
-
- for (k=m; k>=0; k--)
- {
- d[k+l]=d[k];
- }
- for (k=0; k<l; k++)
- {
- d[k]=i[k];
- }
- }
-
-
-
-
-
-
-
-
- /*----------------------------------------------------------------------------
- dnamecpy(s,d)
- => s= ->destination string
- d= ->directory name
- <= s modified to hold the dir name, with '.'s missing
- */
- void dnamecpy(char *s, char *d)
- {
- while (*d)
- {
- if (*d!='.') { *s++=*d; }
- d++;
- }
- *s=0;
- }
-
-
-
-
-
- /*----------------------------------------------------------------------------
- makenameubar(s,d,o)
- => s= ->destination string
- d= ->full path for object (without trainling '.')
- o= ->objectname
- <= s modified, d corrupted
- */
- void makenameubar(char *s, char *d, char *o)
- {
- char *p;
- char *dd;
- char *dirstart;
-
- dd=malloc(strlen(d)+1);
- strcpy(dd,d);
- d=dd;
-
- while (*d!=0)
- {
- dirstart=d;
- for (p=d; *p!='.' && *p; p++)
- ;
- if (*(p-1)=='_')
- {
- dnamecpy(s,dirstart);
- strcat(s,o);
- free(dd);
- return;
- }
- if (*p) { d=p+1; } else { d=p; }
- }
- strcpy(s,o);
- free(dd);
- }
-
-
- /*----------------------------------------------------------------------------
- addnode(tail,dir,objname)
- => tail = ->current tail of list
- dir = ->name of directory 'page' is in
- objname = ->leaf name of object
- <= new tail of list
- */
- node* addnode(node *tail, char* dir, char* objname /*, int ubar*/)
- {
- int i;
- node *newnode;
- char *tptr;
- char *pptr;
-
- newnode = malloc(sizeof(node));
- if ( !newnode )
- {
- fprintf(stderr,"insufficient memory (case 2)\n");
- exit(4);
- }
- tail->next = newnode;
- newnode->next = 0;
- i=strlen(dir)+strlen(objname)+2;
- tptr = malloc(i*sizeof(char));
- pptr = malloc((strlen(objname)+30)*sizeof(char));
- if (!(tptr && pptr))
- {
- fprintf(stderr,"insufficient memory (case 2a)\n");
- exit(4);
- }
- newnode->path = tptr;
- newnode->pagename = pptr;
- strcpy(tptr,dir);
- strcat(tptr,".");
- strcat(tptr,objname);
-
- /*
- * if (ubar && 0) was || 1
- * {
- * makenameubar(pptr,dir,objname);
- * } else {
- * strcpy(pptr,objname);
- * }
- * REPLACED BY NEXT LINE */
- strcpy(pptr,objname);
-
- newnode->referenced=0;
-
- lowerise(tptr);
- lowerise(pptr);
-
- /*
- if (debugmd)
- {
- printf(" added page '%s', path '%s'\n",pptr,tptr);
- }
- */
- return newnode;
- }
-
-
- /*----------------------------------------------------------------------------
- endinubar(s)
- => s = ->directory name
- <= 1 => s ends in a _, 0 otherwise
- */
- int endinubar(char *s)
- {
- while(*++s)
- ;
- return (*--s=='_');
- }
-
-
-
-
- /*----------------------------------------------------------------------------
- buildlist(dir,tail,ubar)
- => dir->manual name or subdirectory
- *tail is the node to add the list on to (ie. the tail)
- ubar = 1 => a directory with an _ ending leads to this dir
- <= ->new tail of list
- builds the linked list of page information for directory 'name'.
- NB: RECURSIVE
- */
- node *buildlist(char* dir,node *tail /*, int ubar*/ )
- {
- char pathname[256];
- int offset;
- int read;
- int *filetype = (int*) (block);
- int *objtype = (int*) (block+16);
- char *objname = (block+20);
-
- offset = 0;
- do
- {
- r.r[0]=10; /* OS_GBPB 10 */
- r.r[1]=(int) dir; /* ->directory name */
- r.r[2]=(int) block; /* ->buffer */
- r.r[3]=1; /* entries to read */
- r.r[4]=offset; /* offset to start from */
- r.r[5]=1024; /* size of buffer */
- r.r[6]=(int) "*"; /* filename to match */
- e=_kernel_swi(OS_GBPB,&r,&r);
- if (e)
- {
- if (debugmd)
- {
- fprintf(stderr,"FS error: %s\n",e->errmess);
- }
- fserror++;
- return tail;
- }
- read = r.r[3];
- offset = r.r[4];
-
- if (read>0)
- {
- switch ( *objtype )
- {
- case 1 : switch ( (*filetype) & 0xffffff00 )
- {
- case 0xffffff00 : /* text file */
- case 0xfffffd00 : /* data file */
- tail=addnode(tail,dir,
- objname /*,ubar*/);
- break;
- default : ; /* skip anything else */
- }
- break;
- case 2 : strcpy(pathname,dir);
- strcat(pathname,".");
- strcat(pathname,objname);
- tail=buildlist(pathname,tail /*,endinubar(objname)*/);
- break;
- default: ; /* Huh? what the hell is *this* doing here?!?! */
- }
- }
- } while (offset!=-1);
-
- return tail;
- }
-
-
-
-
- /*----------------------------------------------------------------------------
- isexternal(s)
- => s = ->string (manual page name)
- <= 1 is page is *probably* external, 0 otherwise
- checks page name for ':' or '.'
- */
- int isexternal(char* s)
- {
- int e = 0;
-
- while(*s && !e)
- {
- if (*s==':' || *s=='.') { e=1; }
- s++;
- }
- return e;
- }
-
-
-
- /*-----------------------------------------------------------------------------
- testpartial(pagename,path,link)
- => pagename ->pagename to test link against
- path = ->pathname of page
- link ->link to test
- <= !0 if link fails, 0 if link succedes.
- */
-
- int testpartial(char *pagename, char *path, char *link)
- {
- char temp[256];
- char *t = path;
- char *u = temp+255;
- int linklen;
- int templen;
- int dotflag = 0;
-
- *u-- = 0; /* terminate temp string */
- templen = 0; /* length of temp string */
- linklen = strlen(link); /* length of link */
-
- while ( *++t )
- ; /* find last char of pathname */
- t--;
-
- while (templen<linklen && *t)
- {
- if ( *t !='.' )
- {
- *u-- = /*tolower*/(*t);
- templen++;
- }
- else
- {
- dotflag = 1;
- }
- t--;
- }
-
- /*
- if (debugmd)
- {
- printf("+++testing partial %s=>%s ??? ",link,u+1);
- printf("[%s,%s]\n",link,u+1);
- }
- */
-
- if ( (templen!=linklen) || !dotflag )
- {
- return 1; /* no need for string cmp */
- }
-
- return strcmp(link,u+1);
- }
-
-
-
- /*----------------------------------------------------------------------------
- tonlcpy(d,s)
- => d = ->dest string
- s = ->source string
- <= d updated with s upto \n or 0. Leading whitespace in s is skipped.
- */
- void tonlcpy(char *d, char *s)
- {
- while (isspace(*s) && *s!='\n' && *s!=0)
- {
- s++;
- }
- while (*s!='\n' && *s!=0)
- {
- *d++ = *s++;
- }
- *d = 0; /* terminate dest. */
- }
-
-
- /*----------------------------------------------------------------------------
- lowmatch(t,a)
- => t = ->test string
- a = ->wanted string
- <= ->char after wanted string in test string or NULL if no match
- */
- char *lowmatch(char *t, char *a)
- {
- while ( (*a == tolower(*t)) && *a!=0)
- {
- a++;
- t++;
- }
- return (*a==0 ? t : NULL);
- }
-
-
-
- /*---------------------------------------------------------------------------
- testsubpage(lab,page)
- => lab = ->search link (incl '.')
- page = ->pagetext (null terminated)
- <= -1 if no subpage match, 1 if a match
- */
- int testsubpage(char *lab, char *page)
- {
- char temp[256];
- int state = 0;
- char *t;
- if (debugmd)
- {
- printf("@@@testing subpage %s ???\n",lab+1);
- }
-
- lab++; /* skip over leading '.' */
- while (*page && (state != 100) )
- {
- switch(state)
- {
- case 0 : if (*page == '#')
- {
- t=lowmatch(page+1,"subpage");
- if (t)
- {
- tonlcpy(temp,t);
- if (strcmp(lab,temp)==0)
- {
- state = 100;
- }
- }
- }
- state = 1;
- break;
- case 1 : if (*page=='\n')
- {
- state = 0;
- }
- break;
- }
- page++;
- }
- return (state==100 ? 1 : -1);
- }
-
-
-
-
- /*----------------------------------------------------------------------------
- testlink(name,dest,page,line,thrown,pagetext)
- => name = ->name of link (for messages, etc)
- dest = ->link destination (pagename)
- <= n/a (global dangling updated if necessary, referenced element of
- list node of destination page updated as necessary).
- */
- void testlink(char *name, char *dest, node *page,int line,int *thrown,char *p)
- {
- node *scan;
- int succeded = 0;
- char search[256];
- char search2[256];
-
- lowcpy(search,dest);
- unpad(search); /* moved from below */
- if (1 || endinubar(search)) /* || 1 is to force test <x=>x.!Root>*/
- {
- strcpy(search2,search);
- strcat(search2,"!root");
- } else
- {
- *search2=65;
- *(search2+1)=0;
- }
- /* unpad was here */
- if (debugmd)
- {
- printf("***testing link <%s=>%s> [%s,%s]\n",name,dest,search,search2);
- }
-
- if (*search=='*') { return; } /* don't test OS commands! */
- if (*search=='.')
- {
- succeded = testsubpage(search,p); /* either -1 or 1 */
- }
-
- if (isexternal(search) && succeded==0) /* don't test external links */
- {
- if (warnext)
- {
- warnings++;
- if (strcmp(name,dest)==0)
- {
- if (verbose)
- {
- fprintf(stderr,"Warning: page '%s' line %d - link <%s> "
- "is external (not tested)\n", page->pagename,line,name);
- }
- sprintf(search,"link <%s> is external (not tested)",name);
- if (throwback)
- {
- throwback_warning(page->path,line,search,*thrown);
- *thrown=1;
- }
- } else {
- if (verbose)
- {
- fprintf(stderr,"Warning: page '%s' line %d - link "
- "<%s=>%s> is external (not tested)\n",
- page->pagename,line,name,dest);
- }
- sprintf(search,"link <%s=>%s> is external (not tested)",name,dest);
- if (throwback)
- {
- throwback_warning(page->path,line,search,*thrown);
- *thrown=1;
- }
- }
- }
- return;
- }
-
- scan=head->next;
- while (scan && succeded==0)
- {
- if ( strcmp(scan->pagename,search)==0
- /* || strcmp(scan->pagename,search2)==0*/ )
-
- {
- if (debugmd)
- {
- printf(" succedes (normal): ->page '%s'\n",scan->pagename);
- }
- succeded=1;
- (scan->referenced)++;
- }
- else
- {
- if ( testpartial(scan->pagename,scan->path,search)==0 )
- {
- if (debugmd)
- {
- printf(" succedes (partial): ->page '%s'\n",scan->pagename);
- }
- succeded=1;
- (scan->referenced)++;
- }
- else
- {
- if ( testpartial(scan->pagename,scan->path,search2)==0 )
- {
- if (debugmd)
- {
- printf(" succedes (partial.!Root): ->page '%s'\n",scan->pagename);
- }
- succeded=1;
- (scan->referenced)++;
- }
- }
- }
- scan=scan->next;
- }
-
- if (succeded==0)
- {
- if (strcmp(name,dest)==0)
- {
- if (strlen(name)==0)
- {
- if (verbose)
- {
- fprintf(stderr,"page '%s', line %d - Missing '\\' in \"\\<>\"\n",
- page->pagename,line);
- }
- sprintf(search,"Missing \\ in \"\\<>\"");
- if (throwback)
- {
- throwback_error(page->path,line,search,*thrown);
- *thrown=1;
- }
- dangling--; /* because it'll be incremented after this block */
- missingslash++;
- }
- else
- {
- if (verbose)
- {
- fprintf(stderr,"page '%s', line %d - link <%s> fails\n",
- page->pagename,line,name);
- }
- sprintf(search,"link <%s> fails",name);
- if (throwback)
- {
- throwback_error(page->path,line,search,*thrown);
- *thrown=1;
- }
- }
- } else {
- if (verbose)
- {
- fprintf(stderr,"page '%s', line %d - link <%s=>%s> "
- "fails\n",page->pagename,line,name,dest);
- }
- sprintf(search,"link <%s=>%s> fails",name,dest);
- if (throwback)
- {
- throwback_error(page->path,line,search,*thrown);
- *thrown=1;
- }
- }
- dangling++;
- }
- }
-
-
- /*----------------------------------------------------------------------------
- prepost(ptr,*pre,*post)
- => ptr = ->page text, null terminated
- <= *pre & *post = -> prefix & postfix for simple links
- */
- void prepost(char *page, char* *pre, char* *post)
- {
- static char prefix[128];
- static char postfix[128];
- int state = 0;
- char *t;
-
- *prefix = *postfix = 0;
-
- while (*page)
- {
- switch(state)
- {
- case 0 : if ( *page == '#' )
- {
- t = lowmatch(page+1,"prefix");
- if (t)
- {
- tonlcpy(prefix,t);
- }
- else
- {
- t = lowmatch(page+1,"postfix");
- if (t)
- {
- tonlcpy(postfix,t);
- }
- }
- }
- state = 1;
- break;
- case 1 : if (*page == '\n')
- {
- state = 0;
- }
- break;
- }
- page++;
- }
- *pre = prefix;
- *post = postfix;
- }
-
-
-
-
-
-
- /*----------------------------------------------------------------------------
- testpage(ptr)
- => ptr = ->node containg page information
- <= n/a (dangling, fserror, badchars updated)
- tests the page for bad characters & dangling links.
- */
- void testpage(node* ptr)
- {
- int size;
- char *pagetext;
- char linkname[256];
- char linkdest[256];
- char temp[128];
- char at,prev,next;
- int p;
- int status;
- int lnp;
- int ldp;
- int line;
- int thrown = 0;
- char *prefix, *postfix;
-
- if (debugmd)
- {
- printf("\n---testing page '%s'\n",ptr->pagename);
- }
- r.r[0]=17;
- r.r[1]=(int) (ptr->path);
- e=_kernel_swi(OS_File,&r,&r); /* get size of page */
- if (e)
- {
- fserror++;
- if (debugmd)
- {
- fprintf(stderr,"FS error: %s\n",e->errmess);
- }
- return;
- }
- size=r.r[4];
- pagetext=malloc(size+1); /* allocate memory for page */
- if (!pagetext)
- {
- fprintf(stderr,"insufficient memory (case 3)\n");
- exit(4);
- }
- r.r[0]=16;
- r.r[1]=(int) (ptr->path);
- r.r[2]=(int) pagetext;
- r.r[3]=0;
- e=_kernel_swi(OS_File,&r,&r); /* load page */
- if (e)
- {
- fserror++;
- if (debugmd)
- {
- fprintf(stderr,"FS error: %s\n",e->errmess);
- }
- return;
- }
- if (debugmd)
- {
- printf(" page loaded OK.\n");
- }
- pagetext[size]=0; /* terminate page so we can treat it as a string */
-
- prepost(pagetext,&prefix,&postfix); /* Get prefix & postfix (if any) */
-
- for (p=0; pagetext[p]!='\n' && pagetext[p]!=0; p++)
- ; /* Skip over first (page title) line */
- p++;
-
- status=0; at='!'; line = 2;
- for ( /*p=0*/ ; p<size; p++)
- {
- prev=at;
- at=pagetext[p];
- next=pagetext[p+1];
- if (at=='\n') { line++; }
- if (at<32 && at!='\n' && at!='\t' && at!='\r')
- {
- badchars++;
- if (verbose)
- {
- fprintf(stderr,"'%s', line %d - bad character %x\n",
- ptr->pagename,line,at);
- }
- if (throwback)
- {
- sprintf(temp,"Bad character &%x (%d)",at,at);
- throwback_error(ptr->path, line, temp, thrown);
- thrown=1;
- }
- }
- switch (status)
- {
- case 0 : if (at=='<' && prev!='\\' && prev!='<' && next!='<'
- && next!='-' && next!='=')
- {
- status=1; lnp=0;
- }
- if (at=='#' && prev=='\n')
- {
- status=3;
- }
- break;
- case 1 : if (at=='=' && prev!='\\')
- {
- if (next=='>')
- {
- linkname[lnp]=0;
- status=2; ldp=0;
- p++;
- }
- } else {
- if (at=='>' && prev!='\\')
- {
- linkname[lnp]=0;
- strcpy(linkdest,prefix);
- strcat(linkdest,linkname);
- strcat(linkdest,postfix);
- testlink(linkname,linkdest,ptr,line,&thrown,pagetext);
- status=0;
- } else {
- linkname[lnp++]=at;
- if (lnp>255)
- {
- warnings++;
- if (verbose)
- {
- fprintf(stderr,"Can't check page '%s' as it "
- "contains a link name more than 255 chars "
- "long.\n",ptr->pagename);
- }
- if (throwback)
- {
- throwback_warning(ptr->path,line,"Link "
- "name >255 chars",thrown);
- thrown=1;
- }
- free(pagetext);
- return;
- }
- }
- }
- break;
- case 2 : if (at=='>' && prev!='\\')
- {
- linkdest[ldp]=0;
- testlink(linkname,linkdest,ptr,line,&thrown,pagetext);
- status=0;
- } else {
- linkdest[ldp++]=at;
- if (ldp>255)
- {
- warnings++;
- if (verbose)
- {
- fprintf(stderr,"Can't check page '%s' as it contains"
- " a link destination more than 255 chars "
- "long.\n", ptr->pagename);
- }
- if (throwback)
- {
- throwback_warning(ptr->path,line,"Link dest >255 "
- "chars",thrown);
- thrown=1;
- }
- free(pagetext);
- return;
- }
- }
- break;
- case 3 : if (at=='\n')
- {
- status=0;
- }
- break;
- default: fprintf(stderr,"Page '%s' testing abandonned: "
- "status has escaped!\n", ptr->pagename);
- free(pagetext);
- return;
- }
- }
-
- free(pagetext); /* free the memory we've claimed */
- }
-
-
-
-
-
-
-
-
- /*----------------------------------------------------------------------------
- testmanual(name)
- => name ->manual name to test (full filename)
- <= returns 0 if manual is good, code otherwise:
- bit meaning
- 3 dangling link(s)
- 4 unaccessible pages(s)
- 5 filing system error(s)
- 6 non ASCII chars in page(s)
- 7 missing \ in \<>
- */
- int testmanual(char *manual)
- {
- node *tail;
- node *scan;
- char temp[256];
- char temp2[256];
-
- printf("Scanning manual...\n");
-
- tail=buildlist(manual,head /*,0*/ );
-
- /*
- if (debugmd)
- {
- printf("List contents:\n");
- printlist(head);
- printf("\n\n");
- }
- */
-
- printf("Testing links...\n");
-
- throwbackstarted=0;
- scan=head->next;
- while (scan)
- {
- testpage(scan);
- scan=scan->next;
- }
-
- /* if (throwback && throwbackstarted)... moved to below */
-
- if (debugmd) { printf("\n-------------------------\n"); }
-
- printf("Testing accessibility...\n");
-
- scan=head->next;
-
- lowcpy(temp2,manual);
- strcat(temp2,".!root");
-
- while (scan)
- {
- if ( (scan->referenced)==0 )
- {
- if (strcmp(scan->path,temp2)!=0
- && strcmp(scan->pagename,"!configure")!=0)
- {
- if (isconversion(scan->pagename))
- {
- if (warnext)
- {
- if (verbose)
- {
- fprintf(stderr,"page '%s' is an external conversion\n",
- scan->pagename);
- }
- if (throwback)
- {
- sprintf(temp,"Page '%s' is an external conversion",scan->pagename);
- throwback_warning(scan->path,0,temp,0);
- }
- warnings++;
- }
- else
- {
- unaccessible--; /* cuz we'll increment it after this block */
- }
- }
- else
- {
- if (verbose)
- {
- fprintf(stderr,"page '%s' is inaccessible\n",
- scan->pagename);
- }
- if (throwback)
- {
- sprintf(temp,"Page '%s' is inaccessible",scan->pagename);
- throwback_error(scan->path,0,temp,0);
- }
- }
- unaccessible++;
- }
- }
- scan=scan->next;
- }
-
- printf("\nTesting complete:\n\n");
-
- if (throwback && throwbackstarted)
- {
- throwback_end();
- }
-
- if (dangling)
- {
- printf("found %d dangling link%s\n",dangling,plural(dangling,"s"));
- }
- if (unaccessible)
- {
- printf("found %d inaccessible page%s\n",unaccessible,plural(unaccessible,"s"));
- }
- if (missingslash)
- {
- printf("found %d missing \\%s in \\<>\n",missingslash,plural(missingslash,"s"));
- }
- if (fserror)
- {
- printf("%d FS error%s occurred during testing\n",fserror,plural(fserror,"s"));
- }
- if (badchars)
- {
- printf("%d illegal character%s found\n",badchars,plural(badchars,"s"));
- }
-
- return ( (dangling ? 8 : 0) | (unaccessible ? 16 : 0)
- | (fserror ? 32 : 0) | (badchars ? 64 : 0)
- | (missingslash ? 128 : 0) );
- }
-
-
-
-
-
-
- /*-----------------------------------------------------------------------------
- main.
- tests args, makes sure that the manual to be tested actually is a manual
- (ie. is an image filetype 3d6). NB: returns an error if StrongHelp isn't
- running - this is because the image wouldn't be accessible.
- => command line args
- <= result of testmanual(<manual>) q.v.
- */
- int main(int argc, char * argv[])
- {
- int goodbad;
- int gotname = 0;
- int i;
-
- if (argc<2 || argc>5)
- {
- fprintf(stderr,"syntax: strongtest [-t] [-v] [-w] <manual>\n");
- exit(1);
- }
-
- for (i=1; i<argc; i++)
- {
- switch (*argv[i])
- {
- case '-' : switch (*(argv[i]+1))
- {
- case 't' : case 'T' : throwback=1; break;
- case 'v' : case 'V' : verbose=1; break;
- case 'd' : case 'D' : debugmd=1; break;
- case 'w' : case 'W' : warnext=1; break;
- default: fprintf(stderr,"bad switch -%c\n",
- *(argv[i]+1));
- exit(1);
- }
- break;
- default : if (gotname)
- {
- fprintf(stderr,"syntax: strongtest [-t] [-v] "
- "<manual>\n");
- exit(1);
- }
- gotname=1;
- strcpy(manual,argv[i]);
- }
- }
-
- if (!gotname)
- {
- fprintf(stderr,"syntax: strongtest [-t] [-v] <manual>\n");
- exit(1);
- }
-
- printf(identity); /* Output name, version, compilation date & © */
-
- if (debugmd)
- {
- printf("DEBUG: testing '%s', throwback %s\n",
- manual, oof(throwback));
- }
-
- r.r[0]=17;
- r.r[1]=(int) manual;
- _kernel_swi(OS_File,&r,&r); /* read cat. info for 'manual' */
-
- switch (r.r[0]) /* r0 = object type */
- {
- case 0 : fprintf(stderr,"'%s' not found\n",manual);
- exit(2);
- break;
- case 1 : fprintf(stderr,"'%s' is a file "
- "(is Stronghelp running?)\n",manual);
- exit(2);
- break;
- case 2 : fprintf(stderr,"'%s' is a directory\n",manual);
- exit(2);
- break;
- case 3 : if ( (r.r[2] & 0xffffff00)!=0xfff3d600 )
- {
- fprintf(stderr,"'%s' is not a manual\n",manual);
- exit(2);
- }
- break;
- default: fprintf(stderr,"unrecognised object type"
- " (%d) for '%s'\n",r.r[0],manual);
- exit(2);
- }
-
- head=malloc(sizeof(node));
- if (head==0)
- {
- fprintf(stderr,"nowhere near enough memory to run!\n");
- exit(4);
- }
-
- goodbad = testmanual(manual);
- i = dangling+unaccessible+badchars+fserror+missingslash;
- if (goodbad)
- {
- fprintf(stderr,"Manual '%s' contains %d error%s\n",
- leafname(manual),i,plural(i,"s"));
- if (warnings)
- {
- fprintf(stderr,"and raised %d warning%s\n",warnings,plural(warnings,"s"));
- }
- } else {
- printf("Manual '%s' checks out OK.\n",leafname(manual));
- if (warnings)
- {
- printf("(with %d warning%s)\n",warnings,plural(warnings,"s"));
- }
- }
-
- return goodbad;
- }
-
- /* Phew! */
-
- /*
- © Musus Umbra, 1996
- See Help file for Licence
- */
-