Beispiel #1
0
DIR *
opendir(char *filename)
{
    DIR *dirp = typecalloc(DIR);
    long status;

    if (dirp == 0)
	return (0);

    zfab = cc$rms_fab;
    zfab.fab$l_fop = FAB$M_NAM;
    zfab.fab$l_nam = &znam;	/* FAB => NAM block     */
    zfab.fab$l_dna = (global_g_val(GMDALL_VERSIONS)
		      ? "*.*;*"
		      : "*.*;");
    zfab.fab$b_dns = strlen(zfab.fab$l_dna);

    zfab.fab$l_fna = filename;
    zfab.fab$b_fns = strlen(filename);

    znam = cc$rms_nam;
    znam.nam$b_ess = NAM$C_MAXRSS;
    znam.nam$l_esa = zesa;
    znam.nam$b_rss = NAM$C_MAXRSS;
    znam.nam$l_rsa = zrsa;

    if (sys$parse(&zfab) != RMS$_NORMAL) {
	(void) closedir(dirp);
	dirp = 0;
    }
    return (dirp);
}
Beispiel #2
0
PRIVATE void append_close_tag ARGS3(
	    char*,	  tagname,
	    HT_tagspec**, head,
	    HT_tagspec**, tail)
{
    int idx, nattr;
    HTTag* tag;
    HT_tagspec* subj;

    idx = html_src_tag_index(tagname);
    tag = HTML_dtd.tags+idx;
    nattr = tag->number_of_attributes;

    if (idx == -1) {
	fprintf(stderr,
	"internal error: previous check didn't find bad HTML tag %s", tagname);
	exit_immediately(EXIT_FAILURE);
    }

    subj = typecalloc(HT_tagspec);
    subj->element = idx;
    subj->present = typecallocn(BOOL, nattr);
    subj->value = typecallocn(char *, nattr);
    subj->start = FALSE;
#ifdef USE_COLOR_STYLE
    subj->class_name = NULL;
#endif

    if (!*head) {
	*head = subj; *tail = subj;
    } else {
	(*tail)->next = subj; *tail = subj;
    }
}
Beispiel #3
0
HTStyleSheet *HTStyleSheetNew(void)
{
    HTStyleSheet *self = typecalloc(HTStyleSheet);

    if (self == NULL)
	outofmem(__FILE__, "HTStyleSheetNew");
    return self;
}
Beispiel #4
0
/*	Create a chunk with a certain allocation unit
**	--------------
*/
PUBLIC HTChunk * HTChunkCreate ARGS1 (int,grow)
{
    HTChunk * ch = typecalloc(HTChunk);
    if (ch == NULL)
	outofmem(__FILE__, "creation of chunk");

    HTChunkInit (ch, grow);
    return ch;
}
Beispiel #5
0
int HTAddRule(HTRuleOp op, const char *pattern,
	      const char *equiv,
	      const char *cond_op,
	      const char *cond)
{				/* BYTE_ADDRESSING removed and memory check - AS - 1 Sep 93 */
    rule *temp;
    char *pPattern = NULL;

    temp = typecalloc(rule);
    if (temp == NULL)
	outofmem(__FILE__, "HTAddRule");
    if (equiv) {		/* Two operands */
	char *pEquiv = NULL;

	StrAllocCopy(pEquiv, equiv);
	temp->equiv = pEquiv;
    } else {
	temp->equiv = 0;
    }
    if (cond_op) {
	StrAllocCopy(temp->condition_op, cond_op);
	StrAllocCopy(temp->condition, cond);
    }
    StrAllocCopy(pPattern, pattern);
    temp->pattern = pPattern;
    temp->op = op;

    if (equiv) {
	CTRACE((tfp, "Rule: For `%s' op %d `%s'", pattern, op, equiv));
    } else {
	CTRACE((tfp, "Rule: For `%s' op %d", pattern, op));
    }
    if (cond_op) {
	CTRACE((tfp, "\t%s %s\n", cond_op, NONNULL(cond)));
    } else {
	CTRACE((tfp, "\n"));
    }

    if (!rules) {
#ifdef LY_FIND_LEAKS
	atexit(HTClearRules);
#endif
    }
#ifdef PUT_ON_HEAD
    temp->next = rules;
    rules = temp;
#else
    temp->next = 0;
    if (rule_tail)
	rule_tail->next = temp;
    else
	rules = temp;
    rule_tail = temp;
#endif

    return 0;
}
Beispiel #6
0
static BI_NODE *
new_elapsed(BI_DATA * a)
{
    BI_NODE *p;

    beginDisplay();
    if ((p = typecalloc(BI_NODE)) != 0) {
	BI_DATA *q = &(p->value);
	if ((BI_KEY(p) = strmalloc(a->bi_key)) == 0
	    || (q->data = typecalloc(ELAPSED_DATA)) == 0) {
	    old_elapsed(p);
	    p = 0;
	}
    }
    endofDisplay();

    return p;
}
Beispiel #7
0
PRIVATE HTChildAnchor * HTChildAnchor_new ARGS1(
	HTParentAnchor0 *,	parent)
{
    HTChildAnchor *p = typecalloc(HTChildAnchor);
    if (p == NULL)
	outofmem(__FILE__, "HTChildAnchor_new");

    p->parent = parent;		/* parent reference */
    return p;
}
Beispiel #8
0
/*
**  Purpose:	Capture all requests to free information and also
**		remove items from the allocation list.
**  Arguments:	vp_Alloced	The memory to free.
**		cp_File		The file calling free.
**		ssi_Line	The line of cp_File calling free.
**  Return Value:	void
**  Remarks/Portability/Dependencies/Restrictions:
**		If the pointer value is invalid, then an item will be added
**		to the list and nothing else is done.
**		I really like the name of this function and one day hope
**		that Lynx is Leak Free.
**  Revision History:
**	05-26-94	created Lynx 2-3-1 Garrett Arch Blythe
*/
PUBLIC void LYLeakFree ARGS3(
	void *,		vp_Alloced,
	CONST char *,	cp_File,
	CONST short,	ssi_Line)
{
    AllocationList *ALp_free;

    if (LYfind_leaks == FALSE) {
	free(vp_Alloced);
	return;
    }

    /*
     *	Find the pointer in the allocated list.
     *	If not found, bad pointer.
     *	If found, free list item and vp_Allloced.
     */
    ALp_free = FindInList(vp_Alloced);
    if (ALp_free == NULL) {
	/*
	 *  Create the final entry before exiting marking this error.
	 *  If unable to allocate more memory just exit.
	 */
	AllocationList *ALp_new = typecalloc(AllocationList);

	if (ALp_new == NULL) {
	    exit(EXIT_FAILURE);
	}

	/*
	 *  Set up the information, no memory need be allocated
	 *  for the file name since it is a static string.
	 */
	ALp_new->vp_Alloced = NULL;
	ALp_new->vp_BadRequest = vp_Alloced;
	ALp_new->SL_memory.cp_FileName = cp_File;
	ALp_new->SL_memory.ssi_LineNumber = ssi_Line;

	/*
	 *  Add the entry to the list and then return.
	 */
	AddToList(ALp_new);
	return;
    } else {
	/*
	 *  Free off the memory.
	 *  Take entry out of allocation list.
	 */
	CountFrees(ALp_free->st_Bytes);
	RemoveFromList(ALp_free);
	FREE(ALp_free);
	FREE(vp_Alloced);
    }
}
Beispiel #9
0
/*	The creation method
*/
PUBLIC HTStream * HTNetToText ARGS1(HTStream *, sink)
{
    HTStream* me = typecalloc(HTStream);

    if (me == NULL)
	outofmem(__FILE__, "NetToText");
    me->isa = &NetToTextClass;

    me->had_cr = NO;
    me->sink = sink;
    return me;
}
Beispiel #10
0
/*
**  Purpose:	Add information about new allocation to the list,
**		after a call to malloc or calloc or an equivalent
**		function which may or may not have already created
**		a list entry.
**  Arguments:	vp_malloc	The pointer to newly allocated memory.
**  Arguments:	st_bytes	The size of the allocation requested
**				in bytes.
**		cp_File		The file from which the request for
**				allocation came from.
**		ssi_Line	The line number in cp_File where the
**				allocation request came from.
**  Return Value:	void *	A pointer to the allocated memory or NULL on
**				failure.
**  Remarks/Portability/Dependencies/Restrictions:
**		If no memory is allocated, then no entry is added to the
**		allocation list.
**  Revision History:
**	1999-02-08	created, modelled after LYLeakMalloc - kw
*/
PUBLIC AllocationList *LYLeak_mark_malloced ARGS4(
	void *,		vp_malloced,
	size_t,		st_bytes,
	CONST char *,	cp_File,
	CONST short,	ssi_Line)
{
    AllocationList *ALp_new = NULL;

    if (LYfind_leaks == FALSE)
	return NULL;

    /*
     *	The actual allocation has already been done!
     *
     *	Only on successful allocation do we track any information.
     */
    if (vp_malloced != NULL) {
	/*
	 *  See if there is already an entry.  If so, just
	 *  update the source location info.
	 */
	ALp_new = FindInList(vp_malloced);
	if (ALp_new) {
	    ALp_new->SL_memory.cp_FileName = cp_File;
	    ALp_new->SL_memory.ssi_LineNumber = ssi_Line;
	    return(ALp_new);
	}
	/*
	 *  Further allocate memory to store the information.
	 *  Just return on failure to allocate more.
	 */
	ALp_new = typecalloc(AllocationList);

	if (ALp_new == NULL) {
	    return(NULL);
	}
	/*
	 *  Copy over the relevant information.
	 */
	ALp_new->vp_Alloced = vp_malloced;
	ALp_new->st_Bytes = st_bytes;
	ALp_new->SL_memory.cp_FileName = cp_File;
	ALp_new->SL_memory.ssi_LineNumber = ssi_Line;

	/*
	 *  Add the new item to the allocation list.
	 */
	AddToList(ALp_new);
    }

    return(ALp_new);
}
Beispiel #11
0
static SGML_dtd *load_flatfile(FILE *input)
{
    AttrType *attr_types = 0;
    SGML_dtd *result = 0;
    size_t n;
    size_t number_of_attrs = 0;
    size_t number_of_tags = 0;
    HTTag *tag;
    int code;

    code = fscanf(input, "%d attr_types\n", &number_of_attrs);
    if (code
	&& number_of_attrs
	&& (attr_types = typecallocn(AttrType, number_of_attrs + 1)) != 0) {
	for (n = 0; n < number_of_attrs; ++n) {
	    if (!load_flat_AttrType(input, attr_types + n, n)) {
		break;
	    }
	}
    }

    code = fscanf(input, "%d tags\n", &number_of_tags);
    if (code == 1) {
	if ((result = typecalloc(SGML_dtd)) != 0
	    && (result->tags = typecallocn(HTTag, (number_of_tags + 2))) != 0) {
	    for (n = 0; n < number_of_tags; ++n) {
		if (load_flat_HTTag(input, n, &(result->tags[n]), attr_types)) {
		    result->number_of_tags = (n + 1);
		} else {
		    break;
		}
	    }
	    tag = 0;
	    for (n = 0; n < number_of_tags; ++n) {
		if (result->tags[n].name != 0
		    && !strcmp(result->tags[n].name, "OBJECT")) {
		    tag = result->tags + number_of_tags;
		    *tag = result->tags[n];
		    tag->contents = SGML_MIXED;
		    tag->flags = Tgf_strict;
		    break;
		}
	    }
	    if (tag == 0) {
		fprintf(stderr, "Did not find OBJECT tag\n");
		result = 0;
	    }
	}
    }
    return result;
}
Beispiel #12
0
/*				Creation Methods
**				================
**
**	Do not use "new" by itself outside this module.  In order to enforce
**	consistency, we insist that you furnish more information about the
**	anchor you are creating : use newWithParent or newWithAddress.
*/
PRIVATE HTParentAnchor0 * HTParentAnchor0_new ARGS2(
	CONST char *,	address,
	short,		hash)
{
    HTParentAnchor0 *newAnchor = typecalloc(HTParentAnchor0);
    if (newAnchor == NULL)
	outofmem(__FILE__, "HTParentAnchor0_new");

    newAnchor->parent = newAnchor;	/* self */
    StrAllocCopy(newAnchor->address, address);
    newAnchor->adult_hash = hash;

    return(newAnchor);
}
Beispiel #13
0
/*
**  Purpose:	Capture allocations by calloc (stdlib.h) and
**		save relevant information in a list.
**  Arguments:	st_number	The number of items to allocate.
**		st_bytes	The size of each item.
**		cp_File		The file which wants to allocation.
**		ssi_Line	The line number in cp_File requesting
**				the allocation.
**  Return Value:	void *	The allocated memory, or NULL on failure as
**				per calloc (stdlib.h)
**  Remarks/Portability/Dependencies/Restrictions:
**		If no memory can be allocated, then no entry will be added
**		to the list.
**  Revision History:
**		05-26-94	created Lynx 2-3-1 Garrett Arch Blythe
*/
PUBLIC void *LYLeakCalloc ARGS4(
	size_t,		st_number,
	size_t,		st_bytes,
	CONST char *,	cp_File,
	CONST short,	ssi_Line)
{
    void *vp_calloc;

    if (LYfind_leaks == FALSE)
	return (void *)calloc(st_number, st_bytes);

    /*
     *	Allocate the requested memory.
     */
    vp_calloc = (void *)calloc(st_number, st_bytes);
    CountMallocs(st_bytes);

    /*
     *	Only if the allocation was a success do we track information.
     */
    if (vp_calloc != NULL) {
	/*
	 *  Allocate memory for the item to be in the list.
	 *  If unable, just return.
	 */
	AllocationList *ALp_new = typecalloc(AllocationList);

	if (ALp_new == NULL) {
		return(vp_calloc);
	}

	/*
	 *  Copy over the relevant information.
	 *  There is no need to allocate memory for the file
	 *  name as it is a static string anyway.
	 */
	ALp_new->st_Sequence = count_mallocs;
	ALp_new->vp_Alloced = vp_calloc;
	ALp_new->st_Bytes = (st_number * st_bytes);
	ALp_new->SL_memory.cp_FileName = cp_File;
	ALp_new->SL_memory.ssi_LineNumber = ssi_Line;

	/*
	 *	Add the item to the allocation list.
	 */
	AddToList(ALp_new);
    }

    return(vp_calloc);
}
Beispiel #14
0
PUBLIC HTChunk * HTChunkCreateMayFail ARGS2 (int,grow, int,failok)
{
    HTChunk * ch = typecalloc(HTChunk);
    if (ch == NULL) {
	if (!failok) {
	    outofmem(__FILE__, "creation of chunk");
	} else {
	    return ch;
	}
    }
    HTChunkInit (ch, grow);
    ch->failok = failok;
    return ch;
}
Beispiel #15
0
/*
**  Purpose:	Capture allocations using malloc (stdlib.h) and track
**		the information in a list.
**  Arguments:	st_bytes	The size of the allocation requested
**				in bytes.
**		cp_File		The file from which the request for
**				allocation came from.
**		ssi_Line	The line number in cp_File where the
**				allocation request came from.
**  Return Value:	void *	A pointer to the allocated memory or NULL on
**				failure as per malloc (stdlib.h)
**  Remarks/Portability/Dependencies/Restrictions:
**		If no memory is allocated, then no entry is added to the
**		allocation list.
**  Revision History:
**	05-26-94	created Lynx 2-3-1 Garrett Arch Blythe
*/
PUBLIC void *LYLeakMalloc ARGS3(
	size_t,		st_bytes,
	CONST char *,	cp_File,
	CONST short,	ssi_Line)
{
    void *vp_malloc;

    if (LYfind_leaks == FALSE)
	return (void *)malloc(st_bytes);

    /*
     *	Do the actual allocation.
     */
    vp_malloc = (void *)malloc(st_bytes);
    CountMallocs(st_bytes);

    /*
     *	Only on successful allocation do we track any information.
     */
    if (vp_malloc != NULL) {
	/*
	 *  Further allocate memory to store the information.
	 *  Just return on failure to allocate more.
	 */
	AllocationList *ALp_new = typecalloc(AllocationList);

	if (ALp_new == NULL) {
	    return(vp_malloc);
	}
	/*
	 *  Copy over the relevant information.
	 *  There is no need to allocate more memory for the
	 *  file name as it is a static string anyhow.
	 */
	ALp_new->st_Sequence = count_mallocs;
	ALp_new->vp_Alloced = vp_malloc;
	ALp_new->st_Bytes = st_bytes;
	ALp_new->SL_memory.cp_FileName = cp_File;
	ALp_new->SL_memory.ssi_LineNumber = ssi_Line;

	/*
	 *  Add the new item to the allocation list.
	 */
	AddToList(ALp_new);
    }

    return(vp_malloc);
}
Beispiel #16
0
/*	Create a chunk with a certain allocation unit and ensured size
**	--------------
*/
PUBLIC HTChunk * HTChunkCreate2 ARGS2 (int,grow, size_t, needed)
{
    HTChunk * ch = typecalloc(HTChunk);
    if (ch == NULL)
	outofmem(__FILE__, "HTChunkCreate2");

    HTChunkInit (ch, grow);
    if (needed > 0) {
	ch->allocated = needed-1 - ((needed-1) % ch->growby)
	    + ch->growby; /* Round up */
	CTRACE((tfp, "HTChunkCreate2: requested %d, allocate %d\n",
	       (int) needed, ch->allocated));
	ch->data = typecallocn(char, ch->allocated);
	if (!ch->data)
	    outofmem(__FILE__, "HTChunkCreate2 data");
    }
Beispiel #17
0
static BI_NODE *
new_tags(BI_DATA * a)
{
    BI_NODE *p;

    beginDisplay();
    if ((p = typecalloc(BI_NODE)) != 0) {
	p->value = *a;
	if ((BI_KEY(p) = strmalloc(a->bi_key)) == 0) {
	    old_tags(p);
	    p = 0;
	}
    }
    endofDisplay();

    return p;
}
Beispiel #18
0
PRIVATE HTParentAnchor * HTParentAnchor_new ARGS1(
	HTParentAnchor0 *,	parent)
{
    HTParentAnchor *newAnchor = typecalloc(HTParentAnchor);
    if (newAnchor == NULL)
	outofmem(__FILE__, "HTParentAnchor_new");

    newAnchor->parent = parent;		/* cross reference */
    parent->info = newAnchor;		/* cross reference */
    newAnchor->address = parent->address;  /* copy pointer */

    newAnchor->isISMAPScript = FALSE;	/* Lynx appends ?0,0 if TRUE. - FM */
    newAnchor->isHEAD = FALSE;		/* HEAD request if TRUE. - FM */
    newAnchor->safe = FALSE;		/* Safe. - FM */
    newAnchor->no_cache = FALSE;	/* no-cache? - FM */
    newAnchor->inBASE = FALSE;		/* duplicated from HTML.c/h */
    newAnchor->content_length = 0;	/* Content-Length. - FM */
    return(newAnchor);
}
Beispiel #19
0
/*	Create a chunk with a certain allocation unit and ensured size
 *	--------------
 */
HTChunk *HTChunkCreate2(int grow, size_t needed)
{
    HTChunk *ch = typecalloc(HTChunk);

    if (ch == NULL)
        outofmem(__FILE__, "HTChunkCreate2");

    HTChunkInit(ch, grow);
    if (needed > 0) {
        /* Round up */
        ch->allocated = (int) (needed - 1 - ((needed - 1) % ch->growby)
                               + (unsigned) ch->growby);
        CTRACE((tfp, "HTChunkCreate2: requested %d, allocate %u\n",
                (int) needed, (unsigned) ch->allocated));
        ch->data = typecallocn(char, (unsigned) ch->allocated);

        if (!ch->data)
            outofmem(__FILE__, "HTChunkCreate2 data");
    }
Beispiel #20
0
/*	Define a presentation system command for a content-type
**	-------------------------------------------------------
*/
PUBLIC void HTSetPresentation ARGS6(
	CONST char *,	representation,
	CONST char *,	command,
	double,		quality,
	double,		secs,
	double,		secs_per_byte,
	long int,	maxbytes)
{
    HTPresentation * pres = typecalloc(HTPresentation);
    if (pres == NULL)
	outofmem(__FILE__, "HTSetPresentation");

    pres->rep = HTAtom_for(representation);
    pres->rep_out = WWW_PRESENT;		/* Fixed for now ... :-) */
    pres->converter = HTSaveAndExecute;		/* Fixed for now ...	 */
    pres->quality = (float) quality;
    pres->secs = (float) secs;
    pres->secs_per_byte = (float) secs_per_byte;
    pres->maxbytes = maxbytes;
    pres->command = NULL;
    StrAllocCopy(pres->command, command);

    /*
     *	Memory leak fixed.
     *	05-28-94 Lynx 2-3-1 Garrett Arch Blythe
     */
    if (!HTPresentations)	{
	HTPresentations = HTList_new();
#ifdef LY_FIND_LEAKS
	atexit(HTFreePresentations);
#endif
    }

    if (strcmp(representation, "*")==0) {
	FREE(default_presentation);
	default_presentation = pres;
    } else {
	HTList_addObject(HTPresentations, pres);
    }
}
Beispiel #21
0
/*	Define a built-in function for a content-type
**	---------------------------------------------
*/
PUBLIC void HTSetConversion ARGS7(
	CONST char *,	representation_in,
	CONST char *,	representation_out,
	HTConverter*,	converter,
	float,		quality,
	float,		secs,
	float,		secs_per_byte,
	long int,	maxbytes)
{
    HTPresentation * pres = typecalloc(HTPresentation);
    if (pres == NULL)
	outofmem(__FILE__, "HTSetConversion");

    pres->rep = HTAtom_for(representation_in);
    pres->rep_out = HTAtom_for(representation_out);
    pres->converter = converter;
    pres->command = NULL;		/* Fixed */
    pres->quality = quality;
    pres->secs = secs;
    pres->secs_per_byte = secs_per_byte;
    pres->maxbytes = maxbytes;
    pres->command = NULL;

    /*
     *	Memory Leak fixed.
     *	05-28-94 Lynx 2-3-1 Garrett Arch Blythe
     */
    if (!HTPresentations)	{
	HTPresentations = HTList_new();
#ifdef LY_FIND_LEAKS
	atexit(HTFreePresentations);
#endif
    }

    HTList_addObject(HTPresentations, pres);
}
Beispiel #22
0
/*
**  We store charset info in the HTParentAnchor object, for several
**  "stages".  (See UCDefs.h)
**  A stream method is supposed to know what stage in the model it is.
**
**  General model	MIME	 ->  parser  ->  structured  ->  HText
**  e.g., text/html
**	from HTTP:	HTMIME.c ->  SGML.c  ->  HTML.c      ->  GridText.c
**     text/plain
**	from file:	HTFile.c ->  HTPlain.c		     ->  GridText.c
**
**  The lock/set_by is used to lock e.g. a charset set by an explicit
**  HTTP MIME header against overriding by a HTML META tag - the MIME
**  header has higher priority.  Defaults (from -assume_.. options etc.)
**  will not override charset explicitly given by server.
**
**  Some advantages of keeping this in the HTAnchor:
**  - Global variables are bad.
**  - Can remember a charset given by META tag when toggling to SOURCE view.
**  - Can remember a charset given by <A CHARSET=...> href in another doc.
**
**  We don't modify the HTParentAnchor's charset element
**  here, that one will only be set when explicitly given.
*/
PUBLIC LYUCcharset * HTAnchor_getUCInfoStage ARGS2(
	HTParentAnchor *,	me,
	int,			which_stage)
{
    if (me && !me->UCStages) {
	int i;
	int chndl = UCLYhndl_for_unspec;  /* always >= 0 */
	UCAnchorInfo * stages = typecalloc(UCAnchorInfo);
	if (stages == NULL)
	    outofmem(__FILE__, "HTAnchor_getUCInfoStage");
	for (i = 0; i < UCT_STAGEMAX; i++) {
	    stages->s[i].C.MIMEname = "";
	    stages->s[i].LYhndl = -1;
	}
	if (me->charset) {
	    chndl = UCGetLYhndl_byMIME(me->charset);
	    if (chndl < 0)
		chndl = UCLYhndl_for_unrec;
	    if (chndl < 0)
		/*
		**  UCLYhndl_for_unrec not defined :-(
		**  fallback to UCLYhndl_for_unspec which always valid.
		*/
		chndl = UCLYhndl_for_unspec;  /* always >= 0 */
	}
	memcpy(&stages->s[UCT_STAGE_MIME].C, &LYCharSet_UC[chndl],
	       sizeof(LYUCcharset));
	stages->s[UCT_STAGE_MIME].lock = UCT_SETBY_DEFAULT;
	stages->s[UCT_STAGE_MIME].LYhndl = chndl;
	me->UCStages = stages;
    }
    if (me) {
	return( &me->UCStages->s[which_stage].C);
    }
    return(NULL);
}
Beispiel #23
0
/*
**  Purpose:	Capture any realloc (stdlib.h) calls in order to
**		properly keep track of our run time allocation
**		table.
**  Arguments:	vp_Alloced	The previously allocated block of
**				memory to resize.  If NULL,
**				realloc works just like
**				malloc.
**		st_newBytes	The new size of the chunk of memory.
**		cp_File		The file containing the realloc.
**		ssi_Line	The line containing the realloc in cp_File.
**  Return Value:	void *	The new pointer value (could be the same) or
**				NULL if unable to resize (old block
**				still exists).
**  Remarks/Portability/Dependencies/Restrictions:
**		If unable to resize vp_Alloced, then no change in the
**		allocation list will be made.
**		If vp_Alloced is an invalid pointer value, the program will
**		exit after one last entry is added to the allocation list.
**  Revision History:
**	05-26-94	created Lynx 2-3-1 Garrett Arch Blythe
*/
PUBLIC void *LYLeakRealloc ARGS4(
	void *,		vp_Alloced,
	size_t,		st_newBytes,
	CONST char *,	cp_File,
	CONST short,	ssi_Line)
{
    void *vp_realloc;
    AllocationList *ALp_renew;

    if (LYfind_leaks == FALSE)
	return (void *)realloc(vp_Alloced, st_newBytes);

    /*
     *	If we are asked to resize a NULL pointer, this is just a
     *	malloc call.
     */
    if (vp_Alloced == NULL) {
	return(LYLeakMalloc(st_newBytes, cp_File, ssi_Line));
    }

    /*
     *	Find the current vp_Alloced block in the list.
     *	If NULL, this is an invalid pointer value.
     */
    ALp_renew = FindInList(vp_Alloced);
    if (ALp_renew == NULL) {
	/*
	 *  Track the invalid pointer value and then exit.
	 *  If unable to allocate, just exit.
	 */
	auto AllocationList *ALp_new = typecalloc(AllocationList);

	if (ALp_new == NULL) {
	    exit(EXIT_FAILURE);
	}

	/*
	 *  Set the information up; no need to allocate file name
	 *  since it is a static string.
	 */
	ALp_new->vp_Alloced = NULL;
	ALp_new->vp_BadRequest = vp_Alloced;
	ALp_new->SL_realloc.cp_FileName = cp_File;
	ALp_new->SL_realloc.ssi_LineNumber = ssi_Line;

	/*
	 *  Add the item to the list.
	 *  Exit.
	 */
	AddToList(ALp_new);
	exit(EXIT_FAILURE);
    }

    /*
     *	Perform the resize.
     *	If not NULL, record the information.
     */
    vp_realloc = (void *)realloc(vp_Alloced, st_newBytes);
    CountMallocs(st_newBytes);
    CountFrees(ALp_renew->st_Bytes);

    if (vp_realloc != NULL) {
	ALp_renew->st_Sequence = count_mallocs;
	ALp_renew->vp_Alloced = vp_realloc;
	ALp_renew->st_Bytes = st_newBytes;

	/*
	 *  Update the realloc information, too.
	 *  No need to allocate file name, static string.
	 */
	ALp_renew->SL_realloc.cp_FileName = cp_File;
	ALp_renew->SL_realloc.ssi_LineNumber = ssi_Line;
    }

    return(vp_realloc);
}
Beispiel #24
0
/*
 * Utility for listing visited links, making any repeated links the most
 * current in the list.  - FM
 */
void LYAddVisitedLink(DocInfo *doc)
{
    VisitedLink *tmp;
    HTList *cur;
    const char *title = (doc->title ? doc->title : NO_TITLE);

    if (isEmpty(doc->address)) {
	PrevVisitedLink = NULL;
	return;
    }

    /*
     * Exclude POST or HEAD replies, and bookmark, menu or list files.  - FM
     */
    if (doc->post_data || doc->isHEAD || doc->bookmark ||
	(			/* special url or a temp file */
	    (!StrNCmp(doc->address, "LYNX", 4) ||
	     !StrNCmp(doc->address, "file://localhost/", 17)))) {
	int related = 1;	/* First approximation only */

	if (LYIsUIPage(doc->address, UIP_HISTORY) ||
	    LYIsUIPage(doc->address, UIP_VLINKS) ||
	    LYIsUIPage(doc->address, UIP_SHOWINFO) ||
	    isLYNXMESSAGES(doc->address) ||
	    ((related = 0) != 0) ||
#ifdef DIRED_SUPPORT
	    LYIsUIPage(doc->address, UIP_DIRED_MENU) ||
	    LYIsUIPage(doc->address, UIP_UPLOAD_OPTIONS) ||
	    LYIsUIPage(doc->address, UIP_PERMIT_OPTIONS) ||
#endif /* DIRED_SUPPORT */
	    LYIsUIPage(doc->address, UIP_PRINT_OPTIONS) ||
	    LYIsUIPage(doc->address, UIP_DOWNLOAD_OPTIONS) ||
	    LYIsUIPage(doc->address, UIP_OPTIONS_MENU) ||
	    isLYNXEDITMAP(doc->address) ||
	    isLYNXKEYMAP(doc->address) ||
	    LYIsUIPage(doc->address, UIP_LIST_PAGE) ||
#ifdef USE_ADDRLIST_PAGE
	    LYIsUIPage(doc->address, UIP_ADDRLIST_PAGE) ||
#endif
	    LYIsUIPage(doc->address, UIP_CONFIG_DEF) ||
	    LYIsUIPage(doc->address, UIP_LYNXCFG) ||
	    isLYNXCOOKIE(doc->address) ||
	    LYIsUIPage(doc->address, UIP_TRACELOG)) {
	    if (!related)
		PrevVisitedLink = NULL;
	    return;
	}
    }

    if (!Visited_Links) {
	Visited_Links = HTList_new();
#ifdef LY_FIND_LEAKS
	atexit(Visited_Links_free);
#endif
	Latest_last.prev_latest = &Latest_first;
	Latest_first.next_latest = &Latest_last;
	Latest_last.next_latest = NULL;		/* Find bugs quick! */
	Latest_first.prev_latest = NULL;
	Last_by_first = Latest_tree = First_tree = NULL;
    }

    cur = Visited_Links;
    while (NULL != (tmp = (VisitedLink *) HTList_nextObject(cur))) {
	if (!strcmp(NonNull(tmp->address),
		    NonNull(doc->address))) {
	    PrevVisitedLink = PrevActiveVisitedLink = tmp;
	    /* Already visited.  Update the last-visited info. */
	    if (tmp->next_latest == &Latest_last)	/* optimization */
		return;

	    /* Remove from "latest" chain */
	    tmp->prev_latest->next_latest = tmp->next_latest;
	    tmp->next_latest->prev_latest = tmp->prev_latest;

	    /* Insert at the end of the "latest" chain */
	    Latest_last.prev_latest->next_latest = tmp;
	    tmp->prev_latest = Latest_last.prev_latest;
	    tmp->next_latest = &Latest_last;
	    Latest_last.prev_latest = tmp;
	    return;
	}
    }

    if ((tmp = typecalloc(VisitedLink)) == NULL)
	outofmem(__FILE__, "LYAddVisitedLink");

    StrAllocCopy(tmp->address, doc->address);
    LYformTitle(&(tmp->title), title);

    /* First-visited chain */
    HTList_appendObject(Visited_Links, tmp);	/* At end */
    tmp->prev_first = Last_by_first;
    Last_by_first = tmp;

    /* Tree structure */
    if (PrevVisitedLink) {
	VisitedLink *a = PrevVisitedLink;
	VisitedLink *b = a->next_tree;
	int l = PrevVisitedLink->level;

	/* Find last on the deeper levels */
	while (b && b->level > l)
	    a = b, b = b->next_tree;

	if (!b)			/* a == Latest_tree */
	    Latest_tree = tmp;
	tmp->next_tree = a->next_tree;
	a->next_tree = tmp;

	tmp->level = PrevVisitedLink->level + 1;
    } else {
	if (Latest_tree)
	    Latest_tree->next_tree = tmp;
	tmp->level = 0;
	tmp->next_tree = NULL;
	Latest_tree = tmp;
    }
    PrevVisitedLink = PrevActiveVisitedLink = tmp;
    if (!First_tree)
	First_tree = tmp;

    /* "latest" chain */
    Latest_last.prev_latest->next_latest = tmp;
    tmp->prev_latest = Latest_last.prev_latest;
    tmp->next_latest = &Latest_last;
    Latest_last.prev_latest = tmp;

    return;
}
Beispiel #25
0
/*
** Purpose:	A wrapper around StrAllocVsprintf (the workhorse of
**		HTSprintf/HTSprintf0, implemented in HTString.c) that
**		tries to make sure that our allocation list is always
**		properly updated, whether StrAllocVsprintf itself was
**		compiled with memory tracking or not (or even a mixture,
**		like tracking the freeing but not the new allocation).
**		Some source files can be compiled with LY_FIND_LEAKS_EXTENDED
**		in effect while others only have LY_FIND_LEAKS in effect,
**		and as long as HTString.c is complied with memory tracking
**		(of either kind) string objects allocated by HTSprintf/
**		HTSprintf0 (or otherwise) can be passed around among them and
**		manipulated both ways.
**  Arguments:	dest		As for StrAllocVsprintf.
**		cp_File		The source file of the caller (i.e. the
**				caller of HTSprintf/HTSprintf0, hopefully).
**		ssi_Line	The line of cp_File calling.
**		inuse,fmt,ap	As for StrAllocVsprintf.
**  Return Value:	The char pointer to resulting string, as set
**			by StrAllocVsprintf, or
**			NULL if dest==0 (wrong use!).
**  Remarks/Portability/Dependencies/Restrictions:
**		The price for generality is severe inefficiency: several
**		list lookups are done to be on the safe side.
**		We don't get he real allocation size, only a minimum based
**		on the string length of the result.  So the amount of memory
**		leakage may get underestimated.
**		If *dest is an invalid pointer value on entry (i.e. was not
**		tracked), the program will exit after one last entry is added
**		to the allocation list.
**		If StrAllocVsprintf fails to return a valid string via the
**		indirect string pointer (its first parameter), invalid memory
**		access will result and the program will probably terminate
**		with a signal.  This can happen if, on entry, *dest is NULL
**		and fmt is empty or NULL, so just Don't Do That.
**  Revision History:
**	1999-02-11	created kw
**	1999-10-15	added comments kw
*/
PRIVATE char * LYLeakSAVsprintf ARGS6(
	char **,	dest,
	CONST char *,	cp_File,
	CONST short,	ssi_Line,
	size_t,		inuse,
	CONST char *,	fmt,
	va_list *,	ap)
{
    AllocationList *ALp_old;
    void *vp_oldAlloced;

    CONST char * old_cp_File = __FILE__;
    short old_ssi_Line = __LINE__;

    if (!dest)
	return NULL;

    if (LYfind_leaks == FALSE) {
	StrAllocVsprintf(dest, inuse, fmt, ap);
	return (*dest);
    }

    vp_oldAlloced = *dest;
    if (!vp_oldAlloced) {
	StrAllocVsprintf(dest, inuse, fmt, ap);
	LYLeak_mark_malloced(*dest, strlen(*dest) + 1, cp_File, ssi_Line);
	return(*dest);
    } else {
	void * vp_realloced;
	ALp_old = FindInList(vp_oldAlloced);
	if (ALp_old == NULL) {
	    /*
	     *  Track the invalid pointer value and then exit.
	     *  If unable to allocate, just exit.
	     */
	    auto AllocationList *ALp_new = typecalloc(AllocationList);

	    if (ALp_new == NULL) {
		exit(EXIT_FAILURE);
	    }

	    /*
	     *  Set the information up; no need to allocate file name
	     *  since it is a static string.
	     */
	    ALp_new->vp_Alloced = NULL;
	    ALp_new->vp_BadRequest = vp_oldAlloced;
	    ALp_new->SL_realloc.cp_FileName = cp_File;
	    ALp_new->SL_realloc.ssi_LineNumber = ssi_Line;

	    /*
	     *  Add the item to the list.
	     *  Exit.
	     */
	    AddToList(ALp_new);
	    exit(EXIT_FAILURE);
	}

	old_cp_File = ALp_old->SL_memory.cp_FileName;
	old_ssi_Line = ALp_old->SL_memory.ssi_LineNumber;
	/*
	 *	DO THE REAL WORK, by calling StrAllocVsprintf.
	 *	If result is not NULL, record the information.
	 */
	StrAllocVsprintf(dest, inuse, fmt, ap);
	vp_realloced = (void *)*dest;
	if (vp_realloced != NULL) {
	    AllocationList *ALp_new = FindInList(vp_realloced);
	    if (!ALp_new) {
		/* Look up again, list may have changed! - kw */
		ALp_old = FindInList(vp_oldAlloced);
		if (ALp_old == NULL) {
		    LYLeak_mark_malloced(*dest, strlen(*dest) + 1, cp_File, ssi_Line);
		    return(*dest);
		}
		mark_realloced(ALp_old, *dest, strlen(*dest) + 1, cp_File, ssi_Line);
		return(*dest);
	    }
	    if (vp_realloced == vp_oldAlloced) {
		ALp_new->SL_memory.cp_FileName = old_cp_File;
		ALp_new->SL_memory.ssi_LineNumber = old_ssi_Line;
		ALp_new->SL_realloc.cp_FileName = cp_File;
		ALp_new->SL_realloc.ssi_LineNumber = ssi_Line;
		return(*dest);
	    }
	    /* Look up again, list may have changed! - kw */
	    ALp_old = FindInList(vp_oldAlloced);
	    if (ALp_old == NULL) {
		ALp_new->SL_memory.cp_FileName = old_cp_File;
		ALp_new->SL_memory.ssi_LineNumber = old_ssi_Line;
		ALp_new->SL_realloc.cp_FileName = cp_File;
		ALp_new->SL_realloc.ssi_LineNumber = ssi_Line;
	    } else {
		ALp_new->SL_memory.cp_FileName = old_cp_File;
		ALp_new->SL_memory.ssi_LineNumber = old_ssi_Line;
		ALp_new->SL_realloc.cp_FileName = cp_File;
		ALp_new->SL_realloc.ssi_LineNumber = ssi_Line;
	    }
	}
	return(*dest);
    }
}