[Mybusinessbasic-devel] mybb functions.c,1.2,1.3
Status: Alpha
Brought to you by:
mikecurry1974
From: <mti...@us...> - 2003-12-31 17:36:05
|
Update of /cvsroot/mybusinessbasic/mybb In directory sc8-pr-cvs1:/tmp/cvs-serv30443 Modified Files: functions.c Log Message: added ITR() function and also reworked RTI() Index: functions.c =================================================================== RCS file: /cvsroot/mybusinessbasic/mybb/functions.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** functions.c 20 Dec 2003 13:08:23 -0000 1.2 --- functions.c 31 Dec 2003 17:36:01 -0000 1.3 *************** *** 45,67 **** int fnc_err(statement *stmt, int start); int fnc_tcb(int num); ! long fnc_rti(const char *str); struct utsname Uname; - struct numeral { - long val; - int ch; - }; - - static struct numeral numerals[] = { - { 1L, 'I' }, - { 5L, 'V' }, - { 10L, 'X' }, - { 50L, 'L' }, - { 100L, 'C' }, - { 500L, 'D' }, - { 1000L, 'M' } - }; - void exec_function(program *pgm, statement *stmt, int pos) { --- 45,53 ---- int fnc_err(statement *stmt, int start); int fnc_tcb(int num); ! void fnc_rti(void); ! void fnc_itr(void); struct utsname Uname; void exec_function(program *pgm, statement *stmt, int pos) { *************** *** 362,368 **** break; case FNC_RTI: ! c = strexecpop(); ! fltexecpush(int2flt(fnc_rti(c.str))); break; --- 348,357 ---- break; + case FNC_ITR: + fnc_itr(); + break; + case FNC_RTI: ! fnc_rti(); break; *************** *** 1644,1672 **** } - long fnc_rti(const char *str) - { - int i, j, k; - long retval = 0L; ! if (!str || '\0' == *str) ! return -1L; ! for (i = 0, k = -1; str[i]; ++i) { ! for (j = 0; j < 7; ++j) ! { ! if (numerals[j].ch == toupper(str[i])) ! break; ! } ! if (7 == j) ! return -1L; ! if (k >= 0 && k < j) ! { ! retval -= numerals[k].val * 2; ! retval += numerals[j].val; ! } ! else retval += numerals[j].val; ! k = j; } ! return retval; } --- 1633,1768 ---- } ! //----- ! // Convert an number to a (extened) Roman number ! //----- ! void fnc_itr( void ) ! { ! long p=0; ! long w=0; ! long arabic=0; ! char *roman=NULL; ! ! typedef struct ! { ! long highNum; // arabic number ! char *highStr; // roman numeral ! char highLen; // length of roman numeral ! long lowNum; // arabic number ! char *lowStr; // roman numeral ! char lowLen; // length of roman numeral ! } ROMAN; ! ! static ROMAN Roman[]= ! { ! { 1000000L, "m", 1, 900000L, "cm", 2 }, ! { 500000L, "d", 1, 400000L, "cd", 2 }, ! { 100000L, "c", 1, 90000L, "xc", 2 }, ! { 50000L, "l", 1, 40000L, "xl", 2 }, ! { 10000L, "x", 1, 9000L, "ix", 2 }, ! { 5000L, "v", 1, 4000L, "iv", 2 }, ! { 1000L, "M", 1, 900L, "CM", 2 }, ! { 500L, "D", 1, 400L, "CD", 2 }, ! { 100L, "C", 1, 90L, "XC", 2 }, ! { 50L, "L", 1, 40L, "XL", 2 }, ! { 10L, "X", 1, 9L, "IX", 2 }, ! { 5L, "V", 1, 4L, "IV", 2 }, ! { 1L, "I", 1, 1L, "I", 1 } ! }; ! ! arabic = flt2long(fltexecpop()); ! ! //----- allocate space for roman number ----- ! roman = (char*) calloc(1,128); ! if( !roman ) { strexecpush(""); return; } ! ! //----- keep processing the arabic until its zero ----- ! do ! { ! //----- try all of the "high" Roman numerals ----- ! while( arabic >= Roman[w].highNum ) { ! memcpy( roman+p, Roman[w].highStr, Roman[w].highLen ); ! p += Roman[w].highLen; ! arabic -= Roman[w].highNum; ! if( p>= 128 ) { strexecpush(""); return; } } ! ! //----- try all of the "low" Roman numerals ----- ! if( arabic>= Roman[w].lowNum ) ! { ! memcpy( roman+p, Roman[w].lowStr, Roman[w].lowLen ); ! p += Roman[w].lowLen; ! arabic -= Roman[w].lowNum; ! if( p >= 128 ) { strexecpush(""); return; } ! } ! w++; ! } while( arabic>0 ); ! realloc(roman,p+1); // reallocate base on space used ! ! strexecpush(roman); ! ! return; } + + //----- + // convert a (extended) Roman numeral to arabic. lower case roman numerals + // represent the "bar" syntax. which means that the numeral is 1000 + // times its normal (upper case) value. + //----- + void fnc_rti( void ) + { + char *p=NULL; // temp ptr + char *rom=NULL; // copy of original roman numeral + long i=0; // forloop counter + long l=0; // length of original roman numeral + long arabic=0; // result to return + mybbstring roman; + + typedef struct + { + char *roman; // a roman numeral + char len; // its length + int arabic; // its arabic equivalent + } ROMAN; + + static ROMAN Roman[]= + { + {"i", 1, 1000}, + {"iv", 2, 4000}, {"ix", 2, 9000}, {"xl", 2, 40000}, + {"xc", 2, 90000}, {"cd", 2, 400000}, {"cm", 2, 900000}, + {"v", 1, 5000}, {"x", 1, 10000}, {"l", 1, 50000}, + {"c", 1, 100000}, {"d", 1, 500000}, {"m", 1, 1000000}, + {"IV", 2, 4}, {"IX", 2, 9}, {"XL", 2, 40}, + {"XC", 2, 90}, {"CD", 2, 400}, {"CM", 2, 900}, + {"I", 1, 1}, {"V", 1, 5}, {"X", 1, 10}, + {"L", 1, 50}, {"C", 1, 100}, {"D", 1, 500}, + {"M", 1, 1000}, + {NULL, 0, 0} + }; + + roman = strexecpop(); + + l = roman.len; // get len of original + rom = (char *)calloc(1,l+1); // get space for a copy + memcpy(rom,roman.str,l); // make a copy + + // test each entry in the Roman table + while( Roman[i].roman ) + { + while( (p=strstr(rom,Roman[i].roman)) ) // found one? + { + arabic += Roman[i].arabic; // increment arabic + memset(p,' ',Roman[i].len); // "delete" found numeral + } + i++; + } + + free(rom); + + fltexecpush(long2flt(arabic)); + + return; + } + |