trunk: changeset 6

Wed, 19 Apr 2000 22:03:38 +0200

author
tuomov
date
Wed, 19 Apr 2000 22:03:38 +0200
changeset 3
b1fbfab67908
parent 2
e14a1aba4c56
child 4
ee28b655297b

trunk: changeset 6
- Simpler optparser

- New Makefile system

Makefile file | annotate | diff | comparison | revisions
README file | annotate | diff | comparison | revisions
misc.c file | annotate | diff | comparison | revisions
np-conv.h file | annotate | diff | comparison | revisions
numparser2.h file | annotate | diff | comparison | revisions
optparser.c file | annotate | diff | comparison | revisions
tester3.c file | annotate | diff | comparison | revisions
tokenizer.c file | annotate | diff | comparison | revisions
--- a/Makefile	Wed Feb 23 08:47:59 2000 +0100
+++ b/Makefile	Wed Apr 19 22:03:38 2000 +0200
@@ -1,38 +1,13 @@
-#
-# libtu Makefile
-#
-
-# Where to install? ($PREFIX/lib/libtu.a, $PREFIX/include/libtu/)
-#
-PREFIX=/usr/local
-
-# Any extra defines needed
-#
-#DEFINES=
+##
+## libtu Makefile
+##
 
-# Any extra include paths needed
-#
-#INCLUDES=
-
-######################################
-
-WARN=	-W -Wimplicit -Wreturn-type -Wswitch -Wcomment \
-	-Wtrigraphs -Wformat -Wchar-subscripts -Wuninitialized \
-	-Wparentheses -pedantic-errors
-
-CC_FLAGS=-g -O2 -ansi $(DEFINES) $(INCLUDES) $(WARN)
-CC=gcc
-AR=ar
-AR_FLAGS=crs
-
-INSTALL=install
-MODE=644
+# System-specific configuration is in system.mk
+include system.mk
 
 ######################################
 
 OBJS= misc.o output.o util.o optparser.o parser.o tokenizer.o
-	
-DEPEND= .depend
 
 LIBDIR=$(PREFIX)/lib
 INCDIR=$(PREFIX)/include/libtu
@@ -42,7 +17,9 @@
 
 ######################################
 
-all: $(TARGETS)
+include rules.mk
+
+######################################
 
 testers: $(TESTERS)
 
@@ -52,24 +29,9 @@
 %: %.c libtu.a
 	$(CC) $(CC_FLAGS) $+ -L. -ltu -lm -o $@
 
-%.o: %.c
-	$(CC) $(CC_FLAGS) -c $< -o $@
-
-clean:
-	rm -f $(OBJS) $(DEPEND)
-
-realclean: clean
-	rm -f $(TARGETS)
-
-depend:
-	$(CC) -M $(CC_FLAGS) *.c > $(DEPEND)
-
-install:
+_install:
 	$(INSTALL) -d $(LIBDIR)
 	$(INSTALL) -d $(INCDIR)
-	$(INSTALL) -m $(MODE) libtu.a $(LIBDIR)
-	$(INSTALL) -m $(MODE) include/* $(INCDIR)
+	$(INSTALL) -m $(DATA_MODE) libtu.a $(LIBDIR)
+	$(INSTALL) -m $(DATA_MODE) include/*.h $(INCDIR)
 
-ifeq ($(DEPEND),$(wildcard $(DEPEND)))
-include $(DEPEND)
-endif
--- a/README	Wed Feb 23 08:47:59 2000 +0100
+++ b/README	Wed Apr 19 22:03:38 2000 +0200
@@ -12,7 +12,7 @@
 libtu is free software under the "Artistic License". See the file
 LICENSE for details.
 
-To build the library, first edit Makefile to customize it for your
+To build the library, first edit system.mk to customize it for your
 system if necessary. Then 'make depend && make'.
 To install it run 'make install' (perhaps as root depending on
 where you are installing it).
--- a/misc.c	Wed Feb 23 08:47:59 2000 +0100
+++ b/misc.c	Wed Apr 19 22:03:38 2000 +0200
@@ -10,7 +10,6 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include <malloc.h>
 
 #include "include/misc.h"
 
--- a/np-conv.h	Wed Feb 23 08:47:59 2000 +0100
+++ b/np-conv.h	Wed Apr 19 22:03:38 2000 +0200
@@ -9,6 +9,52 @@
 
 #include <math.h>
 
+#ifdef NP_SIMPLE_IMPL
+
+#define FN_NUM_TO_SIGNED(T, UMAX, MAX, MIN)                          \
+ static int num_to_##T(T *ret, const NPNum *num, bool allow_uns_big) \
+ {                                                                   \
+	if(num->type!=NPNUM_INT)                                         \
+		return E_TOKZ_NOTINT;                                        \
+	                                                                 \
+	if(!num->negative){                                              \
+		*ret=num->ival;                                              \
+		if(allow_uns_big?num->ival>UMAX:num->ival>MAX)               \
+		return E_TOKZ_RANGE;                                         \
+	}else{                                                           \
+		*ret=-num->ival;                                             \
+		if(num->ival>-(ulong)MIN)                                    \
+		return E_TOKZ_RANGE;                                         \
+	}                                                                \
+	return 0;                                                        \
+ }
+
+#define FN_NUM_TO_UNSIGNED(T, UMAX, MIN)                         \
+ static int num_to_##T(T *ret, const NPNum *num, bool allow_neg) \
+ {                                                               \
+	if(num->type!=NPNUM_INT)                                     \
+		return E_TOKZ_NOTINT;                                    \
+	                                                             \
+	if(!num->negative){                                          \
+		*ret=num->ival;                                          \
+		if(num->ival>UMAX)                                       \
+		return E_TOKZ_RANGE;                                     \
+	}else{                                                       \
+		*ret=-num->ival;                                         \
+		if(!allow_neg || num->ival>(ulong)-MIN)                  \
+		return E_TOKZ_RANGE;                                     \
+	}                                                            \
+	return 0;                                                    \
+ }
+
+#define FN_NUM_TO_FLOAT(T, POW)                  \
+ static int num_to_##T(T *ret, const NPNum *num) \
+ {                                               \
+	*ret=(num->negative?-num->fval:num->fval);   \
+	return 0;                                    \
+ }
+
+#else /* NP_SIMPLE_IMPL */
 
 #define FN_NUM_TO_SIGNED(T, UMAX, MAX, MIN)                          \
  static int num_to_##T(T *ret, const NPNum *num, bool allow_uns_big) \
@@ -60,12 +106,14 @@
 	for(i=num->nmantissa;i>=0;i--)               \
 		d=d*(T)(ULONG_MAX+1.0)+num->mantissa[i]; \
                                                  \
-	d*=POW(10, num->exponent);                   \
+	d*=POW(num->base, num->exponent);            \
 	*ret=d;                                      \
 	                                             \
 	return 0;                                    \
  }
 
+#endif /* NP_SIMPLE_IMPL */
+
 FN_NUM_TO_SIGNED(long, ULONG_MAX, LONG_MAX, LONG_MIN)
 FN_NUM_TO_SIGNED(char, UCHAR_MAX, CHAR_MAX, CHAR_MIN)
 FN_NUM_TO_FLOAT(double, pow)
--- a/numparser2.h	Wed Feb 23 08:47:59 2000 +0100
+++ b/numparser2.h	Wed Apr 19 22:03:38 2000 +0200
@@ -10,17 +10,41 @@
 #define MAX_MANTISSA 10  /* should be enough for our needs */
 #define ULONG_SIZE (sizeof(ulong)*8)
 
-/*
- * Can handle quite big numbers (depends on MAX_MANTISSA). This is really
- * a crappy little hack (especially the generic (non-i386asm) mulby10
- * algorithm... hopefully it works...) but this'll do for now.
- */
-
 enum{
 	NPNUM_INT,
 	NPNUM_FLOAT
 };
 
+#ifdef NP_SIMPLE_IMPL
+
+typedef struct _NPNum{
+	int type;
+	int base;
+ 	bool negative;
+	long double fval;
+	ulong ival;
+} NPNum;
+
+#define NUM_INIT {0, 0, 0, 0.0, 0}
+
+static int npnum_mulbase_add(NPNum *num, long base, long v)
+{
+	long double iold=num->ival;
+	
+	num->fval=num->fval*base+(long double)v;
+	
+	num->ival*=base;
+	
+	if(num->ival<iold)
+		num->type=NPNUM_FLOAT;
+	
+	num->ival+=v;
+	
+	return 0;
+}
+
+#else /* NP_SIMPLE_IMPL */
+
 typedef struct _NPNum{
 	unsigned char nmantissa;
 	int type;
@@ -34,20 +58,20 @@
 
 #define ADD_EXP(NUM, X) (NUM)->exponent+=(X);
 
-#if defined(__GNUG__) && defined(i386) && !defined(LIBTU_NP_NO_I386_ASM)
- #define LIBTU_NP_I386_ASM
+#if defined(__GNUG__) && defined(i386) && !defined(NP_NO_I386_ASM)
+ #define NP_I386_ASM
 #endif
 
 static int npnum_mulbase_add(NPNum *num, long base, long v)
 {
 	long i, j;
 	ulong overflow;
-#ifndef LIBTU_NP_I386_ASM
+#ifndef NP_I386_ASM
 	ulong val;
 #endif
 	
 	for(i=num->nmantissa;i>=0;i--){
-#ifdef LIBTU_NP_I386_ASM
+#ifdef NP_I386_ASM
 		__asm__("mul %4\n"
 				: "=a" (num->mantissa[i]), "=d" (overflow)
 				: "0" (num->mantissa[i]), "1" (0), "q" (base)
@@ -84,7 +108,9 @@
 	return 0;
 }
 
-#undef LIBTU_NP_I386_ASM
+#undef NP_I386_ASM
+
+#endif /* NP_SIMPLE_IMPL */
 
 
 /* */
@@ -128,9 +154,12 @@
 
 	if(neg)
 		exp*=-1;
-	
+
+#ifndef NP_SIMPLE_IMPL
 	ADD_EXP(num, exp);
-	
+#else
+	num->fval*=pow(num->base, exp);
+#endif	
 	return err;
 }
 
@@ -141,14 +170,19 @@
 	int dm=1;
 	int err=0;
 	int tmp;
-
+#ifdef NP_SIMPLE_IMPL
+	long double divisor=base;
+#endif	
+	
 	if(c=='-' || c=='+'){
 		if(c=='-')
 			num->negative=TRUE;
 		c=GETCH();
 		if(!isdigit(c))
 			err=E_TOKZ_NUMFMT;
-	}else if(c=='0'){
+	}
+	
+	if(c=='0'){
 		dm=0;
 		c=GETCH();
 		if(c=='x' || c=='X'){
@@ -158,7 +192,7 @@
 			base=2;
 			c=GETCH();
 		}else if('0'<=c && c<='7'){
-			base=7;
+			base=8;
 		}else{
 			dm=2;
 		}
@@ -188,24 +222,37 @@
 			
 			if(c>=base)
 				err=E_TOKZ_NUMFMT;
-			
-			tmp=npnum_mulbase_add(num, base, c);
-			if(err==0)
-				err=tmp;
+
+#ifdef NP_SIMPLE_IMPL
+			if(dm==3){
+				num->fval+=(long double)c/divisor;
+				divisor*=base;
+			}else
+#endif
+			{
+				tmp=npnum_mulbase_add(num, base, c);
+				if(err==0)
+					err=tmp;
+			}
 			
 			if(dm==1)
 				dm=2;
+#ifndef NP_SIMPLE_IMPL			
 			else if(dm==3)
 				ADD_EXP(num, -1);
-			
+#endif			
 			continue;
 		}
 		
 		if(c=='.'){
-			if(dm!=2)
+			if(dm!=2){
 				err=E_TOKZ_NUMFMT;
-			else
-				dm=3;
+			}
+			dm=3;
+#ifdef NP_SIMPLE_IMPL
+			num->type=NPNUM_FLOAT;
+			divisor=base;
+#endif
 			continue;
 		}
 		
@@ -217,7 +264,9 @@
 		err=E_TOKZ_NUMFMT;
 	}
 	
+#ifndef NP_SIMPLE_IMPL			
 	num->type=(num->exponent==0 ? NPNUM_INT : NPNUM_FLOAT);
-	
+#endif
+
 	return err;
 }
--- a/optparser.c	Wed Feb 23 08:47:59 2000 +0100
+++ b/optparser.c	Wed Apr 19 22:03:38 2000 +0200
@@ -16,11 +16,6 @@
 #include "include/output.h"
 
 
-#define O_CHAINABLE(o)	(o->flags&OPT_CHAINABLE)
-#define O_IMM_ARG(o)	(o->flags&OPT__IMM_ARG)
-#define O_NO_DASH(o)	(o->flags&OPT_NO_DASH)
-#define O_MIDLONG(o)	(o->flags&OPT_MIDLONG)
-#define O_NO_LONG(o)	(o->flags&OPT_NO_LONG)
 #define O_ARGS(o)		(o->flags&OPT_OPT_ARG)
 #define O_ARG(o)		(o->flasg&OPT_ARG)
 #define O_OPT_ARG(o)	(O_ARGS(o)==OPT_OPT_ARG)
@@ -34,13 +29,16 @@
 static int o_args_left=0;
 static const char*o_tmp=NULL;
 static int o_error=0;
+static int o_mode=OPTP_CHAIN;
 
 
 /* */
 
 
-void optparser_init(int argc, char *const argv[], const OptParserOpt *opts)
+void optparser_init(int argc, char *const argv[], int mode,
+					const OptParserOpt *opts)
 {
+	o_mode=mode;
 	o_opts=opts;
 	o_current=argv+1;
 	o_left=argc-1;
@@ -56,14 +54,14 @@
 static const OptParserOpt *find_chain_opt(char p, const OptParserOpt *o)
 {
 	for(;O_ID(o);o++){
-		if(O_CHAINABLE(o) && O_ID(o)==p)
+		if(O_ID(o)==p)
 			return o;
 	}
 	return NULL;
 }
 
 
-static bool valid_chain(const char *p, const OptParserOpt *o)
+/*static bool valid_chain(const char *p, const OptParserOpt *o)
 {
 	while(*p!='\0'){
 		if(!find_chain_opt(*p, o))
@@ -71,7 +69,7 @@
 		p++;
 	}
 	return TRUE;
-}
+}*/
 	
 
 static bool is_option(const char *p)
@@ -90,12 +88,17 @@
 
 /* */
 
+enum{
+	SHORT, MIDLONG, LONG
+};
+
 
 int optparser_get_opt()
 {
 #define RET(X) return o_tmp=p, o_error=X
 	const char *p, *p2=NULL;
-	bool lo=FALSE, dash=TRUE;
+	bool dash=TRUE;
+	int type=SHORT;
 	const OptParserOpt *o;
 	int l;
 
@@ -104,7 +107,7 @@
 
 	o_tmp=NULL;
 
-	/* Are we doing a chain (i.e. opt. of style 'tar xzf') ? */
+	/* Are we doing a chain (i.e. opt. of style 'tar xzf')? */
 	if(o_chain_ptr!=NULL){
 		p=o_chain_ptr++;
 		if(!*o_chain_ptr)
@@ -125,16 +128,21 @@
 	p=*o_current++;
 	
 	if(*p!='-'){
-		/* foo */
 		dash=FALSE;
+		if(o_mode!=OPTP_NO_DASH)
+			RET(OPT_ID_ARGUMENT);
 	}else if(*(p+1)=='-'){
 		/* --foo */
 		if(*(p+2)=='\0'){
-			/* -- */
+			/* -- arguments */
 			o_args_left=o_left;
 			RET(OPT_ID_ARGUMENT);
 		}
-		lo=TRUE;
+		/*argptr=strchr(p, '=');
+		if(argptr!=NULL)
+			argptr++;
+		*/
+		type=LONG;
 		p2=p+2;
 	}else{
 		/* -foo */
@@ -143,6 +151,9 @@
 			o_args_left=1;
 			RET(OPT_ID_ARGUMENT);
 		}
+		if(*(p+2)!='\0' && o_mode==OPTP_MIDLONG)
+			type=MIDLONG;
+	
 		p2=p+1;
 	}
 
@@ -150,7 +161,7 @@
 
 again:
 	for(;O_ID(o);o++){
-		if(lo){
+		if(type==LONG){
 			/* Do long option (--foo=bar) */
 			if(o->longopt==NULL)
 				continue;
@@ -158,9 +169,6 @@
 			if(strncmp(p2, o->longopt, l)!=0)
 				continue;
 			
-			if(O_NO_LONG(o))
-				RET(E_OPT_INVALID_OPTION);
-
 			if(p2[l]=='\0'){
 				if(O_ARGS(o)==OPT_ARG)
 					 RET(E_OPT_MISSING_ARGUMENT);
@@ -174,44 +182,52 @@
 				o_args_left=1;
 				return O_ID(o);
 			}
-		}else{
-			/* Do midlong option (-foobar) */
-			if(dash && o->longopt!=NULL && strcmp(p2, o->longopt)==0){
-				if(!O_MIDLONG(o))
-					 RET(E_OPT_INVALID_OPTION);
-				goto do_arg;
-			}
-	
-			/* Do short option (-f) */
-			if((!dash && !O_NO_DASH(o)) || *p2!=O_ID(o))
+			continue;
+		}else if(type==MIDLONG){
+			if(o->longopt==NULL)
+				continue;
+			
+			if(strcmp(p2, o->longopt)!=0)
+				continue;
+		}else{ /* type==SHORT */
+			if(*p2!=O_ID(o))
 				continue;
 			   
 			if(*(p2+1)!='\0'){
-				if(O_CHAINABLE(o) && valid_chain(p2+1, o_opts)){
-					 o_chain_ptr=p2+1;
-				}else if(O_IMM_ARG(o)){
-					 o_tmp=p2+1;
-					 o_args_left=1;
-					 return O_ID(o);
+				if(o_mode==OPTP_CHAIN || o_mode==OPTP_NO_DASH){
+					/*valid_chain(p2+1, o_opts)*/
+					o_chain_ptr=p2+1;
+					p++;
+				}else if(o_mode==OPTP_IMMEDIATE){
+					if(!O_ARGS(o)){
+						if(*(p2+1)!='\0')
+							RET(E_OPT_UNEXPECTED_ARGUMENT);
+					}else{
+						if(*(p2+1)=='\0')
+							RET(E_OPT_MISSING_ARGUMENT);
+						o_tmp=p2+1;
+						o_args_left=1;
+					}
+					return O_ID(o);
 				}else{
-					 continue;
+					RET(E_OPT_SYNTAX_ERROR);
 				}
 			}
-do_arg:
-			if(!O_ARGS(o))
+		}
+		
+	do_arg:
+		
+		if(!O_ARGS(o))
+			return O_ID(o);
+		
+		if(!o_left || is_option(*o_current)){
+			if(O_ARGS(o)==OPT_OPT_ARG)
 				return O_ID(o);
-			   
-			if(O_ARGS(o)==OPT_ARG){
-				if(o_left==0)
-					 RET(E_OPT_MISSING_ARGUMENT);
-			}else{
-				if(!o_left || is_option(*o_current))
-					 return O_ID(o);
-			}
+			RET(E_OPT_MISSING_ARGUMENT);
+		}
 
-			o_args_left=1;
-			return O_ID(o);
-		}
+		o_args_left=1;
+		return O_ID(o);
 	}
 
 	if(dash)
@@ -254,7 +270,7 @@
 
 static void warn_arg(const char *e)
 {
-	const char*p=optparser_get_arg();
+	const char *p=optparser_get_arg();
 	
 	if(p==NULL)
 		warn("%s (null)", e);
@@ -265,7 +281,7 @@
 
 static void warn_opt(const char *e)
 {
-	if(o_chain_ptr!=NULL && o_tmp!=NULL)
+	if(o_tmp!=NULL && o_chain_ptr!=NULL)
 		warn("%s \'-%c\'", e, *o_tmp);
 	else
 		warn_arg(e);
@@ -276,13 +292,10 @@
 {
 	switch(o_error){
 	case E_OPT_INVALID_OPTION:
+	case E_OPT_INVALID_CHAIN_OPTION:
 		warn_opt(TR("Invalid option"));
 		break;
 
-	case E_OPT_INVALID_CHAIN_OPTION:
-		warn_opt(TR("Invalid option in chain (this cannot happen)"));
-		break;		
-
 	case E_OPT_SYNTAX_ERROR:
 		warn_arg(TR("Syntax error while parsing"));
 		break;
@@ -292,7 +305,7 @@
 		break;
 
 	case E_OPT_UNEXPECTED_ARGUMENT:
-		warn_opt(TR("No argument expected to"));
+		warn_opt(TR("No argument expected:"));
 		break;
 		
 	case OPT_ID_ARGUMENT:
--- a/tester3.c	Wed Feb 23 08:47:59 2000 +0100
+++ b/tester3.c	Wed Apr 19 22:03:38 2000 +0200
@@ -33,11 +33,11 @@
 
 
 static OptParserOpt opts[]={
-	{'o',	"opt",		OPT_IMM_ARG},
-	{'f',	"file",		OPT_CHAINABLE|OPT_NO_DASH|OPT_ARG},
-	{'v',	"view",		OPT_CHAINABLE|OPT_NO_DASH},
-	{'z',	"zip",		OPT_CHAINABLE|OPT_NO_DASH},
-	{'x',	"extract",	OPT_CHAINABLE|OPT_NO_DASH},
+	{'o',	"opt",		OPT_ARG},
+	{'f',	"file",		OPT_ARG},
+	{'v',	"view",		0},
+	{'z',	"zip",		0},
+	{'x',	"extract",	0},
 	{0, NULL, 0}
 };
 	
@@ -48,7 +48,7 @@
 	
 	libtu_init(&argc, argv, &proginfo);
 	
-	optparser_init(argc, argv, opts);
+	optparser_init(argc, argv, OPTP_NO_DASH, opts);
 	
 	while((opt=optparser_get_opt())){
 		switch(opt){
--- a/tokenizer.c	Wed Feb 23 08:47:59 2000 +0100
+++ b/tokenizer.c	Wed Apr 19 22:03:38 2000 +0200
@@ -10,7 +10,6 @@
 #include <errno.h>
 #include <stdio.h>
 #include <ctype.h>
-#include <malloc.h>
 #include <limits.h>
 #include <assert.h>
 #include <math.h>
@@ -418,7 +417,7 @@
 	return 0;
 }
 
-
+#define NP_SIMPLE_IMPL
 #include "numparser2.h"
 #include "np-conv.h"
 

mercurial