--- capa/capa51/pProj/capaUnit.c 1999/09/28 21:26:21 1.1.1.1 +++ capa/capa51/pProj/capaUnit.c 2000/09/20 17:20:33 1.10 @@ -1,13 +1,37 @@ +/* functions to handle the unit parser/comparison engine + Copyright (C) 1992-2000 Michigan State University + + The CAPA system is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The CAPA system is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public + License along with the CAPA system; see the file COPYING. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + As a special exception, you have permission to link this program + with the TtH/TtM library and distribute executables, as long as you + follow the requirements of the GNU GPL in regard to all of the + software in the executable aside from TtH/TtM. +*/ /* =||>|===================== capaUnit.c =====================|<||= */ /* created by Isaac Tsai 1997 */ -/* copyrighted by Isaac Tsai 1997, 1998, 1999 */ +/* by Isaac Tsai 1997, 1998, 1999 */ /* =||>|========================================================|<||= */ #include /* fopen() */ #include #include /* isalnum() */ #include #include +#include #include "capaParser.h" @@ -632,6 +656,7 @@ postorder_utree(node_p) Unit_t *node_p; return (result); } +/* returns 1 on okay, 2 on error*/ int postwalk_utree(Unit_t *n_p) { @@ -640,25 +665,32 @@ postwalk_utree(Unit_t *n_p) if( n_p == NULL ) return (1); result = postwalk_utree(U_LEFT(n_p)); - if( result ) result = postwalk_utree(U_RIGHT(n_p)); - if( result ) { - switch(U_TYPE(n_p)) { - case U_DERIVED: Ptopidx++; Pstack[Ptopidx] = n_p; /* push into stack */ - break; - case U_CONSTANT: Ptopidx++; Pstack[Ptopidx] = n_p; /* push into stack */ - break; - case U_OP_POWER: printf("^"); - break; - case U_OP_TIMES: process_op(U_OP_TIMES); /* process operator */ - break; - case U_OP_PLUS: printf("+"); - break; - case U_OP_MINUS: printf("-"); - break; - case U_OP_DIVIDE: process_op(U_OP_DIVIDE); /* process operator */ - break; - default: printf("()"); - break; + if (result !=2) { + if( result ) result = postwalk_utree(U_RIGHT(n_p)); + if (result !=2) { + if( result ) { + switch(U_TYPE(n_p)) { + case U_DERIVED: Ptopidx++; Pstack[Ptopidx] = n_p; /* push into stack */ + break; + case U_CONSTANT: Ptopidx++; Pstack[Ptopidx] = n_p; /* push into stack */ + break; + case U_UNKNOWN: result=2; + /*push into stack anyway, try to parse rest of tree */ + break; + case U_OP_POWER: printf("^"); result=2; + break; + case U_OP_TIMES: process_op(U_OP_TIMES); /* process operator */ + break; + case U_OP_PLUS: printf("+"); result=2; + break; + case U_OP_MINUS: printf("-"); result=2; + break; + case U_OP_DIVIDE: process_op(U_OP_DIVIDE); /* process operator */ + break; + default: printf("()"); result=2; + break; + } + } } } return (result); @@ -727,30 +759,38 @@ int check_correct_unit(char *u_symb,Uni int result=UNIT_OK; #ifdef UNIT_DBUG - if ((ufp=fopen("unit.DBUG","a"))==NULL) { fprintf(stderr,"Error: can't open login debug\n"); return; } + if ((ufp=fopen("unit.DBUG","a"))==NULL) { fprintf(stderr,"Error: can't open login debug\n"); return UNIT_FAIL; } #endif - while( isspace(*u_symb) ) u_symb++; + while( isspace(*u_symb) ) u_symb++; + /* <= change this to search from the end of string */ + /* or to get rid of all the white spaces */ + + ap = parse_unit_expr(u_symb); Ptopidx=0; - postwalk_utree(ap); + + if (postwalk_utree(ap)==1) { #ifdef UNIT_DBUG - fprintf(ufp,"Ptopidx %d\n",Ptopidx); + fprintf(ufp,"Ptopidx %d\n",Ptopidx); #endif - if( Ptopidx == 1 ) { - simplify_unit(Pstack[Ptopidx]); - - if( (Pstack[Ptopidx]->u_count != 0) || - (Pstack[Ptopidx]->u_count == t->u_count) ) { /* has unit */ - *scale = units_ratio(Pstack[Ptopidx], t); - if( *scale == 0.0 ) { - result = UNIT_FAIL; + if( Ptopidx == 1 ) { + simplify_unit(Pstack[Ptopidx]); + + if( (Pstack[Ptopidx]->u_count != 0) || + (Pstack[Ptopidx]->u_count == t->u_count) ) { /* has unit */ + *scale = units_ratio(Pstack[Ptopidx], t); + if( *scale == 0.0 ) { + result = UNIT_FAIL; + } + free_utree(ap); + } else { + result = UNIT_FAIL; } - free_utree(ap); - } else { + } else { /* invalid unit representation */ result = UNIT_FAIL; } - } else { /* invalid unit representation */ + } else { result = UNIT_FAIL; } #ifdef UNIT_DBUG @@ -856,7 +896,7 @@ u_copy_unit(Unit_t *a_p, Unit_t *b_p, do a_p->u_scale = a_p->u_scale * scale; /* printf("Found scale=%g=%g\n",a_p->u_scale,b_p->u_scale); */ } else { - if( b_p->u_type == U_BASE || b_p->u_type == U_DERIVED) { + if( b_p->u_type == U_BASE ) { /* *b_p is a base unit, so create a one element unit */ ne_p = (Unit_E *) capa_malloc(1, sizeof(Unit_E)); /* *** */ ne_p->ue_scale = b_p->u_scale; @@ -870,6 +910,12 @@ u_copy_unit(Unit_t *a_p, Unit_t *b_p, do } last_p = ne_p; a_p->u_count++; + } else if( b_p->u_type == U_DERIVED) { + /* derived units but without any units elements (scalar) */ + /* do nothing, ignore this units WE REALLY MEAN THIS DON'T DO THE NEXT LINE!*/ + /*a_p->u_count++;*/ + scale = pow(b_p->u_scale, exp_scale); + a_p->u_scale = a_p->u_scale * scale; } else if( b_p->u_type == U_CONSTANT ) { scale = pow(b_p->u_scale, exp_scale); a_p->u_scale = a_p->u_scale * scale; @@ -1363,9 +1409,10 @@ u_insert_derived(n_p,s_p,c_p,u_p)char * strcpy(new_p->u_comment,c_p); simplify_unit(new_p); - - /* print_unit_t(new_p); */ - +#ifdef UNIT_DBUG + printf("Derived Unit:%s\n",new_p->u_name); + print_unit_t(new_p); +#endif if (c_result < 0 ) { new_p->u_left = t->u_left; new_p->u_right = t; t->u_left = NULL; @@ -1411,6 +1458,10 @@ simplify_unit(u_p) Unit_t *u_p; CScale[ii] = 0.0; CExp[ii] = 0.0; } + /* + printf("Before Simplify:: \n"); + print_unit_t(u_p); + */ if( u_p->u_count > 0 ) { for(eu_p=u_p->u_list; eu_p; eu_p = eu_p->ue_nextp) { @@ -1422,11 +1473,14 @@ simplify_unit(u_p) Unit_t *u_p; CScale[idx] = CScale[idx] * eu_p->ue_scale; CExp[idx] = CExp[idx] + eu_p->ue_exp; } - /* + /* debugging for(ii=0;iiu_list); @@ -1448,10 +1502,11 @@ simplify_unit(u_p) Unit_t *u_p; u_p->u_count++; } } - - } - + /* + printf("After Simplify:: \n"); + print_unit_t(u_p); + */ } /* before comparing two units, make sure they are of basic form */ @@ -1688,17 +1743,20 @@ p_new_unit(Unit_t *left_p, Unit_t *right } else { /* unit *tmp_str not found */ /* printf(" not found\n"); */ err_code = 3; + cu_p->u_type = U_UNKNOWN; } - } else { + } else { /* symb_str is not in form */ /* printf("<<%s>>", symb_str); */ err_code = 2; + cu_p->u_type = U_UNKNOWN; } } else {/* len == 1 */ - /* printf(" not found\n"); */ + /* printf(" not found in symbol tree \n"); */ err_code = 1; + cu_p->u_type = U_UNKNOWN; } } - } else { + } else { /* why would we have a length less than zero symb_str ? */ err_code = 4; }