1
/* mpitest.c - test the mpi functions
2
* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4
* This is an RPN calculator; values must be given in hex.
5
* Operation is like dc(1) except that the input/output radix is
6
* always 16 and you can use a '-' to prefix a negative number.
7
* Addition operators: ++ and --. All operators must be delimited by a blank
10
* This file is part of GnuPG.
12
* GnuPG is free software; you can redistribute it and/or modify
13
* it under the terms of the GNU General Public License as published by
14
* the Free Software Foundation; either version 2 of the License, or
15
* (at your option) any later version.
17
* GnuPG is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* You should have received a copy of the GNU General Public License
23
* along with this program; if not, write to the Free Software
24
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
37
static MPI stack[STACKSIZE];
47
case 0: p = "mpicalc - v" VERSION "; "
48
"Copyright 1997 Werner Koch (dd9jn)" ; break;
49
case 13: p = "mpicalc"; break;
50
case 14: p = VERSION; break;
52
case 11: p = "Usage: mpicalc (-h for help)";
56
"\nSyntax: mpicalc [options] [files]\n"
57
"MPI RPN calculator\n";
59
default: p = default_strusage(level);
69
#ifdef HAVE_LC_MESSAGES
70
setlocale( LC_MESSAGES, "" );
72
setlocale( LC_ALL, "" );
74
bindtextdomain( PACKAGE, G10_LOCALEDIR );
75
textdomain( PACKAGE );
84
fputs("stack underflow\n",stderr);
87
mpi_add( stack[stackidx-2], stack[stackidx-2], stack[stackidx-1] );
95
fputs("stack underflow\n", stderr);
98
mpi_sub( stack[stackidx-2], stack[stackidx-2], stack[stackidx-1] );
106
fputs("stack underflow\n", stderr);
109
mpi_add_ui( stack[stackidx-1], stack[stackidx-1], 1 );
116
fputs("stack underflow\n", stderr);
119
/* mpi_sub_ui( stack[stackidx-1], stack[stackidx-1], 1 ); */
126
fputs("stack underflow\n", stderr);
129
mpi_mul( stack[stackidx-2], stack[stackidx-2], stack[stackidx-1] );
137
fputs("stack underflow\n", stderr);
140
mpi_mulm( stack[stackidx-3], stack[stackidx-3],
141
stack[stackidx-2], stack[stackidx-1] );
149
fputs("stack underflow\n", stderr);
152
mpi_fdiv_q( stack[stackidx-2], stack[stackidx-2], stack[stackidx-1] );
160
fputs("stack underflow\n", stderr);
163
mpi_fdiv_r( stack[stackidx-2], stack[stackidx-2], stack[stackidx-1] );
172
fputs("stack underflow\n", stderr);
176
mpi_powm( a, stack[stackidx-3], stack[stackidx-2], stack[stackidx-1] );
177
mpi_free(stack[stackidx-3]);
178
stack[stackidx-3] = a;
185
MPI a = mpi_alloc(40);
187
fputs("stack underflow\n", stderr);
190
mpi_invm( a, stack[stackidx-2], stack[stackidx-1] );
191
mpi_set(stack[stackidx-2],a);
199
MPI a = mpi_alloc(40);
201
fputs("stack underflow\n", stderr);
204
mpi_gcd( a, stack[stackidx-2], stack[stackidx-1] );
205
mpi_set(stack[stackidx-2],a);
214
fputs("stack underflow\n", stderr);
217
mpi_rshift( stack[stackidx-1],stack[stackidx-1], 1 );
222
main(int argc, char **argv)
224
static ARGPARSE_OPTS opts[] = {
237
while( arg_parse( &pargs, opts) ) {
238
switch( pargs.r_opt ) {
239
default : pargs.err = 2; break;
246
for(i=0; i < STACKSIZE; i++ )
250
while( (c=getc(stdin)) != EOF ) {
251
if( !state ) { /* waiting */
259
else if( isspace(c) )
264
if( (c=getc(stdin)) == '+' )
272
if( (c=getc(stdin)) == '-' )
274
else if( isdigit(c) || (c >='A' && c <= 'F') ) {
311
case 'i': /* dummy */
313
fputs("stack underflow\n", stderr);
315
mpi_free(stack[stackidx-1]);
319
case 'd': /* duplicate the tos */
321
fputs("stack underflow\n", stderr);
322
else if( stackidx < STACKSIZE ) {
323
mpi_free(stack[stackidx]);
324
stack[stackidx] = mpi_copy( stack[stackidx-1] );
328
fputs("stack overflow\n", stderr);
331
for(i=0; i < stackidx; i++ )
332
mpi_free(stack[i]), stack[i] = NULL;
335
case 'p': /* print the tos */
337
puts("stack is empty");
339
mpi_print(stdout, stack[stackidx-1], 1 );
343
case 'f': /* print the stack */
344
for( i = stackidx-1 ; i >= 0; i-- ) {
345
printf("[%2d]: ", i );
346
mpi_print(stdout, stack[i], 1 );
351
fputs("invalid operator\n", stderr);
355
else if( state == 1 ) { /* in a number */
356
if( !isxdigit(c) ) { /* store the number */
362
if( stackidx < STACKSIZE ) {
363
if( !stack[stackidx] )
364
stack[stackidx] = mpi_alloc(10);
365
if( mpi_fromstr(stack[stackidx], strbuf) )
366
fputs("invalid number\n", stderr);
371
fputs("stack overflow\n", stderr);
373
else { /* store digit */
375
strbuf[stridx++] = c;
376
else if( stridx == 999 ) {
378
fputs("string too large - truncated\n", stderr);
385
for(i=0; i < stackidx; i++ )