/* ===========================================================
* DUMMY CALC 1.0, by migf1
*
* A dummy calculator, just to demonstrate the use of a jump-table
* consisting of function pointers, in ANCI C. No overflow checks, no
* operator priorities, no parentheses... just dummy cumulative calcs
* with an operator and an operand per line (some operators are unary
* so they ignore the operand and are applied to the previous result.
*
* 15 Supported Operators:
*
* addition (+)
* subtraction (-)
* multiplication (*)
* division (/)
* modulus (%)
* power (^)
* exponent of e (e) unary
* square root (@) unary
* cube root (#) unary
* negation (~) unary
* factorial (!) unary
* natural log (') unary
* base-10 log (") unary
* integral part (_) unary
* fractional part (.) unary
*
* Type h inside the program for help
* ===========================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// -- Macros ----------------
#define MAXINBUF (255+1)
#define MAXOPS 15 // max number of supported ops
// --- Custom Types ----------
typedef enum { FALSE=0, TRUE } Bool; // our custom boolean type
typedef enum { // operator codes
ADD, SUB, MUL, DIV, MOD, POW, EXPO, SQRT, CBRT, NEG,
FACT, LOGE, LOGTEN, TRUNC, FRAC
} OpCode;
typedef struct opstruct { // operator structure
char symbol; // a single char
OpCode code; // corersponding code
Bool unary; // UNUSED: is unary operator?
} OpStruct;
// -------------------------------------------------------------------------------------
void help( void )
{
puts("\n\tcommands are case sensitive"); puts("\tc\t: clear result"); puts("\t~\t: -result\t\tNegation"); puts("\t!\t: result!\t\tFactorial"); puts("\t_\t: trunc( result )\tTruncate Integral Part"); puts("\t.\t: fractional( result )\tFractional Part of Result"); puts("\te\t: exp( result )\t\tExponent of Result"); puts("\t'\t: log( result )\t\tNatural Logarithm"); puts("\t\"\t: log10( result )\tBase 10 Logarithm"); puts("\t@\t: sqrt( result )\tSquare Root"); puts("\t#\t: cbrt( result )\tCube Root"); puts("\t+ num\t: result + num\t\tAddition"); puts("\t- num\t: result - num\t\tSubtraction"); puts("\t* num\t: result * num\t\tMultiplication"); puts("\t/ num\t: result / num\t\tDivision"); puts("\t% num\t: result % num\t\tModulus (remainder)"); puts("\t^ num\t: result ^ num\t\tPower");
return;
}
// Functions for Supported Operations (some of them only use their first argument)
// -------------------------------------------------------------------------------------
double add( const double x, const double y ) // addition
{ return x + y; }
// -------------------------------------------------------------------------------------
double sub( const double x, const double y ) // subtraction
{ return x - y; }
// -------------------------------------------------------------------------------------
double mul( const double x, const double y ) // multiplication
{ return x * y; }
// -------------------------------------------------------------------------------------
double over( const double x, const double y ) // division
{ return y != 0 ? x/y : 0; }
// -------------------------------------------------------------------------------------
double modulus( const double x, const double y ) // x modulus y
{ return y != 0 ? fmod(x, y) : 0; }
// -------------------------------------------------------------------------------------
double pwr( const double x, const double y ) // power: x at y
// -------------------------------------------------------------------------------------
double expo( const double x, const double y ) // power: e at x
// -------------------------------------------------------------------------------------
double sqroot( const double x, const double y ) // square root of x
{ return x
< 1 ? 0 : sqrt(x
); } // -------------------------------------------------------------------------------------
double cbroot( const double x, const double y ) // cube root of x
{ return cbrt(x); }
// -------------------------------------------------------------------------------------
double neg( const double x, const double y ) // negation of x
{ return x != 0 ? -x : 0; }
// -------------------------------------------------------------------------------------
double fact( const double x, const double y ) // factorial of x
{ return x < 2 ? 1 : x * fact(x-1, 0.0); }
// -------------------------------------------------------------------------------------
double loge( const double x, const double y ) // natural log of x
{ return x
< 1 ? 0 : log(x
); } // -------------------------------------------------------------------------------------
double logten( const double x, const double y ) // base-10 log of x
{ return x
< 1 ? 0 : log10(x
); } // -------------------------------------------------------------------------------------
double truncate( const double x, const double y ) // integral part of x
{ return trunc(x); }
// -------------------------------------------------------------------------------------
double frac( const double x, const double y ) // fractional part of x
{ return x - trunc(x); }
// -------------------------------------------------------------------------------------
// Return the operator code that corresponds to sym, or -1 on failure
//
OpCode sym2opcode( const char sym, const OpStruct *tabops )
{
int i;
for (i=0; i < MAXOPS; i++)
if ( sym == tabops[i].symbol )
return tabops[i].code;
return -1;
}
// -------------------------------------------------------------------------------------
// Read the input line and assign appropriate values to x, opsym and opcode
// (return the number of input tokens read)
//
int get_input( double *x, char *opsym, OpCode *opcode,
const OpStruct tabops[], const double res )
{
char inbuf[MAXINBUF] = ""; // our input buffer
int ntokens; // # of tokens to return
do {
printf("%9lg: ", res
); // show prompt fgets(inbuf
, MAXINBUF
, stdin
); // read input line ntokens
= sscanf(inbuf
, "%c %lg", opsym
, x
); // extract opsym & x
if ( ntokens == 0 ) // no tokens read
continue;
// opsym was a command
if ( *opsym == 'x' || *opsym == 'c' || *opsym == 'h') {
*opcode = -1; // invalidate opcode
return 1; // exit function
}
// opsym was operator
*opcode = sym2opcode(*opsym, tabops); // assign valid opcode
} while ( ntokens == 0 || *opcode == -1);
return ntokens; // # of tokens read
}
// -----------------------------------------------------------------------
int main( void )
{
double x=0.0, res=0.0; // x from input, res for result
char opsym; // operator symbol from input
OpCode opcode; // operator code (from opsym)
// table of operator structures
const OpStruct tabops[ MAXOPS ] = { // (.unary inited but not used)
{'+', ADD, FALSE}, {'-', SUB, FALSE}, {'*', MUL, FALSE},
{'/', DIV, FALSE}, {'%', MOD, FALSE}, {'^', POW, FALSE},
{'e', EXPO, TRUE}, {'@', SQRT, TRUE}, {'#', CBRT, TRUE},
{'~', NEG, TRUE }, {'!', FACT, TRUE}, {'\'', LOGE, TRUE},
{'\"', LOGTEN, TRUE}, {'_', TRUNC, TRUE}, {'.', FRAC, TRUE}
};
// jump-table of func pointers
double (*pf[MAXOPS])(const double, const double) = {
&add, &sub, &mul, &over, &modulus, &pwr, &expo, &sqroot, &cbroot,
&neg, &fact, &loge, &logten, &truncate, &frac
};
puts("\tDUMMY CALC 1.0 by migf1\n\t\tprompt is the result, type h for help\n"); do { // our main loop
// read opsym, x and opcode
get_input(&x, &opsym, &opcode, tabops, res);
if ( opsym == 'x') // exit program
break;
if ( opsym == 'c' ) { // clear the result
res = 0.0;
continue;
}
if (opsym == 'h') { // show help
help();
continue;
}
// at this point opcode != -1
res = (*pf[opcode])(res, x); // do the requested operation
} while ( 1 );
}
LyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICogRFVNTVkgQ0FMQyAxLjAsIGJ5IG1pZ2YxCiAqCiAqIEEgZHVtbXkgY2FsY3VsYXRvciwganVzdCB0byBkZW1vbnN0cmF0ZSB0aGUgdXNlIG9mIGEganVtcC10YWJsZQogKiBjb25zaXN0aW5nIG9mIGZ1bmN0aW9uIHBvaW50ZXJzLCBpbiBBTkNJIEMuIE5vIG92ZXJmbG93IGNoZWNrcywgbm8KICogb3BlcmF0b3IgcHJpb3JpdGllcywgbm8gcGFyZW50aGVzZXMuLi4ganVzdCBkdW1teSBjdW11bGF0aXZlIGNhbGNzCiAqIHdpdGggYW4gb3BlcmF0b3IgYW5kIGFuIG9wZXJhbmQgcGVyIGxpbmUgKHNvbWUgb3BlcmF0b3JzIGFyZSB1bmFyeQogKiBzbyB0aGV5IGlnbm9yZSB0aGUgb3BlcmFuZCBhbmQgYXJlIGFwcGxpZWQgdG8gdGhlIHByZXZpb3VzIHJlc3VsdC4KICoKICogMTUgU3VwcG9ydGVkIE9wZXJhdG9yczoKICoKICoJYWRkaXRpb24JKCspCiAqCXN1YnRyYWN0aW9uCSgtKQogKgltdWx0aXBsaWNhdGlvbgkoKikKICoJZGl2aXNpb24JKC8pCiAqCW1vZHVsdXMJCSglKQogKglwb3dlcgkJKF4pCiAqCWV4cG9uZW50IG9mIGUJKGUpCXVuYXJ5CiAqCXNxdWFyZSByb290CShAKQl1bmFyeQogKgljdWJlIHJvb3QJKCMpCXVuYXJ5CiAqCW5lZ2F0aW9uCSh+KQl1bmFyeQogKglmYWN0b3JpYWwJKCEpCXVuYXJ5CiAqCW5hdHVyYWwgbG9nCSgnKQl1bmFyeQogKgliYXNlLTEwIGxvZwkoIikJdW5hcnkKICoJaW50ZWdyYWwgcGFydAkoXykJdW5hcnkKICoJZnJhY3Rpb25hbCBwYXJ0CSguKQl1bmFyeQogKgogKiBUeXBlIGggaW5zaWRlIHRoZSBwcm9ncmFtIGZvciBoZWxwCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPG1hdGguaD4KCi8vIC0tIE1hY3JvcyAtLS0tLS0tLS0tLS0tLS0tCgojZGVmaW5lIE1BWElOQlVGCSgyNTUrMSkKI2RlZmluZSBNQVhPUFMJCTE1CQkJCS8vIG1heCBudW1iZXIgb2Ygc3VwcG9ydGVkIG9wcwoKLy8gLS0tIEN1c3RvbSBUeXBlcyAtLS0tLS0tLS0tCgp0eXBlZGVmIGVudW0geyBGQUxTRT0wLCBUUlVFIH0gQm9vbDsJCQkvLyBvdXIgY3VzdG9tIGJvb2xlYW4gdHlwZQp0eXBlZGVmIGVudW0gewkJCQkJCS8vIG9wZXJhdG9yIGNvZGVzCglBREQsIFNVQiwgTVVMLCBESVYsIE1PRCwgUE9XLCBFWFBPLCBTUVJULCBDQlJULCBORUcsCglGQUNULCBMT0dFLCBMT0dURU4sIFRSVU5DLCBGUkFDCn0gT3BDb2RlOwoKdHlwZWRlZiBzdHJ1Y3Qgb3BzdHJ1Y3QgewkJCQkvLyBvcGVyYXRvciBzdHJ1Y3R1cmUKCWNoYXIgc3ltYm9sOwkJCQkJLy8gYSBzaW5nbGUgY2hhcgoJT3BDb2RlIGNvZGU7CQkJCQkvLyBjb3JlcnNwb25kaW5nIGNvZGUKCUJvb2wgdW5hcnk7CQkJCQkvLyBVTlVTRUQ6IGlzIHVuYXJ5IG9wZXJhdG9yPwp9IE9wU3RydWN0OwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIGhlbHAoIHZvaWQgKQp7CglwdXRzKCJcblx0Y29tbWFuZHMgYXJlIGNhc2Ugc2Vuc2l0aXZlIik7CglwdXRzKCJcdHhcdDogZXhpdCIpOwoJcHV0cygiXHRjXHQ6IGNsZWFyIHJlc3VsdCIpOwoJcHV0cygiXHR+XHQ6IC1yZXN1bHRcdFx0TmVnYXRpb24iKTsKCXB1dHMoIlx0IVx0OiByZXN1bHQhXHRcdEZhY3RvcmlhbCIpOwoJcHV0cygiXHRfXHQ6IHRydW5jKCByZXN1bHQgKVx0VHJ1bmNhdGUgSW50ZWdyYWwgUGFydCIpOwoJcHV0cygiXHQuXHQ6IGZyYWN0aW9uYWwoIHJlc3VsdCApXHRGcmFjdGlvbmFsIFBhcnQgb2YgUmVzdWx0Iik7CglwdXRzKCJcdGVcdDogZXhwKCByZXN1bHQgKVx0XHRFeHBvbmVudCBvZiBSZXN1bHQiKTsKCXB1dHMoIlx0J1x0OiBsb2coIHJlc3VsdCApXHRcdE5hdHVyYWwgTG9nYXJpdGhtIik7CglwdXRzKCJcdFwiXHQ6IGxvZzEwKCByZXN1bHQgKVx0QmFzZSAxMCBMb2dhcml0aG0iKTsKCXB1dHMoIlx0QFx0OiBzcXJ0KCByZXN1bHQgKVx0U3F1YXJlIFJvb3QiKTsKCXB1dHMoIlx0I1x0OiBjYnJ0KCByZXN1bHQgKVx0Q3ViZSBSb290Iik7CglwdXRzKCJcdCsgbnVtXHQ6IHJlc3VsdCArIG51bVx0XHRBZGRpdGlvbiIpOwoJcHV0cygiXHQtIG51bVx0OiByZXN1bHQgLSBudW1cdFx0U3VidHJhY3Rpb24iKTsKCXB1dHMoIlx0KiBudW1cdDogcmVzdWx0ICogbnVtXHRcdE11bHRpcGxpY2F0aW9uIik7CglwdXRzKCJcdC8gbnVtXHQ6IHJlc3VsdCAvIG51bVx0XHREaXZpc2lvbiIpOwoJcHV0cygiXHQlIG51bVx0OiByZXN1bHQgJSBudW1cdFx0TW9kdWx1cyAocmVtYWluZGVyKSIpOwoJcHV0cygiXHReIG51bVx0OiByZXN1bHQgXiBudW1cdFx0UG93ZXIiKTsKCXB1dGNoYXIoJ1xuJyk7CgoJcmV0dXJuOwp9CgovLyBGdW5jdGlvbnMgZm9yIFN1cHBvcnRlZCBPcGVyYXRpb25zIChzb21lIG9mIHRoZW0gb25seSB1c2UgdGhlaXIgZmlyc3QgYXJndW1lbnQpCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmRvdWJsZSBhZGQoIGNvbnN0IGRvdWJsZSB4LCBjb25zdCBkb3VibGUgeSApCQkJLy8gYWRkaXRpb24KeyByZXR1cm4geCArIHk7IH0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpkb3VibGUgc3ViKCBjb25zdCBkb3VibGUgeCwgY29uc3QgZG91YmxlIHkgKQkJCS8vIHN1YnRyYWN0aW9uCnsgcmV0dXJuIHggLSB5OyB9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZG91YmxlIG11bCggY29uc3QgZG91YmxlIHgsIGNvbnN0IGRvdWJsZSB5ICkJCQkvLyBtdWx0aXBsaWNhdGlvbgp7IHJldHVybiB4ICogeTsgfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmRvdWJsZSBvdmVyKCBjb25zdCBkb3VibGUgeCwgY29uc3QgZG91YmxlIHkgKQkJCS8vIGRpdmlzaW9uCnsgcmV0dXJuIHkgIT0gMCA/IHgveSA6IDA7IH0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpkb3VibGUgbW9kdWx1cyggY29uc3QgZG91YmxlIHgsIGNvbnN0IGRvdWJsZSB5ICkJCS8vIHggbW9kdWx1cyB5CnsgcmV0dXJuIHkgIT0gMCA/IGZtb2QoeCwgeSkgOiAwOyB9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZG91YmxlIHB3ciggY29uc3QgZG91YmxlIHgsIGNvbnN0IGRvdWJsZSB5ICkJCQkvLyBwb3dlcjogeCBhdCB5CnsgcmV0dXJuIHBvdyh4LCB5KTsgfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCmRvdWJsZSBleHBvKCBjb25zdCBkb3VibGUgeCwgY29uc3QgZG91YmxlIHkgKQkJCS8vIHBvd2VyOiBlIGF0IHgKeyByZXR1cm4gZXhwKHgpOyB9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZG91YmxlIHNxcm9vdCggY29uc3QgZG91YmxlIHgsIGNvbnN0IGRvdWJsZSB5ICkJCQkvLyBzcXVhcmUgcm9vdCBvZiB4CnsgcmV0dXJuIHggPCAxID8gMCA6IHNxcnQoeCk7IH0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpkb3VibGUgY2Jyb290KCBjb25zdCBkb3VibGUgeCwgY29uc3QgZG91YmxlIHkgKQkJCS8vIGN1YmUgcm9vdCBvZiB4CnsgcmV0dXJuIGNicnQoeCk7IH0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpkb3VibGUgbmVnKCBjb25zdCBkb3VibGUgeCwgY29uc3QgZG91YmxlIHkgKQkJCS8vIG5lZ2F0aW9uIG9mIHgKeyByZXR1cm4geCAhPSAwID8gLXggOiAwOyB9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZG91YmxlIGZhY3QoIGNvbnN0IGRvdWJsZSB4LCBjb25zdCBkb3VibGUgeSApCQkJLy8gZmFjdG9yaWFsIG9mIHgKeyByZXR1cm4geCA8IDIgPyAxIDogeCAqIGZhY3QoeC0xLCAwLjApOyB9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KZG91YmxlIGxvZ2UoIGNvbnN0IGRvdWJsZSB4LCBjb25zdCBkb3VibGUgeSApCQkJLy8gbmF0dXJhbCBsb2cgb2YgeAp7IHJldHVybiB4IDwgMSA/IDAgOiBsb2coeCk7IH0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpkb3VibGUgbG9ndGVuKCBjb25zdCBkb3VibGUgeCwgY29uc3QgZG91YmxlIHkgKQkJCS8vIGJhc2UtMTAgbG9nIG9mIHgKeyByZXR1cm4geCA8IDEgPyAwIDogbG9nMTAoeCk7IH0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpkb3VibGUgdHJ1bmNhdGUoIGNvbnN0IGRvdWJsZSB4LCBjb25zdCBkb3VibGUgeSApCQkvLyBpbnRlZ3JhbCBwYXJ0IG9mIHgKeyByZXR1cm4gdHJ1bmMoeCk7IH0KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpkb3VibGUgZnJhYyggY29uc3QgZG91YmxlIHgsIGNvbnN0IGRvdWJsZSB5ICkJCQkvLyBmcmFjdGlvbmFsIHBhcnQgb2YgeAp7IHJldHVybiB4IC0gdHJ1bmMoeCk7IH0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gUmV0dXJuIHRoZSBvcGVyYXRvciBjb2RlIHRoYXQgY29ycmVzcG9uZHMgdG8gc3ltLCBvciAtMSBvbiBmYWlsdXJlCi8vCk9wQ29kZSBzeW0yb3Bjb2RlKCBjb25zdCBjaGFyIHN5bSwgY29uc3QgT3BTdHJ1Y3QgKnRhYm9wcyApCnsKCWludCBpOwoJZm9yIChpPTA7IGkgPCBNQVhPUFM7IGkrKykKCQlpZiAoIHN5bSA9PSB0YWJvcHNbaV0uc3ltYm9sICkKCQkJcmV0dXJuIHRhYm9wc1tpXS5jb2RlOwoKCXJldHVybiAtMTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyBSZWFkIHRoZSBpbnB1dCBsaW5lIGFuZCBhc3NpZ24gYXBwcm9wcmlhdGUgdmFsdWVzIHRvIHgsIG9wc3ltIGFuZCBvcGNvZGUKLy8gKHJldHVybiB0aGUgbnVtYmVyIG9mIGlucHV0IHRva2VucyByZWFkKQovLwppbnQgZ2V0X2lucHV0KAlkb3VibGUgKngsIGNoYXIgKm9wc3ltLCBPcENvZGUgKm9wY29kZSwKCQljb25zdCBPcFN0cnVjdCB0YWJvcHNbXSwgY29uc3QgZG91YmxlIHJlcyApCnsKCWNoYXIgaW5idWZbTUFYSU5CVUZdID0gIiI7CQkJCS8vIG91ciBpbnB1dCBidWZmZXIKCWludCBudG9rZW5zOwkJCQkJCS8vICMgb2YgdG9rZW5zIHRvIHJldHVybgoKCWRvIHsKCQlwcmludGYoIiU5bGc6ICIsIHJlcyk7CQkJCS8vIHNob3cgcHJvbXB0CgkJZmdldHMoaW5idWYsIE1BWElOQlVGLCBzdGRpbik7CQkJLy8gcmVhZCBpbnB1dCBsaW5lCgkJbnRva2VucyA9IHNzY2FuZihpbmJ1ZiwgIiVjICVsZyIsIG9wc3ltLCB4KTsJLy8gZXh0cmFjdCBvcHN5bSAmIHgKCgkJaWYgKCBudG9rZW5zID09IDAgKQkJCQkvLyBubyB0b2tlbnMgcmVhZAoJCQljb250aW51ZTsKCQkJCQkJCQkvLyBvcHN5bSB3YXMgYSBjb21tYW5kCgkJaWYgKCAqb3BzeW0gPT0gJ3gnIHx8ICpvcHN5bSA9PSAnYycgfHwgKm9wc3ltID09ICdoJykgewoJCQkqb3Bjb2RlID0gLTE7CQkJCS8vIGludmFsaWRhdGUgb3Bjb2RlCgkJCXJldHVybiAxOwkJCQkvLyBleGl0IGZ1bmN0aW9uCgkJfQoJCQkJCQkJCS8vIG9wc3ltIHdhcyBvcGVyYXRvcgoJCSpvcGNvZGUgPSBzeW0yb3Bjb2RlKCpvcHN5bSwgdGFib3BzKTsJCS8vIGFzc2lnbiB2YWxpZCBvcGNvZGUKCgl9IHdoaWxlICggbnRva2VucyA9PSAwIHx8ICpvcGNvZGUgPT0gLTEpOwoKCXJldHVybiBudG9rZW5zOwkJCQkJCS8vICMgb2YgdG9rZW5zIHJlYWQKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQppbnQgbWFpbiggdm9pZCApCnsKCWRvdWJsZSB4PTAuMCwgcmVzPTAuMDsJCQkJLy8geCBmcm9tIGlucHV0LCByZXMgZm9yIHJlc3VsdAoJY2hhciBvcHN5bTsJCQkJCS8vIG9wZXJhdG9yIHN5bWJvbCBmcm9tIGlucHV0CglPcENvZGUgb3Bjb2RlOwkJCQkJLy8gb3BlcmF0b3IgY29kZSAoZnJvbSBvcHN5bSkKCgkJCQkJCQkvLyB0YWJsZSBvZiBvcGVyYXRvciBzdHJ1Y3R1cmVzCgljb25zdCBPcFN0cnVjdCB0YWJvcHNbIE1BWE9QUyBdID0gewkJLy8gKC51bmFyeSBpbml0ZWQgYnV0IG5vdCB1c2VkKQoJCXsnKycsIEFERCwgRkFMU0V9LCB7Jy0nLCBTVUIsIEZBTFNFfSwgeycqJywgTVVMLCBGQUxTRX0sCgkJeycvJywgRElWLCBGQUxTRX0sIHsnJScsIE1PRCwgRkFMU0V9LCB7J14nLCBQT1csIEZBTFNFfSwKCQl7J2UnLCBFWFBPLCBUUlVFfSwgeydAJywgU1FSVCwgVFJVRX0sIHsnIycsIENCUlQsIFRSVUV9LAoJCXsnficsIE5FRywgVFJVRSB9LCB7JyEnLCBGQUNULCBUUlVFfSwgeydcJycsIExPR0UsIFRSVUV9LAoJCXsnXCInLCBMT0dURU4sIFRSVUV9LCB7J18nLCBUUlVOQywgVFJVRX0sIHsnLicsIEZSQUMsIFRSVUV9Cgl9OwoJCQkJCQkJLy8ganVtcC10YWJsZSBvZiBmdW5jIHBvaW50ZXJzCglkb3VibGUgKCpwZltNQVhPUFNdKShjb25zdCBkb3VibGUsIGNvbnN0IGRvdWJsZSkgPSB7CgkJJmFkZCwgJnN1YiwgJm11bCwgJm92ZXIsICZtb2R1bHVzLCAmcHdyLCAmZXhwbywgJnNxcm9vdCwgJmNicm9vdCwKCQkmbmVnLCAmZmFjdCwgJmxvZ2UsICZsb2d0ZW4sICZ0cnVuY2F0ZSwgJmZyYWMKCX07CgoJcHV0cygiXHREVU1NWSBDQUxDIDEuMCBieSBtaWdmMVxuXHRcdHByb21wdCBpcyB0aGUgcmVzdWx0LCB0eXBlIGggZm9yIGhlbHBcbiIpOwoJZG8gewkJCQkJCS8vIG91ciBtYWluIGxvb3AKCQkJCQkJCS8vIHJlYWQgb3BzeW0sIHggYW5kIG9wY29kZQoJCWdldF9pbnB1dCgmeCwgJm9wc3ltLCAmb3Bjb2RlLCB0YWJvcHMsIHJlcyk7CgkJaWYgKCBvcHN5bSA9PSAneCcpCQkJLy8gZXhpdCBwcm9ncmFtCgkJCWJyZWFrOwoJCWlmICggb3BzeW0gPT0gJ2MnICkgewkJCS8vIGNsZWFyIHRoZSByZXN1bHQKCQkJcmVzID0gMC4wOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKG9wc3ltID09ICdoJykgewkJCS8vIHNob3cgaGVscAoJCQloZWxwKCk7CgkJCWNvbnRpbnVlOwoJCX0KCgkJLy8gYXQgdGhpcyBwb2ludCBvcGNvZGUgIT0gLTEKCQlyZXMgPSAoKnBmW29wY29kZV0pKHJlcywgeCk7CQkvLyBkbyB0aGUgcmVxdWVzdGVkIG9wZXJhdGlvbgoJfSB3aGlsZSAoIDEgKTsKCglleGl0KCBFWElUX1NVQ0NFU1MgKTsKfQo=