[comp.unix.questions] "Error" in libPW

guy@gorodish.Sun.COM (Guy Harris) (06/08/88)

> The problem is that almost none of libPW seems to be documented.
> The only routines I've found with documentation are the regular
> expression routines (regcmp(3X)), and this manual page only mentions
> libPW in passing.
> 
> Does anyone know if there is other documentation available for this
> stuff?

I think libPW is considered obsolete cruft; I have never seen any AT&T
documentation for it in any (generally distributed) release subsequent to
PWB/UNIX 1.0.  The regular expression stuff is definitely cruft; use <regexp.h>
instead (it's what the S5 "ed", "sed", "grep", and "pg" use).

gwyn@brl-smoke.ARPA (Doug Gwyn ) (06/09/88)

In article <2319@quacky.mips.COM> dce@mips.COM (David Elliott) writes:
>One of the programmers here was using the regular expression stuff
>in libPW ...

This doesn't directly answer your specific question, but:
libPW exists merely to support old code from PWB/UNIX.
It should NOT be used for new applications!
In particular, use the regexp(5) stuff for regular expressions.
If you need a BSD-like interface, try something like the
following (taken from the BRL Bourne shell; you need to use
"cc -DHISTORY" when compiling):

#!/bin/sh
# Self-unpacking archive format.  To unbundle, sh this file.
echo 'regex.c' 1>&2
cat >'regex.c' <<'END OF regex.c'
/*
	BSD-style regular expression interface for UNIX System V shell

	last edit:	04-Nov-1987	D A Gwyn
*/

#if !defined(HISTORY) || defined(BSD)
#ifndef lint
char	regex_dummy;      /* some systems can't handle empty object modules */
#endif
#else

extern struct re_msg
	{
	int	number;
	char	*message;
	}	re_msgtab[];

static char	*re_err;		/* sneak path to error string */

/*	Handle error from <regexp.h>	*/

static void
re_error( n )
	register int		n;	/* error number */
	{
	register struct re_msg	*mp;

	for ( mp = re_msgtab; mp->number > 0; ++mp )
		if ( mp->number == n )
			break;

	re_err = mp->message;
	}

/* macros for <regexp.h> */
#define INIT		register char	*re_str = instring;
#define GETC()		(*re_str == '\0' ? '\0' : (int)*re_str++)
#define UNGETC( c )	--re_str
#define PEEKC()		((int)*re_str)
#define RETURN( c )	return (char *)0
#define ERROR( n )	re_error( n )

/* following for safety's sake */
#define	sed	re_sed
#define	nbra	re_nbra
#define	loc1	re_loc1
#define	loc2	re_loc2
#define	locs	re_locs
#define	circf	re_circf
#define	compile	re_cmpl			/* avoid truncated name collision! */
#define	step	re_step
#define	advance	re_advance

#include	<regexp.h>

#define	ESIZE	512
static char	re_buf[ESIZE];		/* compiled r.e. */

/*	Compile regular expression	*/

char	*
re_comp( s )				/* returns 0 or ptr to error message */
	char	*s;
	{
	re_err = (char *)0;

	if ( s != (char *)0 && *s != '\0' )
		(void)compile( s, re_buf, &re_buf[ESIZE], '\0' );
	else if ( re_buf[0] == '\0' )
		ERROR( 41 );		/* no remembered search string */
	/* else use remembered search string from previous call */

	return re_err;
	}

/*	Test for match against compiled expression	*/

int
re_exec( s )				/* returns 1 if s matches, else 0 */
	char	*s;
	{
	locs = 0;			/* ??? */
	return step( s, re_buf );
	}
#endif
END OF regex.c
echo 'redata.c' 1>&2
cat >'redata.c' <<'END OF redata.c'
/*
	messages for BSD-style regular expression interface for UNIX System V shell

	last edit:	04-Nov-1987	D A Gwyn
*/

#if !defined(HISTORY) || defined(BSD)
#ifndef lint
char	redata_dummy;      /* some systems can't handle empty object modules */
#endif
#else

struct	{
	int	number;
	char	*message;
	}	re_msgtab[] =
	{
	{	11,	"range endpoint too large"	},
	{	16,	"bad number"	},
	{	25,	"`\\digit' out of range"	},
	{	35,	"no match"	},
	{	36,	"illegal or missing delimiter"	},
	{	41,	"no remembered search string"	},
	{	42,	"'\\( \\)' imbalance"	},
	{	43,	"too many `\\(' s"	},
	{	44,	"more than 2 numbers given"	},
	{	45,	"'\\}' expected"	},
	{	46,	"first number exceeds second"	},
	{	49,	"'[ ]' imbalance"	},
	{	50,	"regular expression overflow"	},
	{	51,	"regular expression error"	},
	{	0,	"unknown r.e. error"	}
	};

#endif
END OF redata.c