PPWIZARD is a free preprocessor for HTML, REXX, Visual Basic or any text files.
[Bottom][Contents][Search][Prev]: PPWIZARD Extensions[Next]: PPWSORT.H - Sorting
\ -> PPWIZARD Extensions -> VALRURL.H - Remote Resource Validation

VALRURL.H - Remote Resource Validation

This section describes how PPWIZARD can be used to validate remote resources, by remote I mean any resource that you could not determine if it existed or not purely by examining the local machines environment.

The header file "VALRURL.H" can be used to validate ftp and http URLs on remote servers. This will for example warn you if a particular link would generate a 404 in a browser.

Currently the header works under OS/2, http (web page) validation may work as is under Windows (95/98/NT) or may require small changes. If you have another operating system you may still wish to examine the header file as only minor work would probably be required to get it to work if you already have a method to validate a URL.

EXAMPLE - Immediate Validation

This example is not real life in that the URLs would normally not be used on their own but would be part of a hypertext link. You are expected to be online (to the internet) at the time you try the example as the URL checking is done immediately after a otherwise successful build. The example also demonstates setting up debugging:

;--- Load external URL validation support ---
;;#define  VALRURL_NO_CHECK_HTTP
;;#define  VALRURL_NO_CHECK_FTP
#define  VALRURL_FTP_EMAIL       db0@bnz.com
#define  VALRURL_DEBUG           +out\DEBUG.URL\*.DBG    ;;Append to end of any existing debug file
#include "VALRURL.H"

;--- Check some HTTP URLS ---
<$RemHttp url="http://bnz.com">                          ;;Does not exist
<$RemHttp url="http://dennisbareis.id.au/ppwizard.htm">  ;;Exists
<$RemHttp url="http://dennisbareis.id.au/zips_fw">       ;;Needs a '/'
<$RemHttp url="http://dennisbareis.id.au/no_such.htm">   ;;Does not exist

;--- Check some FTP URLS ---
<$RemFtp  url="ftp://ftp.bnz.com">                                  ;;Does not exist
<$RemFtp  url="ftp://ftp.pc.ibm.com/pub/pccbbs/os2_ews">            ;;Directory
<$RemFtp  url="ftp://ftp.pc.ibm.com/pub/pccbbs/os2_ews/aping.txt">  ;;File

EXAMPLE - Delayed Validation

This example is more real life. It also creates a URL list so that you don't need to be online when the html is built. You can run the generated URL files through the validator (supplied with ppwizard for OS/2 - http may work under windows) whenever you wish.

It shows one possible way of defining a common header file containing a useful front end macro as well as the definition of a remote URL. As the URL is only mentioned in one place no matter where or how many times it appears on your web pages it is simple to fix if it becomes out of date.

The common header file "MyCommon.IH" follows:

;--- Load external URL validation support -----------
#define  VALRURL_FTP_EMAIL         db4@bnz.com
#define  VALRURL_CHECK_LATER_MASK  out\REMOTE.URL\*.URL
#include "VALRURL.H"

;--- Useful macro: Validate URL and generate link ---
#define InternetLink                         \
        <A HREF="<$RemHttp URL=^{$URL}^>">  -\
           {$VISIBLE=^{$URL}^}              -\
        </A>

;--- Define URLs (usually in common header file -----
#define HttpPpwizardHomePage   \
        http://dennisbareis.id.au/ppwizard.htm

What might appear in one of your pages follows:

;--- Load common header file ---
#include "MyCommon.IH"

;--- Check some HTTP URLS ------
<P>Please see my <$InternetLink URL="<$HttpPpwizardHomePage>">
for a great
<$InternetLink URL="<$HttpPpwizardHomePage>" VISIBLE=^preprocessor^>.

At some future stage when you are online to the internet you might start the validation process with a command similar to:

checkurl.cmd CheckListedUrls remote.url\*.URL

VALRURL.H

;----------------------------------------------------------------------------
;     MODULE NAME:   VALRURL.IH
;
;         $Author:   USER "Dennis"  $
;       $Revision:   1.4  $
;           $Date:   13 Jan 2005 11:48:50  $
;        $Logfile:   C:/DBAREIS/Projects.PVCS/MultiOs/PPWIZARD/valrurl.h.pvcs  $
;
;     DESCRIPTION:   This is a header file for checking HTTP/FTP urls on
;                    remote servers. All URLs are passed with a leading
;                    "http://' or "ftp://".
;
;                    This routine does not validate that any "#Section"
;                    on http URLs are correct. It will validate that the
;                    html page exists on the server.
;
;                    It will only check a URL once. This is the case even
;                    across builds of multiple ".IT" files if they are being
;                    built using the one call to PPWIZARD.
;
;                    Note that I don't search a table to work out if a URL
;                    has already been used, my method is much faster however
;                    on very long URLs which appear in multiple files in the
;                    same PPWIZARD invokation it may repeat the test.
;
;
;                    OPERATING SYSTEMS
;                    ~~~~~~~~~~~~~~~~~
;                    This header has only been tested under OS/2. The
;                    required DLLs appear to have been installed by OS/2
;                    version 4 (Merlin). If these are unavailable on your
;                    machine you may need a TCP-IP fixpack, otherwise you
;                    will need to locate a web page containing the files.
;
;                    Since there is a "RxSock.DLL" available for windows
;                    http checking will also work there (if any changes
;                    required please let me know the details).
;                    There is no "RxFtp.DLL" for windows (that I know of).
;
;                    You can get RxSock for windows from:
;
;                                http://home.hiwaay.net/~abbott/regina/
;
;
;                    COMMENTS
;                    ~~~~~~~~
;                    Error messages could be improved a bit!
;
;                    Not sure about all error handling, please let me know
;                    of any issues you have. If you can see that I'm doing
;                    something wrong, please tell me!
;
;
;                    EXAMPLE
;                    ~~~~~~~
;                    ;;#define  VALRURL_NO_CHECK_HTTP
;                    ;;#define  VALRURL_NO_CHECK_FTP
;                    ;;#define  VALRURL_DEBUG            out\DEBUG.URL\*.DBG
;                    #define    VALRURL_CHECK_LATER_MASK out\REMOTE.URL\*.URL
;                    #define    VALRURL_FTP_EMAIL        db0@bnz.com
;                    #include "VALRURL.H"
;
;                    <P>Please see
;                    <A HREF="<$RemHttp url="http://dennisbareis.id.au/ppwizard.htm">">
;                       PPWIZARD's homepage
;                    </A>.
;
;                    You may wish to come up with your own set of "front end"
;                    macros to simplify the above. Also in general I recommend
;                    defining the external URL's in a header if they are to
;                    be used in more than one place.
;----------------------------------------------------------------------------


;--- Initialization (for this compile) --------------------------------------
#ifdef  VALRURL_CHECK_LATER_MASK
        #DefineRexx ''
           ;--- Create URL file name based on input name ---
           UrlListFile = GenerateFileName('<?InputFile>', '<$VALRURL_CHECK_LATER_MASK>');

           ;--- Delete the file for starters, will get created if any URLs ---
           call stream UrlListFile, 'c', 'close';
           call _SysFileDelete UrlListFile;
        #DefineRexx
#endif


;--- Only do rest of header once! -------------------------------------------
#ifndef VERSION_VALRURL_IH
   ;--- Define the version number of this header file -----------------------
   #define   VERSION_VALRURL_IH    01.266
   #require  99.315

   ;--- Need access to sort stuff ------------------------------------------
   #include "PPWSORT.H"

   ;--- Allow user to prevent generation if they only wish validation ------
   #ifndef RemHttpGenerate
       #define RemHttpGenerate      {$URL}
   #endif
   #ifndef RemFtpGenerate
       #define RemFtpGenerate       {$URL}
   #endif

   ;--- Allow user to modify what happens on failing validation ------------
   #ifndef VALRURL_FAILED_VALIDATION_REXX
           #DefineRexx VALRURL_FAILED_VALIDATION_REXX
                   call warning "CRURL", ThisUrl || ' ==> ' || UrlChkRc;
           #DefineRexx
   #endif

   ;--- Allow user to modify what happens on successful validation ---------
   #ifndef VALRURL_VALIDATED_OK_REXX
           ;--- Default is display success only when debug is on -----------
           #ifdef  VALRURL_DEBUG
                   ;--- Display successful URL as debug is on --------------
                   #DefineRexx VALRURL_VALIDATED_OK_REXX
                               call info 'DEBUG: ' || ThisUrl || ' successfully validated';
                   #DefineRexx
           #elseif
                   ;--- Define empty handler if debug is off ---------------
                   #define VALRURL_VALIDATED_OK_REXX
           #endif
   #endif


   ;--- Allow user to specify email address for FTP site logon -------------
   #ifndef VALRURL_FTP_EMAIL
           #define VALRURL_FTP_EMAIL VALRURL_<$VERSION_VALRURL_IH>@real.email.address.unknown
   #endif

   ;--- User calls these macros to perform validation ----------------------
   #define RemHttp                                                  \
           <$ValidateHttpR    URL="{$URL}">     ;;Check Remote URL -\
           <$RemHttpGenerate  URL="{$URL}">     ;;Generate URL
   #define RemFtp                                                   \
           <$ValidateFtpR     URL="{$URL}">     ;;Check Remote URL -\
           <$RemHttpGenerate  URL="{$URL}">     ;;Generate URL

   ;--- Checking HTTP:// ? -------------------------------------------------
   #ifdef  VALRURL_NO_CHECK_HTTP
           #define ValidateHttpR   ;;No checking
   #elseif
           #define ValidateHttpR   <$ValidateUrlR Type="http://" URL="{$URL}">
   #endif


   ;--- Checking FTP:// ? --------------------------------------------------
   #ifdef  VALRURL_NO_CHECK_FTP
           #define ValidateFtpR    ;;No checking
   #elseif
           #define ValidateFtpR    <$ValidateUrlR Type="ftp://" URL="{$URL}">
   #endif

   ;--- Initialization - Once per PPWIZARD Invokation (NOT build!) ---------
   #if symbol('UrlCheckerPgm') <> 'VAR'
       ;--- No need to do anything if delaying the checking! ---------------
       #ifndef VALRURL_CHECK_LATER_MASK
           #if Defined('VALRURL_NO_CHECK_HTTP') = 'N' | Defined('VALRURL_NO_CHECK_FTP') = 'N'
               ;--- Find External program ----------------------------------
               #define VALRURL_EXT_CMD   CHECKURL.CMD
               #evaluate ''                                                                                           \
               ^                                                                                                      \
                   UrlCheckerPgm = _SysSearchPath('PATH', '<$VALRURL_EXT_CMD>');                                      \
                   if  UrlCheckerPgm = '' then;                                                                       \
                   do;                                                                                                \
                       parse source . . PpwRexxFile;                                                                  \
                       UrlCheckerPgm = FilePart('location', PpwRexxFile) || '<$VALRURL_EXT_CMD>';                    \
                           if  stream(UrlCheckerPgm, 'c', 'query exists') = '' then;                                  \
                               Error('Could not locate "<$VALRURL_EXT_CMD>" (searched PATH and PPWIZARD directory)'); \
                   end;                                                                                               \
               ^

               ;--- Display version numbers of DLLs we are using -----------
               #evaluate '' ^interpret 'ExtCmdVersion = "<??UrlCheckerPgm>"("VERSION?")'^
               #info        'Header file version <$VERSION_VALRURL_IH>'
               #info        'Using Check URL external command <??ExtCmdVersion>'
               #ifndef  VALRURL_NO_CHECK_HTTP
                   #evaluate '' ^interpret 'SocketVersion = "<??UrlCheckerPgm>"("SOCKETVERSION?")'^
                   #info     'Validating remote http URLs with <??SocketVersion>'
               #endif
               #ifndef  VALRURL_NO_CHECK_FTP
                   #evaluate '' ^interpret 'FtpVersion    = "<??UrlCheckerPgm>"("FTPVERSION?")'^
                   #info     'Validating remote ftp  URLs with <??FtpVersion>'
               #endif

               ;--- Set email address for FTP downloads --------------------
               #ifndef  VALRURL_NO_CHECK_FTP
                   #evaluate '' ^call SetEnv "CHECKURL_EMAIL", "<$VALRURL_FTP_EMAIL>"^
               #endif
           #endif
       #endif
   #endif

   ;--- Set up debug? ----------------------------------------------
   #ifndef  VALRURL_DEBUG
       #evaluate '' ^call SetEnv "CHECKURL_DEBUG", ''^            ;;Prevent Debug
   #elseif
       #evaluate '' ^TDbgFile = GenerateFileName('<?InputFile>', '<$VALRURL_DEBUG>')^
       #evaluate '' ^call _SysFileDelete TDbgFile^
       #evaluate '' ^call SetEnv "CHECKURL_DEBUG", TDbgFile^      ;;Turn it on
       #info        'Any debugger output goes to "<??TDbgFile>"'
   #endif

   ;--- Make sure we have required support for this compile -----------------
   #ifndef VALRURL_CHECK_LATER_MASK
       #ifndef  VALRURL_NO_CHECK_HTTP
           #evaluate '' ^interpret 'SupportHttp = "<??UrlCheckerPgm>"("SOCKETREADY?")'^
           #if SupportHttp <> 'OK'
               ;--- Can't validate HTTP URLs -----------------------------------
               #Warning "CRURL"  "Can't validate HTTP URLs"
               #define+ RemHttp <$RemHttpGenerate  URL="{$URL}"> ;;Can't validate URL
           #endif
       #endif
       #ifndef  VALRURL_NO_CHECK_FTP
           #evaluate '' ^interpret 'SupportFtp  = "<??UrlCheckerPgm>"("FTPREADY?")'^
           #if SupportFtp <> 'OK'
               ;--- Can't validate FTP URLs -----------------------------------
               #Warning "CRURL"  "Can't validate FTP URLs"
               #define+ RemFtp <$RemFtpGenerate  URL="{$URL}">   ;;Can't validate URL
           #endif
       #endif
   #endif

   ;--- Initialization for this build ---------------------------------------
   #RexxVar ValUrlCount = 0            ;;Counts elements in URL array
   #OnExit  <$ProcessRemoteUrlList>    ;;Handle the list (user could override macro)

   ;--- Handle URL (just add to array, don't worry about duplicates here) ---
   #define ValidateUrlR                                                      \
           ;--- Make sure we validate a full URL -------------              -\
           #evaluate '' ^<$ValidateUrlR_REXX_FullUrl Type="{$Type}" URL="{$URL}">^  -\
                                                                            -\
           ;--- Add URL (in "FullUrl" var) to end of array ---              -\
           #RexxVar ValUrlCount + 1                                         -\
           #RexxVar ValUtlList.ValUrlCount = FullUrl                        -\
                                                                            -\
           ;--- Add location ---------------------------------              -\
           #evaluate '' ^<$ValidateUrlR_REXX_Location>^                     -\
           #RexxVar ValUtlLocn.ValUrlCount = UrlSourceLocation
   #DefineRexx ValidateUrlR_REXX_FullUrl
               ;--- Make sure URL starts with "http:" etc ---
               UrlType = "{$Type}";
               FullUrl = "{$URL}";
               if  abbrev(FullUrl, UrlType) = 0 then;
                   FullUrl = UrlType || FullUrl;

               ;--- Remove any "#section" bit ---
               #Option PUSH AllowPack=NO
               parse var FullUrl (UrlType) httpServer '/' HttpPageAddr;
               #Option POP
               parse var HttpPageAddr HttpPageAddr '#';
               FullUrl = UrlType || httpServer || '/' || HttpPageAddr;
   #DefineRexx
   #ifndef ValidateUrlR_REXX_Location              ;;Allow caller to create their own "location"
       #DefineRexx ValidateUrlR_REXX_Location
                   #Option PUSH AllowPack=NO
                   do  IncIndex = 1 to <?IncludeLevel>
                   #Option POP
                       ;--- Format the input file at this level ---
                       ThisBit = FilePart('name', InputComponentLevel(IncIndex));
                       ThisBit = ThisBit || '(' || AddCommasToDecimalNumber(InputComponentLineLevel(IncIndex)) || ')';

                       ;--- Update location string ----------------
                       if  IncIndex = 1 then
                           UrlSourceLocation = ThisBit;
                       else
                           UrlSourceLocation = UrlSourceLocation || '->' || ThisBit;
                   end
       #DefineRexx
   #endif

   ;--- Work though URL list and end of successful build --------------------
   #define ProcessRemoteUrlList                                \
           #if [ValUrlCount = 0]                              -\
               #info 'No remote URLs to validate'             -\
           #elseif                                            -\
               #info 'Validating <??ValUrlCount> remote URLs' -\
               ;--- Sort the array ---                        -\
               #RexxVar ValUtlList.0 = ValUrlCount            -\
               #evaluate '' ^<$GenRexx2Sort2Arrays ARRAY1='ValUtlList' ARRAY2='ValUtlLocn'>^ -\
                                                              -\
               ;--- Process the array ---                     -\
               #evaluate '' ^<$ProcessRemoteUrlList_REXX>^    -\
           #endif
   #DefineRexx ProcessRemoteUrlList_REXX_COMMON_START
           ;--- Work through URL list (drop duplicates) ---
           LastUrl = '';
           LastLoc = '';
           do  UrlIndex = 1 to ValUtlList.0
               ThisUrl = ValUtlList.UrlIndex;
               ThisLoc = ValUtlLocn.UrlIndex;
               if  ThisUrl <> LastUrl | ThisLoc <> LastLoc then;
               do
   #DefineRexx
   #DefineRexx ProcessRemoteUrlList_REXX_COMMON_END
                   LastUrl = ThisUrl;
                   LastLoc = ThisLoc;
               end;
           end;
   #DefineRexx

   ;--- What are we doing with the list of URLs? ----------------------------
   #ifndef ProcessRemoteUrlList_REXX
       #ifdef  VALRURL_CHECK_LATER_MASK
           ;--- Generate file (user will check URLs later / when online) ----
           #DefineRexx ProcessRemoteUrlList_REXX
                   ;--- We already know URL filename & its been deleted ---
                   #ifndef VALRURL_DONT_DEPEND_ON_GENERATED_URL_LIST
                           call AddOutputFileToDependancyList UrlListFile;
                   #endif
                   call Info 'Generating: ' || UrlListFile;
                   call lineout UrlListFile, ';---';
                   call lineout UrlListFile, ';--- Remote URLs from "<?InputFile>"';
                   call lineout UrlListFile, ';--- Use CHECKURL.CMD under OS/2 or other similar';
                   call lineout UrlListFile, ';--- tool to process the list.';
                   call lineout UrlListFile, ';---';
                   call lineout UrlListFile, '';
                   call lineout UrlListFile, '';

                   ;--- Now work through the list of URLs ---
                   <$ProcessRemoteUrlList_REXX_COMMON_START>;
                       ;--- Need to output new location pragma? ---
                       if  ThisLoc <> LastLoc then
                           call lineout UrlListFile, ';PRAGMA(URL_SOURCE)=' || ThisLoc;

                       call lineout UrlListFile, ThisUrl;
                   <$ProcessRemoteUrlList_REXX_COMMON_END>;

                   ;--- Close the listing file ---
                   call DieIfIoErrorOccurred UrlListFile;
                   CloseRc = stream(UrlListFile, 'c', 'close');
           #DefineRexx
       #elseif
           ;--- We are online, do immediate check of URLs -------------------
           #DefineRexx ProcessRemoteUrlList_REXX
                   <$ProcessRemoteUrlList_REXX_COMMON_START>;
                       ;--- Calculate ID for this URL ---
                       FullPageId     = '!R_' || c2x(ThisUrl);
                       FullPageIdStat = symbol(FullPageId);    ;;Exists/Name too long?

                       ;--- Already done this URL (previous build)? ---
                       if  FullPageIdStat = 'VAR' then;
                           UrlChkRc = _valueG(FullPageId);   ;;Already know if valid!
                       else;
                       do;
                           ;--- Haven't checked yet ---
                           interpret 'UrlChkRc = "<??UrlCheckerPgm>"("CHECK1URL " || ThisUrl)';

                           ;--- Set ID so we won't repeat this exercise! ---
                           if  FullPageIdStat <> 'BAD' then;
                               call _valueS FullPageId, UrlChkRc;
                       end;

                       ;--- Handle return code ---
                       if  UrlChkRc = 'OK' then;
                       do;
                           <$VALRURL_VALIDATED_OK_REXX>;
                       end;
                       else;
                       do;
                           <$VALRURL_FAILED_VALIDATION_REXX>;
                       end;
                   <$ProcessRemoteUrlList_REXX_COMMON_END>;
           #DefineRexx
       #endif
   #endif

#endif



email me  any feedback, additional information or corrections.
See this page online (look for updates)

[Top][Contents][Search][Prev]: PPWIZARD Extensions[Next]: PPWSORT.H - Sorting


PPWIZARD Manual
My whole website and this manual itself was developed using PPWIZARD (free preprocessor written by Dennis Bareis)
Saturday May 28 2022 at 2:55pm