Wed, 19 Apr 2000 22:03:38 +0200
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"