- Fix for possible unset uid/gid in toproto
 - Fix for default mtree style
 - Update libelf
 - Importing libexecinfo
 - Resynchronize GCC, mpc, gmp, mpfr
 - build.sh: Replace params with show-params.
     This has been done as the make target has been renamed in the same
     way, while a new target named params has been added. This new
     target generates a file containing all the parameters, instead of
     printing it on the console.
 - Update test48 with new etc/services (Fix by Ben Gras <ben@minix3.org)
     get getservbyport() out of the inner loop
Change-Id: Ie6ad5226fa2621ff9f0dee8782ea48f9443d2091
		
	
			
		
			
				
	
	
		
			354 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			354 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*	$NetBSD: ifile.c,v 1.4 2013/09/04 19:44:21 tron Exp $	*/
 | 
						|
 | 
						|
/*
 | 
						|
 * Copyright (C) 1984-2012  Mark Nudelman
 | 
						|
 *
 | 
						|
 * You may distribute under the terms of either the GNU General Public
 | 
						|
 * License or the Less License, as specified in the README file.
 | 
						|
 *
 | 
						|
 * For more information, see the README file.
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
 * An IFILE represents an input file.
 | 
						|
 *
 | 
						|
 * It is actually a pointer to an ifile structure,
 | 
						|
 * but is opaque outside this module.
 | 
						|
 * Ifile structures are kept in a linked list in the order they 
 | 
						|
 * appear on the command line.
 | 
						|
 * Any new file which does not already appear in the list is
 | 
						|
 * inserted after the current file.
 | 
						|
 */
 | 
						|
 | 
						|
#include "less.h"
 | 
						|
 | 
						|
extern IFILE	curr_ifile;
 | 
						|
 | 
						|
struct ifile {
 | 
						|
	struct ifile *h_next;		/* Links for command line list */
 | 
						|
	struct ifile *h_prev;
 | 
						|
	char *h_filename;		/* Name of the file */
 | 
						|
	void *h_filestate;		/* File state (used in ch.c) */
 | 
						|
	int h_index;			/* Index within command line list */
 | 
						|
	int h_hold;			/* Hold count */
 | 
						|
	char h_opened;			/* Has this ifile been opened? */
 | 
						|
	struct scrpos h_scrpos;		/* Saved position within the file */
 | 
						|
};
 | 
						|
 | 
						|
/*
 | 
						|
 * Convert an IFILE (external representation)
 | 
						|
 * to a struct file (internal representation), and vice versa.
 | 
						|
 */
 | 
						|
#define int_ifile(h)	((struct ifile *)(h))
 | 
						|
#define ext_ifile(h)	((IFILE)(h))
 | 
						|
 | 
						|
/*
 | 
						|
 * Anchor for linked list.
 | 
						|
 */
 | 
						|
static struct ifile anchor = { &anchor, &anchor, NULL, NULL, 0, 0, '\0',
 | 
						|
				{ NULL_POSITION, 0 } };
 | 
						|
static int ifiles = 0;
 | 
						|
 | 
						|
static void incr_index __P((struct ifile *, int));
 | 
						|
static void link_ifile __P((struct ifile *, struct ifile *));
 | 
						|
static void unlink_ifile __P((struct ifile *));
 | 
						|
static struct ifile *new_ifile __P((char *, struct ifile *));
 | 
						|
static struct ifile *find_ifile __P((char *));
 | 
						|
 | 
						|
	static void
 | 
						|
incr_index(p, incr)
 | 
						|
	register struct ifile *p;
 | 
						|
	int incr;
 | 
						|
{
 | 
						|
	for (;  p != &anchor;  p = p->h_next)
 | 
						|
		p->h_index += incr;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Link an ifile into the ifile list.
 | 
						|
 */
 | 
						|
	static void
 | 
						|
link_ifile(p, prev)
 | 
						|
	struct ifile *p;
 | 
						|
	struct ifile *prev;
 | 
						|
{
 | 
						|
	/*
 | 
						|
	 * Link into list.
 | 
						|
	 */
 | 
						|
	if (prev == NULL)
 | 
						|
		prev = &anchor;
 | 
						|
	p->h_next = prev->h_next;
 | 
						|
	p->h_prev = prev;
 | 
						|
	prev->h_next->h_prev = p;
 | 
						|
	prev->h_next = p;
 | 
						|
	/*
 | 
						|
	 * Calculate index for the new one,
 | 
						|
	 * and adjust the indexes for subsequent ifiles in the list.
 | 
						|
	 */
 | 
						|
	p->h_index = prev->h_index + 1;
 | 
						|
	incr_index(p->h_next, 1);
 | 
						|
	ifiles++;
 | 
						|
}
 | 
						|
	
 | 
						|
/*
 | 
						|
 * Unlink an ifile from the ifile list.
 | 
						|
 */
 | 
						|
	static void
 | 
						|
unlink_ifile(p)
 | 
						|
	struct ifile *p;
 | 
						|
{
 | 
						|
	p->h_next->h_prev = p->h_prev;
 | 
						|
	p->h_prev->h_next = p->h_next;
 | 
						|
	incr_index(p->h_next, -1);
 | 
						|
	ifiles--;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Allocate a new ifile structure and stick a filename in it.
 | 
						|
 * It should go after "prev" in the list
 | 
						|
 * (or at the beginning of the list if "prev" is NULL).
 | 
						|
 * Return a pointer to the new ifile structure.
 | 
						|
 */
 | 
						|
	static struct ifile *
 | 
						|
new_ifile(filename, prev)
 | 
						|
	char *filename;
 | 
						|
	struct ifile *prev;
 | 
						|
{
 | 
						|
	register struct ifile *p;
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Allocate and initialize structure.
 | 
						|
	 */
 | 
						|
	p = (struct ifile *) ecalloc(1, sizeof(struct ifile));
 | 
						|
	p->h_filename = save(filename);
 | 
						|
	p->h_scrpos.pos = NULL_POSITION;
 | 
						|
	p->h_opened = 0;
 | 
						|
	p->h_hold = 0;
 | 
						|
	p->h_filestate = NULL;
 | 
						|
	link_ifile(p, prev);
 | 
						|
	return (p);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Delete an existing ifile structure.
 | 
						|
 */
 | 
						|
	public void
 | 
						|
del_ifile(h)
 | 
						|
	IFILE h;
 | 
						|
{
 | 
						|
	register struct ifile *p;
 | 
						|
 | 
						|
	if (h == NULL_IFILE)
 | 
						|
		return;
 | 
						|
	/*
 | 
						|
	 * If the ifile we're deleting is the currently open ifile,
 | 
						|
	 * move off it.
 | 
						|
	 */
 | 
						|
	unmark(h);
 | 
						|
	if (h == curr_ifile)
 | 
						|
		curr_ifile = getoff_ifile(curr_ifile);
 | 
						|
	p = int_ifile(h);
 | 
						|
	unlink_ifile(p);
 | 
						|
	free(p->h_filename);
 | 
						|
	free(p);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Get the ifile after a given one in the list.
 | 
						|
 */
 | 
						|
	public IFILE
 | 
						|
next_ifile(h)
 | 
						|
	IFILE h;
 | 
						|
{
 | 
						|
	register struct ifile *p;
 | 
						|
 | 
						|
	p = (h == NULL_IFILE) ? &anchor : int_ifile(h);
 | 
						|
	if (p->h_next == &anchor)
 | 
						|
		return (NULL_IFILE);
 | 
						|
	return (ext_ifile(p->h_next));
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Get the ifile before a given one in the list.
 | 
						|
 */
 | 
						|
	public IFILE
 | 
						|
prev_ifile(h)
 | 
						|
	IFILE h;
 | 
						|
{
 | 
						|
	register struct ifile *p;
 | 
						|
 | 
						|
	p = (h == NULL_IFILE) ? &anchor : int_ifile(h);
 | 
						|
	if (p->h_prev == &anchor)
 | 
						|
		return (NULL_IFILE);
 | 
						|
	return (ext_ifile(p->h_prev));
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return a different ifile from the given one.
 | 
						|
 */
 | 
						|
	public IFILE
 | 
						|
getoff_ifile(ifile)
 | 
						|
	IFILE ifile;
 | 
						|
{
 | 
						|
	IFILE newifile;
 | 
						|
	
 | 
						|
	if ((newifile = prev_ifile(ifile)) != NULL_IFILE)
 | 
						|
		return (newifile);
 | 
						|
	if ((newifile = next_ifile(ifile)) != NULL_IFILE)
 | 
						|
		return (newifile);
 | 
						|
	return (NULL_IFILE);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return the number of ifiles.
 | 
						|
 */
 | 
						|
	public int
 | 
						|
nifile()
 | 
						|
{
 | 
						|
	return (ifiles);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Find an ifile structure, given a filename.
 | 
						|
 */
 | 
						|
	static struct ifile *
 | 
						|
find_ifile(filename)
 | 
						|
	char *filename;
 | 
						|
{
 | 
						|
	register struct ifile *p;
 | 
						|
 | 
						|
	for (p = anchor.h_next;  p != &anchor;  p = p->h_next)
 | 
						|
		if (strcmp(filename, p->h_filename) == 0)
 | 
						|
			return (p);
 | 
						|
	return (NULL);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Get the ifile associated with a filename.
 | 
						|
 * If the filename has not been seen before,
 | 
						|
 * insert the new ifile after "prev" in the list.
 | 
						|
 */
 | 
						|
	public IFILE
 | 
						|
get_ifile(filename, prev)
 | 
						|
	char *filename;
 | 
						|
	IFILE prev;
 | 
						|
{
 | 
						|
	register struct ifile *p;
 | 
						|
 | 
						|
	if ((p = find_ifile(filename)) == NULL)
 | 
						|
		p = new_ifile(filename, int_ifile(prev));
 | 
						|
	return (ext_ifile(p));
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Get the filename associated with a ifile.
 | 
						|
 */
 | 
						|
	public char *
 | 
						|
get_filename(ifile)
 | 
						|
	IFILE ifile;
 | 
						|
{
 | 
						|
	if (ifile == NULL)
 | 
						|
		return (NULL);
 | 
						|
	return (int_ifile(ifile)->h_filename);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Get the index of the file associated with a ifile.
 | 
						|
 */
 | 
						|
	public int
 | 
						|
get_index(ifile)
 | 
						|
	IFILE ifile;
 | 
						|
{
 | 
						|
	return (int_ifile(ifile)->h_index); 
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Save the file position to be associated with a given file.
 | 
						|
 */
 | 
						|
	public void
 | 
						|
store_pos(ifile, scrpos)
 | 
						|
	IFILE ifile;
 | 
						|
	struct scrpos *scrpos;
 | 
						|
{
 | 
						|
	int_ifile(ifile)->h_scrpos = *scrpos;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Recall the file position associated with a file.
 | 
						|
 * If no position has been associated with the file, return NULL_POSITION.
 | 
						|
 */
 | 
						|
	public void
 | 
						|
get_pos(ifile, scrpos)
 | 
						|
	IFILE ifile;
 | 
						|
	struct scrpos *scrpos;
 | 
						|
{
 | 
						|
	*scrpos = int_ifile(ifile)->h_scrpos;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Mark the ifile as "opened".
 | 
						|
 */
 | 
						|
	public void
 | 
						|
set_open(ifile)
 | 
						|
	IFILE ifile;
 | 
						|
{
 | 
						|
	int_ifile(ifile)->h_opened = 1;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return whether the ifile has been opened previously.
 | 
						|
 */
 | 
						|
	public int
 | 
						|
opened(ifile)
 | 
						|
	IFILE ifile;
 | 
						|
{
 | 
						|
	return (int_ifile(ifile)->h_opened);
 | 
						|
}
 | 
						|
 | 
						|
	public void
 | 
						|
hold_ifile(ifile, incr)
 | 
						|
	IFILE ifile;
 | 
						|
	int incr;
 | 
						|
{
 | 
						|
	int_ifile(ifile)->h_hold += incr;
 | 
						|
}
 | 
						|
 | 
						|
	public int
 | 
						|
held_ifile(ifile)
 | 
						|
	IFILE ifile;
 | 
						|
{
 | 
						|
	return (int_ifile(ifile)->h_hold);
 | 
						|
}
 | 
						|
 | 
						|
	public void *
 | 
						|
get_filestate(ifile)
 | 
						|
	IFILE ifile;
 | 
						|
{
 | 
						|
	return (int_ifile(ifile)->h_filestate);
 | 
						|
}
 | 
						|
 | 
						|
	public void
 | 
						|
set_filestate(ifile, filestate)
 | 
						|
	IFILE ifile;
 | 
						|
	void *filestate;
 | 
						|
{
 | 
						|
	int_ifile(ifile)->h_filestate = filestate;
 | 
						|
}
 | 
						|
 | 
						|
#if 0
 | 
						|
	public void
 | 
						|
if_dump()
 | 
						|
{
 | 
						|
	register struct ifile *p;
 | 
						|
 | 
						|
	for (p = anchor.h_next;  p != &anchor;  p = p->h_next)
 | 
						|
	{
 | 
						|
		printf("%x: %d. <%s> pos %d,%x\n", 
 | 
						|
			p, p->h_index, p->h_filename, 
 | 
						|
			p->h_scrpos.ln, p->h_scrpos.pos);
 | 
						|
		ch_dump(p->h_filestate);
 | 
						|
	}
 | 
						|
}
 | 
						|
#endif
 |