/* 
 * Starting with C: Primitive 2 operands calculator 
 */ 
 
#include <stdio.h> 
#include <ctype.h>				// for tolower() 
#include <math.h>				// for pow(), sqrt(), ... 
#include <stdlib.h>				// for exit() 
#include <errno.h>				// for errno 
 
#define MAXSLEN_LINEBUF		255+1		// for reading menu * nums as a strings 
 
typedef  enum  {  FALSE= 0 ,  TRUE }  bool; 		// our custom boolean type 
 
// ------------------------------------------------------------------------------- 
// Read s from stdin until either 'ENTER is pressed or len-1 chars have been entered 
// Remove ENTER (if any), null terminate s and return it 
// 
char  * s_get( char  * s,  size_t  len) 
{ 
	register  char  * cp; 
 
	for  ( cp
= s
;  ( * cp
= getc ( stdin
) )  !=  '\n '  &&  ( cp
- s
)  <  len
- 1 ;  cp
++  )  		; 					// for-loop with empty body */ 
	* cp =  '\0 ' ; 					// null-terminate last character 
 
	return  s; 
} 
 
// ------------------------------------------------------------------------------- 
// Read num as a string from stdin and convert it to double. Demand a successfull 
// convertion (otherwise keep asking). The conversion is done via the standard 
// function: strtod()... read the C manual for more info. 
// 
void  num_askuser(  char  * prompt,  double  * num,  int  maxslen_num ) 
{ 
	char  inbuf[  maxslen_num ] ,  * pend= NULL; 
	bool stop; 
 
	do 
	{ 
		errno =  0 ; 								// reset errno (defined in <errno.h> 
		stop =  TRUE; 			// reset boolen flag 
 
		printf (  prompt 
) ; 		// display a prompt asking for input  		fflush ( stdin
) ; 			// clear the input buffer (stdin)  		s_get(  inbuf,  maxslen_num ) ; 	// read user input as string in inbuf 
 
		* num 
=  strtod (  inbuf
,  & pend 
) ; 	// convert it to double  		if  (  * pend ) 			// *pend != '\0', possibly invalid num 
		{ 
			if  (  * num ==  0.0  )  {  	// num was indeed invalid, not converted 
				puts ( "\t *** error: invalid number" ) ;  				stop =  FALSE; 
				continue ; 
			} 
			else  { 			// converted ok, invalid chars ignored 
				printf ( "\t *** info: \" %s\"  ignored\n " ,  pend
) ;  				stop =  TRUE; 
				continue ; 
			} 
		} 
 
		if  (  errno ==  ERANGE ) 		// too big (or too small) num 
		{ 
			puts ( "\t *** error: number out of range" ) ;  			stop =  FALSE; 
		} 
 
	}  while  (  ! stop ||  * inbuf == '\0 '  ) ; 
 
	return ; 
} 
 
// ------------------------------------------------------------------------------- 
int  main ( void ) 
{ 
	double  x,  y;  				// operands 
	int  stop =  FALSE; 			// boolean controlling the main loop 
#ifdef __GNUC__ 
	char  inbuf[  MAXSLEN_LINEBUF ] ; 		// menu choice  
#endif 
	do  { 					// display menu 
		puts ( "\n \n AVAILABLE OPTIONS\n =================" ) ;  		printf ( "1 or +\t  add\n 2 or -\t  subtract\n 3 or *\t  multiply\n 4 or /\t  divide\n 5 or %%\t  percentage\n 6 or ^\t  power\n 7\t  square root\n 8 or x\t  exit\n \n Your choice: " ) ;   
		fflush ( stdin
) ; 			// clear input buffer  #ifdef __GNUC__ 
		switch  (  tolower (  * s_get
( inbuf
,  MAXSLEN_LINEBUF
)  )  ) // GET USER CHOICE  #else 
#endif 
		{ 
			case  '1' : 		// 1. ADDITTION 
			case  '+' : 
				puts ( "\n Addition\n --------" ) ;  				num_askuser( "1st addendum: " ,  & x,  MAXSLEN_LINEBUF) ; 
				num_askuser( "2nd addendum: " ,  & y,  MAXSLEN_LINEBUF) ; 
				printf ( "--------\n RESULT: %g + %g = %g\n " ,  				x,  y,  x +  y ) ; 
			break ; 
 
			case  '2' : 		// 2. SUBTRACTION 
			case  '-' : 
				puts ( "\n Subtraction\n -----------" ) ;  				num_askuser( "Reducer   : " ,  & x,  MAXSLEN_LINEBUF) ; 
				num_askuser( "Subtrahend: " ,  & y,  MAXSLEN_LINEBUF) ; 
				printf ( "-----------\n RESULT: %g - %g = %g\n " ,  					x,  y,  x -  y ) ; 
			break ; 
 
			case  '3' : 		// 3. MULTIPLICATION 
			case  '*' : 
				puts ( "\n Multiplication\n --------------" ) ;  				num_askuser( "1st number: " ,  & x,  MAXSLEN_LINEBUF) ; 
				num_askuser( "2nd number: " ,  & y,  MAXSLEN_LINEBUF) ; 
				printf ( "--------------\n RESULT: %g * %g = %g\n " ,  					x,  y,  x *  y ) ; 
			break ; 
 
			case  '4' : 		// 4. DIVISION 
			case  '/' : 
			{ 	double  intpart; 
				puts ( "\n Division\n --------" ) ;  				num_askuser( "Divident: " ,  & x,  MAXSLEN_LINEBUF) ; 
				do  { 							// demand non-zero value 
				   num_askuser( "Divisor : " ,  & y,  MAXSLEN_LINEBUF) ; 
				   if  (  y ==  0.0  ) 
					  puts ( "*** error: divisor cannot be 0" ) ;  				}  while  ( y ==  0.0 ) ; 
				printf ( "--------\n RESULT: %g / %g = %g (quotient = %g, remainder = %g)\n " ,  					x
,  y
,  x
/ y
,  trunc
( x
/ y
) ,  y 
*  modf ( x
/ y
,  & intpart
)  ) ; 			} 
			break ; 
 
			case  '5' : 		// 5. PERCENTAGE 
			case  '%' : 
				puts ( "\n Percentage\n ----------" ) ;  				num_askuser( "Number: " ,  & x,  MAXSLEN_LINEBUF) ; 
				printf ( "----------\n RESULT: %g%% = %g\n " ,  x
,  x
/ 100 ) ;  			break ; 
 
			case  '6' : 		// 6. POWER 
			case  '^' : 
				num_askuser( "Base    : " ,  & x,  MAXSLEN_LINEBUF) ; 
				num_askuser( "Exponent: " ,  & y,  MAXSLEN_LINEBUF) ; 
				printf ( "-----\n RESULT: %g ^ %g = %g\n " ,  x
,  y
,  pow ( x
,  y
) ) ;  			break ; 
 
			case  '7' : 		// 7. SQUARE ROOT 
				puts ( "\n Square Root\n -----------" ) ;  				num_askuser( "Number: " ,  & x,  MAXSLEN_LINEBUF) ; 
				printf ( "-----------\n RESULT: sqrt(%g) = %g\n " ,  x
,  sqrt ( x
)  ) ;  			break ; 
 
			case  '8' : 		// 8. EXIT 
			case  'x' : 
				stop =  TRUE; 
			break ; 
 
			default : 		// ALL OTHER CHOICES 
				puts ( "*** error: invalid choice, try again..." ) ;  			break ; 
		} 	// switch 
 
	}  while  (  ! stop ) ; 
 
} 
 
LyoKICogU3RhcnRpbmcgd2l0aCBDOiBQcmltaXRpdmUgMiBvcGVyYW5kcyBjYWxjdWxhdG9yCiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgkJCQkvLyBmb3IgdG9sb3dlcigpCiNpbmNsdWRlIDxtYXRoLmg+CQkJCS8vIGZvciBwb3coKSwgc3FydCgpLCAuLi4KI2luY2x1ZGUgPHN0ZGxpYi5oPgkJCQkvLyBmb3IgZXhpdCgpCiNpbmNsdWRlIDxlcnJuby5oPgkJCQkvLyBmb3IgZXJybm8KCiNkZWZpbmUgTUFYU0xFTl9MSU5FQlVGCQkyNTUrMQkJLy8gZm9yIHJlYWRpbmcgbWVudSAqIG51bXMgYXMgYSBzdHJpbmdzCgp0eXBlZGVmIGVudW0geyBGQUxTRT0wLCBUUlVFIH0gYm9vbDsJCS8vIG91ciBjdXN0b20gYm9vbGVhbiB0eXBlCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vIFJlYWQgcyBmcm9tIHN0ZGluIHVudGlsIGVpdGhlciAnRU5URVIgaXMgcHJlc3NlZCBvciBsZW4tMSBjaGFycyBoYXZlIGJlZW4gZW50ZXJlZAovLyBSZW1vdmUgRU5URVIgKGlmIGFueSksIG51bGwgdGVybWluYXRlIHMgYW5kIHJldHVybiBpdAovLwpjaGFyICpzX2dldChjaGFyICpzLCBzaXplX3QgbGVuKQp7CglyZWdpc3RlciBjaGFyICpjcDsKCglmb3IgKGNwPXM7ICgqY3A9Z2V0YyhzdGRpbikpICE9ICdcbicgJiYgKGNwLXMpIDwgbGVuLTE7IGNwKysgKQoJCTsJCQkJCS8vIGZvci1sb29wIHdpdGggZW1wdHkgYm9keSAqLwoJKmNwID0gJ1wwJzsJCQkJCS8vIG51bGwtdGVybWluYXRlIGxhc3QgY2hhcmFjdGVyCgoJcmV0dXJuIHM7Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gUmVhZCBudW0gYXMgYSBzdHJpbmcgZnJvbSBzdGRpbiBhbmQgY29udmVydCBpdCB0byBkb3VibGUuIERlbWFuZCBhIHN1Y2Nlc3NmdWxsCi8vIGNvbnZlcnRpb24gKG90aGVyd2lzZSBrZWVwIGFza2luZykuIFRoZSBjb252ZXJzaW9uIGlzIGRvbmUgdmlhIHRoZSBzdGFuZGFyZAovLyBmdW5jdGlvbjogc3RydG9kKCkuLi4gcmVhZCB0aGUgQyBtYW51YWwgZm9yIG1vcmUgaW5mby4KLy8Kdm9pZCBudW1fYXNrdXNlciggY2hhciAqcHJvbXB0LCBkb3VibGUgKm51bSwgaW50IG1heHNsZW5fbnVtICkKewoJY2hhciBpbmJ1ZlsgbWF4c2xlbl9udW0gXSwgKnBlbmQ9TlVMTDsKCWJvb2wgc3RvcDsKCglkbwoJewoJCWVycm5vID0gMDsJCQkJCQkJCS8vIHJlc2V0IGVycm5vIChkZWZpbmVkIGluIDxlcnJuby5oPgoJCXN0b3AgPSBUUlVFOwkJCS8vIHJlc2V0IGJvb2xlbiBmbGFnCgoJCXByaW50ZiggcHJvbXB0ICk7CQkvLyBkaXNwbGF5IGEgcHJvbXB0IGFza2luZyBmb3IgaW5wdXQKCQlmZmx1c2goc3RkaW4pOwkJCS8vIGNsZWFyIHRoZSBpbnB1dCBidWZmZXIgKHN0ZGluKQoJCXNfZ2V0KCBpbmJ1ZiwgbWF4c2xlbl9udW0gKTsJLy8gcmVhZCB1c2VyIGlucHV0IGFzIHN0cmluZyBpbiBpbmJ1ZgoKCQkqbnVtID0gc3RydG9kKCBpbmJ1ZiwgJnBlbmQgKTsJLy8gY29udmVydCBpdCB0byBkb3VibGUKCQlpZiAoICpwZW5kICkJCQkvLyAqcGVuZCAhPSAnXDAnLCBwb3NzaWJseSBpbnZhbGlkIG51bQoJCXsKCQkJaWYgKCAqbnVtID09IDAuMCApIHsgCS8vIG51bSB3YXMgaW5kZWVkIGludmFsaWQsIG5vdCBjb252ZXJ0ZWQKCQkJCXB1dHMoIlx0KioqIGVycm9yOiBpbnZhbGlkIG51bWJlciIpOwoJCQkJc3RvcCA9IEZBTFNFOwoJCQkJY29udGludWU7CgkJCX0KCQkJZWxzZSB7CQkJLy8gY29udmVydGVkIG9rLCBpbnZhbGlkIGNoYXJzIGlnbm9yZWQKCQkJCXByaW50ZigiXHQqKiogaW5mbzogXCIlc1wiIGlnbm9yZWRcbiIsIHBlbmQpOwoJCQkJc3RvcCA9IFRSVUU7CgkJCQljb250aW51ZTsKCQkJfQoJCX0KCgkJaWYgKCBlcnJubyA9PSBFUkFOR0UgKQkJLy8gdG9vIGJpZyAob3IgdG9vIHNtYWxsKSBudW0KCQl7CgkJCXB1dHMoIlx0KioqIGVycm9yOiBudW1iZXIgb3V0IG9mIHJhbmdlIik7CgkJCXN0b3AgPSBGQUxTRTsKCQl9CgoJfSB3aGlsZSAoICFzdG9wIHx8ICppbmJ1ZiA9PSdcMCcgKTsKCglyZXR1cm47Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KaW50IG1haW4gKHZvaWQpCnsKCWRvdWJsZSB4LCB5OyAJCQkJLy8gb3BlcmFuZHMKCWludCBzdG9wID0gRkFMU0U7CQkJLy8gYm9vbGVhbiBjb250cm9sbGluZyB0aGUgbWFpbiBsb29wCiNpZmRlZiBfX0dOVUNfXwoJY2hhciBpbmJ1ZlsgTUFYU0xFTl9MSU5FQlVGIF07CQkvLyBtZW51IGNob2ljZSAKI2VuZGlmCglkbyB7CQkJCQkvLyBkaXNwbGF5IG1lbnUKCQlwdXRzKCJcblxuQVZBSUxBQkxFIE9QVElPTlNcbj09PT09PT09PT09PT09PT09Iik7CgkJcHJpbnRmICgiMSBvciArXHQgYWRkXG4yIG9yIC1cdCBzdWJ0cmFjdFxuMyBvciAqXHQgbXVsdGlwbHlcbjQgb3IgL1x0IGRpdmlkZVxuNSBvciAlJVx0IHBlcmNlbnRhZ2VcbjYgb3IgXlx0IHBvd2VyXG43XHQgc3F1YXJlIHJvb3Rcbjggb3IgeFx0IGV4aXRcblxuWW91ciBjaG9pY2U6ICIpOwoKCQlmZmx1c2goc3RkaW4pOwkJCS8vIGNsZWFyIGlucHV0IGJ1ZmZlcgojaWZkZWYgX19HTlVDX18KCQlzd2l0Y2ggKCB0b2xvd2VyKCAqc19nZXQoaW5idWYsIE1BWFNMRU5fTElORUJVRikgKSApLy8gR0VUIFVTRVIgQ0hPSUNFCiNlbHNlCgkJc3dpdGNoICggdG9sb3dlciggZ2V0Y2hhcigpICkgKQkvLyBHRVQgVVNFUiBDSE9JQ0UKI2VuZGlmCgkJewoJCQljYXNlICcxJzoJCS8vIDEuIEFERElUVElPTgoJCQljYXNlICcrJzoKCQkJCXB1dHMoIlxuQWRkaXRpb25cbi0tLS0tLS0tIik7CgkJCQludW1fYXNrdXNlcigiMXN0IGFkZGVuZHVtOiAiLCAmeCwgTUFYU0xFTl9MSU5FQlVGKTsKCQkJCW51bV9hc2t1c2VyKCIybmQgYWRkZW5kdW06ICIsICZ5LCBNQVhTTEVOX0xJTkVCVUYpOwoJCQkJcHJpbnRmICgiLS0tLS0tLS1cblJFU1VMVDogJWcgKyAlZyA9ICVnXG4iLAoJCQkJeCwgeSwgeCArIHkgKTsKCQkJYnJlYWs7CgoJCQljYXNlICcyJzoJCS8vIDIuIFNVQlRSQUNUSU9OCgkJCWNhc2UgJy0nOgoJCQkJcHV0cygiXG5TdWJ0cmFjdGlvblxuLS0tLS0tLS0tLS0iKTsKCQkJCW51bV9hc2t1c2VyKCJSZWR1Y2VyICAgOiAiLCAmeCwgTUFYU0xFTl9MSU5FQlVGKTsKCQkJCW51bV9hc2t1c2VyKCJTdWJ0cmFoZW5kOiAiLCAmeSwgTUFYU0xFTl9MSU5FQlVGKTsKCQkJCXByaW50ZiAoIi0tLS0tLS0tLS0tXG5SRVNVTFQ6ICVnIC0gJWcgPSAlZ1xuIiwKCQkJCQl4LCB5LCB4IC0geSApOwoJCQlicmVhazsKCgkJCWNhc2UgJzMnOgkJLy8gMy4gTVVMVElQTElDQVRJT04KCQkJY2FzZSAnKic6CgkJCQlwdXRzKCJcbk11bHRpcGxpY2F0aW9uXG4tLS0tLS0tLS0tLS0tLSIpOwoJCQkJbnVtX2Fza3VzZXIoIjFzdCBudW1iZXI6ICIsICZ4LCBNQVhTTEVOX0xJTkVCVUYpOwoJCQkJbnVtX2Fza3VzZXIoIjJuZCBudW1iZXI6ICIsICZ5LCBNQVhTTEVOX0xJTkVCVUYpOwoJCQkJcHJpbnRmICgiLS0tLS0tLS0tLS0tLS1cblJFU1VMVDogJWcgKiAlZyA9ICVnXG4iLAoJCQkJCXgsIHksIHggKiB5ICk7CgkJCWJyZWFrOwoKCQkJY2FzZSAnNCc6CQkvLyA0LiBESVZJU0lPTgoJCQljYXNlICcvJzoKCQkJewlkb3VibGUgaW50cGFydDsKCQkJCXB1dHMoIlxuRGl2aXNpb25cbi0tLS0tLS0tIik7CgkJCQludW1fYXNrdXNlcigiRGl2aWRlbnQ6ICIsICZ4LCBNQVhTTEVOX0xJTkVCVUYpOwoJCQkJZG8gewkJCQkJCQkvLyBkZW1hbmQgbm9uLXplcm8gdmFsdWUKCQkJCSAgIG51bV9hc2t1c2VyKCJEaXZpc29yIDogIiwgJnksIE1BWFNMRU5fTElORUJVRik7CgkJCQkgICBpZiAoIHkgPT0gMC4wICkKCQkJCQkgIHB1dHMoIioqKiBlcnJvcjogZGl2aXNvciBjYW5ub3QgYmUgMCIpOwoJCQkJfSB3aGlsZSAoeSA9PSAwLjApOwoJCQkJcHJpbnRmICgiLS0tLS0tLS1cblJFU1VMVDogJWcgLyAlZyA9ICVnIChxdW90aWVudCA9ICVnLCByZW1haW5kZXIgPSAlZylcbiIsCgkJCQkJeCwgeSwgeC95LCB0cnVuYyh4L3kpLCB5ICogbW9kZih4L3ksICZpbnRwYXJ0KSApOwoJCQl9CgkJCWJyZWFrOwoKCQkJY2FzZSAnNSc6CQkvLyA1LiBQRVJDRU5UQUdFCgkJCWNhc2UgJyUnOgoJCQkJcHV0cygiXG5QZXJjZW50YWdlXG4tLS0tLS0tLS0tIik7CgkJCQludW1fYXNrdXNlcigiTnVtYmVyOiAiLCAmeCwgTUFYU0xFTl9MSU5FQlVGKTsKCQkJCXByaW50ZiAoIi0tLS0tLS0tLS1cblJFU1VMVDogJWclJSA9ICVnXG4iLCB4LCB4LzEwMCk7CgkJCWJyZWFrOwoKCQkJY2FzZSAnNic6CQkvLyA2LiBQT1dFUgoJCQljYXNlICdeJzoKCQkJCXB1dHMoIlxuUG93ZXJcbi0tLS0tIik7CgkJCQludW1fYXNrdXNlcigiQmFzZSAgICA6ICIsICZ4LCBNQVhTTEVOX0xJTkVCVUYpOwoJCQkJbnVtX2Fza3VzZXIoIkV4cG9uZW50OiAiLCAmeSwgTUFYU0xFTl9MSU5FQlVGKTsKCQkJCXByaW50ZiAoIi0tLS0tXG5SRVNVTFQ6ICVnIF4gJWcgPSAlZ1xuIiwgeCwgeSwgcG93KHgsIHkpKTsKCQkJYnJlYWs7CgoJCQljYXNlICc3JzoJCS8vIDcuIFNRVUFSRSBST09UCgkJCQlwdXRzKCJcblNxdWFyZSBSb290XG4tLS0tLS0tLS0tLSIpOwoJCQkJbnVtX2Fza3VzZXIoIk51bWJlcjogIiwgJngsIE1BWFNMRU5fTElORUJVRik7CgkJCQlwcmludGYgKCItLS0tLS0tLS0tLVxuUkVTVUxUOiBzcXJ0KCVnKSA9ICVnXG4iLCB4LCBzcXJ0KHgpICk7CgkJCWJyZWFrOwoKCQkJY2FzZSAnOCc6CQkvLyA4LiBFWElUCgkJCWNhc2UgJ3gnOgoJCQkJc3RvcCA9IFRSVUU7CgkJCWJyZWFrOwoKCQkJZGVmYXVsdDoJCS8vIEFMTCBPVEhFUiBDSE9JQ0VTCgkJCQlwdXRzKCIqKiogZXJyb3I6IGludmFsaWQgY2hvaWNlLCB0cnkgYWdhaW4uLi4iKTsKCQkJYnJlYWs7CgkJfQkvLyBzd2l0Y2gKCgl9IHdoaWxlICggIXN0b3AgKTsKCglleGl0KCAwICk7Cn0K