summaryrefslogtreecommitdiffstats
path: root/tkhtml1/src/htmlurl.c
diff options
context:
space:
mode:
Diffstat (limited to 'tkhtml1/src/htmlurl.c')
-rw-r--r--tkhtml1/src/htmlurl.c402
1 files changed, 0 insertions, 402 deletions
diff --git a/tkhtml1/src/htmlurl.c b/tkhtml1/src/htmlurl.c
deleted file mode 100644
index bf8808f..0000000
--- a/tkhtml1/src/htmlurl.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
-** Routines for processing URLs.
-**
-** Copyright (C) 1997-2000 D. Richard Hipp
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Library General Public
-** License as published by the Free Software Foundation; either
-** version 2 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Library General Public License for more details.
-**
-** You should have received a copy of the GNU Library General Public
-** License along with this library; if not, write to the
-** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-** Boston, MA 02111-1307, USA.
-**
-** Author contact information:
-** drh@acm.org
-** http://www.hwaci.com/drh/
-*/
-#include <tk.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdlib.h>
-#include "htmlurl.h"
-
-#if LOCAL_INTERFACE
-/*
-** A parsed URI is held in an instance of the following structure.
-** Each component is recorded in memory obtained from HtmlAlloc().
-**
-** The examples are from the URI
-**
-** http://192.168.1.1:8080/cgi-bin/printenv?name=xyzzy&addr=none#frag
-*/
-struct HtmlUri {
- char *zScheme; /* Ex: "http" */
- char *zAuthority; /* Ex: "192.168.1.1:8080" */
- char *zPath; /* Ex: "cgi-bin/printenv" */
- char *zQuery; /* Ex: "name=xyzzy&addr=none" */
- char *zFragment; /* Ex: "frag" */
-};
-#endif
-
-/*
-** Return the length of the next component of the URL in z[] given
-** that the component starts at z[0]. The initial sequence of the
-** component must be zInit[]. The component is terminated by any
-** character in zTerm[]. The length returned is 0 if the component
-** doesn't exist. The length includes the zInit[] string, but not
-** the termination character.
-**
-** Component zInit zTerm
-** ---------- ------- -------
-** scheme "" ":/?#"
-** authority "//" "/?#"
-** path "/" "?#"
-** query "?" "#"
-** fragment "#" ""
-*/
-static int ComponentLength(const char *z, const char *zInit, const char *zTerm){
- int i, n;
- for(n=0; zInit[n]; n++){
- if( zInit[n]!=z[n] ) return 0;
- }
- while( z[n] ){
- for(i=0; zTerm[i]; i++){
- if( z[n]==zTerm[i] ) return n;
- }
- n++;
- }
- return n;
-}
-
-/*
-** Duplicate a string of length n.
-*/
-static char *StrNDup(const char *z, int n){
- char *zResult;
- if(!n)
- return NULL;
- if( n<=0 ){
- n = strlen(z);
- }
- zResult = HtmlAlloc( n + 1 );
- if( zResult ){
- memcpy(zResult, z, n);
- zResult[n] = 0;
- TestPoint(0);
- }
- return zResult;
-}
-
-/*
-** Parse a text URI into an HtmlUri structure.
-*/
-static HtmlUri *ParseUri(const char *zUri){
- HtmlUri *p;
- int n;
-
- p = HtmlAlloc( sizeof(*p) );
- if( p==0 ) return 0;
- memset(p, 0, sizeof(*p));
- if( zUri==0 || zUri[0]==0 ) return p;
- while( isspace(zUri[0]) ){ zUri++; }
- n = ComponentLength(zUri, "", ":/?# ");
- if( n>0 && zUri[n]==':' ){
- p->zScheme = StrNDup(zUri, n);
- zUri += n+1;
- }
- n = ComponentLength(zUri, "//", "/?# ");
- if( n>0 ){
- p->zAuthority = StrNDup(&zUri[2], n-2);
- zUri += n;
- }
- /* allow spaces in path */
- /* n = ComponentLength(zUri, "", "?# ");*/
- n = ComponentLength(zUri, "", "?#");
- if( n>0 ){
- p->zPath = StrNDup(zUri, n);
- zUri += n;
- }
- n = ComponentLength(zUri, "?", "# ");
- if( n>0 ){
- p->zQuery = StrNDup(&zUri[1], n-1);
- zUri += n;
- }
- n = ComponentLength(zUri, "#", " ");
- if( n>0 ){
- p->zFragment = StrNDup(&zUri[1], n-1);
- }
- return p;
-}
-
-/*
-** Delete an HtmlUri structure.
-*/
-static void FreeUri(HtmlUri *p){
- if( p==0 ) return;
- if( p->zScheme ) HtmlFree(p->zScheme);
- if( p->zAuthority ) HtmlFree(p->zAuthority);
- if( p->zPath ) HtmlFree(p->zPath);
- if( p->zQuery ) HtmlFree(p->zQuery);
- if( p->zFragment ) HtmlFree(p->zFragment);
- HtmlFree(p);
-}
-
-/*
-** Create a string to hold the given URI. Memory to hold the string
-** is obtained from HtmlAlloc() and must be freed by the calling
-** function.
-*/
-static char *BuildUri(HtmlUri *p){
- int n = 1;
- char *z;
- if( p->zScheme ) n += strlen(p->zScheme)+1;
- if( p->zAuthority ) n += strlen(p->zAuthority)+2;
- if( p->zPath ) n += strlen(p->zPath)+1;
- if( p->zQuery ) n += strlen(p->zQuery)+1;
- if( p->zFragment ) n += strlen(p->zFragment)+1;
- z = HtmlAlloc( n );
- if( z==0 ) return 0;
- n = 0;
- if( p->zScheme ){
- sprintf(z, "%s:", p->zScheme);
- n = strlen(z);
- }
- if( p->zAuthority ){
- sprintf(&z[n], "//%s", p->zAuthority);
- n += strlen(&z[n]);
- }
- if( p->zPath ){
- sprintf(&z[n], "%s", p->zPath);
- n += strlen(&z[n]);
- }
- if( p->zQuery ){
- sprintf(&z[n], "?%s", p->zQuery);
- n += strlen(&z[n]);
- }
- if( p->zFragment ){
- sprintf(&z[n], "#%s", p->zFragment);
- }else{
- z[n] = 0;
- }
- return z;
-}
-
-/*
-** Replace the string in *pzDest with the string in zSrc
-*/
-static void ReplaceStr(char **pzDest, const char *zSrc){
- if( *pzDest!=0 ) HtmlFree(*pzDest);
- if( zSrc==0 ){
- *pzDest = 0;
- }else{
- *pzDest = StrNDup(zSrc, -1);
- }
-}
-
-/*
-** Remove leading and trailing spaces from the given string. Return
-** a new string obtained from HtmlAlloc().
-*/
-static char *Trim(char *z){
- int i;
- char *zNew;
- while( isspace(*z) ) z++;
- i = strlen(z);
- zNew = HtmlAlloc( i+1 );
- if( zNew==0 ) return 0;
- strcpy(zNew, z);
- if( i>0 && isspace(zNew[i-1]) ){
- i--;
- zNew[i] = 0;
- }
- return zNew;
-}
-
-/*
-** The input azSeries[] is a sequence of URIs. This command must
-** resolve them all and put the result in the interp->result field
-** of the interpreter associated with the HTML widget. Return
-** TCL_OK on success and TCL_ERROR if there is a failure.
-**
-** This function can cause the HTML widget to be deleted or changed
-** arbitrarily.
-*/
-int HtmlCallResolver(
- HtmlWidget *htmlPtr, /* The widget that is doing the resolving. */
- char **azSeries /* A list of URIs. NULL terminated */
-){
- int rc = TCL_OK; /* Return value of this function. */
- char *z;
-
- HtmlVerifyLock(htmlPtr);
- if( htmlPtr->zResolverCommand && htmlPtr->zResolverCommand[0] ){
- /*
- ** Append the current base URI then the azSeries arguments to the
- ** TCL command specified by the -resolvercommand optoin, then execute
- ** the result.
- **
- ** The -resolvercommand could do nasty things, such as delete
- ** the HTML widget out from under us. Be prepared for the worst.
- */
- Tcl_DString cmd;
- Tcl_DStringInit(&cmd);
- Tcl_DStringAppend(&cmd, htmlPtr->zResolverCommand, -1);
- if( htmlPtr->zBaseHref && htmlPtr->zBaseHref[0] ){
- z = Trim(htmlPtr->zBaseHref);
- }else if( htmlPtr->zBase && htmlPtr->zBase[0] ){
- z = Trim(htmlPtr->zBase);
- }
- else
- z=0;
-
- if( z ){
- Tcl_DStringAppendElement(&cmd, z);
- HtmlFree(z);
- }
- while( azSeries[0] ){
- z = Trim(azSeries[0]);
- if( z ){
- Tcl_DStringAppendElement(&cmd, z);
- HtmlFree(z);
- }
- azSeries++;
- }
- HtmlLock(htmlPtr);
- rc = Tcl_GlobalEval(htmlPtr->interp, Tcl_DStringValue(&cmd));
- Tcl_DStringFree(&cmd);
- if( HtmlUnlock(htmlPtr) ) return TCL_ERROR;
- if( rc!=TCL_OK ){
- Tcl_AddErrorInfo(htmlPtr->interp,
- "\n (-resolvercommand executed by HTML widget)");
- }
- }else{
- /*
- ** No -resolvercommand has been specified. Do the default
- ** resolver algorithm specified in section 5.2 of RFC 2396.
- */
- HtmlUri *base, *term;
- if( htmlPtr->zBaseHref && htmlPtr->zBaseHref[0] ){
- base = ParseUri(htmlPtr->zBaseHref);
- }else{
- base = ParseUri(htmlPtr->zBase);
- }
- while( azSeries[0] ){
- term = ParseUri(azSeries[0]);
- azSeries++;
- if( term->zScheme==0 && term->zAuthority==0 && term->zPath==0
- && term->zQuery==0 && term->zFragment ){
- ReplaceStr(&base->zFragment, term->zFragment);
- }else if( term->zScheme ){
- HtmlUri temp;
- temp = *term;
- *term = *base;
- *base = temp;
- }else if( term->zAuthority ){
- ReplaceStr(&base->zAuthority, term->zAuthority);
- ReplaceStr(&base->zPath, term->zPath);
- ReplaceStr(&base->zQuery, term->zQuery);
- ReplaceStr(&base->zFragment, term->zFragment);
- }else if( term->zPath && (term->zPath[0]=='/' || base->zPath==0) ){
- ReplaceStr(&base->zPath, term->zPath);
- ReplaceStr(&base->zQuery, term->zQuery);
- ReplaceStr(&base->zFragment, term->zFragment);
- }else if( term->zPath && base->zPath ){
- char *zBuf;
- int i, j;
- zBuf = HtmlAlloc( strlen(base->zPath) + strlen(term->zPath) + 2 );
- if( zBuf ){
- sprintf(zBuf,"%s", base->zPath);
- for(i=strlen(zBuf)-1; i>=0 && zBuf[i]!='/'; i--){ zBuf[i] = 0; }
- strcat(zBuf, term->zPath);
- for(i=0; zBuf[i]; i++){
- if( zBuf[i]=='/' && zBuf[i+1]=='.' && zBuf[i+2]=='/' ){
- // strcpy into same buf is undefined
- // strcpy(&zBuf[i+1], &zBuf[i+3]);
- int ll = strlen(zBuf+i+3)+1;
- char* tmp = malloc(ll);
- strncpy(tmp,zBuf+i+3,ll);
- strcpy(zBuf+i+1, tmp);
- free(tmp);
- i--;
- continue;
- }
- if( zBuf[i]=='/' && zBuf[i+1]=='.' && zBuf[i+2]==0 ){
- zBuf[i+1] = 0;
- continue;
- }
- if( i>0 && zBuf[i]=='/' && zBuf[i+1]=='.' && zBuf[i+2]=='.'
- && (zBuf[i+3]=='/' || zBuf[i+3]==0) ){
- for(j=i-1; j>=0 && zBuf[j]!='/'; j--){}
- if( zBuf[i+3] ){
- // strcpy into same buf is undefined
- // strcpy(&zBuf[j+1], &zBuf[i+4]);
- int ll = strlen(zBuf+i+4)+1;
- char* tmp = malloc(ll);
- strncpy(tmp,zBuf+i+4,ll);
- strcpy(zBuf+j+1, tmp);
- free(tmp);
- }else{
- zBuf[j+1] = 0;
- }
- i = j-1;
- if( i<-1 ) i = -1;
- continue;
- }
- }
- /* look for /../ at begining */
- if (!strncmp(zBuf,"/../",4)) {
- // strcpy into same buf is undefined
- // strcpy(zBuf,zBuf+3);
- int ll = strlen(zBuf+3)+1;
- char* tmp = malloc(ll);
- strncpy(tmp,zBuf+3,ll);
- strcpy(zBuf, tmp);
- free(tmp);
- }
- HtmlFree(base->zPath);
- base->zPath = zBuf;
- }
- ReplaceStr(&base->zQuery, term->zQuery);
- ReplaceStr(&base->zFragment, term->zFragment);
- }
- FreeUri(term);
- }
- Tcl_SetResult(htmlPtr->interp, BuildUri(base), TCL_DYNAMIC);
- FreeUri(base);
- }
- return rc;
-}
-
-/*
-** This is a convenient wrapper routine for HtmlCallResolver.
-** It makes a copy of the result into memory obtained from HtmlAlloc()
-** and invokes Tcl_ResetResult().
-*/
-char *HtmlResolveUri(HtmlWidget *htmlPtr, char *zUri){
- char *azSeq[2];
- char *zSrc;
- int result;
-
- if( zUri==0 || *zUri==0 ) return 0;
- azSeq[0] = zUri;
- azSeq[1] = 0;
- HtmlLock(htmlPtr);
- result = HtmlCallResolver(htmlPtr, azSeq);
- if( HtmlUnlock(htmlPtr) ) return 0;
- if( result==TCL_OK ){
- zSrc = HtmlAlloc( strlen(Tcl_GetStringResult(htmlPtr->interp)) + 1 );
- if( zSrc ) strcpy(zSrc, Tcl_GetStringResult(htmlPtr->interp));
- }else{
- zSrc = 0;
- }
- Tcl_ResetResult(htmlPtr->interp);
- return zSrc;
-}